Skip to content

Commit b02bdc7

Browse files
Feature: Custom Templates (#3169)
* New Feature: Custom Templates in the marketplace. * New Feature: Custom Templates in the marketplace. * Custom Template Delete and Shortcut in the dropdown menu * auto detect framework * minor ui fixes * adding custom template feature for tools * ui tool dialog save template --------- Co-authored-by: Henry <[email protected]>
1 parent 44b70ca commit b02bdc7

File tree

23 files changed

+1213
-166
lines changed

23 files changed

+1213
-166
lines changed

packages/server/src/Interface.ts

+13
Original file line numberDiff line numberDiff line change
@@ -273,5 +273,18 @@ export interface IApiKey {
273273
updatedDate: Date
274274
}
275275

276+
export interface ICustomTemplate {
277+
id: string
278+
name: string
279+
flowData: string
280+
updatedDate: Date
281+
createdDate: Date
282+
description?: string
283+
type?: string
284+
badge?: string
285+
framework?: string
286+
usecases?: string
287+
}
288+
276289
// DocumentStore related
277290
export * from './Interface.DocumentStore'

packages/server/src/controllers/marketplaces/index.ts

+45-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { Request, Response, NextFunction } from 'express'
22
import marketplacesService from '../../services/marketplaces'
3+
import { InternalFlowiseError } from '../../errors/internalFlowiseError'
4+
import { StatusCodes } from 'http-status-codes'
35

46
// Get all templates for marketplaces
57
const getAllTemplates = async (req: Request, res: Response, next: NextFunction) => {
@@ -11,6 +13,48 @@ const getAllTemplates = async (req: Request, res: Response, next: NextFunction)
1113
}
1214
}
1315

16+
const deleteCustomTemplate = async (req: Request, res: Response, next: NextFunction) => {
17+
try {
18+
if (typeof req.params === 'undefined' || !req.params.id) {
19+
throw new InternalFlowiseError(
20+
StatusCodes.PRECONDITION_FAILED,
21+
`Error: marketplacesService.deleteCustomTemplate - id not provided!`
22+
)
23+
}
24+
const apiResponse = await marketplacesService.deleteCustomTemplate(req.params.id)
25+
return res.json(apiResponse)
26+
} catch (error) {
27+
next(error)
28+
}
29+
}
30+
31+
const getAllCustomTemplates = async (req: Request, res: Response, next: NextFunction) => {
32+
try {
33+
const apiResponse = await marketplacesService.getAllCustomTemplates()
34+
return res.json(apiResponse)
35+
} catch (error) {
36+
next(error)
37+
}
38+
}
39+
40+
const saveCustomTemplate = async (req: Request, res: Response, next: NextFunction) => {
41+
try {
42+
if ((!req.body && !(req.body.chatflowId || req.body.tool)) || !req.body.name) {
43+
throw new InternalFlowiseError(
44+
StatusCodes.PRECONDITION_FAILED,
45+
`Error: marketplacesService.saveCustomTemplate - body not provided!`
46+
)
47+
}
48+
const apiResponse = await marketplacesService.saveCustomTemplate(req.body)
49+
return res.json(apiResponse)
50+
} catch (error) {
51+
next(error)
52+
}
53+
}
54+
1455
export default {
15-
getAllTemplates
56+
getAllTemplates,
57+
getAllCustomTemplates,
58+
saveCustomTemplate,
59+
deleteCustomTemplate
1660
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { ICustomTemplate } from '../../Interface'
2+
import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'
3+
4+
@Entity('custom_template')
5+
export class CustomTemplate implements ICustomTemplate {
6+
@PrimaryGeneratedColumn('uuid')
7+
id: string
8+
9+
@Column()
10+
name: string
11+
12+
@Column({ type: 'text' })
13+
flowData: string
14+
15+
@Column({ nullable: true, type: 'text' })
16+
description?: string
17+
18+
@Column({ nullable: true, type: 'text' })
19+
badge?: string
20+
21+
@Column({ nullable: true, type: 'text' })
22+
framework?: string
23+
24+
@Column({ nullable: true, type: 'text' })
25+
usecases?: string
26+
27+
@Column({ nullable: true, type: 'text' })
28+
type?: string
29+
30+
@Column({ type: 'timestamp' })
31+
@CreateDateColumn()
32+
createdDate: Date
33+
34+
@Column({ type: 'timestamp' })
35+
@UpdateDateColumn()
36+
updatedDate: Date
37+
}

packages/server/src/database/entities/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { DocumentStoreFileChunk } from './DocumentStoreFileChunk'
1010
import { Lead } from './Lead'
1111
import { UpsertHistory } from './UpsertHistory'
1212
import { ApiKey } from './ApiKey'
13+
import { CustomTemplate } from './CustomTemplate'
1314

1415
export const entities = {
1516
ChatFlow,
@@ -23,5 +24,6 @@ export const entities = {
2324
DocumentStoreFileChunk,
2425
Lead,
2526
UpsertHistory,
26-
ApiKey
27+
ApiKey,
28+
CustomTemplate
2729
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { MigrationInterface, QueryRunner } from 'typeorm'
2+
3+
export class AddCustomTemplate1725629836652 implements MigrationInterface {
4+
public async up(queryRunner: QueryRunner): Promise<void> {
5+
await queryRunner.query(
6+
`CREATE TABLE IF NOT EXISTS \`custom_template\` (
7+
\`id\` varchar(36) NOT NULL,
8+
\`name\` varchar(255) NOT NULL,
9+
\`flowData\` text NOT NULL,
10+
\`description\` varchar(255) DEFAULT NULL,
11+
\`badge\` varchar(255) DEFAULT NULL,
12+
\`framework\` varchar(255) DEFAULT NULL,
13+
\`usecases\` varchar(255) DEFAULT NULL,
14+
\`type\` varchar(30) DEFAULT NULL,
15+
\`createdDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
16+
\`updatedDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
17+
PRIMARY KEY (\`id\`)
18+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;`
19+
)
20+
}
21+
22+
public async down(queryRunner: QueryRunner): Promise<void> {
23+
await queryRunner.query(`DROP TABLE custom_template`)
24+
}
25+
}

packages/server/src/database/migrations/mariadb/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { AddTypeToChatFlow1716300000000 } from './1716300000000-AddTypeToChatFlo
2323
import { AddApiKey1720230151480 } from './1720230151480-AddApiKey'
2424
import { AddActionToChatMessage1721078251523 } from './1721078251523-AddActionToChatMessage'
2525
import { LongTextColumn1722301395521 } from './1722301395521-LongTextColumn'
26+
import { AddCustomTemplate1725629836652 } from './1725629836652-AddCustomTemplate'
2627

2728
export const mariadbMigrations = [
2829
Init1693840429259,
@@ -49,5 +50,6 @@ export const mariadbMigrations = [
4950
AddTypeToChatFlow1716300000000,
5051
AddApiKey1720230151480,
5152
AddActionToChatMessage1721078251523,
52-
LongTextColumn1722301395521
53+
LongTextColumn1722301395521,
54+
AddCustomTemplate1725629836652
5355
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { MigrationInterface, QueryRunner } from 'typeorm'
2+
3+
export class AddCustomTemplate1725629836652 implements MigrationInterface {
4+
public async up(queryRunner: QueryRunner): Promise<void> {
5+
await queryRunner.query(
6+
`CREATE TABLE IF NOT EXISTS \`custom_template\` (
7+
\`id\` varchar(36) NOT NULL,
8+
\`name\` varchar(255) NOT NULL,
9+
\`flowData\` text NOT NULL,
10+
\`description\` varchar(255) DEFAULT NULL,
11+
\`badge\` varchar(255) DEFAULT NULL,
12+
\`framework\` varchar(255) DEFAULT NULL,
13+
\`usecases\` varchar(255) DEFAULT NULL,
14+
\`type\` varchar(30) DEFAULT NULL,
15+
\`createdDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
16+
\`updatedDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
17+
PRIMARY KEY (\`id\`)
18+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;`
19+
)
20+
}
21+
22+
public async down(queryRunner: QueryRunner): Promise<void> {
23+
await queryRunner.query(`DROP TABLE custom_template`)
24+
}
25+
}

packages/server/src/database/migrations/mysql/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { AddTypeToChatFlow1716300000000 } from './1716300000000-AddTypeToChatFlo
2424
import { AddApiKey1720230151480 } from './1720230151480-AddApiKey'
2525
import { AddActionToChatMessage1721078251523 } from './1721078251523-AddActionToChatMessage'
2626
import { LongTextColumn1722301395521 } from './1722301395521-LongTextColumn'
27+
import { AddCustomTemplate1725629836652 } from './1725629836652-AddCustomTemplate'
2728

2829
export const mysqlMigrations = [
2930
Init1693840429259,
@@ -51,5 +52,6 @@ export const mysqlMigrations = [
5152
AddVectorStoreConfigToDocStore1715861032479,
5253
AddApiKey1720230151480,
5354
AddActionToChatMessage1721078251523,
54-
LongTextColumn1722301395521
55+
LongTextColumn1722301395521,
56+
AddCustomTemplate1725629836652
5557
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { MigrationInterface, QueryRunner } from 'typeorm'
2+
3+
export class AddCustomTemplate1725629836652 implements MigrationInterface {
4+
public async up(queryRunner: QueryRunner): Promise<void> {
5+
await queryRunner.query(
6+
`CREATE TABLE IF NOT EXISTS custom_template (
7+
id uuid NOT NULL DEFAULT uuid_generate_v4(),
8+
"name" varchar NOT NULL,
9+
"flowData" text NOT NULL,
10+
"description" varchar NULL,
11+
"badge" varchar NULL,
12+
"framework" varchar NULL,
13+
"usecases" varchar NULL,
14+
"type" varchar NULL,
15+
"createdDate" timestamp NOT NULL DEFAULT now(),
16+
"updatedDate" timestamp NOT NULL DEFAULT now(),
17+
CONSTRAINT "PK_3c7cea7d087ac4b91764574cdbf" PRIMARY KEY (id)
18+
);`
19+
)
20+
}
21+
22+
public async down(queryRunner: QueryRunner): Promise<void> {
23+
await queryRunner.query(`DROP TABLE custom_template`)
24+
}
25+
}

packages/server/src/database/migrations/postgres/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { AddAgentReasoningToChatMessage1714679514451 } from './1714679514451-Add
2424
import { AddTypeToChatFlow1716300000000 } from './1716300000000-AddTypeToChatFlow'
2525
import { AddApiKey1720230151480 } from './1720230151480-AddApiKey'
2626
import { AddActionToChatMessage1721078251523 } from './1721078251523-AddActionToChatMessage'
27+
import { AddCustomTemplate1725629836652 } from './1725629836652-AddCustomTemplate'
2728

2829
export const postgresMigrations = [
2930
Init1693891895163,
@@ -51,5 +52,6 @@ export const postgresMigrations = [
5152
AddTypeToChatFlow1716300000000,
5253
AddVectorStoreConfigToDocStore1715861032479,
5354
AddApiKey1720230151480,
54-
AddActionToChatMessage1721078251523
55+
AddActionToChatMessage1721078251523,
56+
AddCustomTemplate1725629836652
5557
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { MigrationInterface, QueryRunner } from 'typeorm'
2+
3+
export class AddCustomTemplate1725629836652 implements MigrationInterface {
4+
public async up(queryRunner: QueryRunner): Promise<void> {
5+
await queryRunner.query(
6+
`CREATE TABLE IF NOT EXISTS "custom_template" (
7+
"id" varchar PRIMARY KEY NOT NULL,
8+
"name" varchar NOT NULL,
9+
"flowData" text NOT NULL,
10+
"description" varchar,
11+
"badge" varchar,
12+
"framework" varchar,
13+
"usecases" varchar,
14+
"type" varchar,
15+
"updatedDate" datetime NOT NULL DEFAULT (datetime('now')),
16+
"createdDate" datetime NOT NULL DEFAULT (datetime('now')));`
17+
)
18+
}
19+
20+
public async down(queryRunner: QueryRunner): Promise<void> {
21+
await queryRunner.query(`DROP TABLE IF EXISTS "custom_template";`)
22+
}
23+
}

packages/server/src/database/migrations/sqlite/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { AddAgentReasoningToChatMessage1714679514451 } from './1714679514451-Add
2323
import { AddTypeToChatFlow1716300000000 } from './1716300000000-AddTypeToChatFlow'
2424
import { AddApiKey1720230151480 } from './1720230151480-AddApiKey'
2525
import { AddActionToChatMessage1721078251523 } from './1721078251523-AddActionToChatMessage'
26+
import { AddCustomTemplate1725629836652 } from './1725629836652-AddCustomTemplate'
2627

2728
export const sqliteMigrations = [
2829
Init1693835579790,
@@ -49,5 +50,6 @@ export const sqliteMigrations = [
4950
AddTypeToChatFlow1716300000000,
5051
AddVectorStoreConfigToDocStore1715861032479,
5152
AddApiKey1720230151480,
52-
AddActionToChatMessage1721078251523
53+
AddActionToChatMessage1721078251523,
54+
AddCustomTemplate1725629836652
5355
]

packages/server/src/routes/marketplaces/index.ts

+8
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,12 @@ const router = express.Router()
55
// READ
66
router.get('/templates', marketplacesController.getAllTemplates)
77

8+
router.post('/custom', marketplacesController.saveCustomTemplate)
9+
10+
// READ
11+
router.get('/custom', marketplacesController.getAllCustomTemplates)
12+
13+
// DELETE
14+
router.delete(['/', '/custom/:id'], marketplacesController.deleteCustomTemplate)
15+
816
export default router

0 commit comments

Comments
 (0)