Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions app-backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ WORKDIR /home/user/
RUN git clone --depth 1 https://github.com/opea-project/GenAIComps.git

WORKDIR /home/user/GenAIComps
RUN pip install --no-cache-dir --upgrade pip==24.3.1 setuptools==75.3.0 && \
pip install --no-cache-dir -r /home/user/GenAIComps/requirements.txt
RUN pip install --no-cache-dir --upgrade pip==24.3.1 setuptools==78.1.1 && \
pip install --no-cache-dir -r /home/user/GenAIComps/requirements.txt && \
pip install --no-cache-dir --upgrade mcp==1.10.0 pillow==11.3.0

COPY ./templates/microservices/* /home/user/templates/microservices/
COPY ./megaservice.py /home/user/megaservice.py
Expand Down
2 changes: 1 addition & 1 deletion studio-backend/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ RUN apt-get update -y && apt-get install -y --no-install-recommends --fix-missin
rm -rf /var/lib/apt/lists/*

# Upgrade setuptools to a safe version and install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir --upgrade pip==24.3.1 setuptools==75.3.0 && \
RUN pip install --no-cache-dir --upgrade pip==24.3.1 setuptools==78.1.1 && \
pip install --no-cache-dir -r /usr/src/app/requirements.txt

# Define environment variable
Expand Down
302 changes: 53 additions & 249 deletions studio-backend/app/routers/clickdeploy_router.py

Large diffs are not rendered by default.

392 changes: 357 additions & 35 deletions studio-backend/app/services/clickdeploy_service.py

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions studio-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@
"sqlite3"
],
"overrides": {
"set-value": "^3.0.3"
"set-value": "^3.0.3",
"form-data": "4.0.4"
}
},
"engines": {
Expand All @@ -79,7 +80,8 @@
"esbuild": ">=0.25.0",
"cross-spawn": ">=7.0.5",
"solid-js": ">=1.9.4",
"tar-fs": ">=3.0.8"
"tar-fs": ">=3.0.8",
"form-data": "4.0.4"
},
"eslintIgnore": [
"**/dist",
Expand Down
53 changes: 53 additions & 0 deletions studio-frontend/packages/server/src/controllers/chatflows/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,57 @@ const getPublicKey = async (req: Request, res: Response, next: NextFunction) =>
}
}

const getDeploymentStatus = async (req: Request, res: Response, next: NextFunction) => {
try {
if (typeof req.params === 'undefined' || !req.params.id) {
throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: chatflowsRouter.getDeploymentStatus - id not provided!`)
}
const chatflow = await chatflowsService.getChatflowById(req.params.id)
if (!chatflow) {
return res.status(404).json({ error: 'Chatflow not found' })
}

let config = null
let logs = []

try {
config = chatflow.deploymentConfig ? JSON.parse(chatflow.deploymentConfig) : null
} catch (e) {
console.error('Error parsing deploymentConfig:', e)
}

try {
logs = chatflow.deploymentLogs ? JSON.parse(chatflow.deploymentLogs) : []
} catch (e) {
console.error('Error parsing deploymentLogs:', e)
}

const response = {
status: chatflow.deploymentStatus || 'Not Started',
message: '',
config: config,
logs: logs
}

return res.json(response)
} catch (error) {
next(error)
}
}

const updateDeploymentStatus = async (req: Request, res: Response, next: NextFunction) => {
try {
if (typeof req.params === 'undefined' || !req.params.id) {
throw new InternalFlowiseError(StatusCodes.PRECONDITION_FAILED, `Error: chatflowsRouter.updateDeploymentStatus - id not provided!`)
}
const { status, message, logs, config } = req.body
const result = await chatflowsService.updateDeploymentStatus(req.params.id, status, message, logs, config)
return res.json(result)
} catch (error) {
next(error)
}
}

const oneClickDeployment = async (req: Request, res: Response, next: NextFunction) => {
console.log('Deploying one click')
try {
Expand Down Expand Up @@ -316,5 +367,7 @@ export default {
stopChatflowSandbox,
buildDeploymentPackage,
getPublicKey,
getDeploymentStatus,
updateDeploymentStatus,
oneClickDeployment
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ export class ChatFlow implements IChatFlow {
@Column({nullable: true, type: 'text'})
sandboxDebugLogsUrl?: string

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

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

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

@Column({ type: 'timestamp' })
@CreateDateColumn()
createdDate: Date
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { MigrationInterface, QueryRunner } from 'typeorm'

export class AddDeploymentStatusToChatFlow1754700956637 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
const deploymentStatusExists = await queryRunner.hasColumn('chat_flow', 'deploymentStatus')
if (!deploymentStatusExists) {
await queryRunner.query(`ALTER TABLE \`chat_flow\` ADD COLUMN \`deploymentStatus\` varchar(255) DEFAULT NULL;`)
}

const deploymentConfigExists = await queryRunner.hasColumn('chat_flow', 'deploymentConfig')
if (!deploymentConfigExists) {
await queryRunner.query(`ALTER TABLE \`chat_flow\` ADD COLUMN \`deploymentConfig\` TEXT DEFAULT NULL;`)
}

const deploymentLogsExists = await queryRunner.hasColumn('chat_flow', 'deploymentLogs')
if (!deploymentLogsExists) {
await queryRunner.query(`ALTER TABLE \`chat_flow\` ADD COLUMN \`deploymentLogs\` TEXT DEFAULT NULL;`)
}
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE \`chat_flow\` DROP COLUMN \`deploymentStatus\`;`)
await queryRunner.query(`ALTER TABLE \`chat_flow\` DROP COLUMN \`deploymentConfig\`;`)
await queryRunner.query(`ALTER TABLE \`chat_flow\` DROP COLUMN \`deploymentLogs\`;`)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { AddArtifactsToChatMessage1726156258465 } from './1726156258465-AddArtif
import { AddStudioFieldsToChatFlow1733282099772 } from './1733282099772-AddStudioFieldsToChatFlow'
import { AddSandboxTracerUrlToChatFlow1743740099772 } from './1743740099772-AddSandboxTracerUrlToChatFlow'
import { AddSandboxDebugLogsUrlToChatFlow1749612373191 } from './1749612373191-AddSandboxDebugLogsUrlToChatFlow'
import { AddDeploymentStatusToChatFlow1754700956637 } from './1754700956637-AddDeploymentStatusToChatFlow'


export const mysqlMigrations = [
Expand Down Expand Up @@ -62,5 +63,6 @@ export const mysqlMigrations = [
AddArtifactsToChatMessage1726156258465,
AddStudioFieldsToChatFlow1733282099772,
AddSandboxTracerUrlToChatFlow1743740099772,
AddSandboxDebugLogsUrlToChatFlow1749612373191
AddSandboxDebugLogsUrlToChatFlow1749612373191,
AddDeploymentStatusToChatFlow1754700956637
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { MigrationInterface, QueryRunner } from 'typeorm'

export class AddDeploymentStatusToChatFlow1754700956637 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
const deploymentStatusExists = await queryRunner.hasColumn('chat_flow', 'deploymentStatus')
if (!deploymentStatusExists) {
await queryRunner.query(`ALTER TABLE \`chat_flow\` ADD COLUMN \`deploymentStatus\` varchar(255) DEFAULT NULL;`)
}

const deploymentConfigExists = await queryRunner.hasColumn('chat_flow', 'deploymentConfig')
if (!deploymentConfigExists) {
await queryRunner.query(`ALTER TABLE \`chat_flow\` ADD COLUMN \`deploymentConfig\` TEXT DEFAULT NULL;`)
}

const deploymentLogsExists = await queryRunner.hasColumn('chat_flow', 'deploymentLogs')
if (!deploymentLogsExists) {
await queryRunner.query(`ALTER TABLE \`chat_flow\` ADD COLUMN \`deploymentLogs\` TEXT DEFAULT NULL;`)
}
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE \`chat_flow\` DROP COLUMN \`deploymentStatus\`;`)
await queryRunner.query(`ALTER TABLE \`chat_flow\` DROP COLUMN \`deploymentConfig\`;`)
await queryRunner.query(`ALTER TABLE \`chat_flow\` DROP COLUMN \`deploymentLogs\`;`)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { AddCustomTemplate1725629836652 } from './1725629836652-AddCustomTemplat
import { AddStudioFieldsToChatFlow1733282099772 } from './1733282099772-AddStudioFieldsToChatFlow'
import { AddSandboxTracerUrlToChatFlow1743740099772 } from './1743740099772-AddSandboxTracerUrlToChatFlow'
import { AddSandboxDebugLogsUrlToChatFlow1749612373191 } from './1749612373191-AddSandboxDebugLogsUrlToChatFlow'
import { AddDeploymentStatusToChatFlow1754700956637 } from './1754700956637-AddDeploymentStatusToChatFlow'

export const sqliteMigrations = [
Init1693835579790,
Expand Down Expand Up @@ -59,5 +60,6 @@ export const sqliteMigrations = [
AddCustomTemplate1725629836652,
AddStudioFieldsToChatFlow1733282099772,
AddSandboxTracerUrlToChatFlow1743740099772,
AddSandboxDebugLogsUrlToChatFlow1749612373191
AddSandboxDebugLogsUrlToChatFlow1749612373191,
AddDeploymentStatusToChatFlow1754700956637
]
2 changes: 2 additions & 0 deletions studio-frontend/packages/server/src/routes/chatflows/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ router.post('/importchatflows', chatflowsController.importChatflows)
// READ
router.get('/pubkey', chatflowsController.getPublicKey)
router.get('/', chatflowsController.getAllChatflowsbyUserId)
router.get('/deployment-status/:id', chatflowsController.getDeploymentStatus)
router.get(['/', '/:id'], chatflowsController.getChatflowById)
router.get(['/apikey/', '/apikey/:apikey'], chatflowsController.getChatflowByApiKey)

// UPDATE
router.put(['/', '/:id'], chatflowsController.updateChatflow)
router.put('/deployment-status/:id', chatflowsController.updateDeploymentStatus)

// DELETE
router.delete(['/', '/:id'], chatflowsController.deleteChatflow)
Expand Down
70 changes: 65 additions & 5 deletions studio-frontend/packages/server/src/services/chatflows/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -504,10 +504,14 @@ const oneClickDeploymentService = async (chatflowId: string, deploymentConfig: R
try {
const chatflow = await generatePipelineJson(chatflowId)
const studioServerUrl = STUDIO_SERVER_URL
const endpoint = 'studio-backend/upload-pipeline-files'
console.log('chatflow', JSON.stringify(chatflow))
console.log('studioServerUrl', studioServerUrl)
console.log('deploymentConfig', deploymentConfig)
const endpoint = 'studio-backend/click-deployment'
// console.log('chatflow', JSON.stringify(chatflow))
// console.log('studioServerUrl', studioServerUrl)
// console.log('deploymentConfig', deploymentConfig)

// Update chatflow with deployment status and config from backend response
const appServer = getRunningExpressApp()
const chatflowEntity = await appServer.AppDataSource.getRepository(ChatFlow).findOneBy({ id: chatflowId })
const response = await axios.post(`${studioServerUrl}/${endpoint}`, {
remoteHost: deploymentConfig.hostname,
remoteUser: deploymentConfig.username,
Expand All @@ -516,8 +520,24 @@ const oneClickDeploymentService = async (chatflowId: string, deploymentConfig: R
headers: { 'Content-Type': 'application/json' },
timeout: 60 * 1000
})
if (chatflowEntity) {
chatflowEntity.deploymentStatus = response.data.status
chatflowEntity.deploymentConfig = JSON.stringify(deploymentConfig)
chatflowEntity.deploymentLogs = JSON.stringify([response.data.message])
await appServer.AppDataSource.getRepository(ChatFlow).save(chatflowEntity)
}

return response.data
} catch (error: unknown) {
// Update chatflow with error status
const appServer = getRunningExpressApp()
const chatflowEntity = await appServer.AppDataSource.getRepository(ChatFlow).findOneBy({ id: chatflowId })
if (chatflowEntity) {
chatflowEntity.deploymentStatus = 'Error'
chatflowEntity.deploymentLogs = JSON.stringify([`Error: ${error instanceof Error ? error.message : String(error)}`])
await appServer.AppDataSource.getRepository(ChatFlow).save(chatflowEntity)
}

if (error instanceof Error) {
console.error(`Error: ${error.stack}`)
} else {
Expand All @@ -527,6 +547,45 @@ const oneClickDeploymentService = async (chatflowId: string, deploymentConfig: R
}
}

const updateDeploymentStatus = async (chatflowId: string, status: string, message?: string, logs?: string[], config?: Record<string, any>) => {
try {
const appServer = getRunningExpressApp()
const chatflow = await appServer.AppDataSource.getRepository(ChatFlow).findOneBy({ id: chatflowId })
if (chatflow) {
chatflow.deploymentStatus = status

// Update logs array - either use provided logs or append message to existing logs
let updatedLogs: string[] = []
if (logs && logs.length > 0) {
updatedLogs = logs
} else {
// Parse existing logs and append new message
try {
const existingLogs = chatflow.deploymentLogs ? JSON.parse(chatflow.deploymentLogs) : []
updatedLogs = Array.isArray(existingLogs) ? existingLogs : []
if (message) {
updatedLogs.push(message)
}
} catch (e) {
updatedLogs = message ? [message] : []
}
}
chatflow.deploymentLogs = JSON.stringify(updatedLogs)

if (config) {
chatflow.deploymentConfig = JSON.stringify(config)
}
await appServer.AppDataSource.getRepository(ChatFlow).save(chatflow)
}
return chatflow
} catch (error) {
throw new InternalFlowiseError(
StatusCodes.INTERNAL_SERVER_ERROR,
`Error: chatflowsService.updateDeploymentStatus - ${getErrorMessage(error)}`
)
}
}

const _checkAndUpdateDocumentStoreUsage = async (chatflow: ChatFlow) => {
const parsedFlowData: IReactFlowObject = JSON.parse(chatflow.flowData)
const nodes = parsedFlowData.nodes
Expand Down Expand Up @@ -556,5 +615,6 @@ export default {
stopChatflowSandboxService,
buildDeploymentPackageService,
getSinglePublicChatbotConfig,
oneClickDeploymentService
oneClickDeploymentService,
updateDeploymentStatus
}
8 changes: 7 additions & 1 deletion studio-frontend/packages/ui/src/api/chatflows.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ const getPublicKey = () => client.get('/chatflows/pubkey')

const clickDeployment = (id, body) => client.post(`chatflows-sandbox/one-click-deployment/${id}`, body)

const getDeploymentStatus = (id) => client.get(`/chatflows/deployment-status/${id}`)

const updateDeploymentStatus = (id, body) => client.put(`/chatflows/deployment-status/${id}`, body)

export default {
getAllChatflows,
getAllAgentflows,
Expand All @@ -55,5 +59,7 @@ export default {
stopSandbox,
buildDeploymentPackage,
getPublicKey,
clickDeployment
clickDeployment,
getDeploymentStatus,
updateDeploymentStatus
}
Loading
Loading