@infuro/cms-core 1.0.19 → 1.0.20

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.
@@ -0,0 +1,57 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ export class LlmAgents1775300000000 implements MigrationInterface {
4
+ name = 'LlmAgents1775300000000';
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(`
8
+ CREATE TABLE IF NOT EXISTS "llm_agents" (
9
+ "id" SERIAL NOT NULL,
10
+ "name" character varying NOT NULL,
11
+ "slug" character varying NOT NULL,
12
+ "system_instruction" text NOT NULL DEFAULT '',
13
+ "model" character varying,
14
+ "temperature" double precision,
15
+ "max_tokens" integer,
16
+ "validation_rules" text,
17
+ "enabled" boolean NOT NULL DEFAULT true,
18
+ "createdAt" TIMESTAMP NOT NULL DEFAULT now(),
19
+ "updatedAt" TIMESTAMP NOT NULL DEFAULT now(),
20
+ "deletedAt" TIMESTAMP,
21
+ "deleted" boolean NOT NULL DEFAULT false,
22
+ "createdBy" integer,
23
+ "updatedBy" integer,
24
+ "deletedBy" integer,
25
+ CONSTRAINT "PK_llm_agents" PRIMARY KEY ("id")
26
+ )
27
+ `);
28
+ await queryRunner.query(`
29
+ CREATE UNIQUE INDEX IF NOT EXISTS "UQ_llm_agents_slug_active"
30
+ ON "llm_agents" ("slug")
31
+ WHERE "deleted" = false
32
+ `);
33
+ await queryRunner.query(`
34
+ INSERT INTO "permissions" ("groupId", entity, "canCreate", "canRead", "canUpdate", "canDelete")
35
+ SELECT g.id, 'llm_agents', true, true, true, true
36
+ FROM "user_groups" g
37
+ WHERE g.name = 'Administrator' AND g.deleted = false
38
+ ON CONFLICT ("groupId", entity) DO UPDATE SET
39
+ "canCreate" = EXCLUDED."canCreate",
40
+ "canRead" = EXCLUDED."canRead",
41
+ "canUpdate" = EXCLUDED."canUpdate",
42
+ "canDelete" = EXCLUDED."canDelete",
43
+ "updatedAt" = now()
44
+ `);
45
+ }
46
+
47
+ public async down(queryRunner: QueryRunner): Promise<void> {
48
+ await queryRunner.query(`
49
+ DELETE FROM "permissions" p
50
+ USING "user_groups" g
51
+ WHERE p."groupId" = g.id AND g.name = 'Administrator'
52
+ AND p.entity = 'llm_agents'
53
+ `);
54
+ await queryRunner.query(`DROP INDEX IF EXISTS "UQ_llm_agents_slug_active"`);
55
+ await queryRunner.query(`DROP TABLE IF EXISTS "llm_agents"`);
56
+ }
57
+ }
@@ -0,0 +1,43 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ /**
4
+ * If `1775300000000` ran with jsonb before the column was changed to text, convert existing data.
5
+ */
6
+ export class LlmAgentsValidationRulesText1775300000001 implements MigrationInterface {
7
+ name = 'LlmAgentsValidationRulesText1775300000001';
8
+
9
+ public async up(queryRunner: QueryRunner): Promise<void> {
10
+ await queryRunner.query(`
11
+ DO $$
12
+ BEGIN
13
+ IF EXISTS (
14
+ SELECT 1 FROM information_schema.columns
15
+ WHERE table_schema = 'public' AND table_name = 'llm_agents' AND column_name = 'validation_rules'
16
+ AND data_type = 'jsonb'
17
+ ) THEN
18
+ ALTER TABLE "llm_agents" ALTER COLUMN "validation_rules" TYPE text USING ("validation_rules"::text);
19
+ END IF;
20
+ END $$;
21
+ `);
22
+ }
23
+
24
+ public async down(queryRunner: QueryRunner): Promise<void> {
25
+ await queryRunner.query(`
26
+ DO $$
27
+ BEGIN
28
+ IF EXISTS (
29
+ SELECT 1 FROM information_schema.columns
30
+ WHERE table_schema = 'public' AND table_name = 'llm_agents' AND column_name = 'validation_rules'
31
+ AND data_type = 'text'
32
+ ) THEN
33
+ ALTER TABLE "llm_agents" ALTER COLUMN "validation_rules" TYPE jsonb USING (
34
+ CASE
35
+ WHEN "validation_rules" IS NULL OR trim("validation_rules") = '' THEN NULL
36
+ ELSE "validation_rules"::jsonb
37
+ END
38
+ );
39
+ END IF;
40
+ END $$;
41
+ `);
42
+ }
43
+ }
@@ -0,0 +1,33 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ /**
4
+ * Ensures the Administrator group has full CRUD on `llm_agents` (matches CMS_ENTITY_MAP and CRUD RBAC).
5
+ * Idempotent: safe if LlmAgents1775300000000 already inserted the same row.
6
+ */
7
+ export class SeedLlmAgentsPermissions1775300000002 implements MigrationInterface {
8
+ name = 'SeedLlmAgentsPermissions1775300000002';
9
+
10
+ public async up(queryRunner: QueryRunner): Promise<void> {
11
+ await queryRunner.query(`
12
+ INSERT INTO "permissions" ("groupId", entity, "canCreate", "canRead", "canUpdate", "canDelete")
13
+ SELECT g.id, 'llm_agents', true, true, true, true
14
+ FROM "user_groups" g
15
+ WHERE g.name = 'Administrator' AND g.deleted = false
16
+ ON CONFLICT ("groupId", entity) DO UPDATE SET
17
+ "canCreate" = EXCLUDED."canCreate",
18
+ "canRead" = EXCLUDED."canRead",
19
+ "canUpdate" = EXCLUDED."canUpdate",
20
+ "canDelete" = EXCLUDED."canDelete",
21
+ "updatedAt" = now()
22
+ `);
23
+ }
24
+
25
+ public async down(queryRunner: QueryRunner): Promise<void> {
26
+ await queryRunner.query(`
27
+ DELETE FROM "permissions" p
28
+ USING "user_groups" g
29
+ WHERE p."groupId" = g.id AND g.name = 'Administrator' AND g.deleted = false
30
+ AND p.entity = 'llm_agents'
31
+ `);
32
+ }
33
+ }
@@ -0,0 +1,50 @@
1
+ import { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ export class LlmAgentKnowledgeDocuments1775300000003 implements MigrationInterface {
4
+ name = 'LlmAgentKnowledgeDocuments1775300000003';
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(`
8
+ CREATE TABLE IF NOT EXISTS "llm_agent_knowledge_documents" (
9
+ "id" SERIAL NOT NULL,
10
+ "agentId" integer NOT NULL,
11
+ "documentId" integer NOT NULL,
12
+ "createdAt" TIMESTAMP NOT NULL DEFAULT now(),
13
+ CONSTRAINT "PK_llm_agent_knowledge_documents" PRIMARY KEY ("id")
14
+ )`);
15
+ await queryRunner.query(`
16
+ DO $$ BEGIN
17
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'FK_llm_agent_knowledge_agent') THEN
18
+ ALTER TABLE "llm_agent_knowledge_documents"
19
+ ADD CONSTRAINT "FK_llm_agent_knowledge_agent"
20
+ FOREIGN KEY ("agentId") REFERENCES "llm_agents"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
21
+ END IF;
22
+ END $$;`);
23
+ await queryRunner.query(`
24
+ DO $$ BEGIN
25
+ IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'FK_llm_agent_knowledge_document') THEN
26
+ ALTER TABLE "llm_agent_knowledge_documents"
27
+ ADD CONSTRAINT "FK_llm_agent_knowledge_document"
28
+ FOREIGN KEY ("documentId") REFERENCES "knowledge_base_documents"("id") ON DELETE CASCADE ON UPDATE NO ACTION;
29
+ END IF;
30
+ END $$;`);
31
+ await queryRunner.query(`
32
+ CREATE UNIQUE INDEX IF NOT EXISTS "UQ_llm_agent_knowledge_agent_document"
33
+ ON "llm_agent_knowledge_documents" ("agentId", "documentId")`);
34
+ await queryRunner.query(`
35
+ CREATE INDEX IF NOT EXISTS "IDX_llm_agent_knowledge_agent"
36
+ ON "llm_agent_knowledge_documents" ("agentId")`);
37
+ }
38
+
39
+ public async down(queryRunner: QueryRunner): Promise<void> {
40
+ await queryRunner.query(`DROP INDEX IF EXISTS "IDX_llm_agent_knowledge_agent"`);
41
+ await queryRunner.query(`DROP INDEX IF EXISTS "UQ_llm_agent_knowledge_agent_document"`);
42
+ await queryRunner.query(
43
+ `ALTER TABLE "llm_agent_knowledge_documents" DROP CONSTRAINT IF EXISTS "FK_llm_agent_knowledge_document"`
44
+ );
45
+ await queryRunner.query(
46
+ `ALTER TABLE "llm_agent_knowledge_documents" DROP CONSTRAINT IF EXISTS "FK_llm_agent_knowledge_agent"`
47
+ );
48
+ await queryRunner.query(`DROP TABLE IF EXISTS "llm_agent_knowledge_documents"`);
49
+ }
50
+ }
@@ -0,0 +1,32 @@
1
+ import type { MigrationInterface, QueryRunner } from 'typeorm';
2
+
3
+ /**
4
+ * Alter knowledge_base_chunks.embedding from vector(1536) to vector(384)
5
+ * to match HF embedding models like BAAI/bge-small-en-v1.5.
6
+ *
7
+ * Existing rows with 1536-dim vectors will be dropped (set to NULL) by
8
+ * pgvector on dimension change — re-run an embedding pass after this migration.
9
+ */
10
+ export class KnowledgeBaseVectorDimension3841775400000000 implements MigrationInterface {
11
+ name = 'KnowledgeBaseVectorDimension3841775400000000';
12
+
13
+ public async up(queryRunner: QueryRunner): Promise<void> {
14
+ // Clear existing embeddings that have the wrong dimension before altering
15
+ await queryRunner.query(
16
+ `UPDATE "knowledge_base_chunks" SET "embedding" = NULL WHERE "embedding" IS NOT NULL`
17
+ );
18
+ await queryRunner.query(
19
+ `ALTER TABLE "knowledge_base_chunks" ALTER COLUMN "embedding" TYPE vector(384)`
20
+ );
21
+ }
22
+
23
+ public async down(queryRunner: QueryRunner): Promise<void> {
24
+ // Revert to original 1536 dimensions; clear embeddings first
25
+ await queryRunner.query(
26
+ `UPDATE "knowledge_base_chunks" SET "embedding" = NULL WHERE "embedding" IS NOT NULL`
27
+ );
28
+ await queryRunner.query(
29
+ `ALTER TABLE "knowledge_base_chunks" ALTER COLUMN "embedding" TYPE vector(1536)`
30
+ );
31
+ }
32
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@infuro/cms-core",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -54,7 +54,8 @@
54
54
  "link": "npm run build && npm link",
55
55
  "prepublishOnly": "npm run build",
56
56
  "migration:run": "cross-env TYPEORM_CLI=1 tsx -r dotenv/config node_modules/typeorm/cli.js migration:run -d src/scripts/migration-datasource.cjs",
57
- "migration:revert": "cross-env TYPEORM_CLI=1 tsx -r dotenv/config node_modules/typeorm/cli.js migration:revert -d src/scripts/migration-datasource.cjs"
57
+ "migration:revert": "cross-env TYPEORM_CLI=1 tsx -r dotenv/config node_modules/typeorm/cli.js migration:revert -d src/scripts/migration-datasource.cjs",
58
+ "test:chat-agent": "tsx -r dotenv/config scripts/test-chat-agent.ts"
58
59
  },
59
60
  "peerDependencies": {
60
61
  "@craftjs/core": ">=0.2.0",
@@ -65,21 +66,21 @@
65
66
  "typeorm": ">=0.3.20"
66
67
  },
67
68
  "devDependencies": {
68
- "cross-env": "^7.0.3",
69
- "dotenv": "^16.4.5",
70
- "shx": "^0.3.4",
71
- "tsx": "^4.19.2",
72
69
  "@craftjs/core": "^0.2.12",
73
70
  "@types/adm-zip": "^0.5.5",
74
71
  "@types/node": "^22",
75
72
  "@types/nodemailer": "^6.4.0",
76
73
  "@types/papaparse": "^5.3.14",
77
74
  "@types/react": "19.0.8",
75
+ "cross-env": "^7.0.3",
76
+ "dotenv": "^16.4.5",
78
77
  "next": "^15.5.13",
79
78
  "next-auth": "^4.24.11",
80
79
  "react": "19.0.1",
81
80
  "react-dom": "19.0.1",
81
+ "shx": "^0.3.4",
82
82
  "tsup": "^8.0.0",
83
+ "tsx": "^4.19.2",
83
84
  "typeorm": "^0.3.20",
84
85
  "typescript": "^5.3.3"
85
86
  },
@@ -114,6 +115,7 @@
114
115
  "next-themes": "^0.2.1",
115
116
  "nodemailer": "^8.0.2",
116
117
  "papaparse": "^5.4.1",
118
+ "pdf-parse": "^1.1.1",
117
119
  "pg": "^8.20.0",
118
120
  "razorpay": "^2.9.6",
119
121
  "react-chartjs-2": "^5.3.0",