@memberjunction/ai-vector-sync 2.3.2 → 2.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +0 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +12 -12
package/dist/index.d.ts
CHANGED
|
@@ -1410,7 +1410,6 @@ declare class AIModelEntity extends BaseEntity<AIModelEntityType> {
|
|
|
1410
1410
|
* * Field Name: ModelSelectionInsights
|
|
1411
1411
|
* * Display Name: Model Selection Insights
|
|
1412
1412
|
* * SQL Data Type: nvarchar(MAX)
|
|
1413
|
-
* * Default Value: null
|
|
1414
1413
|
* * Description: This column stores unstructured text notes that provide insights into what the model is particularly good at and areas where it may not perform as well. These notes can be used by a human or an AI to determine if the model is a good fit for various purposes.
|
|
1415
1414
|
*/
|
|
1416
1415
|
get ModelSelectionInsights(): string | null;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var B=Object.defineProperty;var f=(I,e)=>B(I,"name",{value:e,configurable:!0});var V=require("@memberjunction/ai"),K=require("@memberjunction/ai-vectordb"),O=require("@memberjunction/ai-vectors"),u=require("@memberjunction/core"),R=require("@memberjunction/global"),U=require("node:stream/promises"),b=require("node:stream"),q=require("node:worker_threads"),F=require("node:path"),k=require("@memberjunction/aiengine"),C=require("@memberjunction/templates");const z="JONATHAN - FIX THIS TO USE BaseEngine DERVIED SUB-CLASS";class G extends b.Transform{static{f(this,"BatchWorker")}_batchSize=10;_workerFile="./worker.js";_workerContext={};_concurrencyLimit=4;_running=0;_buffer=[];_queue=[];_contextUser=void 0;constructor(e={}){super({objectMode:!0}),this._batchSize=e.batchSize??this._batchSize,this._workerFile=e.workerFile??this._workerFile,this._workerContext=e.workerContext??this._workerContext,this._concurrencyLimit=e.concurrencyLimit??this._concurrencyLimit,this._contextUser=e.contextUser??this._contextUser}_next(){if(this._queue.length>0&&this._running<this._concurrencyLimit){const e=this._queue.shift();e&&e().then(()=>this._next())}}_enqueue(e){this._queue.push(e),this._next()}async _transform(e,t,r){if(this._buffer.push(e),this._buffer.length>=this._batchSize){const n=this._buffer.splice(0,this._batchSize);this._enqueue(()=>this._processBatchInWorker(n).then(()=>r()).catch(r))}else r()}async _flush(e){this._buffer.length>0&&this._enqueue(()=>this._processBatchInWorker(this._buffer)),Promise.all(this._queue).then(()=>e()).catch(e)}_processBatchInWorker(e){return new Promise((t,r)=>{this._running++;const n=new q.Worker(this._workerFile,{workerData:{batch:e,context:this._workerContext}});n.on("message",({batch:a})=>{a.forEach(s=>this.push(s)),this._running--,t()}),n.on("error",a=>{this._running--,r(a)})})}}class p{static{f(this,"EntityDocumentCache")}static _instance;_loaded=!1;_cache={};_typeCache={};_contextUser=null;constructor(){this._cache={},this._typeCache={}}static get Instance(){return p._instance||(p._instance=new p),p._instance}get IsLoaded(){return this._loaded}Cache(){return this._cache}TypeCache(){return this._typeCache}GetDocument(e){let t=this._cache[e];return t||u.LogStatus(`EntityDocumentCache.GetDocument: Cache miss for EntityDocumentID: ${e}`),t||null}GetFirstActiveDocumentForEntityByID(e){let t=this.GetDocumentTypeByName("Record Duplicate");return t?Object.values(this._cache).find(r=>{r.EntityID===e&&r.Status==="Active"&&(r.TypeID,t.ID)}):null}GetFirstActiveDocumentForEntityByName(e){let t=this.GetDocumentTypeByName("Record Duplicate");return t?Object.values(this._cache).find(r=>{r.Entity===e&&r.Status==="Active"&&(r.TypeID,t.ID)}):null}GetDocumentByName(e){const t=e.trim().toLowerCase();let r=Object.values(this._cache).find(n=>{n.Name.trim().toLowerCase()});return r||u.LogStatus(`EntityDocumentCache.GetDocumentByName: Cache miss for EntityDocumentName: ${e}`),r||null}GetDocumentType(e){let t=this._typeCache[e];return t||(u.LogStatus(`EntityDocumentCache.GetDocument: Cache miss for EntityDocumentID: ${e}`),null)}GetDocumentTypeByName(e){const t=e.trim().toLowerCase();let r=Object.values(this._typeCache).find(n=>n.Name.trim().toLowerCase()===t);return r||(u.LogStatus(`EntityDocumentCache.GetDocumentByName: Cache miss for EntityDocumentName: ${e}`),null)}SetCurrentUser(e){this._contextUser=e}async Refresh(e,t){if(!e&&this._loaded)return;u.LogStatus("Refreshing Entity Document Cache"),this._cache={},this._typeCache={};const n=await new u.RunView().RunViews([{EntityName:"Entity Documents",ResultType:"entity_object"},{EntityName:"Entity Document Types",ResultType:"entity_object"}],t||this._contextUser);if(n[0]&&n[0].Success)for(const a of n[0].Results)this._cache[a.ID]=a;if(n[1]&&n[1].Success)for(const a of n[1].Results)this._typeCache[a.ID]=a;this._loaded=!0}}class W extends b.Readable{static{f(this,"PagedRecords")}constructor(){super({objectMode:!0})}_read(){}addPage(e){e.forEach(t=>this.push(t))}endStream(){this.push(null)}}class j extends O.VectorBase{static{f(this,"EntityVectorSyncer")}_startTime;_endTime;constructor(){super()}async Config(e,t){super.CurrentUser=t,await p.Instance.Refresh(e,t),await k.AIEngine.Instance.Config(e,t),await C.TemplateEngineServer.Instance.Config(e,t)}async VectorizeEntity(e,t){if(!t)throw new Error("ContextUser is required to vectorize the entity");const r=250,n=new Date().getTime();super.CurrentUser=t,await C.TemplateEngineServer.Instance.Config(!1,t);const a=await this.GetEntityDocument(e.entityDocumentID),s=await this.GetOrCreateVectorIndex(a),o=await this.GetVectorDatabaseAndEmbeddingClassByEntityDocumentID(e.entityDocumentID),i=new u.Metadata().Entities.find(E=>E.ID===e.entityID);if(!i)throw new Error(`Entity with ID ${e.entityID} not found.`);const l=C.TemplateEngineServer.Instance.Templates.find(E=>E.ID===a.TemplateID);if(!l)throw new Error(`Template not found with ID ${a.TemplateID}`);if(l.Content.length===0)throw new Error(`Template ${l.ID} does not have an associated Template Content record`);if(l.Content.length>1)throw new Error("Templates used by Entity Documents should only have one associated Template Content record.");this.ValidateTemplateContextParamAlignment(l);const d=e.batchCount||20,y=new W;let m={...l.GetAll(),Params:l.Params.map(E=>E.To())};const D={executionId:Date.now(),entity:i,entityDocument:a.To(),template:m,templateContent:l.Content[0].To(),vectorDBClassKey:o.vectorDBClassKey,vectorDBAPIKey:o.vectorDBAPIKey,embeddingDriverClass:o.embeddingDriverClass,embeddingAPIKey:o.embeddingAPIKey,delayTimeMS:r},h=new G({workerFile:F.resolve(__dirname,"workers/VectorizeTemplates.js"),batchSize:3,concurrencyLimit:2,contextUser:super.CurrentUser,workerContext:D}),N=new G({workerFile:F.resolve(__dirname,"workers/UpsertVectors.js"),batchSize:4,contextUser:super.CurrentUser,workerContext:D}),v=new b.Transform({objectMode:!0,transform:(E,S,_)=>{this.UpsertEntityRecordDocumentRecords(E,super.CurrentUser).then(()=>_(null)).catch(_)}});f(async()=>{let E=0,S=!0;for(;S;){let _={EntityID:e.entityID,PageNumber:E,PageSize:d,ResultType:"simple"};const P=await super.PageRecordsByEntityID(_),M=await this.GetRelatedTemplateDataForBatch(i,P,l),L=[];for(const A of P){const T=await this.GetTemplateData(i,A,l,M);T.__mj_recordID=A[i.FirstPrimaryKey.Name],T.__mj_compositeKey=i.PrimaryKeys.map(x=>`${x.Name}|${A[x.Name]}`).join("||"),T.VectorIndexID=s.ID,T.TemplateContent=l.Content[0].TemplateText,L.push(T)}if(y.addPage(L),P.length<d){S=!1;break}E++}y.endStream()},"getData")(),console.log("Starting pipeline"),await U.pipeline(y,h,N,v,new b.PassThrough({objectMode:!0}));const w=new Date().getTime();return u.LogStatus(`Finished vectorizing ${a.Entity} entity in ${w-n} ms`),null}async CreateDefaultEntityDocument(e,t,r){const n=new u.Metadata,a=n.Entities.find(i=>i.ID===e);if(!a)throw new Error(`Entity with ID ${e} not found.`);const s=a.Fields.map(i=>`${i.Name}: \${${i.Name}}`).join(" "),o=await n.GetEntityObject("Entity Documents");if(o.NewRecord(),o.Name=`Default duplicate record Entity Document for the ${a.Name} entity using vector database ${t.Name} and AI Model ${r.Name}`,o.EntityID=e,o.TypeID=z,o.Status="Active",o.TemplateID=s,o.VectorDatabaseID=t.ID,o.AIModelID=r.ID,await this.SaveEntity(o))return o;throw new Error(`Failed to save Entity Document for ${e}`)}async GetVectorDatabaseAndEmbeddingClassByEntityDocumentID(e,t){let r=p.Instance.GetDocument(e);if(!r)if(t){u.LogStatus(`No active Entity Document found for entity ${e}, creating one`);const d=this.GetVectorDatabase(),y=this.GetAIModel();r=await this.CreateDefaultEntityDocument(e,d,y)}else throw new Error(`No Entity Document found for ID=${e}`);const n=this.GetVectorDatabase(r.VectorDatabaseID),a=this.GetAIModel(r.AIModelID),s=V.GetAIAPIKey(a.DriverClass),o=V.GetAIAPIKey(n.ClassKey);if(!s)throw Error(`No API Key found for AI Model ${a.DriverClass}`);if(!o)throw Error(`No API Key found for Vector Database ${n.ClassKey}`);const c=R.MJGlobal.Instance.ClassFactory.CreateInstance(V.Embeddings,a.DriverClass,s),i=R.MJGlobal.Instance.ClassFactory.CreateInstance(K.VectorDBBase,n.ClassKey,o);if(!c)throw Error(`Failed to create Embeddings instance for AI Model ${a.DriverClass}`);if(!i)throw Error(`Failed to create Vector Database instance for ${n.ClassKey}`);return u.LogStatus(`Using vector database ${n.Name} and AI Model ${a.Name}`),{embedding:c,vectorDB:i,vectorDBClassKey:n.ClassKey,vectorDBAPIKey:o,embeddingDriverClass:a.DriverClass,embeddingAPIKey:s}}async GetEntityDocument(e){const t=p.Instance;return t.IsLoaded||await t.Refresh(!1,super.CurrentUser),t.GetDocument(e)}async GetEntityDocumentByName(e,t){const r=p.Instance;return r.IsLoaded||await r.Refresh(!1,t),r.GetDocumentByName(e)}async GetActiveEntityDocuments(e){await p.Instance.Refresh(!1,super.CurrentUser);const t=p.Instance.GetDocumentTypeByName("Record Duplicate");if(!t)throw new Error("Entity Document Type not found");let r=`TypeID = '${t.ID}' AND Status = 'Active' `;e&&e.length>0&&(r+=` AND Entity IN (${e.map(o=>`'${o}'`).join(",")})`);const n=await super.RunView.RunView({EntityName:"Entity Documents",ExtraFilter:r,ResultType:"entity_object"},super.CurrentUser);if(!n.Success)throw new Error(n.ErrorMessage);let a=[],s=[];for(const o of n.Results)s.includes(o.EntityID)||(a.push(o),s.push(o.EntityID));return a}async GetOrCreateVectorIndex(e){let t=await super.RunViewForSingleValue("Vector Indexes",`VectorDatabaseID = '${e.VectorDatabaseID}' AND EmbeddingModelID = '${e.AIModelID}'`);if(t)return t;u.LogStatus(`No Vector Index found for entityDocument ${e.ID}, creating one`);try{return t=await super.Metadata.GetEntityObject("Vector Indexes"),t.NewRecord(),t.VectorDatabaseID=e.VectorDatabaseID,t.EmbeddingModelID=e.AIModelID,t.Name=`Vector Index for entityDocument ${e.EntityID}`,t.Set("EntityRecordUpdatedAt",new Date),t.Set("EntityDocumentID",e.ID),t.Description=`Vector Index that uses the Vector database ${e.VectorDatabaseID} and ${e.AIModelID} as the embedding model`,await super.SaveEntity(t)?(u.LogStatus("Successfully created new Vector Index Entity"),t):(u.LogError("Error saving Vector Index Entity"),null)}catch(r){return console.error(JSON.stringify(r)),u.LogError(r),null}}async CreateTemplateForEntityDocument(e){const t=await super.Metadata.GetEntityObject("Templates");if(t.NewRecord(),t.Name=`Template for EntityDocument ${e.EntityID}`,t.Description=`The template used by EntityDocument ${e.ID}`,t.UserID=super.CurrentUser.ID,t.IsActive=!0,t.CategoryID=null,!await super.SaveEntity(t))throw u.LogError("Error saving Template Entity",void 0,t.LatestResult),new Error(t.LatestResult.Message);u.LogStatus(`Successfully created new Template Entity ${t.ID}`),await C.TemplateEngineServer.Instance.Config(!1,super.CurrentUser);const n=C.TemplateEngineServer.Instance.TemplateContentTypes.find(l=>l.Name==="Text");if(!n)throw new Error("Text template content type not found");const a=await this.GetEntityFieldsForSimilaritySearch(e.EntityID),s=await super.Metadata.GetEntityObject("Template Contents");if(s.NewRecord(),s.TemplateID=t.ID,s.TypeID=n.ID,s.Priority=1,s.IsActive=!0,s.TemplateText=this.BuildTemplateContent(a),!await super.SaveEntity(s))throw u.LogError("Error saving Template Entity",void 0,s.LatestResult),new Error(s.LatestResult.Message);u.LogStatus(`Successfully created new Template Content Entity ${s.ID}`);const c=await super.Metadata.GetEntityObject("Template Params");if(c.NewRecord(),c.TemplateID=t.ID,c.Name="Entity",c.Description="The entity object to be used in the template",c.Type="Record",c.DefaultValue=null,c.IsRequired=!0,c.LinkedParameterName=null,c.LinkedParameterField=null,c.ExtraFilter=null,c.EntityID=e.EntityID,c.RecordID=null,!await super.SaveEntity(c))throw u.LogError("Error saving Template Entity",void 0,c.LatestResult),new Error(c.LatestResult.Message);return u.LogStatus(`Successfully created new Template Param Entity ${c.ID}`),t.Content.push(s),t.Params.push(c),C.TemplateEngineServer.Instance.AddTemplate(t),t}BuildTemplateContent(e){return e.map(t=>`{{Entity.${t.Name}}}`).join(" ")}async GetEntityFieldsForSimilaritySearch(e){const t=await super.RunView.RunView({EntityName:"Entity Fields",ExtraFilter:`EntityID = '${e}' AND IsPrimaryKey = 0 AND IsUnique = 0 AND AutoIncrement = 0 and Type NOT IN ('datetimeoffset', 'datetime')`,ResultType:"entity_object"},super.CurrentUser);if(!t.Success)throw new Error(t.ErrorMessage);return t.Results}async GetTemplateData(e,t,r,n){const a={};for(const s of r.Params)if(!a[s.Name])switch(s.Type){case"Record":a[s.Name]=t;break;case"Entity":const o=n.find(c=>c.ParamName===s.Name);if(!o){u.LogError(`No related data found for param ${s.Name} in template ${r.ID}`);break}a[s.Name]=o.Data.filter(c=>c[s.LinkedParameterField]===t[e.FirstPrimaryKey.Name]);break;case"Array":case"Scalar":case"Object":u.LogError(`Unsupported parameter type ${s.Type} for parameter ${s.Name} in template ${r.ID}`);break}return a}async GetRelatedTemplateDataForBatch(e,t,r){const n=[];for(const a of r.Params){if(a.Type!=="Entity")continue;const s=a.Entity,o=a.LinkedParameterField,c=e.FirstPrimaryKey.NeedsQuotes?"'":"",i=`${o} in (${t.map(y=>`${c}${y[e.FirstPrimaryKey.Name]}${c}`).join(",")})`,l=a.ExtraFilter?`(${i}) AND (${a.ExtraFilter})`:i,d=await super.RunView.RunView({EntityName:s,ExtraFilter:l,ResultType:"simple"},super.CurrentUser);if(d&&d.Success){const y={ParamName:"",Data:[]};y.ParamName=a.Name,y.Data=d.Results,n.push(y)}else u.LogError(`Error getting related data for entity ${s} with filter ${l}`,void 0,d.ErrorMessage)}return n}async UpsertEntityRecordDocumentRecords(e,t){let r=super.Metadata,n=super.RunView,a=!0,s=await r.GetEntityObject("Vector Indexes",t),o=e.VectorIndexID.toString();if(!await s.Load(o)){u.LogError(`Vector Index with ID ${e.VectorIndexID} not found`);return}let i=e.EntityDocument,l=i.EntityID,d=[];const y=await n.RunView({EntityName:"Entity Record Documents",ExtraFilter:`EntityID = '${l}' AND EntityDocumentID = '${i.ID}' AND RecordID in (${e.__mj_recordID})`,ResultType:"entity_object"},t);y.Success?d=y.Results:u.LogError("Error getting existing Entity Record Documents",void 0,y.ErrorMessage);let m=d.find(h=>h.Get("RecordID").toString()===e.__mj_recordID.toString());m||(m=await r.GetEntityObject("Entity Record Documents",t),m.NewRecord()),m.Set("EntityID",l.toString()),m.Set("RecordID",e.__mj_recordID.toString()),m.Set("DocumentText",e.TemplateContent),m.Set("VectorID",e.VectorID.toString()),m.Set("VectorJSON",JSON.stringify(e.Vector)),m.Set("VectorIndexID",e.VectorIndexID.toString()),m.Set("EntityRecordUpdatedAt",new Date),m.Set("EntityDocumentID",e.EntityDocument.ID.toString()),m.ContextCurrentUser=t,await m.Save()||(u.LogError("Error saving Entity Record Document Entity",void 0,m.LatestResult),a=!1),a?u.LogStatus("Upserting Entity Record Documents: Complete"):u.LogError("Upserting Entity Record Documents: Fail")}ValidateTemplateContextParamAlignment(e){const t={};for(const r of e.Params){const n=t[r.Name];if(n&&n.Type!==r.Type)throw new Error(`Parameter ${n.Name} has different types in different templates`);t[r.Name]=r}return!0}}class g{static{f(this,"EntityDocumentTemplateParserBase")}static ClearCache(){g.__cache={}}static CreateCacheKey(e,t,r){return`${e}___${t}___${r}`}static __cache={};static get _cache(){return g.__cache}async Parse(e,t,r,n){if(!n)throw new Error("ContextUser is required to parse the template");const s=new u.Metadata().Entities.find(m=>m.ID===t);if(!s)throw new Error(`Entity with ID ${t} not found.`);let o=new u.CompositeKey;o.LoadFromEntityInfoAndRecord(s,r);const c=/\$\{([^{}]+)\}/g,i=e.matchAll(c),l=Array.from(i).map(async m=>{const D=m[1],h=g.CreateCacheKey(t,o.ToString(),D);return g._cache[h]||(g._cache[h]=await this.evalSingleArgument(D,t,r,n)),{old:m[0],new:g._cache[h]}}),d=await Promise.all(l);let y=e;return d.forEach(m=>{y=y.replace(m.old,m.new)}),y}async evalSingleArgument(e,t,r,n){const a=e.match(/(\w+)\(([^)]*)\)/);if(a){const[,s,o]=a,c=o.split(",").map(i=>(i=i.trim(),i.startsWith('"')&&i.endsWith('"')||i.startsWith("'")&&i.endsWith("'")?i.slice(1,-1):i));if(typeof this[s]=="function")return this[s](t,r,n,...c);throw new Error(`Function ${s} is not defined.`)}else return r[e]!==void 0?r[e]:""}}var J=Object.defineProperty,H=Object.getOwnPropertyDescriptor,Q=f((I,e,t,r)=>{for(var n=r>1?void 0:r?H(e,t):e,a=I.length-1,s;a>=0;a--)(s=I[a])&&(n=(r?s(e,t,n):s(n))||n);return r&&n&&J(e,t,n),n},"__decorateClass");exports.EntityDocumentTemplateParser=class extends g{static{f(this,"EntityDocumentTemplateParser")}static CreateInstance(){return R.MJGlobal.Instance.ClassFactory.CreateInstance(exports.EntityDocumentTemplateParser)}async Relationship(e,t,r,n,a,s){const o=new u.Metadata,c=new j;c.CurrentUser=r;const i=o.Entities.find(h=>h.ID===e);if(!i)throw new Error(`Entity with ID ${e} not found.`);const l=i.RelatedEntities.find(h=>h.RelatedEntity===n);if(!l)throw new Error(`Relationship ${n} not found for entity ${i.Name}`);const d=await o.GetEntityObject(i.Name,r);let y=new u.CompositeKey;if(y.LoadFromEntityInfoAndRecord(i,t),!await d.InnerLoad(y))return u.LogError(`Failed to load entity ${i.Name} with ID ${y.ToString()}`),"";const D=await d.GetRelatedEntityDataExt(l,null,a);if(D&&D.Data)if(s&&s.trim().length>0){const h=await c.GetEntityDocumentByName(s,r);if(h){const N=exports.EntityDocumentTemplateParser.CreateInstance(),v=10,$=[];for(let w=0;w<D.Data.length;w+=v){const E=D.Data.slice(w,w+v).map(_=>N.Parse(h.Template,l.RelatedEntityID,_,r)),S=await Promise.all(E);$.push(...S)}return $.map(w=>w+`
|
|
1
|
+
"use strict";var K=Object.defineProperty;var f=(w,e)=>K(w,"name",{value:e,configurable:!0});var A=require("@memberjunction/ai"),B=require("@memberjunction/ai-vectordb"),U=require("@memberjunction/ai-vectors"),u=require("@memberjunction/core"),S=require("@memberjunction/global"),q=require("node:stream/promises"),b=require("node:stream"),O=require("node:worker_threads"),F=require("node:path"),k=require("@memberjunction/aiengine"),C=require("@memberjunction/templates");class G extends b.Transform{static{f(this,"BatchWorker")}_batchSize=10;_workerFile="./worker.js";_workerContext={};_concurrencyLimit=4;_running=0;_buffer=[];_queue=[];_contextUser=void 0;constructor(e={}){super({objectMode:!0}),this._batchSize=e.batchSize??this._batchSize,this._workerFile=e.workerFile??this._workerFile,this._workerContext=e.workerContext??this._workerContext,this._concurrencyLimit=e.concurrencyLimit??this._concurrencyLimit,this._contextUser=e.contextUser??this._contextUser}_next(){if(this._queue.length>0&&this._running<this._concurrencyLimit){const e=this._queue.shift();e&&e().then(()=>this._next())}}_enqueue(e){this._queue.push(e),this._next()}async _transform(e,t,r){if(this._buffer.push(e),this._buffer.length>=this._batchSize){const n=this._buffer.splice(0,this._batchSize);this._enqueue(()=>this._processBatchInWorker(n).then(()=>r()).catch(r))}else r()}async _flush(e){this._buffer.length>0&&this._enqueue(()=>this._processBatchInWorker(this._buffer)),Promise.all(this._queue).then(()=>e()).catch(e)}_processBatchInWorker(e){return new Promise((t,r)=>{this._running++;const n=new O.Worker(this._workerFile,{workerData:{batch:e,context:this._workerContext}});n.on("message",({batch:a})=>{a.forEach(s=>this.push(s)),this._running--,t()}),n.on("error",a=>{this._running--,r(a)})})}}class E{static{f(this,"EntityDocumentCache")}static _instance;_loaded=!1;_cache={};_typeCache={};_contextUser=null;constructor(){this._cache={},this._typeCache={}}static get Instance(){return E._instance||(E._instance=new E),E._instance}get IsLoaded(){return this._loaded}Cache(){return this._cache}TypeCache(){return this._typeCache}GetDocument(e){let t=this._cache[e];return t||u.LogStatus(`EntityDocumentCache.GetDocument: Cache miss for EntityDocumentID: ${e}`),t||null}GetFirstActiveDocumentForEntityByID(e){let t=this.GetDocumentTypeByName("Record Duplicate");return t?Object.values(this._cache).find(r=>{r.EntityID===e&&r.Status==="Active"&&(r.TypeID,t.ID)}):null}GetFirstActiveDocumentForEntityByName(e){let t=this.GetDocumentTypeByName("Record Duplicate");return t?Object.values(this._cache).find(r=>{r.Entity===e&&r.Status==="Active"&&(r.TypeID,t.ID)}):null}GetDocumentByName(e){const t=e.trim().toLowerCase();let r=Object.values(this._cache).find(n=>{n.Name.trim().toLowerCase()});return r||u.LogStatus(`EntityDocumentCache.GetDocumentByName: Cache miss for EntityDocumentName: ${e}`),r||null}GetDocumentType(e){let t=this._typeCache[e];return t||(u.LogStatus(`EntityDocumentCache.GetDocument: Cache miss for EntityDocumentID: ${e}`),null)}GetDocumentTypeByName(e){const t=e.trim().toLowerCase();let r=Object.values(this._typeCache).find(n=>n.Name.trim().toLowerCase()===t);return r||(u.LogStatus(`EntityDocumentCache.GetDocumentByName: Cache miss for EntityDocumentName: ${e}`),null)}SetCurrentUser(e){this._contextUser=e}async Refresh(e,t){if(!e&&this._loaded)return;u.LogStatus("Refreshing Entity Document Cache"),this._cache={},this._typeCache={};const n=await new u.RunView().RunViews([{EntityName:"Entity Documents",ResultType:"entity_object"},{EntityName:"Entity Document Types",ResultType:"entity_object"}],t||this._contextUser);if(n[0]&&n[0].Success)for(const a of n[0].Results)this._cache[a.ID]=a;if(n[1]&&n[1].Success)for(const a of n[1].Results)this._typeCache[a.ID]=a;this._loaded=!0}}class z extends b.Readable{static{f(this,"PagedRecords")}constructor(){super({objectMode:!0})}_read(){}addPage(e){e.forEach(t=>this.push(t))}endStream(){this.push(null)}}class j extends U.VectorBase{static{f(this,"EntityVectorSyncer")}_startTime;_endTime;constructor(){super()}async Config(e,t){super.CurrentUser=t,await E.Instance.Refresh(e,t),await k.AIEngine.Instance.Config(e,t),await C.TemplateEngineServer.Instance.Config(e,t)}async VectorizeEntity(e,t){if(!t)throw new Error("ContextUser is required to vectorize the entity");const r=250,n=new Date().getTime();super.CurrentUser=t,await C.TemplateEngineServer.Instance.Config(!1,t);const a=await this.GetEntityDocument(e.entityDocumentID),s=await this.GetOrCreateVectorIndex(a),l=await this.GetVectorDatabaseAndEmbeddingClassByEntityDocumentID(e.entityDocumentID),i=new u.Metadata().Entities.find(p=>p.ID===e.entityID);if(!i)throw new Error(`Entity with ID ${e.entityID} not found.`);const c=C.TemplateEngineServer.Instance.Templates.find(p=>p.ID===a.TemplateID);if(!c)throw new Error(`Template not found with ID ${a.TemplateID}`);if(c.Content.length===0)throw new Error(`Template ${c.ID} does not have an associated Template Content record`);if(c.Content.length>1)throw new Error("Templates used by Entity Documents should only have one associated Template Content record.");this.ValidateTemplateContextParamAlignment(c);const d=e.batchCount||20,m=new z;let y={...c.GetAll(),Params:c.Params.map(p=>p.To())};const D={executionId:Date.now(),entity:i,entityDocument:a.To(),template:y,templateContent:c.Content[0].To(),vectorDBClassKey:l.vectorDBClassKey,vectorDBAPIKey:l.vectorDBAPIKey,embeddingDriverClass:l.embeddingDriverClass,embeddingAPIKey:l.embeddingAPIKey,delayTimeMS:r},h=new G({workerFile:F.resolve(__dirname,"workers/VectorizeTemplates.js"),batchSize:3,concurrencyLimit:2,contextUser:super.CurrentUser,workerContext:D}),N=new G({workerFile:F.resolve(__dirname,"workers/UpsertVectors.js"),batchSize:4,contextUser:super.CurrentUser,workerContext:D}),R=new b.Transform({objectMode:!0,transform:(p,v,_)=>{this.UpsertEntityRecordDocumentRecords(p,super.CurrentUser).then(()=>_(null)).catch(_)}});f(async()=>{let p=0,v=!0;for(;v;){let _={EntityID:e.entityID,PageNumber:p,PageSize:d,ResultType:"simple"};const V=await super.PageRecordsByEntityID(_),M=await this.GetRelatedTemplateDataForBatch(i,V,c),L=[];for(const P of V){const T=await this.GetTemplateData(i,P,c,M);T.__mj_recordID=P[i.FirstPrimaryKey.Name],T.__mj_compositeKey=i.PrimaryKeys.map(x=>`${x.Name}|${P[x.Name]}`).join("||"),T.VectorIndexID=s.ID,T.TemplateContent=c.Content[0].TemplateText,L.push(T)}if(m.addPage(L),V.length<d){v=!1;break}p++}m.endStream()},"getData")(),console.log("Starting pipeline"),await q.pipeline(m,h,N,R,new b.PassThrough({objectMode:!0}));const I=new Date().getTime();return u.LogStatus(`Finished vectorizing ${a.Entity} entity in ${I-n} ms`),null}async CreateDefaultEntityDocument(e,t,r){const n=new u.Metadata,a=n.Entities.find(m=>m.ID===e);if(!a)throw new Error(`Entity with ID ${e} not found.`);const s=a.Fields.map(m=>`${m.Name}: \${${m.Name}}`).join(" "),o=await new u.RunView().RunView({EntityName:"Entity Document Types",ExtraFilter:"Name = 'Record Duplicate'"},super.CurrentUser);if(!o.Success)throw new Error(`Unable to fetch Entity Document Type: ${o.ErrorMessage}`);if(o.Results.length===0)throw new Error("Record Duplicate Entity Document Type not found");const i=o.Results[0],c=await n.GetEntityObject("Entity Documents");if(c.NewRecord(),c.Name=`Default duplicate record Entity Document for the ${a.Name} entity using vector database ${t.Name} and AI Model ${r.Name}`,c.EntityID=e,c.TypeID=i.ID,c.Status="Active",c.TemplateID=s,c.VectorDatabaseID=t.ID,c.AIModelID=r.ID,await this.SaveEntity(c))return c;throw new Error(`Failed to save Entity Document for ${e}`)}async GetVectorDatabaseAndEmbeddingClassByEntityDocumentID(e,t){let r=E.Instance.GetDocument(e);if(!r)if(t){u.LogStatus(`No active Entity Document found for entity ${e}, creating one`);const d=this.GetVectorDatabase(),m=this.GetAIModel();r=await this.CreateDefaultEntityDocument(e,d,m)}else throw new Error(`No Entity Document found for ID=${e}`);const n=this.GetVectorDatabase(r.VectorDatabaseID),a=this.GetAIModel(r.AIModelID),s=A.GetAIAPIKey(a.DriverClass),l=A.GetAIAPIKey(n.ClassKey);if(!s)throw Error(`No API Key found for AI Model ${a.DriverClass}`);if(!l)throw Error(`No API Key found for Vector Database ${n.ClassKey}`);const o=S.MJGlobal.Instance.ClassFactory.CreateInstance(A.Embeddings,a.DriverClass,s),i=S.MJGlobal.Instance.ClassFactory.CreateInstance(B.VectorDBBase,n.ClassKey,l);if(!o)throw Error(`Failed to create Embeddings instance for AI Model ${a.DriverClass}`);if(!i)throw Error(`Failed to create Vector Database instance for ${n.ClassKey}`);return u.LogStatus(`Using vector database ${n.Name} and AI Model ${a.Name}`),{embedding:o,vectorDB:i,vectorDBClassKey:n.ClassKey,vectorDBAPIKey:l,embeddingDriverClass:a.DriverClass,embeddingAPIKey:s}}async GetEntityDocument(e){const t=E.Instance;return t.IsLoaded||await t.Refresh(!1,super.CurrentUser),t.GetDocument(e)}async GetEntityDocumentByName(e,t){const r=E.Instance;return r.IsLoaded||await r.Refresh(!1,t),r.GetDocumentByName(e)}async GetActiveEntityDocuments(e){await E.Instance.Refresh(!1,super.CurrentUser);const t=E.Instance.GetDocumentTypeByName("Record Duplicate");if(!t)throw new Error("Entity Document Type not found");let r=`TypeID = '${t.ID}' AND Status = 'Active' `;e&&e.length>0&&(r+=` AND Entity IN (${e.map(l=>`'${l}'`).join(",")})`);const n=await super.RunView.RunView({EntityName:"Entity Documents",ExtraFilter:r,ResultType:"entity_object"},super.CurrentUser);if(!n.Success)throw new Error(n.ErrorMessage);let a=[],s=[];for(const l of n.Results)s.includes(l.EntityID)||(a.push(l),s.push(l.EntityID));return a}async GetOrCreateVectorIndex(e){let t=await super.RunViewForSingleValue("Vector Indexes",`VectorDatabaseID = '${e.VectorDatabaseID}' AND EmbeddingModelID = '${e.AIModelID}'`);if(t)return t;u.LogStatus(`No Vector Index found for entityDocument ${e.ID}, creating one`);try{return t=await super.Metadata.GetEntityObject("Vector Indexes"),t.NewRecord(),t.VectorDatabaseID=e.VectorDatabaseID,t.EmbeddingModelID=e.AIModelID,t.Name=`Vector Index for entityDocument ${e.EntityID}`,t.Set("EntityRecordUpdatedAt",new Date),t.Set("EntityDocumentID",e.ID),t.Description=`Vector Index that uses the Vector database ${e.VectorDatabaseID} and ${e.AIModelID} as the embedding model`,await super.SaveEntity(t)?(u.LogStatus("Successfully created new Vector Index Entity"),t):(u.LogError("Error saving Vector Index Entity"),null)}catch(r){return console.error(JSON.stringify(r)),u.LogError(r),null}}async CreateTemplateForEntityDocument(e){const t=await super.Metadata.GetEntityObject("Templates");if(t.NewRecord(),t.Name=`Template for EntityDocument ${e.EntityID}`,t.Description=`The template used by EntityDocument ${e.ID}`,t.UserID=super.CurrentUser.ID,t.IsActive=!0,t.CategoryID=null,!await super.SaveEntity(t))throw u.LogError("Error saving Template Entity",void 0,t.LatestResult),new Error(t.LatestResult.Message);u.LogStatus(`Successfully created new Template Entity ${t.ID}`),await C.TemplateEngineServer.Instance.Config(!1,super.CurrentUser);const n=C.TemplateEngineServer.Instance.TemplateContentTypes.find(c=>c.Name==="Text");if(!n)throw new Error("Text template content type not found");const a=await this.GetEntityFieldsForSimilaritySearch(e.EntityID),s=await super.Metadata.GetEntityObject("Template Contents");if(s.NewRecord(),s.TemplateID=t.ID,s.TypeID=n.ID,s.Priority=1,s.IsActive=!0,s.TemplateText=this.BuildTemplateContent(a),!await super.SaveEntity(s))throw u.LogError("Error saving Template Entity",void 0,s.LatestResult),new Error(s.LatestResult.Message);u.LogStatus(`Successfully created new Template Content Entity ${s.ID}`);const o=await super.Metadata.GetEntityObject("Template Params");if(o.NewRecord(),o.TemplateID=t.ID,o.Name="Entity",o.Description="The entity object to be used in the template",o.Type="Record",o.DefaultValue=null,o.IsRequired=!0,o.LinkedParameterName=null,o.LinkedParameterField=null,o.ExtraFilter=null,o.EntityID=e.EntityID,o.RecordID=null,!await super.SaveEntity(o))throw u.LogError("Error saving Template Entity",void 0,o.LatestResult),new Error(o.LatestResult.Message);return u.LogStatus(`Successfully created new Template Param Entity ${o.ID}`),t.Content.push(s),t.Params.push(o),C.TemplateEngineServer.Instance.AddTemplate(t),t}BuildTemplateContent(e){return e.map(t=>`{{Entity.${t.Name}}}`).join(" ")}async GetEntityFieldsForSimilaritySearch(e){const t=await super.RunView.RunView({EntityName:"Entity Fields",ExtraFilter:`EntityID = '${e}' AND IsPrimaryKey = 0 AND IsUnique = 0 AND AutoIncrement = 0 and Type NOT IN ('datetimeoffset', 'datetime')`,ResultType:"entity_object"},super.CurrentUser);if(!t.Success)throw new Error(t.ErrorMessage);return t.Results}async GetTemplateData(e,t,r,n){const a={};for(const s of r.Params)if(!a[s.Name])switch(s.Type){case"Record":a[s.Name]=t;break;case"Entity":const l=n.find(o=>o.ParamName===s.Name);if(!l){u.LogError(`No related data found for param ${s.Name} in template ${r.ID}`);break}a[s.Name]=l.Data.filter(o=>o[s.LinkedParameterField]===t[e.FirstPrimaryKey.Name]);break;case"Array":case"Scalar":case"Object":u.LogError(`Unsupported parameter type ${s.Type} for parameter ${s.Name} in template ${r.ID}`);break}return a}async GetRelatedTemplateDataForBatch(e,t,r){const n=[];for(const a of r.Params){if(a.Type!=="Entity")continue;const s=a.Entity,l=a.LinkedParameterField,o=e.FirstPrimaryKey.NeedsQuotes?"'":"",i=`${l} in (${t.map(m=>`${o}${m[e.FirstPrimaryKey.Name]}${o}`).join(",")})`,c=a.ExtraFilter?`(${i}) AND (${a.ExtraFilter})`:i,d=await super.RunView.RunView({EntityName:s,ExtraFilter:c,ResultType:"simple"},super.CurrentUser);if(d&&d.Success){const m={ParamName:"",Data:[]};m.ParamName=a.Name,m.Data=d.Results,n.push(m)}else u.LogError(`Error getting related data for entity ${s} with filter ${c}`,void 0,d.ErrorMessage)}return n}async UpsertEntityRecordDocumentRecords(e,t){let r=super.Metadata,n=super.RunView,a=!0,s=await r.GetEntityObject("Vector Indexes",t),l=e.VectorIndexID.toString();if(!await s.Load(l)){u.LogError(`Vector Index with ID ${e.VectorIndexID} not found`);return}let i=e.EntityDocument,c=i.EntityID,d=[];const m=await n.RunView({EntityName:"Entity Record Documents",ExtraFilter:`EntityID = '${c}' AND EntityDocumentID = '${i.ID}' AND RecordID in (${e.__mj_recordID})`,ResultType:"entity_object"},t);m.Success?d=m.Results:u.LogError("Error getting existing Entity Record Documents",void 0,m.ErrorMessage);let y=d.find(h=>h.Get("RecordID").toString()===e.__mj_recordID.toString());y||(y=await r.GetEntityObject("Entity Record Documents",t),y.NewRecord()),y.Set("EntityID",c.toString()),y.Set("RecordID",e.__mj_recordID.toString()),y.Set("DocumentText",e.TemplateContent),y.Set("VectorID",e.VectorID.toString()),y.Set("VectorJSON",JSON.stringify(e.Vector)),y.Set("VectorIndexID",e.VectorIndexID.toString()),y.Set("EntityRecordUpdatedAt",new Date),y.Set("EntityDocumentID",e.EntityDocument.ID.toString()),y.ContextCurrentUser=t,await y.Save()||(u.LogError("Error saving Entity Record Document Entity",void 0,y.LatestResult),a=!1),a?u.LogStatus("Upserting Entity Record Documents: Complete"):u.LogError("Upserting Entity Record Documents: Fail")}ValidateTemplateContextParamAlignment(e){const t={};for(const r of e.Params){const n=t[r.Name];if(n&&n.Type!==r.Type)throw new Error(`Parameter ${n.Name} has different types in different templates`);t[r.Name]=r}return!0}}class g{static{f(this,"EntityDocumentTemplateParserBase")}static ClearCache(){g.__cache={}}static CreateCacheKey(e,t,r){return`${e}___${t}___${r}`}static __cache={};static get _cache(){return g.__cache}async Parse(e,t,r,n){if(!n)throw new Error("ContextUser is required to parse the template");const s=new u.Metadata().Entities.find(y=>y.ID===t);if(!s)throw new Error(`Entity with ID ${t} not found.`);let l=new u.CompositeKey;l.LoadFromEntityInfoAndRecord(s,r);const o=/\$\{([^{}]+)\}/g,i=e.matchAll(o),c=Array.from(i).map(async y=>{const D=y[1],h=g.CreateCacheKey(t,l.ToString(),D);return g._cache[h]||(g._cache[h]=await this.evalSingleArgument(D,t,r,n)),{old:y[0],new:g._cache[h]}}),d=await Promise.all(c);let m=e;return d.forEach(y=>{m=m.replace(y.old,y.new)}),m}async evalSingleArgument(e,t,r,n){const a=e.match(/(\w+)\(([^)]*)\)/);if(a){const[,s,l]=a,o=l.split(",").map(i=>(i=i.trim(),i.startsWith('"')&&i.endsWith('"')||i.startsWith("'")&&i.endsWith("'")?i.slice(1,-1):i));if(typeof this[s]=="function")return this[s](t,r,n,...o);throw new Error(`Function ${s} is not defined.`)}else return r[e]!==void 0?r[e]:""}}var W=Object.defineProperty,J=Object.getOwnPropertyDescriptor,Q=f((w,e,t,r)=>{for(var n=r>1?void 0:r?J(e,t):e,a=w.length-1,s;a>=0;a--)(s=w[a])&&(n=(r?s(e,t,n):s(n))||n);return r&&n&&W(e,t,n),n},"__decorateClass");exports.EntityDocumentTemplateParser=class extends g{static{f(this,"EntityDocumentTemplateParser")}static CreateInstance(){return S.MJGlobal.Instance.ClassFactory.CreateInstance(exports.EntityDocumentTemplateParser)}async Relationship(e,t,r,n,a,s){const l=new u.Metadata,o=new j;o.CurrentUser=r;const i=l.Entities.find(h=>h.ID===e);if(!i)throw new Error(`Entity with ID ${e} not found.`);const c=i.RelatedEntities.find(h=>h.RelatedEntity===n);if(!c)throw new Error(`Relationship ${n} not found for entity ${i.Name}`);const d=await l.GetEntityObject(i.Name,r);let m=new u.CompositeKey;if(m.LoadFromEntityInfoAndRecord(i,t),!await d.InnerLoad(m))return u.LogError(`Failed to load entity ${i.Name} with ID ${m.ToString()}`),"";const D=await d.GetRelatedEntityDataExt(c,null,a);if(D&&D.Data)if(s&&s.trim().length>0){const h=await o.GetEntityDocumentByName(s,r);if(h){const N=exports.EntityDocumentTemplateParser.CreateInstance(),R=10,$=[];for(let I=0;I<D.Data.length;I+=R){const p=D.Data.slice(I,I+R).map(_=>N.Parse(h.Template,c.RelatedEntityID,_,r)),v=await Promise.all(p);$.push(...v)}return $.map(I=>I+`
|
|
2
2
|
|
|
3
|
-
`).join("")}else return u.LogStatus(`Entity Document with name ${s} not found.`),""}else return JSON.stringify({Relationship:n,Data:D.Data});else return"{ No Data for: "+n+" }"}},exports.EntityDocumentTemplateParser=Q([
|
|
3
|
+
`).join("")}else return u.LogStatus(`Entity Document with name ${s} not found.`),""}else return JSON.stringify({Relationship:n,Data:D.Data});else return"{ No Data for: "+n+" }"}},exports.EntityDocumentTemplateParser=Q([S.RegisterClass(exports.EntityDocumentTemplateParser)],exports.EntityDocumentTemplateParser),exports.EntityVectorSyncer=j;
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/constants.ts","../src/models/BatchWorker.ts","../src/models/EntityDocumentCache.ts","../src/models/PagedRecords.ts","../src/models/entityVectorSync.ts","../src/generic/EntityDocumenTemplateParserBase.ts","../src/generic/EntityDocumentTemplateParser.ts"],"sourcesContent":["export const RECORD_DUPLICATES_TYPE_ID = \"JONATHAN - FIX THIS TO USE BaseEngine DERVIED SUB-CLASS\";","import { UserInfo } from '@memberjunction/core';\nimport { Transform } from 'node:stream';\nimport { Worker } from 'node:worker_threads';\n\nexport type TransformCallback = Parameters<Transform['_flush']>[0];\nexport type WorkerData<TContext = Record<string, unknown>, TRecord = Record<string, unknown>> = {\n batch?: Array<TRecord>;\n context?: TContext;\n};\n\nexport type BatchWorkerOptions<TContext = Record<string, unknown>> = {\n /**\n * The number of records to process in a batch\n */\n batchSize?: number;\n /**\n * The path to the worker file used to launch a worker thread\n */\n workerFile?: string;\n /**\n * An abitrary context to pass to the worker thread\n */\n workerContext?: TContext;\n /**\n * The maximum number of worker threads to run concurrently\n */\n concurrencyLimit?: number;\n /**\n * The user context to pass to the worker thread\n */\n contextUser?: UserInfo;\n /**\n * The time to delay between api calls\n **/\n delayTimeMS?: number;\n};\n\n/**\n * This class processes records in batches using a worker thread. It expects\n * a worker file that exports a function to process the batch of records.\n * The stream operates in object mode and emits processed records.\n */\nexport class BatchWorker<TRecord = Record<string, unknown>, TContext = Record<string, unknown>> extends Transform {\n _batchSize = 10;\n _workerFile = './worker.js';\n _workerContext: TContext | Record<string, never> = {};\n _concurrencyLimit = 4;\n _running = 0;\n\n _buffer: Array<TRecord> = [];\n\n _queue: Array<() => Promise<void>> = [];\n\n _contextUser: UserInfo | undefined = undefined;\n\n /**\n * @param {BatchWorkerOptions} options - Options for the BatchWorker\n */\n constructor(options: BatchWorkerOptions<TContext> = {}) {\n super({ objectMode: true });\n this._batchSize = options.batchSize ?? this._batchSize;\n this._workerFile = options.workerFile ?? this._workerFile;\n this._workerContext = options.workerContext ?? this._workerContext;\n this._concurrencyLimit = options.concurrencyLimit ?? this._concurrencyLimit;\n this._contextUser = options.contextUser ?? this._contextUser;\n }\n\n /**\n * Starts the next task in the queue\n */\n _next() {\n if (this._queue.length > 0 && this._running < this._concurrencyLimit) {\n const task = this._queue.shift();\n task && task().then(() => this._next());\n }\n }\n\n /**\n * Enqueues a task to be processed\n * @param task - The task to enqueue\n */\n _enqueue(task: () => Promise<void>) {\n this._queue.push(task);\n this._next();\n }\n\n async _transform(chunk: TRecord, encoding: BufferEncoding, callback: TransformCallback) {\n this._buffer.push(chunk);\n if (this._buffer.length >= this._batchSize) {\n const batch = this._buffer.splice(0, this._batchSize);\n this._enqueue(() =>\n this._processBatchInWorker(batch)\n .then(() => callback())\n .catch(callback)\n );\n } else {\n callback();\n }\n }\n\n async _flush(callback: TransformCallback) {\n if (this._buffer.length > 0) {\n this._enqueue(() => this._processBatchInWorker(this._buffer));\n }\n\n Promise.all(this._queue)\n .then(() => callback())\n .catch(callback);\n }\n\n _processBatchInWorker(batch: Array<TRecord>): Promise<void> {\n return new Promise((resolve, reject) => {\n this._running++;\n const worker = new Worker(this._workerFile, { workerData: { batch, context: this._workerContext } });\n worker.on('message', ({ batch }: WorkerData<TContext, TRecord>) => {\n // Push batch rows to the stream for reading\n batch.forEach((row) => this.push(row));\n\n // Decrement _running on successful processing\n this._running--;\n resolve();\n });\n worker.on('error', (error) => {\n // Decrement _running and reject on error\n this._running--;\n reject(error);\n });\n });\n }\n}\n","import { UserInfo, RunView, LogStatus, RunViewResult } from \"@memberjunction/core\";\nimport { EntityDocumentEntity, EntityDocumentTypeEntity } from \"@memberjunction/core-entities\";\n\n/**\n * Simple caching class to load all Entity Documents and related data at once into memory\n */\nexport class EntityDocumentCache {\n private static _instance: EntityDocumentCache;\n private _loaded: boolean = false;\n private _cache: { [key: string]: EntityDocumentEntity } = {};\n private _typeCache: { [key: string]: EntityDocumentTypeEntity } = {};\n private _contextUser: UserInfo | null = null;\n\n private constructor() {\n // load up the cache\n this._cache = {};\n this._typeCache = {};\n } \n\n public static get Instance(): EntityDocumentCache {\n if(!EntityDocumentCache._instance){\n EntityDocumentCache._instance = new EntityDocumentCache();\n }\n return EntityDocumentCache._instance;\n }\n\n public get IsLoaded(): boolean {\n return this._loaded;\n }\n\n protected Cache(): { [key: string]: EntityDocumentEntity } {\n return this._cache;\n }\n\n protected TypeCache(): { [key: string]: EntityDocumentTypeEntity } {\n return this._typeCache;\n }\n\n public GetDocument(EntityDocumentID: string): EntityDocumentEntity | null {\n let document: EntityDocumentEntity = this._cache[EntityDocumentID];\n if (!document) {\n LogStatus(`EntityDocumentCache.GetDocument: Cache miss for EntityDocumentID: ${EntityDocumentID}`);\n }\n\n return document || null;\n }\n\n public GetFirstActiveDocumentForEntityByID(EntityID: string): EntityDocumentEntity | null {\n let documentType: EntityDocumentTypeEntity | null = this.GetDocumentTypeByName('Record Duplicate');\n if(!documentType){\n return null;\n }\n\n return Object.values(this._cache).find((ed: EntityDocumentEntity) => {\n ed.EntityID === EntityID && ed.Status === 'Active' && ed.TypeID === documentType.ID;\n });\n\n }\n\n public GetFirstActiveDocumentForEntityByName(EntityName: string): EntityDocumentEntity | null {\n let documentType: EntityDocumentTypeEntity | null = this.GetDocumentTypeByName('Record Duplicate');\n if(!documentType){\n return null;\n }\n\n return Object.values(this._cache).find((ed: EntityDocumentEntity) => {\n ed.Entity === EntityName && ed.Status === 'Active' && ed.TypeID === documentType.ID;\n });\n\n }\n\n public GetDocumentByName(EntityDocumentName: string): EntityDocumentEntity | null {\n const toLower = EntityDocumentName.trim().toLowerCase();\n let document: EntityDocumentEntity = Object.values(this._cache).find((ed: EntityDocumentEntity) => {\n ed.Name.trim().toLowerCase() === toLower;\n });\n\n if (!document) {\n LogStatus(`EntityDocumentCache.GetDocumentByName: Cache miss for EntityDocumentName: ${EntityDocumentName}`);\n }\n\n return document || null;\n }\n\n public GetDocumentType(EntityDocumentTypeID: string): EntityDocumentTypeEntity | null {\n let documentType: EntityDocumentTypeEntity = this._typeCache[EntityDocumentTypeID];\n if (!documentType) {\n LogStatus(`EntityDocumentCache.GetDocument: Cache miss for EntityDocumentID: ${EntityDocumentTypeID}`);\n return null;\n }\n\n return documentType;\n }\n\n public GetDocumentTypeByName(EntityDocumentTypeName: string): EntityDocumentTypeEntity | null {\n const toLower = EntityDocumentTypeName.trim().toLowerCase();\n let documentType: EntityDocumentTypeEntity = Object.values(this._typeCache).find((edt: EntityDocumentTypeEntity) => edt.Name.trim().toLowerCase() === toLower);\n\n if (!documentType) {\n LogStatus(`EntityDocumentCache.GetDocumentByName: Cache miss for EntityDocumentName: ${EntityDocumentTypeName}`);\n return null;\n }\n\n return documentType;;\n }\n\n public SetCurrentUser(user: UserInfo) {\n this._contextUser = user;\n }\n\n public async Refresh(forceRefresh: boolean, ContextUser?: UserInfo) {\n\n if(!forceRefresh && this._loaded){\n return;\n }\n\n LogStatus('Refreshing Entity Document Cache');\n this._cache = {};\n this._typeCache = {};\n\n // now load up the cache with all the entity documents\n const rv = new RunView();\n\n const results: RunViewResult[] = await rv.RunViews([\n {\n EntityName: \"Entity Documents\",\n ResultType: \"entity_object\"\n },\n {\n EntityName: \"Entity Document Types\",\n ResultType: \"entity_object\"\n }\n ], ContextUser || this._contextUser);\n\n if (results[0] && results[0].Success) {\n for (const entityDocument of results[0].Results) {\n this._cache[entityDocument.ID] = entityDocument;\n }\n }\n\n if (results[1] && results[1].Success) {\n for (const entityDocumentType of results[1].Results) {\n this._typeCache[entityDocumentType.ID] = entityDocumentType;\n }\n }\n\n this._loaded = true;\n }\n}","import { Readable } from 'node:stream';\n\n/**\n * A stream to collect pages of records and emit them as individual records\n */\nexport class PagedRecords extends Readable {\n constructor() {\n super({ objectMode: true });\n }\n\n _read() {\n // no-op\n }\n\n /**\n * Adds a page of results to the stream\n * @param {Array<Record<string,unknown>>} page - The page of results to add to the stream\n */\n addPage(page) {\n page.forEach((row) => this.push(row));\n }\n\n /**\n * Called when there are no more pages to add to the stream\n */\n endStream() {\n this.push(null);\n }\n}\n","import { Embeddings, GetAIAPIKey } from '@memberjunction/ai';\nimport { VectorDBBase } from '@memberjunction/ai-vectordb';\nimport { PageRecordsParams, VectorBase } from '@memberjunction/ai-vectors';\nimport { BaseEntity, EntityField, EntityInfo, LogError, LogStatus, Metadata, RunView, RunViewResult, UserInfo } from '@memberjunction/core';\nimport { AIModelEntity, EntityDocumentEntity, EntityDocumentTypeEntity, EntityRecordDocumentEntity, TemplateContentEntity, \n TemplateContentTypeEntity, TemplateEntity, TemplateParamEntity, VectorDatabaseEntity, VectorIndexEntity } from '@memberjunction/core-entities';\nimport { MJGlobal } from '@memberjunction/global';\nimport { pipeline } from 'node:stream/promises';\nimport { RECORD_DUPLICATES_TYPE_ID } from '../constants';\nimport { EmbeddingData, TemplateParamData, VectorEmeddingData, VectorizeEntityParams, VectorizeEntityResponse } from '../generic/vectorSync.types';\nimport { BatchWorker } from './BatchWorker';\nimport { EntityDocumentCache } from './EntityDocumentCache';\nimport { PagedRecords } from './PagedRecords';\nimport { resolve } from 'node:path';\nimport { PassThrough, Transform } from 'node:stream';\nimport { AIEngine } from '@memberjunction/aiengine';\nimport { TemplateEngineServer } from '@memberjunction/templates';\nimport { TemplateEntityExtended } from '@memberjunction/templates-base-types';\n\n/**\n * Class that specializes in vectorizing entities using embedding models and upserting them into Vector Databases \n */\nexport class EntityVectorSyncer extends VectorBase {\n _startTime: Date;\n _endTime: Date;\n\n constructor() {\n super();\n }\n\n /**\n * Refreshes the EntityDocumentCache and configures the AIEngine and TemplateEngineServer\n * @param forceRefresh If true, the cache and enginges will be refreshed even if it is already loaded\n * @param contextUser The context user to use to refresh the cache and configure the engines\n */\n public async Config(forceRefresh: boolean, contextUser?: UserInfo): Promise<void> {\n super.CurrentUser = contextUser;\n await EntityDocumentCache.Instance.Refresh(forceRefresh, contextUser);\n await AIEngine.Instance.Config(forceRefresh, contextUser);\n await TemplateEngineServer.Instance.Config(forceRefresh, contextUser);\n }\n\n public async VectorizeEntity(params: VectorizeEntityParams, contextUser?: UserInfo): Promise<VectorizeEntityResponse> {\n if (!contextUser) {\n throw new Error('ContextUser is required to vectorize the entity');\n }\n\n //start row\n const delayTimeMS: number = 250;\n const startTime: number = new Date().getTime();\n super.CurrentUser = contextUser;\n await TemplateEngineServer.Instance.Config(false, contextUser);\n \n const entityDocument: EntityDocumentEntity = await this.GetEntityDocument(params.entityDocumentID);\n const vectorIndexEntity: VectorIndexEntity = await this.GetOrCreateVectorIndex(entityDocument);\n const obj: VectorEmeddingData = await this.GetVectorDatabaseAndEmbeddingClassByEntityDocumentID(params.entityDocumentID);\n\n const md = new Metadata();\n const entity: EntityInfo | undefined = md.Entities.find((e) => e.ID === params.entityID);\n if (!entity) throw new Error(`Entity with ID ${params.entityID} not found.`);\n\n\n const template: TemplateEntityExtended | undefined = TemplateEngineServer.Instance.Templates.find((t: TemplateEntityExtended) => t.ID === entityDocument.TemplateID);\n if(!template){\n throw new Error(`Template not found with ID ${entityDocument.TemplateID}`);\n }\n\n if(template.Content.length === 0){\n throw new Error(`Template ${template.ID} does not have an associated Template Content record`);\n }\n\n if(template.Content.length > 1){\n throw new Error('Templates used by Entity Documents should only have one associated Template Content record.');\n }\n\n //If this function doesnt throw an error, then the template is valid\n const validTemplate: boolean = this.ValidateTemplateContextParamAlignment(template);\n\n const pageSize: number = params.batchCount || 20;\n const dataStream = new PagedRecords();\n \n let templateObj: {} = {\n ...template.GetAll(),\n Params: template.Params.map((p) => p.To())\n }; \n\n const workerContext = { \n executionId: Date.now(), \n entity, \n entityDocument: entityDocument.To(),\n template: templateObj,\n templateContent: template.Content[0].To(),\n vectorDBClassKey: obj.vectorDBClassKey,\n vectorDBAPIKey: obj.vectorDBAPIKey,\n embeddingDriverClass: obj.embeddingDriverClass,\n embeddingAPIKey: obj.embeddingAPIKey,\n delayTimeMS\n };\n\n //annotator worker handles vectorizing the records \n const annotator = new BatchWorker({\n workerFile: resolve(__dirname, 'workers/VectorizeTemplates.js'),\n batchSize: 3,\n concurrencyLimit: 2,\n contextUser: super.CurrentUser,\n workerContext,\n });\n\n //archiver worker handles upserting the vectors into the vector database\n const archiver = new BatchWorker({ \n workerFile: resolve(__dirname, 'workers/UpsertVectors.js'), \n batchSize: 4,\n contextUser: super.CurrentUser, \n workerContext\n });\n\n const upserter = new Transform({objectMode: true, transform: (chunk, encoding, callback) => {\n this.UpsertEntityRecordDocumentRecords(chunk as EmbeddingData, super.CurrentUser).then(() => callback(null)).catch(callback);\n }});\n\n const getData = async (): Promise<void> => {\n let pageNumber = 0;\n let hasMore = true;\n\n while (hasMore) {\n let pageRecordRequest: PageRecordsParams = {\n EntityID: params.entityID,\n PageNumber: pageNumber,\n PageSize: pageSize,\n ResultType: 'simple'\n };\n\n const recordsPage: unknown[] = await super.PageRecordsByEntityID<unknown>(pageRecordRequest);\n const relatedData: TemplateParamData[] = await this.GetRelatedTemplateDataForBatch(entity, recordsPage, template);\n const items: {}[] = [];\n \n for(const record of recordsPage){\n const templateData: { [key: string]: unknown } = await this.GetTemplateData(entity, record, template, relatedData);\n //we need a reference to this record's ID for the upsert worker\n templateData.__mj_recordID = record[entity.FirstPrimaryKey.Name];\n templateData.__mj_compositeKey = entity.PrimaryKeys.map((key) => `${key.Name}|${record[key.Name]}`).join(\"||\");\n //we also need a reference to the vector index's ID\n templateData.VectorIndexID = vectorIndexEntity.ID;\n templateData.TemplateContent = template.Content[0].TemplateText;\n items.push(templateData);\n }\n\n dataStream.addPage(items);\n if(recordsPage.length < pageSize) {\n hasMore = false;\n break;\n }\n\n pageNumber++;\n }\n\n dataStream.endStream();\n };\n\n // page data asynchrounously and add to the data stream\n getData();\n\n console.log('Starting pipeline');\n await pipeline(dataStream, annotator, archiver, upserter, new PassThrough({ objectMode: true }));\n\n // const chunks: BaseEntity[][] = this.chunkArray(allrecords, batchSize);\n // LogStatus(`Processing ${allrecords.length} records in ${chunks.length} chunks of ${batchSize} records each`);\n // LogStatus(`Processing page ${pageNumber} records of ${pageSize} records each`);\n\n // Now add the records to the vectorize queue\n // The vectorize queue consumer calls the embedding service to get the embeddings\n // Then adds vectors + record metadata to the storage queue\n // The storage queue consumer adds the vectors to the vector database\n\n // let count = 0;\n // for (const batch of chunks) {\n // let templates: string[] = [];\n // for (const record of batch) {\n // let template: string = await parser.Parse(entityDocument.Template, request.entityID, record, contextUser);\n // templates.push(template);\n // }\n // LogStatus(`parsing batch ${count}: done`);\n\n // const embeddings: EmbedTextsResult = await obj.embedding.EmbedTexts({ texts: templates, model: null });\n // LogStatus(`embedding batch ${count}: done`);\n\n // const vectorRecords: VectorRecord[] = embeddings.vectors.map((vector: number[], index: number) => {\n // const record: BaseEntity = batch[index];\n // const recordID = record.PrimaryKey.Values('|');\n // return {\n // //The id breaks down to e.g. \"Accounts_7_117\"\n // id: `${entityDocument.Entity}_${entityDocument.ID}_${recordID}`,\n // values: vector,\n // metadata: {\n // EntityID: entityDocument.EntityID,\n // EntityName: entityDocument.Entity,\n // EntityDocumentID: entityDocument.ID,\n // PrimaryKey: record.PrimaryKey.ToString(),\n // Template: templates[index],\n // Data: this.ConvertEntityFieldsToString(record),\n // },\n // };\n // });\n\n // const response: BaseResponse = await obj.vectorDB.createRecords(vectorRecords);\n // if (response.success && vectorIndexEntity) {\n // LogStatus('Successfully created vector records, creating associated Entity Record Documents...');\n // for (const [index, vectorRecord] of vectorRecords.entries()) {\n // try {\n // let erdEntity: EntityRecordDocumentEntity = await super.Metadata.GetEntityObject('Entity Record Documents');\n // erdEntity.NewRecord();\n // erdEntity.EntityID = entityDocument.EntityID;\n // erdEntity.RecordID = batch[index].PrimaryKey.ToString();\n // erdEntity.DocumentText = templates[index];\n // erdEntity.VectorID = vectorRecord.id;\n // erdEntity.VectorJSON = JSON.stringify(vectorRecord.values);\n // erdEntity.VectorIndexID = vectorIndexEntity.ID;\n // erdEntity.EntityRecordUpdatedAt = new Date();\n // erdEntity.EntityDocumentID = entityDocument.ID;\n // let erdEntitySaveResult: boolean = await super.SaveEntity(erdEntity);\n // if (!erdEntitySaveResult) {\n // LogError('Error saving Entity Record Document Entity');\n // }\n // } catch (err) {\n // LogError('Error saving Entity Record Document Entity');\n // LogError(err);\n // }\n // }\n // } else {\n // LogError('Unable to successfully save records to vector database', undefined, response.message);\n // }\n\n // //add a delay to avoid rate limiting\n // let delayRes = await this.delay(1000);\n // count += 1;\n // LogStatus(`Chunk ${count} of out ${chunks.length} processed`);\n // }\n\n const endTime: number = new Date().getTime();\n LogStatus(`Finished vectorizing ${entityDocument.Entity} entity in ${endTime - startTime} ms`);\n return null;\n }\n\n /**\n * This method will create a default Entity Document for the given entityID, vectorDatabase, and AIModel\n * @param entityID\n * @param vectorDatabase\n * @param AIModel\n * @returns\n */\n public async CreateDefaultEntityDocument(\n EntityID: string,\n VectorDatabase: VectorDatabaseEntity,\n AIModel: AIModelEntity\n ): Promise<EntityDocumentEntity> {\n const md = new Metadata();\n const entity = md.Entities.find((e) => e.ID === EntityID);\n if (!entity) throw new Error(`Entity with ID ${EntityID} not found.`);\n\n const EDTemplate: string = entity.Fields.map((ef) => {\n return `${ef.Name}: \\$\\{${ef.Name}\\}`;\n }).join(' ');\n\n const entityDocument: EntityDocumentEntity = await md.GetEntityObject<EntityDocumentEntity>('Entity Documents');\n entityDocument.NewRecord();\n entityDocument.Name = `Default duplicate record Entity Document for the ${entity.Name} entity using vector database ${VectorDatabase.Name} and AI Model ${AIModel.Name}`;\n entityDocument.EntityID = EntityID;\n entityDocument.TypeID = RECORD_DUPLICATES_TYPE_ID;\n entityDocument.Status = 'Active';\n entityDocument.TemplateID = EDTemplate;\n entityDocument.VectorDatabaseID = VectorDatabase.ID;\n entityDocument.AIModelID = AIModel.ID;\n let saveResult = await this.SaveEntity(entityDocument);\n if (saveResult) {\n return entityDocument;\n } else {\n throw new Error(`Failed to save Entity Document for ${EntityID}`);\n }\n }\n\n protected async GetVectorDatabaseAndEmbeddingClassByEntityDocumentID( entityDocumentID: string, createDocumentIfNotFound?: boolean ): Promise<VectorEmeddingData> {\n let entityDocument: EntityDocumentEntity | null = EntityDocumentCache.Instance.GetDocument(entityDocumentID);\n if (!entityDocument) {\n if (createDocumentIfNotFound) {\n LogStatus(`No active Entity Document found for entity ${entityDocumentID}, creating one`);\n const defaultVectorDB: VectorDatabaseEntity = this.GetVectorDatabase();\n const defaultAIModel: AIModelEntity = this.GetAIModel();\n entityDocument = await this.CreateDefaultEntityDocument(entityDocumentID, defaultVectorDB, defaultAIModel);\n } \n else {\n throw new Error(`No Entity Document found for ID=${entityDocumentID}`);\n }\n }\n\n const vectorDBEntity: VectorDatabaseEntity = this.GetVectorDatabase(entityDocument.VectorDatabaseID);\n const aiModelEntity: AIModelEntity = this.GetAIModel(entityDocument.AIModelID);\n\n const embeddingAPIKey: string = GetAIAPIKey(aiModelEntity.DriverClass);\n const vectorDBAPIKey: string = GetAIAPIKey(vectorDBEntity.ClassKey);\n\n if (!embeddingAPIKey) {\n throw Error(`No API Key found for AI Model ${aiModelEntity.DriverClass}`);\n }\n\n if (!vectorDBAPIKey) {\n throw Error(`No API Key found for Vector Database ${vectorDBEntity.ClassKey}`);\n }\n\n //LogStatus(`Embedding API Key: ${embeddingAPIKey} VectorDB API Key: ${vectorDBAPIKey}`);\n const embedding = MJGlobal.Instance.ClassFactory.CreateInstance<Embeddings>(Embeddings, aiModelEntity.DriverClass, embeddingAPIKey);\n const vectorDB = MJGlobal.Instance.ClassFactory.CreateInstance<VectorDBBase>(VectorDBBase, vectorDBEntity.ClassKey, vectorDBAPIKey);\n\n if (!embedding) {\n throw Error(`Failed to create Embeddings instance for AI Model ${aiModelEntity.DriverClass}`);\n }\n\n if (!vectorDB) {\n throw Error(`Failed to create Vector Database instance for ${vectorDBEntity.ClassKey}`);\n }\n\n LogStatus(`Using vector database ${vectorDBEntity.Name} and AI Model ${aiModelEntity.Name}`);\n\n const obj: VectorEmeddingData = { \n embedding, \n vectorDB, \n vectorDBClassKey: vectorDBEntity.ClassKey, \n vectorDBAPIKey: vectorDBAPIKey,\n embeddingDriverClass: aiModelEntity.DriverClass,\n embeddingAPIKey: embeddingAPIKey\n };\n\n return obj;\n }\n\n public async GetEntityDocument(EntityDocumentID: string): Promise<EntityDocumentEntity | null> {\n const cache = EntityDocumentCache.Instance;\n if (!cache.IsLoaded) {\n await cache.Refresh(false, super.CurrentUser);\n }\n return cache.GetDocument(EntityDocumentID);\n }\n\n public async GetEntityDocumentByName(EntityDocumentName: string, ContextUser?: UserInfo): Promise<EntityDocumentEntity | null> {\n const cache = EntityDocumentCache.Instance;\n if (!cache.IsLoaded) {\n await cache.Refresh(false, ContextUser);\n }\n return cache.GetDocumentByName(EntityDocumentName);\n }\n\n /**\n * Returns all active Entity Documents of the 'Record Duplicate' type.\n * Note that this only returns the first active Entity Document. Meaning if there are multiple Entity Documents for the same entity, \n * only the oldest one will be returned.\n * @param entityIDs If provided, only Entity Documents for the specified entities will be returned.\n */\n public async GetActiveEntityDocuments(entityNames?: string[]): Promise<EntityDocumentEntity[]> {\n await EntityDocumentCache.Instance.Refresh(false, super.CurrentUser);\n const entityDocumentType: EntityDocumentTypeEntity | undefined = EntityDocumentCache.Instance.GetDocumentTypeByName('Record Duplicate');\n if (!entityDocumentType) {\n throw new Error('Entity Document Type not found');\n }\n\n let filter = `TypeID = '${entityDocumentType.ID}' AND Status = 'Active' `;\n if (entityNames && entityNames.length > 0) {\n filter += ` AND Entity IN (${entityNames.map((entityName: string) => `'${entityName}'`).join(',')})`;\n }\n\n const runViewResult: RunViewResult<EntityDocumentEntity> = await super.RunView.RunView<EntityDocumentEntity>({\n EntityName: 'Entity Documents',\n ExtraFilter: filter,\n ResultType: 'entity_object',\n }, super.CurrentUser);\n\n if(!runViewResult.Success){\n throw new Error(runViewResult.ErrorMessage);\n }\n\n let entityDocuments: EntityDocumentEntity[] = [];\n let seenEntities: string[] = [];\n\n //we only want one entity document per entity\n for(const entityDocument of runViewResult.Results){\n if(seenEntities.includes(entityDocument.EntityID)){\n continue;\n }\n \n entityDocuments.push(entityDocument);\n seenEntities.push(entityDocument.EntityID);\n }\n\n return entityDocuments;\n }\n\n private async GetOrCreateVectorIndex(entityDocument: EntityDocumentEntity): Promise<VectorIndexEntity> {\n let vectorIndexEntity: VectorIndexEntity = await super.RunViewForSingleValue(\n 'Vector Indexes',\n `VectorDatabaseID = '${entityDocument.VectorDatabaseID}' AND EmbeddingModelID = '${entityDocument.AIModelID}'`\n );\n\n if (vectorIndexEntity) {\n return vectorIndexEntity;\n }\n\n LogStatus(`No Vector Index found for entityDocument ${entityDocument.ID}, creating one`);\n try {\n vectorIndexEntity = await super.Metadata.GetEntityObject<VectorIndexEntity>('Vector Indexes');\n vectorIndexEntity.NewRecord();\n vectorIndexEntity.VectorDatabaseID = entityDocument.VectorDatabaseID;\n vectorIndexEntity.EmbeddingModelID = entityDocument.AIModelID;\n vectorIndexEntity.Name = `Vector Index for entityDocument ${entityDocument.EntityID}`;\n vectorIndexEntity.Set('EntityRecordUpdatedAt', new Date());\n vectorIndexEntity.Set('EntityDocumentID', entityDocument.ID);\n //not a very descriptive description, but the view has the name of the vectorDB and embedding model used\n vectorIndexEntity.Description = `Vector Index that uses the Vector database ${entityDocument.VectorDatabaseID} and ${entityDocument.AIModelID} as the embedding model`;\n const saveResult = await super.SaveEntity(vectorIndexEntity);\n if (saveResult) {\n LogStatus(`Successfully created new Vector Index Entity`);\n return vectorIndexEntity;\n } else {\n LogError('Error saving Vector Index Entity');\n return null;\n }\n } catch (err) {\n console.error(JSON.stringify(err));\n LogError(err);\n return null;\n }\n }\n\n protected async CreateTemplateForEntityDocument(entityDocument: EntityDocumentEntity): Promise<TemplateEntity> {\n const templateEntity: TemplateEntityExtended = await super.Metadata.GetEntityObject<TemplateEntityExtended>('Templates');\n templateEntity.NewRecord();\n templateEntity.Name = `Template for EntityDocument ${entityDocument.EntityID}`;\n templateEntity.Description = `The template used by EntityDocument ${entityDocument.ID}`\n templateEntity.UserID = super.CurrentUser.ID;\n templateEntity.IsActive = true;\n templateEntity.CategoryID = null;\n\n const templateEntitySaveResult = await super.SaveEntity(templateEntity);\n if(!templateEntitySaveResult){\n LogError('Error saving Template Entity', undefined, templateEntity.LatestResult);\n throw new Error(templateEntity.LatestResult.Message);\n }\n LogStatus(`Successfully created new Template Entity ${templateEntity.ID}`);\n\n //next, create the template contents record\n await TemplateEngineServer.Instance.Config(false, super.CurrentUser);\n const textContentType: TemplateContentTypeEntity = TemplateEngineServer.Instance.TemplateContentTypes.find((type: TemplateContentTypeEntity) => type.Name === 'Text');\n if(!textContentType){\n throw new Error('Text template content type not found');\n }\n\n const entityFields: EntityField[] = await this.GetEntityFieldsForSimilaritySearch(entityDocument.EntityID);\n\n const templateContentsEntity: TemplateContentEntity = await super.Metadata.GetEntityObject<TemplateContentEntity>('Template Contents');\n templateContentsEntity.NewRecord();\n templateContentsEntity.TemplateID = templateEntity.ID;\n templateContentsEntity.TypeID = textContentType.ID;\n templateContentsEntity.Priority = 1;\n templateContentsEntity.IsActive = true;\n templateContentsEntity.TemplateText = this.BuildTemplateContent(entityFields);\n\n const templateContentsEntitySaveResult = await super.SaveEntity(templateContentsEntity);\n if(!templateContentsEntitySaveResult){\n LogError('Error saving Template Entity', undefined, templateContentsEntity.LatestResult);\n throw new Error(templateContentsEntity.LatestResult.Message);\n }\n LogStatus(`Successfully created new Template Content Entity ${templateContentsEntity.ID}`);\n\n //next, create the template params record\n const templateParamsEntity: TemplateParamEntity = await super.Metadata.GetEntityObject<TemplateParamEntity>('Template Params');\n templateParamsEntity.NewRecord();\n templateParamsEntity.TemplateID = templateEntity.ID;\n templateParamsEntity.Name = 'Entity';\n templateParamsEntity.Description = 'The entity object to be used in the template';\n templateParamsEntity.Type = 'Record';\n templateParamsEntity.DefaultValue = null;\n templateParamsEntity.IsRequired = true;\n templateParamsEntity.LinkedParameterName = null;\n templateParamsEntity.LinkedParameterField = null;\n templateParamsEntity.ExtraFilter = null;\n templateParamsEntity.EntityID = entityDocument.EntityID;\n templateParamsEntity.RecordID = null;\n\n const templateParamsEntitySaveResult = await super.SaveEntity(templateParamsEntity);\n if(!templateParamsEntitySaveResult){\n LogError('Error saving Template Entity', undefined, templateParamsEntity.LatestResult);\n throw new Error(templateParamsEntity.LatestResult.Message);\n }\n LogStatus(`Successfully created new Template Param Entity ${templateParamsEntity.ID}`);\n \n templateEntity.Content.push(templateContentsEntity);\n templateEntity.Params.push(templateParamsEntity);\n TemplateEngineServer.Instance.AddTemplate(templateEntity);\n\n return templateEntity;\n }\n\n protected BuildTemplateContent(entityFields: EntityField[]): string {\n return entityFields.map((field: EntityField) => {\n return `{{Entity.${field.Name}}}`;\n }).join(' ');\n }\n\n protected async GetEntityFieldsForSimilaritySearch(entityID: string): Promise<EntityField[]> {\n //We only want fields that can potentially be the same across records\n //which means things such as IDs, timestamps, etc. are not useful\n //as they're likely to be unique or not that helpful in determining similarity\n const runViewResult: RunViewResult<EntityField> = await super.RunView.RunView<EntityField>({\n EntityName: 'Entity Fields',\n ExtraFilter: `EntityID = '${entityID}' AND IsPrimaryKey = 0 AND IsUnique = 0 AND AutoIncrement = 0 and Type NOT IN ('datetimeoffset', 'datetime')`,\n ResultType: 'entity_object',\n }, super.CurrentUser);\n\n if (!runViewResult.Success) {\n throw new Error(runViewResult.ErrorMessage);\n }\n\n return runViewResult.Results;\n }\n\n protected async GetTemplateData(entity: EntityInfo, record: unknown, template: TemplateEntityExtended, relatedData: TemplateParamData[]): Promise<{ [key: string]: any }> {\n const templateData: { [key: string]: unknown } = {};\n for(const param of template.Params){\n if(templateData[param.Name]){\n continue;\n }\n\n switch(param.Type){\n case 'Record':\n // this one is simple, we create a property by the provided name, and set the value to the record we are currently processing\n templateData[param.Name] = record;\n break;\n case 'Entity':\n // here we need to grab the related data from another entity and filter it down for the record we are current processing so it only shows the related data\n // the metadata in the param tells us what we need to know\n const paramData: TemplateParamData | undefined = relatedData.find((rd: TemplateParamData) => rd.ParamName === param.Name);\n if(!paramData){\n LogError(`No related data found for param ${param.Name} in template ${template.ID}`);\n break;\n }\n\n // now filter down the data in d to just this record and set the value of the context data to the filtered data\n templateData[param.Name] = paramData.Data.filter((rdfr: BaseEntity) => rdfr[param.LinkedParameterField] === record[entity.FirstPrimaryKey.Name]);\n break;\n case \"Array\":\n case \"Scalar\":\n case \"Object\":\n // do nothing here, as we don't directly support these param types\n LogError(`Unsupported parameter type ${param.Type} for parameter ${param.Name} in template ${template.ID}`);\n break;\n }\n }\n return templateData;\n }\n\n protected async GetRelatedTemplateDataForBatch(entity: EntityInfo, records: unknown[], template: TemplateEntityExtended): Promise<TemplateParamData[]> {\n const relatedData: TemplateParamData[] = [];\n\n for(const templateParam of template.Params){\n if(templateParam.Type !== 'Entity'){\n continue;\n }\n\n const relatedEntity = templateParam.Entity;\n const relatedField = templateParam.LinkedParameterField;\n\n // construct a filter for the related field so that we constrain the results to just the set of records linked to our recipients\n const quotes = entity.FirstPrimaryKey.NeedsQuotes ? \"'\" : \"\";\n const filter = `${relatedField} in (${records.map((record: unknown) => `${quotes}${record[entity.FirstPrimaryKey.Name]}${quotes}`).join(',')})`;\n const finalFilter = templateParam.ExtraFilter ? `(${filter}) AND (${templateParam.ExtraFilter})` : filter;\n\n const result = await super.RunView.RunView<unknown>({\n EntityName: relatedEntity,\n ExtraFilter: finalFilter,\n ResultType: 'simple'\n }, super.CurrentUser);\n\n if (result && result.Success) {\n const data: TemplateParamData = { ParamName: '', Data: [] };\n data.ParamName = templateParam.Name,\n data.Data = result.Results;\n relatedData.push(data);\n }\n else {\n LogError(`Error getting related data for entity ${relatedEntity} with filter ${finalFilter}`, undefined, result.ErrorMessage);\n }\n }\n\n return relatedData;\n }\n\n // Rather than having this logic inside the EntityRecordDocumentWorker class, it's placed here instead\n //so that the logic behind vectorizing entities isnt spread out across so many files\n protected async UpsertEntityRecordDocumentRecords(embeddingData: EmbeddingData, contextUser: UserInfo): Promise<void> {\n let md: Metadata = super.Metadata;\n let rv: RunView = super.RunView;\n let success: boolean = true;\n\n let vectorIndex: VectorIndexEntity = await md.GetEntityObject<VectorIndexEntity>('Vector Indexes', contextUser);\n let vectorIndexID: string = embeddingData.VectorIndexID.toString();\n let loadResult = await vectorIndex.Load(vectorIndexID);\n if(!loadResult){\n LogError(`Vector Index with ID ${embeddingData.VectorIndexID} not found`);\n return;\n }\n\n let entityDocument: Record<string, unknown> = embeddingData.EntityDocument;\n let entityID: unknown = entityDocument.EntityID;\n\n let existingRecords: BaseEntity[] = [];\n const runViewResult: RunViewResult<BaseEntity> = await rv.RunView<BaseEntity>({\n EntityName: 'Entity Record Documents',\n ExtraFilter: `EntityID = '${entityID}' AND EntityDocumentID = '${entityDocument.ID}' AND RecordID in (${embeddingData.__mj_recordID})`,\n ResultType: 'entity_object'\n }, contextUser);\n \n if(runViewResult.Success){\n existingRecords = runViewResult.Results;\n }\n else {\n LogError(`Error getting existing Entity Record Documents`, undefined, runViewResult.ErrorMessage);\n }\n\n let erdEntity: BaseEntity | undefined = existingRecords.find((er: BaseEntity) => er.Get(\"RecordID\").toString() === embeddingData.__mj_recordID.toString());\n if(!erdEntity){\n erdEntity = await md.GetEntityObject<BaseEntity>('Entity Record Documents', contextUser);\n erdEntity.NewRecord();\n }\n\n erdEntity.Set(\"EntityID\", entityID.toString());\n erdEntity.Set(\"RecordID\", embeddingData.__mj_recordID.toString());\n erdEntity.Set(\"DocumentText\", embeddingData.TemplateContent);\n erdEntity.Set(\"VectorID\", embeddingData.VectorID.toString());\n erdEntity.Set(\"VectorJSON\", JSON.stringify(embeddingData.Vector));\n erdEntity.Set(\"VectorIndexID\", embeddingData.VectorIndexID.toString());\n erdEntity.Set(\"EntityRecordUpdatedAt\", new Date());\n erdEntity.Set(\"EntityDocumentID\", embeddingData.EntityDocument.ID.toString());\n erdEntity.ContextCurrentUser = contextUser;\n \n let erdEntitySaveResult: boolean = await erdEntity.Save();\n if(!erdEntitySaveResult){\n LogError('Error saving Entity Record Document Entity', undefined, erdEntity.LatestResult);\n success = false;\n }\n\n if(success){\n LogStatus(\"Upserting Entity Record Documents: Complete\");\n }\n else{\n LogError(\"Upserting Entity Record Documents: Fail\");\n }\n }\n\n /**\n * This method is resposnible for determining if the template(s) given have aligned parameters, meaning they don't have overlapping parameter names that have \n * different meanings. It is okay for scenarios where there are > 1 template in use for a message to have different parameter names, but if they have the SAME parameter names\n * they must not have different settings.\n */\n protected ValidateTemplateContextParamAlignment(template: TemplateEntityExtended): boolean {\n // the params are defined in each template they will be in the Params property of the template\n const seenParams: {[key: string]: TemplateParamEntity } = {};\n for (const templateParam of template.Params) {\n const param: TemplateParamEntity | undefined = seenParams[templateParam.Name];\n // we have a duplicate parameter name, now we need to check if the definitions are the same\n if(param && param.Type !== templateParam.Type){\n throw new Error(`Parameter ${param.Name} has different types in different templates`);\n }\n else {\n seenParams[templateParam.Name] = templateParam;\n }\n }\n\n // if we get here, we are good, otherwise we will have thrown an exception\n return true;\n }\n}\n","import { CompositeKey, Metadata, UserInfo } from '@memberjunction/core';\n\n/**\n * This is an abstract base class, use the EntityDocumentTemplateParser class or a sub-class thereof.\n */\nexport abstract class EntityDocumentTemplateParserBase {\n public static ClearCache() {\n EntityDocumentTemplateParserBase.__cache = {};\n }\n public static CreateCacheKey(EntityID: string, EntityRecordPrimaryKey: string, Content: string): string {\n return `${EntityID}___${EntityRecordPrimaryKey}___${Content}`;\n }\n\n protected static __cache: { [key: string]: string } = {};\n protected static get _cache(): { [key: string]: string } {\n return EntityDocumentTemplateParserBase.__cache;\n }\n\n /**\n * This method will parse an entity document template and replace values within ${} placeholders with actual values from the entity record. In the case of function calls\n * within the placeholders, the functions object must be provided to parse the function calls.\n * @param Template - the document template to parse\n * @param EntityID - the ID of the entity\n * @param EntityRecord - the values for the entity record\n * @param ContextUser - the current user\n * @returns the evaluated value of the template incorporating fields and function call(s), if any.\n */\n public async Parse(Template: string, EntityID: string, EntityRecord: any, ContextUser: UserInfo): Promise<string> {\n if (!ContextUser) {\n throw new Error('ContextUser is required to parse the template');\n }\n\n const md = new Metadata();\n const entityInfo = md.Entities.find((e) => e.ID === EntityID);\n if (!entityInfo) {\n throw new Error(`Entity with ID ${EntityID} not found.`);\n }\n\n let compositeKey: CompositeKey = new CompositeKey();\n compositeKey.LoadFromEntityInfoAndRecord(entityInfo, EntityRecord);\n\n const regex = /\\$\\{([^{}]+)\\}/g;\n const matches = Template.matchAll(regex);\n\n // Convert matches to an array to handle them asynchronously\n const replacements = Array.from(matches).map(async (match) => {\n const content = match[1]; // The captured group from regex\n const cacheKey = EntityDocumentTemplateParserBase.CreateCacheKey(EntityID, compositeKey.ToString(), content);\n\n // check the cache and if we don't have an entry in the cache, add it\n if (!EntityDocumentTemplateParserBase._cache[cacheKey]) {\n // Cache miss, evaluate and store the result\n EntityDocumentTemplateParserBase._cache[cacheKey] = await this.evalSingleArgument(content, EntityID, EntityRecord, ContextUser);\n }\n\n return {\n old: match[0], // The entire placeholder including ${}\n new: EntityDocumentTemplateParserBase._cache[cacheKey], // The replacement value\n };\n });\n\n // Resolve all promises\n const resolvedReplacements = await Promise.all(replacements);\n\n // Replace each placeholder in the template with its resolved value\n let resolvedTemplate = Template;\n resolvedReplacements.forEach((replacement) => {\n resolvedTemplate = resolvedTemplate.replace(replacement.old, replacement.new);\n });\n\n return resolvedTemplate;\n }\n\n protected async evalSingleArgument(argument: string, entityID: string, entityRecord: any, ContextUser: UserInfo): Promise<string> {\n const funcMatch = argument.match(/(\\w+)\\(([^)]*)\\)/);\n if (funcMatch) {\n const [, funcName, paramsString] = funcMatch;\n const params = paramsString.split(',').map((param) => {\n param = param.trim();\n //if the string is wrapped in single or double quotes, remove them\n if (param.startsWith('\"') && param.endsWith('\"')) {\n return param.slice(1, -1);\n } else if (param.startsWith(\"'\") && param.endsWith(\"'\")) {\n return param.slice(1, -1);\n } else {\n return param;\n }\n });\n\n // Check if the method exists on this instance\n if (typeof this[funcName] === 'function') {\n // Call the instance method dynamically using its name and spread the params\n return this[funcName](entityID, entityRecord, ContextUser, ...params);\n } else {\n throw new Error(`Function ${funcName} is not defined.`);\n }\n } else {\n // not a function match, attempt to return the value from the entity record\n return entityRecord[argument] !== undefined ? entityRecord[argument] : '';\n }\n }\n}\n","import { CompositeKey, LogError, LogStatus, Metadata, UserInfo } from \"@memberjunction/core\";\nimport { MJGlobal, RegisterClass } from \"@memberjunction/global\";\nimport { EntityVectorSyncer } from \"../models/entityVectorSync\";\nimport { EntityDocumentTemplateParserBase } from \"./EntityDocumenTemplateParserBase\";\n\n/**\n * This is the first-level sub-class of EntityDocumentTemplateParserBase. This class is used to parse a string template with variables and functions. \n * If you wish to override functionality you can subclass it and then use the @RegisterClass decorator to register the sub-class of EntityDocumentTemplateParser with a priority of 1 or above to \n * then be used instead of the default implementation.\n */\n@RegisterClass(EntityDocumentTemplateParser)\nexport class EntityDocumentTemplateParser extends EntityDocumentTemplateParserBase {\n\n /** Convenience method to get an instance of the class and uses the ClassFactory so we can create sub-classes if they are registered with higher priorities than the base class */\n public static CreateInstance(): EntityDocumentTemplateParser {\n return MJGlobal.Instance.ClassFactory.CreateInstance<EntityDocumentTemplateParser>(EntityDocumentTemplateParser);\n }\n\n /**\n * This function \n * @param entityID \n * @param entityRecord \n * @param relationshipName \n * @param maxRows \n * @param entityDocumentName \n * @returns \n */\n protected async Relationship(entityID: string, entityRecord: any, ContextUser: UserInfo, relationshipName: string, maxRows: number, entityDocumentName: string): Promise<string> {\n // super inefficient handling to start, we'll optimize this later to call the related stuff in batch\n const md = new Metadata();\n const vectorSyncer: EntityVectorSyncer = new EntityVectorSyncer();\n vectorSyncer.CurrentUser = ContextUser;\n\n const entityInfo = md.Entities.find(e => e.ID === entityID); \n if (!entityInfo){\n throw new Error(`Entity with ID ${entityID} not found.`);\n }\n\n const re = entityInfo.RelatedEntities.find(re => re.RelatedEntity === relationshipName);\n if (!re){\n throw new Error(`Relationship ${relationshipName} not found for entity ${entityInfo.Name}`);\n }\n\n const obj = await md.GetEntityObject(entityInfo.Name, ContextUser);\n let compositeKey: CompositeKey = new CompositeKey();\n compositeKey.LoadFromEntityInfoAndRecord(entityInfo, entityRecord);\n let loadResult: boolean = await obj.InnerLoad(compositeKey);\n if (!loadResult){\n LogError(`Failed to load entity ${entityInfo.Name} with ID ${compositeKey.ToString()}`);\n return \"\";\n }\n\n const reData = await obj.GetRelatedEntityDataExt(re, null, maxRows)\n\n if (reData && reData.Data) {\n // now, get the entity document info if provided\n if (entityDocumentName && entityDocumentName.trim().length > 0) {\n // we have a document name, attempt to locate it\n const doc = await vectorSyncer.GetEntityDocumentByName(entityDocumentName, ContextUser);\n if (doc) {\n // we have the document, now we need to parse it and build a result that is the concatenation of all the parsed documents\n // start off by creating an instance of the parser using CreateInstance() so we're using the highest priority registered subclass\n const parser = EntityDocumentTemplateParser.CreateInstance();\n\n // now we need to batch the requests to the parser to have the right concurrency\n const batchSize = 10; // Set the batch size to the desired number of concurrent requests\n const results = [];\n \n for (let i = 0; i < reData.Data.length; i += batchSize) {\n const batchPromises = reData.Data.slice(i, i + batchSize).map(data => {\n return parser.Parse((doc as any).Template, re.RelatedEntityID, data, ContextUser);\n });\n const batchResults = await Promise.all(batchPromises);\n results.push(...batchResults);\n }\n \n return results.map(r => r + \"\\n\\n\").join('');\n }\n else {\n LogStatus(`Entity Document with name ${entityDocumentName} not found.`);\n return \"\";\n }\n }\n else {\n // no entity document name provided, just return the data in a simple format\n return JSON.stringify({ Relationship: relationshipName, Data: reData.Data});\n }\n }\n else {\n return \"{ No Data for: \" + relationshipName + \" }\"\n }\n }\n}"],"names":["Transform","Worker","LogStatus","RunView","Readable","VectorBase","AIEngine","TemplateEngineServer","Metadata","resolve","pipeline","PassThrough","GetAIAPIKey","MJGlobal","Embeddings","VectorDBBase","LogError","CompositeKey","EntityDocumentTemplateParser","RegisterClass"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/models/BatchWorker.ts","../src/models/EntityDocumentCache.ts","../src/models/PagedRecords.ts","../src/models/entityVectorSync.ts","../src/generic/EntityDocumenTemplateParserBase.ts","../src/generic/EntityDocumentTemplateParser.ts"],"sourcesContent":["import { UserInfo } from '@memberjunction/core';\nimport { Transform } from 'node:stream';\nimport { Worker } from 'node:worker_threads';\n\nexport type TransformCallback = Parameters<Transform['_flush']>[0];\nexport type WorkerData<TContext = Record<string, unknown>, TRecord = Record<string, unknown>> = {\n batch?: Array<TRecord>;\n context?: TContext;\n};\n\nexport type BatchWorkerOptions<TContext = Record<string, unknown>> = {\n /**\n * The number of records to process in a batch\n */\n batchSize?: number;\n /**\n * The path to the worker file used to launch a worker thread\n */\n workerFile?: string;\n /**\n * An abitrary context to pass to the worker thread\n */\n workerContext?: TContext;\n /**\n * The maximum number of worker threads to run concurrently\n */\n concurrencyLimit?: number;\n /**\n * The user context to pass to the worker thread\n */\n contextUser?: UserInfo;\n /**\n * The time to delay between api calls\n **/\n delayTimeMS?: number;\n};\n\n/**\n * This class processes records in batches using a worker thread. It expects\n * a worker file that exports a function to process the batch of records.\n * The stream operates in object mode and emits processed records.\n */\nexport class BatchWorker<TRecord = Record<string, unknown>, TContext = Record<string, unknown>> extends Transform {\n _batchSize = 10;\n _workerFile = './worker.js';\n _workerContext: TContext | Record<string, never> = {};\n _concurrencyLimit = 4;\n _running = 0;\n\n _buffer: Array<TRecord> = [];\n\n _queue: Array<() => Promise<void>> = [];\n\n _contextUser: UserInfo | undefined = undefined;\n\n /**\n * @param {BatchWorkerOptions} options - Options for the BatchWorker\n */\n constructor(options: BatchWorkerOptions<TContext> = {}) {\n super({ objectMode: true });\n this._batchSize = options.batchSize ?? this._batchSize;\n this._workerFile = options.workerFile ?? this._workerFile;\n this._workerContext = options.workerContext ?? this._workerContext;\n this._concurrencyLimit = options.concurrencyLimit ?? this._concurrencyLimit;\n this._contextUser = options.contextUser ?? this._contextUser;\n }\n\n /**\n * Starts the next task in the queue\n */\n _next() {\n if (this._queue.length > 0 && this._running < this._concurrencyLimit) {\n const task = this._queue.shift();\n task && task().then(() => this._next());\n }\n }\n\n /**\n * Enqueues a task to be processed\n * @param task - The task to enqueue\n */\n _enqueue(task: () => Promise<void>) {\n this._queue.push(task);\n this._next();\n }\n\n async _transform(chunk: TRecord, encoding: BufferEncoding, callback: TransformCallback) {\n this._buffer.push(chunk);\n if (this._buffer.length >= this._batchSize) {\n const batch = this._buffer.splice(0, this._batchSize);\n this._enqueue(() =>\n this._processBatchInWorker(batch)\n .then(() => callback())\n .catch(callback)\n );\n } else {\n callback();\n }\n }\n\n async _flush(callback: TransformCallback) {\n if (this._buffer.length > 0) {\n this._enqueue(() => this._processBatchInWorker(this._buffer));\n }\n\n Promise.all(this._queue)\n .then(() => callback())\n .catch(callback);\n }\n\n _processBatchInWorker(batch: Array<TRecord>): Promise<void> {\n return new Promise((resolve, reject) => {\n this._running++;\n const worker = new Worker(this._workerFile, { workerData: { batch, context: this._workerContext } });\n worker.on('message', ({ batch }: WorkerData<TContext, TRecord>) => {\n // Push batch rows to the stream for reading\n batch.forEach((row) => this.push(row));\n\n // Decrement _running on successful processing\n this._running--;\n resolve();\n });\n worker.on('error', (error) => {\n // Decrement _running and reject on error\n this._running--;\n reject(error);\n });\n });\n }\n}\n","import { UserInfo, RunView, LogStatus, RunViewResult } from \"@memberjunction/core\";\nimport { EntityDocumentEntity, EntityDocumentTypeEntity } from \"@memberjunction/core-entities\";\n\n/**\n * Simple caching class to load all Entity Documents and related data at once into memory\n */\nexport class EntityDocumentCache {\n private static _instance: EntityDocumentCache;\n private _loaded: boolean = false;\n private _cache: { [key: string]: EntityDocumentEntity } = {};\n private _typeCache: { [key: string]: EntityDocumentTypeEntity } = {};\n private _contextUser: UserInfo | null = null;\n\n private constructor() {\n // load up the cache\n this._cache = {};\n this._typeCache = {};\n } \n\n public static get Instance(): EntityDocumentCache {\n if(!EntityDocumentCache._instance){\n EntityDocumentCache._instance = new EntityDocumentCache();\n }\n return EntityDocumentCache._instance;\n }\n\n public get IsLoaded(): boolean {\n return this._loaded;\n }\n\n protected Cache(): { [key: string]: EntityDocumentEntity } {\n return this._cache;\n }\n\n protected TypeCache(): { [key: string]: EntityDocumentTypeEntity } {\n return this._typeCache;\n }\n\n public GetDocument(EntityDocumentID: string): EntityDocumentEntity | null {\n let document: EntityDocumentEntity = this._cache[EntityDocumentID];\n if (!document) {\n LogStatus(`EntityDocumentCache.GetDocument: Cache miss for EntityDocumentID: ${EntityDocumentID}`);\n }\n\n return document || null;\n }\n\n public GetFirstActiveDocumentForEntityByID(EntityID: string): EntityDocumentEntity | null {\n let documentType: EntityDocumentTypeEntity | null = this.GetDocumentTypeByName('Record Duplicate');\n if(!documentType){\n return null;\n }\n\n return Object.values(this._cache).find((ed: EntityDocumentEntity) => {\n ed.EntityID === EntityID && ed.Status === 'Active' && ed.TypeID === documentType.ID;\n });\n\n }\n\n public GetFirstActiveDocumentForEntityByName(EntityName: string): EntityDocumentEntity | null {\n let documentType: EntityDocumentTypeEntity | null = this.GetDocumentTypeByName('Record Duplicate');\n if(!documentType){\n return null;\n }\n\n return Object.values(this._cache).find((ed: EntityDocumentEntity) => {\n ed.Entity === EntityName && ed.Status === 'Active' && ed.TypeID === documentType.ID;\n });\n\n }\n\n public GetDocumentByName(EntityDocumentName: string): EntityDocumentEntity | null {\n const toLower = EntityDocumentName.trim().toLowerCase();\n let document: EntityDocumentEntity = Object.values(this._cache).find((ed: EntityDocumentEntity) => {\n ed.Name.trim().toLowerCase() === toLower;\n });\n\n if (!document) {\n LogStatus(`EntityDocumentCache.GetDocumentByName: Cache miss for EntityDocumentName: ${EntityDocumentName}`);\n }\n\n return document || null;\n }\n\n public GetDocumentType(EntityDocumentTypeID: string): EntityDocumentTypeEntity | null {\n let documentType: EntityDocumentTypeEntity = this._typeCache[EntityDocumentTypeID];\n if (!documentType) {\n LogStatus(`EntityDocumentCache.GetDocument: Cache miss for EntityDocumentID: ${EntityDocumentTypeID}`);\n return null;\n }\n\n return documentType;\n }\n\n public GetDocumentTypeByName(EntityDocumentTypeName: string): EntityDocumentTypeEntity | null {\n const toLower = EntityDocumentTypeName.trim().toLowerCase();\n let documentType: EntityDocumentTypeEntity = Object.values(this._typeCache).find((edt: EntityDocumentTypeEntity) => edt.Name.trim().toLowerCase() === toLower);\n\n if (!documentType) {\n LogStatus(`EntityDocumentCache.GetDocumentByName: Cache miss for EntityDocumentName: ${EntityDocumentTypeName}`);\n return null;\n }\n\n return documentType;;\n }\n\n public SetCurrentUser(user: UserInfo) {\n this._contextUser = user;\n }\n\n public async Refresh(forceRefresh: boolean, ContextUser?: UserInfo) {\n\n if(!forceRefresh && this._loaded){\n return;\n }\n\n LogStatus('Refreshing Entity Document Cache');\n this._cache = {};\n this._typeCache = {};\n\n // now load up the cache with all the entity documents\n const rv = new RunView();\n\n const results: RunViewResult[] = await rv.RunViews([\n {\n EntityName: \"Entity Documents\",\n ResultType: \"entity_object\"\n },\n {\n EntityName: \"Entity Document Types\",\n ResultType: \"entity_object\"\n }\n ], ContextUser || this._contextUser);\n\n if (results[0] && results[0].Success) {\n for (const entityDocument of results[0].Results) {\n this._cache[entityDocument.ID] = entityDocument;\n }\n }\n\n if (results[1] && results[1].Success) {\n for (const entityDocumentType of results[1].Results) {\n this._typeCache[entityDocumentType.ID] = entityDocumentType;\n }\n }\n\n this._loaded = true;\n }\n}","import { Readable } from 'node:stream';\n\n/**\n * A stream to collect pages of records and emit them as individual records\n */\nexport class PagedRecords extends Readable {\n constructor() {\n super({ objectMode: true });\n }\n\n _read() {\n // no-op\n }\n\n /**\n * Adds a page of results to the stream\n * @param {Array<Record<string,unknown>>} page - The page of results to add to the stream\n */\n addPage(page) {\n page.forEach((row) => this.push(row));\n }\n\n /**\n * Called when there are no more pages to add to the stream\n */\n endStream() {\n this.push(null);\n }\n}\n","import { Embeddings, GetAIAPIKey } from '@memberjunction/ai';\nimport { VectorDBBase } from '@memberjunction/ai-vectordb';\nimport { PageRecordsParams, VectorBase } from '@memberjunction/ai-vectors';\nimport { BaseEntity, EntityField, EntityInfo, LogError, LogStatus, Metadata, RunView, RunViewResult, UserInfo } from '@memberjunction/core';\nimport { AIModelEntity, EntityDocumentEntity, EntityDocumentTypeEntity, EntityRecordDocumentEntity, TemplateContentEntity, \n TemplateContentTypeEntity, TemplateEntity, TemplateParamEntity, VectorDatabaseEntity, VectorIndexEntity } from '@memberjunction/core-entities';\nimport { MJGlobal } from '@memberjunction/global';\nimport { pipeline } from 'node:stream/promises';\nimport { EmbeddingData, TemplateParamData, VectorEmeddingData, VectorizeEntityParams, VectorizeEntityResponse } from '../generic/vectorSync.types';\nimport { BatchWorker } from './BatchWorker';\nimport { EntityDocumentCache } from './EntityDocumentCache';\nimport { PagedRecords } from './PagedRecords';\nimport { resolve } from 'node:path';\nimport { PassThrough, Transform } from 'node:stream';\nimport { AIEngine } from '@memberjunction/aiengine';\nimport { TemplateEngineServer } from '@memberjunction/templates';\nimport { TemplateEntityExtended } from '@memberjunction/templates-base-types';\n\n/**\n * Class that specializes in vectorizing entities using embedding models and upserting them into Vector Databases \n */\nexport class EntityVectorSyncer extends VectorBase {\n _startTime: Date;\n _endTime: Date;\n\n constructor() {\n super();\n }\n\n /**\n * Refreshes the EntityDocumentCache and configures the AIEngine and TemplateEngineServer\n * @param forceRefresh If true, the cache and enginges will be refreshed even if it is already loaded\n * @param contextUser The context user to use to refresh the cache and configure the engines\n */\n public async Config(forceRefresh: boolean, contextUser?: UserInfo): Promise<void> {\n super.CurrentUser = contextUser;\n await EntityDocumentCache.Instance.Refresh(forceRefresh, contextUser);\n await AIEngine.Instance.Config(forceRefresh, contextUser);\n await TemplateEngineServer.Instance.Config(forceRefresh, contextUser);\n }\n\n public async VectorizeEntity(params: VectorizeEntityParams, contextUser?: UserInfo): Promise<VectorizeEntityResponse> {\n if (!contextUser) {\n throw new Error('ContextUser is required to vectorize the entity');\n }\n\n //start row\n const delayTimeMS: number = 250;\n const startTime: number = new Date().getTime();\n super.CurrentUser = contextUser;\n await TemplateEngineServer.Instance.Config(false, contextUser);\n \n const entityDocument: EntityDocumentEntity = await this.GetEntityDocument(params.entityDocumentID);\n const vectorIndexEntity: VectorIndexEntity = await this.GetOrCreateVectorIndex(entityDocument);\n const obj: VectorEmeddingData = await this.GetVectorDatabaseAndEmbeddingClassByEntityDocumentID(params.entityDocumentID);\n\n const md = new Metadata();\n const entity: EntityInfo | undefined = md.Entities.find((e) => e.ID === params.entityID);\n if (!entity) throw new Error(`Entity with ID ${params.entityID} not found.`);\n\n\n const template: TemplateEntityExtended | undefined = TemplateEngineServer.Instance.Templates.find((t: TemplateEntityExtended) => t.ID === entityDocument.TemplateID);\n if(!template){\n throw new Error(`Template not found with ID ${entityDocument.TemplateID}`);\n }\n\n if(template.Content.length === 0){\n throw new Error(`Template ${template.ID} does not have an associated Template Content record`);\n }\n\n if(template.Content.length > 1){\n throw new Error('Templates used by Entity Documents should only have one associated Template Content record.');\n }\n\n //If this function doesnt throw an error, then the template is valid\n const validTemplate: boolean = this.ValidateTemplateContextParamAlignment(template);\n\n const pageSize: number = params.batchCount || 20;\n const dataStream = new PagedRecords();\n \n let templateObj: {} = {\n ...template.GetAll(),\n Params: template.Params.map((p) => p.To())\n }; \n\n const workerContext = { \n executionId: Date.now(), \n entity, \n entityDocument: entityDocument.To(),\n template: templateObj,\n templateContent: template.Content[0].To(),\n vectorDBClassKey: obj.vectorDBClassKey,\n vectorDBAPIKey: obj.vectorDBAPIKey,\n embeddingDriverClass: obj.embeddingDriverClass,\n embeddingAPIKey: obj.embeddingAPIKey,\n delayTimeMS\n };\n\n //annotator worker handles vectorizing the records \n const annotator = new BatchWorker({\n workerFile: resolve(__dirname, 'workers/VectorizeTemplates.js'),\n batchSize: 3,\n concurrencyLimit: 2,\n contextUser: super.CurrentUser,\n workerContext,\n });\n\n //archiver worker handles upserting the vectors into the vector database\n const archiver = new BatchWorker({ \n workerFile: resolve(__dirname, 'workers/UpsertVectors.js'), \n batchSize: 4,\n contextUser: super.CurrentUser, \n workerContext\n });\n\n const upserter = new Transform({objectMode: true, transform: (chunk, encoding, callback) => {\n this.UpsertEntityRecordDocumentRecords(chunk as EmbeddingData, super.CurrentUser).then(() => callback(null)).catch(callback);\n }});\n\n const getData = async (): Promise<void> => {\n let pageNumber = 0;\n let hasMore = true;\n\n while (hasMore) {\n let pageRecordRequest: PageRecordsParams = {\n EntityID: params.entityID,\n PageNumber: pageNumber,\n PageSize: pageSize,\n ResultType: 'simple'\n };\n\n const recordsPage: unknown[] = await super.PageRecordsByEntityID<unknown>(pageRecordRequest);\n const relatedData: TemplateParamData[] = await this.GetRelatedTemplateDataForBatch(entity, recordsPage, template);\n const items: {}[] = [];\n \n for(const record of recordsPage){\n const templateData: { [key: string]: unknown } = await this.GetTemplateData(entity, record, template, relatedData);\n //we need a reference to this record's ID for the upsert worker\n templateData.__mj_recordID = record[entity.FirstPrimaryKey.Name];\n templateData.__mj_compositeKey = entity.PrimaryKeys.map((key) => `${key.Name}|${record[key.Name]}`).join(\"||\");\n //we also need a reference to the vector index's ID\n templateData.VectorIndexID = vectorIndexEntity.ID;\n templateData.TemplateContent = template.Content[0].TemplateText;\n items.push(templateData);\n }\n\n dataStream.addPage(items);\n if(recordsPage.length < pageSize) {\n hasMore = false;\n break;\n }\n\n pageNumber++;\n }\n\n dataStream.endStream();\n };\n\n // page data asynchrounously and add to the data stream\n getData();\n\n console.log('Starting pipeline');\n await pipeline(dataStream, annotator, archiver, upserter, new PassThrough({ objectMode: true }));\n\n // const chunks: BaseEntity[][] = this.chunkArray(allrecords, batchSize);\n // LogStatus(`Processing ${allrecords.length} records in ${chunks.length} chunks of ${batchSize} records each`);\n // LogStatus(`Processing page ${pageNumber} records of ${pageSize} records each`);\n\n // Now add the records to the vectorize queue\n // The vectorize queue consumer calls the embedding service to get the embeddings\n // Then adds vectors + record metadata to the storage queue\n // The storage queue consumer adds the vectors to the vector database\n\n // let count = 0;\n // for (const batch of chunks) {\n // let templates: string[] = [];\n // for (const record of batch) {\n // let template: string = await parser.Parse(entityDocument.Template, request.entityID, record, contextUser);\n // templates.push(template);\n // }\n // LogStatus(`parsing batch ${count}: done`);\n\n // const embeddings: EmbedTextsResult = await obj.embedding.EmbedTexts({ texts: templates, model: null });\n // LogStatus(`embedding batch ${count}: done`);\n\n // const vectorRecords: VectorRecord[] = embeddings.vectors.map((vector: number[], index: number) => {\n // const record: BaseEntity = batch[index];\n // const recordID = record.PrimaryKey.Values('|');\n // return {\n // //The id breaks down to e.g. \"Accounts_7_117\"\n // id: `${entityDocument.Entity}_${entityDocument.ID}_${recordID}`,\n // values: vector,\n // metadata: {\n // EntityID: entityDocument.EntityID,\n // EntityName: entityDocument.Entity,\n // EntityDocumentID: entityDocument.ID,\n // PrimaryKey: record.PrimaryKey.ToString(),\n // Template: templates[index],\n // Data: this.ConvertEntityFieldsToString(record),\n // },\n // };\n // });\n\n // const response: BaseResponse = await obj.vectorDB.createRecords(vectorRecords);\n // if (response.success && vectorIndexEntity) {\n // LogStatus('Successfully created vector records, creating associated Entity Record Documents...');\n // for (const [index, vectorRecord] of vectorRecords.entries()) {\n // try {\n // let erdEntity: EntityRecordDocumentEntity = await super.Metadata.GetEntityObject('Entity Record Documents');\n // erdEntity.NewRecord();\n // erdEntity.EntityID = entityDocument.EntityID;\n // erdEntity.RecordID = batch[index].PrimaryKey.ToString();\n // erdEntity.DocumentText = templates[index];\n // erdEntity.VectorID = vectorRecord.id;\n // erdEntity.VectorJSON = JSON.stringify(vectorRecord.values);\n // erdEntity.VectorIndexID = vectorIndexEntity.ID;\n // erdEntity.EntityRecordUpdatedAt = new Date();\n // erdEntity.EntityDocumentID = entityDocument.ID;\n // let erdEntitySaveResult: boolean = await super.SaveEntity(erdEntity);\n // if (!erdEntitySaveResult) {\n // LogError('Error saving Entity Record Document Entity');\n // }\n // } catch (err) {\n // LogError('Error saving Entity Record Document Entity');\n // LogError(err);\n // }\n // }\n // } else {\n // LogError('Unable to successfully save records to vector database', undefined, response.message);\n // }\n\n // //add a delay to avoid rate limiting\n // let delayRes = await this.delay(1000);\n // count += 1;\n // LogStatus(`Chunk ${count} of out ${chunks.length} processed`);\n // }\n\n const endTime: number = new Date().getTime();\n LogStatus(`Finished vectorizing ${entityDocument.Entity} entity in ${endTime - startTime} ms`);\n return null;\n }\n\n /**\n * This method will create a default Entity Document for the given entityID, vectorDatabase, and AIModel\n * @param entityID\n * @param vectorDatabase\n * @param AIModel\n * @returns\n */\n public async CreateDefaultEntityDocument(\n EntityID: string,\n VectorDatabase: VectorDatabaseEntity,\n AIModel: AIModelEntity\n ): Promise<EntityDocumentEntity> {\n const md = new Metadata();\n const entity = md.Entities.find((e) => e.ID === EntityID);\n if (!entity) throw new Error(`Entity with ID ${EntityID} not found.`);\n\n const EDTemplate: string = entity.Fields.map((ef) => {\n return `${ef.Name}: \\$\\{${ef.Name}\\}`;\n }).join(' ');\n\n const rv: RunView = new RunView();\n const rvResult: RunViewResult<EntityDocumentTypeEntity> = await rv.RunView<EntityDocumentTypeEntity>({\n EntityName: 'Entity Document Types',\n ExtraFilter: `Name = 'Record Duplicate'`,\n }, super.CurrentUser);\n\n if (!rvResult.Success) {\n throw new Error(`Unable to fetch Entity Document Type: ${rvResult.ErrorMessage}`);\n }\n\n if(rvResult.Results.length === 0){\n throw new Error('Record Duplicate Entity Document Type not found');\n }\n\n const entityDocumentType: EntityDocumentTypeEntity = rvResult.Results[0];\n\n const entityDocument: EntityDocumentEntity = await md.GetEntityObject<EntityDocumentEntity>('Entity Documents');\n entityDocument.NewRecord();\n entityDocument.Name = `Default duplicate record Entity Document for the ${entity.Name} entity using vector database ${VectorDatabase.Name} and AI Model ${AIModel.Name}`;\n entityDocument.EntityID = EntityID;\n entityDocument.TypeID = entityDocumentType.ID;\n entityDocument.Status = 'Active';\n entityDocument.TemplateID = EDTemplate;\n entityDocument.VectorDatabaseID = VectorDatabase.ID;\n entityDocument.AIModelID = AIModel.ID;\n let saveResult = await this.SaveEntity(entityDocument);\n if (saveResult) {\n return entityDocument;\n } else {\n throw new Error(`Failed to save Entity Document for ${EntityID}`);\n }\n }\n\n protected async GetVectorDatabaseAndEmbeddingClassByEntityDocumentID( entityDocumentID: string, createDocumentIfNotFound?: boolean ): Promise<VectorEmeddingData> {\n let entityDocument: EntityDocumentEntity | null = EntityDocumentCache.Instance.GetDocument(entityDocumentID);\n if (!entityDocument) {\n if (createDocumentIfNotFound) {\n LogStatus(`No active Entity Document found for entity ${entityDocumentID}, creating one`);\n const defaultVectorDB: VectorDatabaseEntity = this.GetVectorDatabase();\n const defaultAIModel: AIModelEntity = this.GetAIModel();\n entityDocument = await this.CreateDefaultEntityDocument(entityDocumentID, defaultVectorDB, defaultAIModel);\n } \n else {\n throw new Error(`No Entity Document found for ID=${entityDocumentID}`);\n }\n }\n\n const vectorDBEntity: VectorDatabaseEntity = this.GetVectorDatabase(entityDocument.VectorDatabaseID);\n const aiModelEntity: AIModelEntity = this.GetAIModel(entityDocument.AIModelID);\n\n const embeddingAPIKey: string = GetAIAPIKey(aiModelEntity.DriverClass);\n const vectorDBAPIKey: string = GetAIAPIKey(vectorDBEntity.ClassKey);\n\n if (!embeddingAPIKey) {\n throw Error(`No API Key found for AI Model ${aiModelEntity.DriverClass}`);\n }\n\n if (!vectorDBAPIKey) {\n throw Error(`No API Key found for Vector Database ${vectorDBEntity.ClassKey}`);\n }\n\n //LogStatus(`Embedding API Key: ${embeddingAPIKey} VectorDB API Key: ${vectorDBAPIKey}`);\n const embedding = MJGlobal.Instance.ClassFactory.CreateInstance<Embeddings>(Embeddings, aiModelEntity.DriverClass, embeddingAPIKey);\n const vectorDB = MJGlobal.Instance.ClassFactory.CreateInstance<VectorDBBase>(VectorDBBase, vectorDBEntity.ClassKey, vectorDBAPIKey);\n\n if (!embedding) {\n throw Error(`Failed to create Embeddings instance for AI Model ${aiModelEntity.DriverClass}`);\n }\n\n if (!vectorDB) {\n throw Error(`Failed to create Vector Database instance for ${vectorDBEntity.ClassKey}`);\n }\n\n LogStatus(`Using vector database ${vectorDBEntity.Name} and AI Model ${aiModelEntity.Name}`);\n\n const obj: VectorEmeddingData = { \n embedding, \n vectorDB, \n vectorDBClassKey: vectorDBEntity.ClassKey, \n vectorDBAPIKey: vectorDBAPIKey,\n embeddingDriverClass: aiModelEntity.DriverClass,\n embeddingAPIKey: embeddingAPIKey\n };\n\n return obj;\n }\n\n public async GetEntityDocument(EntityDocumentID: string): Promise<EntityDocumentEntity | null> {\n const cache = EntityDocumentCache.Instance;\n if (!cache.IsLoaded) {\n await cache.Refresh(false, super.CurrentUser);\n }\n return cache.GetDocument(EntityDocumentID);\n }\n\n public async GetEntityDocumentByName(EntityDocumentName: string, ContextUser?: UserInfo): Promise<EntityDocumentEntity | null> {\n const cache = EntityDocumentCache.Instance;\n if (!cache.IsLoaded) {\n await cache.Refresh(false, ContextUser);\n }\n return cache.GetDocumentByName(EntityDocumentName);\n }\n\n /**\n * Returns all active Entity Documents of the 'Record Duplicate' type.\n * Note that this only returns the first active Entity Document. Meaning if there are multiple Entity Documents for the same entity, \n * only the oldest one will be returned.\n * @param entityIDs If provided, only Entity Documents for the specified entities will be returned.\n */\n public async GetActiveEntityDocuments(entityNames?: string[]): Promise<EntityDocumentEntity[]> {\n await EntityDocumentCache.Instance.Refresh(false, super.CurrentUser);\n const entityDocumentType: EntityDocumentTypeEntity | undefined = EntityDocumentCache.Instance.GetDocumentTypeByName('Record Duplicate');\n if (!entityDocumentType) {\n throw new Error('Entity Document Type not found');\n }\n\n let filter = `TypeID = '${entityDocumentType.ID}' AND Status = 'Active' `;\n if (entityNames && entityNames.length > 0) {\n filter += ` AND Entity IN (${entityNames.map((entityName: string) => `'${entityName}'`).join(',')})`;\n }\n\n const runViewResult: RunViewResult<EntityDocumentEntity> = await super.RunView.RunView<EntityDocumentEntity>({\n EntityName: 'Entity Documents',\n ExtraFilter: filter,\n ResultType: 'entity_object',\n }, super.CurrentUser);\n\n if(!runViewResult.Success){\n throw new Error(runViewResult.ErrorMessage);\n }\n\n let entityDocuments: EntityDocumentEntity[] = [];\n let seenEntities: string[] = [];\n\n //we only want one entity document per entity\n for(const entityDocument of runViewResult.Results){\n if(seenEntities.includes(entityDocument.EntityID)){\n continue;\n }\n \n entityDocuments.push(entityDocument);\n seenEntities.push(entityDocument.EntityID);\n }\n\n return entityDocuments;\n }\n\n private async GetOrCreateVectorIndex(entityDocument: EntityDocumentEntity): Promise<VectorIndexEntity> {\n let vectorIndexEntity: VectorIndexEntity = await super.RunViewForSingleValue(\n 'Vector Indexes',\n `VectorDatabaseID = '${entityDocument.VectorDatabaseID}' AND EmbeddingModelID = '${entityDocument.AIModelID}'`\n );\n\n if (vectorIndexEntity) {\n return vectorIndexEntity;\n }\n\n LogStatus(`No Vector Index found for entityDocument ${entityDocument.ID}, creating one`);\n try {\n vectorIndexEntity = await super.Metadata.GetEntityObject<VectorIndexEntity>('Vector Indexes');\n vectorIndexEntity.NewRecord();\n vectorIndexEntity.VectorDatabaseID = entityDocument.VectorDatabaseID;\n vectorIndexEntity.EmbeddingModelID = entityDocument.AIModelID;\n vectorIndexEntity.Name = `Vector Index for entityDocument ${entityDocument.EntityID}`;\n vectorIndexEntity.Set('EntityRecordUpdatedAt', new Date());\n vectorIndexEntity.Set('EntityDocumentID', entityDocument.ID);\n //not a very descriptive description, but the view has the name of the vectorDB and embedding model used\n vectorIndexEntity.Description = `Vector Index that uses the Vector database ${entityDocument.VectorDatabaseID} and ${entityDocument.AIModelID} as the embedding model`;\n const saveResult = await super.SaveEntity(vectorIndexEntity);\n if (saveResult) {\n LogStatus(`Successfully created new Vector Index Entity`);\n return vectorIndexEntity;\n } else {\n LogError('Error saving Vector Index Entity');\n return null;\n }\n } catch (err) {\n console.error(JSON.stringify(err));\n LogError(err);\n return null;\n }\n }\n\n protected async CreateTemplateForEntityDocument(entityDocument: EntityDocumentEntity): Promise<TemplateEntity> {\n const templateEntity: TemplateEntityExtended = await super.Metadata.GetEntityObject<TemplateEntityExtended>('Templates');\n templateEntity.NewRecord();\n templateEntity.Name = `Template for EntityDocument ${entityDocument.EntityID}`;\n templateEntity.Description = `The template used by EntityDocument ${entityDocument.ID}`\n templateEntity.UserID = super.CurrentUser.ID;\n templateEntity.IsActive = true;\n templateEntity.CategoryID = null;\n\n const templateEntitySaveResult = await super.SaveEntity(templateEntity);\n if(!templateEntitySaveResult){\n LogError('Error saving Template Entity', undefined, templateEntity.LatestResult);\n throw new Error(templateEntity.LatestResult.Message);\n }\n LogStatus(`Successfully created new Template Entity ${templateEntity.ID}`);\n\n //next, create the template contents record\n await TemplateEngineServer.Instance.Config(false, super.CurrentUser);\n const textContentType: TemplateContentTypeEntity = TemplateEngineServer.Instance.TemplateContentTypes.find((type: TemplateContentTypeEntity) => type.Name === 'Text');\n if(!textContentType){\n throw new Error('Text template content type not found');\n }\n\n const entityFields: EntityField[] = await this.GetEntityFieldsForSimilaritySearch(entityDocument.EntityID);\n\n const templateContentsEntity: TemplateContentEntity = await super.Metadata.GetEntityObject<TemplateContentEntity>('Template Contents');\n templateContentsEntity.NewRecord();\n templateContentsEntity.TemplateID = templateEntity.ID;\n templateContentsEntity.TypeID = textContentType.ID;\n templateContentsEntity.Priority = 1;\n templateContentsEntity.IsActive = true;\n templateContentsEntity.TemplateText = this.BuildTemplateContent(entityFields);\n\n const templateContentsEntitySaveResult = await super.SaveEntity(templateContentsEntity);\n if(!templateContentsEntitySaveResult){\n LogError('Error saving Template Entity', undefined, templateContentsEntity.LatestResult);\n throw new Error(templateContentsEntity.LatestResult.Message);\n }\n LogStatus(`Successfully created new Template Content Entity ${templateContentsEntity.ID}`);\n\n //next, create the template params record\n const templateParamsEntity: TemplateParamEntity = await super.Metadata.GetEntityObject<TemplateParamEntity>('Template Params');\n templateParamsEntity.NewRecord();\n templateParamsEntity.TemplateID = templateEntity.ID;\n templateParamsEntity.Name = 'Entity';\n templateParamsEntity.Description = 'The entity object to be used in the template';\n templateParamsEntity.Type = 'Record';\n templateParamsEntity.DefaultValue = null;\n templateParamsEntity.IsRequired = true;\n templateParamsEntity.LinkedParameterName = null;\n templateParamsEntity.LinkedParameterField = null;\n templateParamsEntity.ExtraFilter = null;\n templateParamsEntity.EntityID = entityDocument.EntityID;\n templateParamsEntity.RecordID = null;\n\n const templateParamsEntitySaveResult = await super.SaveEntity(templateParamsEntity);\n if(!templateParamsEntitySaveResult){\n LogError('Error saving Template Entity', undefined, templateParamsEntity.LatestResult);\n throw new Error(templateParamsEntity.LatestResult.Message);\n }\n LogStatus(`Successfully created new Template Param Entity ${templateParamsEntity.ID}`);\n \n templateEntity.Content.push(templateContentsEntity);\n templateEntity.Params.push(templateParamsEntity);\n TemplateEngineServer.Instance.AddTemplate(templateEntity);\n\n return templateEntity;\n }\n\n protected BuildTemplateContent(entityFields: EntityField[]): string {\n return entityFields.map((field: EntityField) => {\n return `{{Entity.${field.Name}}}`;\n }).join(' ');\n }\n\n protected async GetEntityFieldsForSimilaritySearch(entityID: string): Promise<EntityField[]> {\n //We only want fields that can potentially be the same across records\n //which means things such as IDs, timestamps, etc. are not useful\n //as they're likely to be unique or not that helpful in determining similarity\n const runViewResult: RunViewResult<EntityField> = await super.RunView.RunView<EntityField>({\n EntityName: 'Entity Fields',\n ExtraFilter: `EntityID = '${entityID}' AND IsPrimaryKey = 0 AND IsUnique = 0 AND AutoIncrement = 0 and Type NOT IN ('datetimeoffset', 'datetime')`,\n ResultType: 'entity_object',\n }, super.CurrentUser);\n\n if (!runViewResult.Success) {\n throw new Error(runViewResult.ErrorMessage);\n }\n\n return runViewResult.Results;\n }\n\n protected async GetTemplateData(entity: EntityInfo, record: unknown, template: TemplateEntityExtended, relatedData: TemplateParamData[]): Promise<{ [key: string]: any }> {\n const templateData: { [key: string]: unknown } = {};\n for(const param of template.Params){\n if(templateData[param.Name]){\n continue;\n }\n\n switch(param.Type){\n case 'Record':\n // this one is simple, we create a property by the provided name, and set the value to the record we are currently processing\n templateData[param.Name] = record;\n break;\n case 'Entity':\n // here we need to grab the related data from another entity and filter it down for the record we are current processing so it only shows the related data\n // the metadata in the param tells us what we need to know\n const paramData: TemplateParamData | undefined = relatedData.find((rd: TemplateParamData) => rd.ParamName === param.Name);\n if(!paramData){\n LogError(`No related data found for param ${param.Name} in template ${template.ID}`);\n break;\n }\n\n // now filter down the data in d to just this record and set the value of the context data to the filtered data\n templateData[param.Name] = paramData.Data.filter((rdfr: BaseEntity) => rdfr[param.LinkedParameterField] === record[entity.FirstPrimaryKey.Name]);\n break;\n case \"Array\":\n case \"Scalar\":\n case \"Object\":\n // do nothing here, as we don't directly support these param types\n LogError(`Unsupported parameter type ${param.Type} for parameter ${param.Name} in template ${template.ID}`);\n break;\n }\n }\n return templateData;\n }\n\n protected async GetRelatedTemplateDataForBatch(entity: EntityInfo, records: unknown[], template: TemplateEntityExtended): Promise<TemplateParamData[]> {\n const relatedData: TemplateParamData[] = [];\n\n for(const templateParam of template.Params){\n if(templateParam.Type !== 'Entity'){\n continue;\n }\n\n const relatedEntity = templateParam.Entity;\n const relatedField = templateParam.LinkedParameterField;\n\n // construct a filter for the related field so that we constrain the results to just the set of records linked to our recipients\n const quotes = entity.FirstPrimaryKey.NeedsQuotes ? \"'\" : \"\";\n const filter = `${relatedField} in (${records.map((record: unknown) => `${quotes}${record[entity.FirstPrimaryKey.Name]}${quotes}`).join(',')})`;\n const finalFilter = templateParam.ExtraFilter ? `(${filter}) AND (${templateParam.ExtraFilter})` : filter;\n\n const result = await super.RunView.RunView<unknown>({\n EntityName: relatedEntity,\n ExtraFilter: finalFilter,\n ResultType: 'simple'\n }, super.CurrentUser);\n\n if (result && result.Success) {\n const data: TemplateParamData = { ParamName: '', Data: [] };\n data.ParamName = templateParam.Name,\n data.Data = result.Results;\n relatedData.push(data);\n }\n else {\n LogError(`Error getting related data for entity ${relatedEntity} with filter ${finalFilter}`, undefined, result.ErrorMessage);\n }\n }\n\n return relatedData;\n }\n\n // Rather than having this logic inside the EntityRecordDocumentWorker class, it's placed here instead\n //so that the logic behind vectorizing entities isnt spread out across so many files\n protected async UpsertEntityRecordDocumentRecords(embeddingData: EmbeddingData, contextUser: UserInfo): Promise<void> {\n let md: Metadata = super.Metadata;\n let rv: RunView = super.RunView;\n let success: boolean = true;\n\n let vectorIndex: VectorIndexEntity = await md.GetEntityObject<VectorIndexEntity>('Vector Indexes', contextUser);\n let vectorIndexID: string = embeddingData.VectorIndexID.toString();\n let loadResult = await vectorIndex.Load(vectorIndexID);\n if(!loadResult){\n LogError(`Vector Index with ID ${embeddingData.VectorIndexID} not found`);\n return;\n }\n\n let entityDocument: Record<string, unknown> = embeddingData.EntityDocument;\n let entityID: unknown = entityDocument.EntityID;\n\n let existingRecords: BaseEntity[] = [];\n const runViewResult: RunViewResult<BaseEntity> = await rv.RunView<BaseEntity>({\n EntityName: 'Entity Record Documents',\n ExtraFilter: `EntityID = '${entityID}' AND EntityDocumentID = '${entityDocument.ID}' AND RecordID in (${embeddingData.__mj_recordID})`,\n ResultType: 'entity_object'\n }, contextUser);\n \n if(runViewResult.Success){\n existingRecords = runViewResult.Results;\n }\n else {\n LogError(`Error getting existing Entity Record Documents`, undefined, runViewResult.ErrorMessage);\n }\n\n let erdEntity: BaseEntity | undefined = existingRecords.find((er: BaseEntity) => er.Get(\"RecordID\").toString() === embeddingData.__mj_recordID.toString());\n if(!erdEntity){\n erdEntity = await md.GetEntityObject<BaseEntity>('Entity Record Documents', contextUser);\n erdEntity.NewRecord();\n }\n\n erdEntity.Set(\"EntityID\", entityID.toString());\n erdEntity.Set(\"RecordID\", embeddingData.__mj_recordID.toString());\n erdEntity.Set(\"DocumentText\", embeddingData.TemplateContent);\n erdEntity.Set(\"VectorID\", embeddingData.VectorID.toString());\n erdEntity.Set(\"VectorJSON\", JSON.stringify(embeddingData.Vector));\n erdEntity.Set(\"VectorIndexID\", embeddingData.VectorIndexID.toString());\n erdEntity.Set(\"EntityRecordUpdatedAt\", new Date());\n erdEntity.Set(\"EntityDocumentID\", embeddingData.EntityDocument.ID.toString());\n erdEntity.ContextCurrentUser = contextUser;\n \n let erdEntitySaveResult: boolean = await erdEntity.Save();\n if(!erdEntitySaveResult){\n LogError('Error saving Entity Record Document Entity', undefined, erdEntity.LatestResult);\n success = false;\n }\n\n if(success){\n LogStatus(\"Upserting Entity Record Documents: Complete\");\n }\n else{\n LogError(\"Upserting Entity Record Documents: Fail\");\n }\n }\n\n /**\n * This method is resposnible for determining if the template(s) given have aligned parameters, meaning they don't have overlapping parameter names that have \n * different meanings. It is okay for scenarios where there are > 1 template in use for a message to have different parameter names, but if they have the SAME parameter names\n * they must not have different settings.\n */\n protected ValidateTemplateContextParamAlignment(template: TemplateEntityExtended): boolean {\n // the params are defined in each template they will be in the Params property of the template\n const seenParams: {[key: string]: TemplateParamEntity } = {};\n for (const templateParam of template.Params) {\n const param: TemplateParamEntity | undefined = seenParams[templateParam.Name];\n // we have a duplicate parameter name, now we need to check if the definitions are the same\n if(param && param.Type !== templateParam.Type){\n throw new Error(`Parameter ${param.Name} has different types in different templates`);\n }\n else {\n seenParams[templateParam.Name] = templateParam;\n }\n }\n\n // if we get here, we are good, otherwise we will have thrown an exception\n return true;\n }\n}\n","import { CompositeKey, Metadata, UserInfo } from '@memberjunction/core';\n\n/**\n * This is an abstract base class, use the EntityDocumentTemplateParser class or a sub-class thereof.\n */\nexport abstract class EntityDocumentTemplateParserBase {\n public static ClearCache() {\n EntityDocumentTemplateParserBase.__cache = {};\n }\n public static CreateCacheKey(EntityID: string, EntityRecordPrimaryKey: string, Content: string): string {\n return `${EntityID}___${EntityRecordPrimaryKey}___${Content}`;\n }\n\n protected static __cache: { [key: string]: string } = {};\n protected static get _cache(): { [key: string]: string } {\n return EntityDocumentTemplateParserBase.__cache;\n }\n\n /**\n * This method will parse an entity document template and replace values within ${} placeholders with actual values from the entity record. In the case of function calls\n * within the placeholders, the functions object must be provided to parse the function calls.\n * @param Template - the document template to parse\n * @param EntityID - the ID of the entity\n * @param EntityRecord - the values for the entity record\n * @param ContextUser - the current user\n * @returns the evaluated value of the template incorporating fields and function call(s), if any.\n */\n public async Parse(Template: string, EntityID: string, EntityRecord: any, ContextUser: UserInfo): Promise<string> {\n if (!ContextUser) {\n throw new Error('ContextUser is required to parse the template');\n }\n\n const md = new Metadata();\n const entityInfo = md.Entities.find((e) => e.ID === EntityID);\n if (!entityInfo) {\n throw new Error(`Entity with ID ${EntityID} not found.`);\n }\n\n let compositeKey: CompositeKey = new CompositeKey();\n compositeKey.LoadFromEntityInfoAndRecord(entityInfo, EntityRecord);\n\n const regex = /\\$\\{([^{}]+)\\}/g;\n const matches = Template.matchAll(regex);\n\n // Convert matches to an array to handle them asynchronously\n const replacements = Array.from(matches).map(async (match) => {\n const content = match[1]; // The captured group from regex\n const cacheKey = EntityDocumentTemplateParserBase.CreateCacheKey(EntityID, compositeKey.ToString(), content);\n\n // check the cache and if we don't have an entry in the cache, add it\n if (!EntityDocumentTemplateParserBase._cache[cacheKey]) {\n // Cache miss, evaluate and store the result\n EntityDocumentTemplateParserBase._cache[cacheKey] = await this.evalSingleArgument(content, EntityID, EntityRecord, ContextUser);\n }\n\n return {\n old: match[0], // The entire placeholder including ${}\n new: EntityDocumentTemplateParserBase._cache[cacheKey], // The replacement value\n };\n });\n\n // Resolve all promises\n const resolvedReplacements = await Promise.all(replacements);\n\n // Replace each placeholder in the template with its resolved value\n let resolvedTemplate = Template;\n resolvedReplacements.forEach((replacement) => {\n resolvedTemplate = resolvedTemplate.replace(replacement.old, replacement.new);\n });\n\n return resolvedTemplate;\n }\n\n protected async evalSingleArgument(argument: string, entityID: string, entityRecord: any, ContextUser: UserInfo): Promise<string> {\n const funcMatch = argument.match(/(\\w+)\\(([^)]*)\\)/);\n if (funcMatch) {\n const [, funcName, paramsString] = funcMatch;\n const params = paramsString.split(',').map((param) => {\n param = param.trim();\n //if the string is wrapped in single or double quotes, remove them\n if (param.startsWith('\"') && param.endsWith('\"')) {\n return param.slice(1, -1);\n } else if (param.startsWith(\"'\") && param.endsWith(\"'\")) {\n return param.slice(1, -1);\n } else {\n return param;\n }\n });\n\n // Check if the method exists on this instance\n if (typeof this[funcName] === 'function') {\n // Call the instance method dynamically using its name and spread the params\n return this[funcName](entityID, entityRecord, ContextUser, ...params);\n } else {\n throw new Error(`Function ${funcName} is not defined.`);\n }\n } else {\n // not a function match, attempt to return the value from the entity record\n return entityRecord[argument] !== undefined ? entityRecord[argument] : '';\n }\n }\n}\n","import { CompositeKey, LogError, LogStatus, Metadata, UserInfo } from \"@memberjunction/core\";\nimport { MJGlobal, RegisterClass } from \"@memberjunction/global\";\nimport { EntityVectorSyncer } from \"../models/entityVectorSync\";\nimport { EntityDocumentTemplateParserBase } from \"./EntityDocumenTemplateParserBase\";\n\n/**\n * This is the first-level sub-class of EntityDocumentTemplateParserBase. This class is used to parse a string template with variables and functions. \n * If you wish to override functionality you can subclass it and then use the @RegisterClass decorator to register the sub-class of EntityDocumentTemplateParser with a priority of 1 or above to \n * then be used instead of the default implementation.\n */\n@RegisterClass(EntityDocumentTemplateParser)\nexport class EntityDocumentTemplateParser extends EntityDocumentTemplateParserBase {\n\n /** Convenience method to get an instance of the class and uses the ClassFactory so we can create sub-classes if they are registered with higher priorities than the base class */\n public static CreateInstance(): EntityDocumentTemplateParser {\n return MJGlobal.Instance.ClassFactory.CreateInstance<EntityDocumentTemplateParser>(EntityDocumentTemplateParser);\n }\n\n /**\n * This function \n * @param entityID \n * @param entityRecord \n * @param relationshipName \n * @param maxRows \n * @param entityDocumentName \n * @returns \n */\n protected async Relationship(entityID: string, entityRecord: any, ContextUser: UserInfo, relationshipName: string, maxRows: number, entityDocumentName: string): Promise<string> {\n // super inefficient handling to start, we'll optimize this later to call the related stuff in batch\n const md = new Metadata();\n const vectorSyncer: EntityVectorSyncer = new EntityVectorSyncer();\n vectorSyncer.CurrentUser = ContextUser;\n\n const entityInfo = md.Entities.find(e => e.ID === entityID); \n if (!entityInfo){\n throw new Error(`Entity with ID ${entityID} not found.`);\n }\n\n const re = entityInfo.RelatedEntities.find(re => re.RelatedEntity === relationshipName);\n if (!re){\n throw new Error(`Relationship ${relationshipName} not found for entity ${entityInfo.Name}`);\n }\n\n const obj = await md.GetEntityObject(entityInfo.Name, ContextUser);\n let compositeKey: CompositeKey = new CompositeKey();\n compositeKey.LoadFromEntityInfoAndRecord(entityInfo, entityRecord);\n let loadResult: boolean = await obj.InnerLoad(compositeKey);\n if (!loadResult){\n LogError(`Failed to load entity ${entityInfo.Name} with ID ${compositeKey.ToString()}`);\n return \"\";\n }\n\n const reData = await obj.GetRelatedEntityDataExt(re, null, maxRows)\n\n if (reData && reData.Data) {\n // now, get the entity document info if provided\n if (entityDocumentName && entityDocumentName.trim().length > 0) {\n // we have a document name, attempt to locate it\n const doc = await vectorSyncer.GetEntityDocumentByName(entityDocumentName, ContextUser);\n if (doc) {\n // we have the document, now we need to parse it and build a result that is the concatenation of all the parsed documents\n // start off by creating an instance of the parser using CreateInstance() so we're using the highest priority registered subclass\n const parser = EntityDocumentTemplateParser.CreateInstance();\n\n // now we need to batch the requests to the parser to have the right concurrency\n const batchSize = 10; // Set the batch size to the desired number of concurrent requests\n const results = [];\n \n for (let i = 0; i < reData.Data.length; i += batchSize) {\n const batchPromises = reData.Data.slice(i, i + batchSize).map(data => {\n return parser.Parse((doc as any).Template, re.RelatedEntityID, data, ContextUser);\n });\n const batchResults = await Promise.all(batchPromises);\n results.push(...batchResults);\n }\n \n return results.map(r => r + \"\\n\\n\").join('');\n }\n else {\n LogStatus(`Entity Document with name ${entityDocumentName} not found.`);\n return \"\";\n }\n }\n else {\n // no entity document name provided, just return the data in a simple format\n return JSON.stringify({ Relationship: relationshipName, Data: reData.Data});\n }\n }\n else {\n return \"{ No Data for: \" + relationshipName + \" }\"\n }\n }\n}"],"names":["Transform","Worker","LogStatus","RunView","Readable","VectorBase","AIEngine","TemplateEngineServer","Metadata","resolve","pipeline","PassThrough","GetAIAPIKey","MJGlobal","Embeddings","VectorDBBase","LogError","CompositeKey","EntityDocumentTemplateParser","RegisterClass"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/ai-vector-sync",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.3",
|
|
4
4
|
"description": "MemberJunction: AI Vector/Entity Sync Package - handles synchronization between MemberJunction entities and vector databases",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -15,17 +15,17 @@
|
|
|
15
15
|
"author": "MemberJunction.com",
|
|
16
16
|
"license": "ISC",
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@memberjunction/ai": "2.3.
|
|
19
|
-
"@memberjunction/ai-vectordb": "2.3.
|
|
20
|
-
"@memberjunction/ai-vectors": "2.3.
|
|
21
|
-
"@memberjunction/ai-vectors-pinecone": "2.3.
|
|
22
|
-
"@memberjunction/ai-mistral": "2.3.
|
|
23
|
-
"@memberjunction/aiengine": "2.3.
|
|
24
|
-
"@memberjunction/core": "2.3.
|
|
25
|
-
"@memberjunction/global": "2.3.
|
|
26
|
-
"@memberjunction/templates": "2.3.
|
|
27
|
-
"@memberjunction/templates-base-types": "2.3.
|
|
28
|
-
"@memberjunction/ai-openai": "2.3.
|
|
18
|
+
"@memberjunction/ai": "2.3.3",
|
|
19
|
+
"@memberjunction/ai-vectordb": "2.3.3",
|
|
20
|
+
"@memberjunction/ai-vectors": "2.3.3",
|
|
21
|
+
"@memberjunction/ai-vectors-pinecone": "2.3.3",
|
|
22
|
+
"@memberjunction/ai-mistral": "2.3.3",
|
|
23
|
+
"@memberjunction/aiengine": "2.3.3",
|
|
24
|
+
"@memberjunction/core": "2.3.3",
|
|
25
|
+
"@memberjunction/global": "2.3.3",
|
|
26
|
+
"@memberjunction/templates": "2.3.3",
|
|
27
|
+
"@memberjunction/templates-base-types": "2.3.3",
|
|
28
|
+
"@memberjunction/ai-openai": "2.3.3",
|
|
29
29
|
"dotenv": "^16.4.1",
|
|
30
30
|
"typeorm": "^0.3.20"
|
|
31
31
|
},
|