Skip to content

Commit

Permalink
Feature: Custom Templates (#3169)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
vinodkiran and HenryHengZJ committed Sep 16, 2024
1 parent 44b70ca commit b02bdc7
Show file tree
Hide file tree
Showing 23 changed files with 1,213 additions and 166 deletions.
13 changes: 13 additions & 0 deletions packages/server/src/Interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,5 +273,18 @@ export interface IApiKey {
updatedDate: Date
}

export interface ICustomTemplate {
id: string
name: string
flowData: string
updatedDate: Date
createdDate: Date
description?: string
type?: string
badge?: string
framework?: string
usecases?: string
}

// DocumentStore related
export * from './Interface.DocumentStore'
46 changes: 45 additions & 1 deletion packages/server/src/controllers/marketplaces/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Request, Response, NextFunction } from 'express'
import marketplacesService from '../../services/marketplaces'
import { InternalFlowiseError } from '../../errors/internalFlowiseError'
import { StatusCodes } from 'http-status-codes'

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

const deleteCustomTemplate = async (req: Request, res: Response, next: NextFunction) => {
try {
if (typeof req.params === 'undefined' || !req.params.id) {
throw new InternalFlowiseError(
StatusCodes.PRECONDITION_FAILED,
`Error: marketplacesService.deleteCustomTemplate - id not provided!`
)
}
const apiResponse = await marketplacesService.deleteCustomTemplate(req.params.id)
return res.json(apiResponse)
} catch (error) {
next(error)
}
}

const getAllCustomTemplates = async (req: Request, res: Response, next: NextFunction) => {
try {
const apiResponse = await marketplacesService.getAllCustomTemplates()
return res.json(apiResponse)
} catch (error) {
next(error)
}
}

const saveCustomTemplate = async (req: Request, res: Response, next: NextFunction) => {
try {
if ((!req.body && !(req.body.chatflowId || req.body.tool)) || !req.body.name) {
throw new InternalFlowiseError(
StatusCodes.PRECONDITION_FAILED,
`Error: marketplacesService.saveCustomTemplate - body not provided!`
)
}
const apiResponse = await marketplacesService.saveCustomTemplate(req.body)
return res.json(apiResponse)
} catch (error) {
next(error)
}
}

export default {
getAllTemplates
getAllTemplates,
getAllCustomTemplates,
saveCustomTemplate,
deleteCustomTemplate
}
37 changes: 37 additions & 0 deletions packages/server/src/database/entities/CustomTemplate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ICustomTemplate } from '../../Interface'
import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'

@Entity('custom_template')
export class CustomTemplate implements ICustomTemplate {
@PrimaryGeneratedColumn('uuid')
id: string

@Column()
name: string

@Column({ type: 'text' })
flowData: string

@Column({ nullable: true, type: 'text' })
description?: string

@Column({ nullable: true, type: 'text' })
badge?: string

@Column({ nullable: true, type: 'text' })
framework?: string

@Column({ nullable: true, type: 'text' })
usecases?: string

@Column({ nullable: true, type: 'text' })
type?: string

@Column({ type: 'timestamp' })
@CreateDateColumn()
createdDate: Date

@Column({ type: 'timestamp' })
@UpdateDateColumn()
updatedDate: Date
}
4 changes: 3 additions & 1 deletion packages/server/src/database/entities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { DocumentStoreFileChunk } from './DocumentStoreFileChunk'
import { Lead } from './Lead'
import { UpsertHistory } from './UpsertHistory'
import { ApiKey } from './ApiKey'
import { CustomTemplate } from './CustomTemplate'

export const entities = {
ChatFlow,
Expand All @@ -23,5 +24,6 @@ export const entities = {
DocumentStoreFileChunk,
Lead,
UpsertHistory,
ApiKey
ApiKey,
CustomTemplate
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { MigrationInterface, QueryRunner } from 'typeorm'

export class AddCustomTemplate1725629836652 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE IF NOT EXISTS \`custom_template\` (
\`id\` varchar(36) NOT NULL,
\`name\` varchar(255) NOT NULL,
\`flowData\` text NOT NULL,
\`description\` varchar(255) DEFAULT NULL,
\`badge\` varchar(255) DEFAULT NULL,
\`framework\` varchar(255) DEFAULT NULL,
\`usecases\` varchar(255) DEFAULT NULL,
\`type\` varchar(30) DEFAULT NULL,
\`createdDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
\`updatedDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;`
)
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE custom_template`)
}
}
4 changes: 3 additions & 1 deletion packages/server/src/database/migrations/mariadb/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { AddTypeToChatFlow1716300000000 } from './1716300000000-AddTypeToChatFlo
import { AddApiKey1720230151480 } from './1720230151480-AddApiKey'
import { AddActionToChatMessage1721078251523 } from './1721078251523-AddActionToChatMessage'
import { LongTextColumn1722301395521 } from './1722301395521-LongTextColumn'
import { AddCustomTemplate1725629836652 } from './1725629836652-AddCustomTemplate'

export const mariadbMigrations = [
Init1693840429259,
Expand All @@ -49,5 +50,6 @@ export const mariadbMigrations = [
AddTypeToChatFlow1716300000000,
AddApiKey1720230151480,
AddActionToChatMessage1721078251523,
LongTextColumn1722301395521
LongTextColumn1722301395521,
AddCustomTemplate1725629836652
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { MigrationInterface, QueryRunner } from 'typeorm'

export class AddCustomTemplate1725629836652 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE IF NOT EXISTS \`custom_template\` (
\`id\` varchar(36) NOT NULL,
\`name\` varchar(255) NOT NULL,
\`flowData\` text NOT NULL,
\`description\` varchar(255) DEFAULT NULL,
\`badge\` varchar(255) DEFAULT NULL,
\`framework\` varchar(255) DEFAULT NULL,
\`usecases\` varchar(255) DEFAULT NULL,
\`type\` varchar(30) DEFAULT NULL,
\`createdDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
\`updatedDate\` datetime(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
PRIMARY KEY (\`id\`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;`
)
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE custom_template`)
}
}
4 changes: 3 additions & 1 deletion packages/server/src/database/migrations/mysql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { AddTypeToChatFlow1716300000000 } from './1716300000000-AddTypeToChatFlo
import { AddApiKey1720230151480 } from './1720230151480-AddApiKey'
import { AddActionToChatMessage1721078251523 } from './1721078251523-AddActionToChatMessage'
import { LongTextColumn1722301395521 } from './1722301395521-LongTextColumn'
import { AddCustomTemplate1725629836652 } from './1725629836652-AddCustomTemplate'

export const mysqlMigrations = [
Init1693840429259,
Expand Down Expand Up @@ -51,5 +52,6 @@ export const mysqlMigrations = [
AddVectorStoreConfigToDocStore1715861032479,
AddApiKey1720230151480,
AddActionToChatMessage1721078251523,
LongTextColumn1722301395521
LongTextColumn1722301395521,
AddCustomTemplate1725629836652
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { MigrationInterface, QueryRunner } from 'typeorm'

export class AddCustomTemplate1725629836652 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE IF NOT EXISTS custom_template (
id uuid NOT NULL DEFAULT uuid_generate_v4(),
"name" varchar NOT NULL,
"flowData" text NOT NULL,
"description" varchar NULL,
"badge" varchar NULL,
"framework" varchar NULL,
"usecases" varchar NULL,
"type" varchar NULL,
"createdDate" timestamp NOT NULL DEFAULT now(),
"updatedDate" timestamp NOT NULL DEFAULT now(),
CONSTRAINT "PK_3c7cea7d087ac4b91764574cdbf" PRIMARY KEY (id)
);`
)
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE custom_template`)
}
}
4 changes: 3 additions & 1 deletion packages/server/src/database/migrations/postgres/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { AddAgentReasoningToChatMessage1714679514451 } from './1714679514451-Add
import { AddTypeToChatFlow1716300000000 } from './1716300000000-AddTypeToChatFlow'
import { AddApiKey1720230151480 } from './1720230151480-AddApiKey'
import { AddActionToChatMessage1721078251523 } from './1721078251523-AddActionToChatMessage'
import { AddCustomTemplate1725629836652 } from './1725629836652-AddCustomTemplate'

export const postgresMigrations = [
Init1693891895163,
Expand Down Expand Up @@ -51,5 +52,6 @@ export const postgresMigrations = [
AddTypeToChatFlow1716300000000,
AddVectorStoreConfigToDocStore1715861032479,
AddApiKey1720230151480,
AddActionToChatMessage1721078251523
AddActionToChatMessage1721078251523,
AddCustomTemplate1725629836652
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { MigrationInterface, QueryRunner } from 'typeorm'

export class AddCustomTemplate1725629836652 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE IF NOT EXISTS "custom_template" (
"id" varchar PRIMARY KEY NOT NULL,
"name" varchar NOT NULL,
"flowData" text NOT NULL,
"description" varchar,
"badge" varchar,
"framework" varchar,
"usecases" varchar,
"type" varchar,
"updatedDate" datetime NOT NULL DEFAULT (datetime('now')),
"createdDate" datetime NOT NULL DEFAULT (datetime('now')));`
)
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE IF EXISTS "custom_template";`)
}
}
4 changes: 3 additions & 1 deletion packages/server/src/database/migrations/sqlite/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { AddAgentReasoningToChatMessage1714679514451 } from './1714679514451-Add
import { AddTypeToChatFlow1716300000000 } from './1716300000000-AddTypeToChatFlow'
import { AddApiKey1720230151480 } from './1720230151480-AddApiKey'
import { AddActionToChatMessage1721078251523 } from './1721078251523-AddActionToChatMessage'
import { AddCustomTemplate1725629836652 } from './1725629836652-AddCustomTemplate'

export const sqliteMigrations = [
Init1693835579790,
Expand All @@ -49,5 +50,6 @@ export const sqliteMigrations = [
AddTypeToChatFlow1716300000000,
AddVectorStoreConfigToDocStore1715861032479,
AddApiKey1720230151480,
AddActionToChatMessage1721078251523
AddActionToChatMessage1721078251523,
AddCustomTemplate1725629836652
]
8 changes: 8 additions & 0 deletions packages/server/src/routes/marketplaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,12 @@ const router = express.Router()
// READ
router.get('/templates', marketplacesController.getAllTemplates)

router.post('/custom', marketplacesController.saveCustomTemplate)

// READ
router.get('/custom', marketplacesController.getAllCustomTemplates)

// DELETE
router.delete(['/', '/custom/:id'], marketplacesController.deleteCustomTemplate)

export default router
Loading

0 comments on commit b02bdc7

Please sign in to comment.