Skip to content

Commit 5bc642d

Browse files
committed
Added a separate endpoint for establishing relations between nodes
1 parent f7065e2 commit 5bc642d

File tree

7 files changed

+166
-9
lines changed

7 files changed

+166
-9
lines changed

ai-assistant/src/RocketChatterApp.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { StyleguideCommand } from "./commands/Styleguide";
2525
import { SuggestCommand } from "./commands/SuggestCommand";
2626
import { TranslateCommand } from "./commands/TranslateCommand";
2727
import { WhyUsedCommand } from "./commands/WhyUsedCommand";
28+
import { EstablishRelationsEndpoint } from "./endpoints/establishRelations";
2829
import { IngestEndpoint } from "./endpoints/ingest";
2930
import { PurgeDBEndpoint } from "./endpoints/purgeDB";
3031
import { handleModalViewSubmit } from "./utils/handleModalViewSubmit";
@@ -69,6 +70,7 @@ export class RocketChatterApp extends App {
6970
endpoints: [
7071
new IngestEndpoint(this),
7172
new PurgeDBEndpoint(this),
73+
new EstablishRelationsEndpoint(this),
7274
],
7375
});
7476

ai-assistant/src/core/db/db.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { IEmbeddingModel } from "../embeddings/embeddings.types";
22

3-
export type DBNodeRelation = "CONTAINS" | "USES";
3+
export type DBNodeRelationType = "CONTAINS" | "USES"
4+
export type DBNodeRelation = { target: string; relation: DBNodeRelationType }
45

56
export class DBNode {
67
id: string;
@@ -10,7 +11,7 @@ export class DBNode {
1011
code: string;
1112

1213
filePath: string;
13-
relations: { target: string; relation: DBNodeRelation }[];
14+
relations: DBNodeRelation[];
1415

1516
nameEmbeddings: number[];
1617
codeEmbeddings: number[];
@@ -24,7 +25,7 @@ export class DBNode {
2425
type: string;
2526
code: string;
2627
filePath: string;
27-
relations: { target: string; relation: DBNodeRelation }[];
28+
relations: DBNodeRelation[];
2829
nameEmbeddings: number[];
2930
codeEmbeddings: number[];
3031
descriptor: "Node" | string;
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import {
2+
IHttp,
3+
IModify,
4+
IPersistence,
5+
IRead,
6+
} from "@rocket.chat/apps-engine/definition/accessors";
7+
import {
8+
ApiEndpoint,
9+
IApiEndpointInfo,
10+
IApiRequest,
11+
IApiResponse,
12+
} from "@rocket.chat/apps-engine/definition/api";
13+
import { IDB } from "../core/db/db.types";
14+
import { Neo4j } from "../core/db/neo4j";
15+
import { EstablishRelationsEndpointRelations, EstablishRelationsEndpointRequestBody, EstablishRelationsEndpointResponseBody } from "./establishRelations.types";
16+
17+
namespace Helpers {
18+
async function establishRelation(
19+
db: IDB,
20+
sourceID: string,
21+
targetID: string,
22+
relation: string
23+
) {
24+
const query = [
25+
`MATCH (n { id: $sourceID })`,
26+
`MATCH (m { id: $targetID })`,
27+
`CREATE (n)-[:${relation}]->(m)\n`,
28+
].join("\n");
29+
try {
30+
await db.run(query, { sourceID, targetID });
31+
} catch (e) {
32+
console.error(e);
33+
}
34+
}
35+
36+
export async function establishRelations(db: IDB, relations: EstablishRelationsEndpointRelations[]) {
37+
const jobs: Promise<any>[] = [];
38+
for (const relation of relations) {
39+
const job = establishRelation(
40+
db,
41+
relation.source,
42+
relation.target,
43+
relation.relation
44+
);
45+
jobs.push(job);
46+
}
47+
await Promise.all(jobs);
48+
}
49+
}
50+
51+
export class EstablishRelationsEndpoint extends ApiEndpoint {
52+
public path = "establishRelations";
53+
54+
makeBodies(
55+
content: any
56+
): [EstablishRelationsEndpointRequestBody, EstablishRelationsEndpointResponseBody] {
57+
const requestBody = JSON.parse(content) as EstablishRelationsEndpointRequestBody;
58+
const responseBody: EstablishRelationsEndpointResponseBody = {
59+
status: 200,
60+
};
61+
62+
return [requestBody, responseBody];
63+
}
64+
65+
async commitProgress(
66+
db: IDB
67+
): Promise<EstablishRelationsEndpointResponseBody["status"]> {
68+
try {
69+
try {
70+
await db.commitTransaction();
71+
} catch (e) {
72+
console.error(e);
73+
await db.rollbackTransaction();
74+
75+
return 500;
76+
}
77+
} catch (e) {
78+
console.error(e);
79+
return 500;
80+
}
81+
82+
return 200;
83+
}
84+
85+
public async post(
86+
request: IApiRequest,
87+
endpoint: IApiEndpointInfo,
88+
read: IRead,
89+
modify: IModify,
90+
http: IHttp,
91+
persis: IPersistence
92+
): Promise<IApiResponse> {
93+
let [{ relations }, responseBody] = this.makeBodies(request.content);
94+
95+
const db = new Neo4j(http);
96+
await db.verifyConnectivity();
97+
// -----------------------------------------------------------------------------------
98+
await db.beginTransaction();
99+
await Helpers.establishRelations(db, relations);
100+
responseBody.status = await this.commitProgress(db);
101+
// -----------------------------------------------------------------------------------
102+
103+
return this.success(JSON.stringify(responseBody));
104+
}
105+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { DBNodeRelationType } from "../core/db/db";
2+
3+
export type EstablishRelationsEndpointRelations = {
4+
source: string;
5+
target: string;
6+
relation: DBNodeRelationType;
7+
}
8+
9+
export type EstablishRelationsEndpointRequestBody = {
10+
relations: EstablishRelationsEndpointRelations[];
11+
};
12+
13+
export type EstablishRelationsEndpointResponseBody = {
14+
status: 200 | 500;
15+
};

ai-assistant/src/endpoints/ingest.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ export class IngestEndpoint extends ApiEndpoint {
126126
await db.beginTransaction();
127127
// -----------------------------------------------------------------------------------
128128
await Helpers.insertNodes(db, nodes);
129-
await Helpers.establishRelations(db, nodes);
130129
// -----------------------------------------------------------------------------------
131130
responseBody.status = await this.commitProgress(db);
132131
// -----------------------------------------------------------------------------------

ingestion/src/core/dbNode.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import { TreeNode } from "../process/prepare/processor/core/treeNode"
1+
import { TreeNode } from "../process/prepare/processor/core/treeNode";
22

3-
export type DBNodeRelation = "CONTAINS" | "USES"
3+
export type DBNodeRelationType = "CONTAINS" | "USES"
4+
export type DBNodeRelation = { target: string; relation: DBNodeRelationType }
45

56
export class DBNode {
67
id: string
@@ -10,7 +11,7 @@ export class DBNode {
1011
code: string
1112

1213
filePath: string
13-
relations: { target: string; relation: DBNodeRelation }[]
14+
relations: DBNodeRelation[]
1415

1516
nameEmbeddings: number[]
1617
codeEmbeddings: number[]
@@ -24,7 +25,7 @@ export class DBNode {
2425
type: string
2526
code: string
2627
filePath: string
27-
relations: { target: string; relation: DBNodeRelation }[]
28+
relations: DBNodeRelation[]
2829
nameEmbeddings: number[]
2930
codeEmbeddings: number[]
3031
descriptor: "Node" | string

ingestion/src/process/ingest/ingest.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import path from "path"
44

55
import { v4 as uuid } from "uuid"
66
import { RC_APP_URI } from "../../constants"
7-
import { DBNode } from "../../core/dbNode"
7+
import { DBNode, DBNodeRelation } from "../../core/dbNode"
88

99
namespace Algorithms {
1010
export async function purgeDB(): Promise<boolean> {
@@ -39,6 +39,23 @@ namespace Algorithms {
3939
return false
4040
}
4141
}
42+
43+
export async function establishRelations(relations: DBNodeRelation[]): Promise<boolean> {
44+
try {
45+
const res = await fetch(`${RC_APP_URI}/establishRelations`, {
46+
method: "POST",
47+
headers: {
48+
"Content-Type": "application/json",
49+
},
50+
body: JSON.stringify({ relations }),
51+
})
52+
53+
return res.status === 200
54+
} catch (e) {
55+
console.log(e);
56+
return false
57+
}
58+
}
4259
}
4360

4461
export async function insertDataIntoDB(batchesDirPath: string) {
@@ -61,12 +78,21 @@ export async function insertDataIntoDB(batchesDirPath: string) {
6178
{
6279
const errorBatches: Set<string> = new Set()
6380

81+
const relations: DBNodeRelation[] = []
82+
6483
// Insert each batch
6584
for (const file of files) {
6685
const batchID = uuid()
6786
const data = await readFile(file, "utf-8")
6887
const nodes = Object.values(JSON.parse(data)) as DBNode[]
6988

89+
for (const node of nodes)
90+
relations.push(...node.relations.map((relation) => ({
91+
source: node.id,
92+
target: relation.target,
93+
relation: relation.relation,
94+
})))
95+
7096
const success = await Algorithms.insertBatch(batchID, nodes)
7197
if (success) {
7298
console.log(`📦 ${batchID} inserted`)
@@ -76,6 +102,14 @@ export async function insertDataIntoDB(batchesDirPath: string) {
76102
}
77103
if (errorBatches.size > 0)
78104
console.log("❌ Error batches", errorBatches)
105+
106+
// Establish relations
107+
const success = await Algorithms.establishRelations(relations)
108+
if (success) {
109+
console.log("🔗 Relations established")
110+
} else {
111+
console.log("❌ Error establishing relations")
112+
}
79113
}
80114

81115
console.log("✅ Inserted")

0 commit comments

Comments
 (0)