refactor(api): remove AI worker, add ai api route, add usage tiers

- Remove separate AI worker service
- Added generation limits:
  FREE: 1000/month (For the beta version)
  PRO: 500/month
  ENTERPRISE: 1000/month
- Integrate AI functionality into main API routes
- Added monthly generations reset and usage tier upgrade API routes
- Upgrade tier page to be added along with profile page section
This commit is contained in:
Akhileshrangani4
2024-11-23 20:31:24 -05:00
parent 4db378b5f1
commit 34994a8c69
29 changed files with 590 additions and 4049 deletions

View File

@ -1,90 +0,0 @@
// AIWorker class for handling AI-related operations
export class AIWorker {
private aiWorkerUrl: string
private cfAiKey: string
private databaseWorkerUrl: string
private workersKey: string
// Constructor to initialize AIWorker with necessary URLs and keys
constructor(
aiWorkerUrl: string,
cfAiKey: string,
databaseWorkerUrl: string,
workersKey: string
) {
this.aiWorkerUrl = aiWorkerUrl
this.cfAiKey = cfAiKey
this.databaseWorkerUrl = databaseWorkerUrl
this.workersKey = workersKey
}
// Method to generate code based on user input
async generateCode(
userId: string,
fileName: string,
code: string,
line: number,
instructions: string
): Promise<{ response: string; success: boolean }> {
try {
const fetchPromise = fetch(
`${process.env.DATABASE_WORKER_URL}/api/sandbox/generate`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `${process.env.WORKERS_KEY}`,
},
body: JSON.stringify({
userId: userId,
}),
}
)
// Generate code from cloudflare workers AI
const generateCodePromise = fetch(
`${process.env.AI_WORKER_URL}/api?fileName=${encodeURIComponent(
fileName
)}&code=${encodeURIComponent(code)}&line=${encodeURIComponent(
line
)}&instructions=${encodeURIComponent(instructions)}`,
{
headers: {
"Content-Type": "application/json",
Authorization: `${process.env.CF_AI_KEY}`,
},
}
)
const [fetchResponse, generateCodeResponse] = await Promise.all([
fetchPromise,
generateCodePromise,
])
if (!generateCodeResponse.ok) {
throw new Error(`HTTP error! status: ${generateCodeResponse.status}`)
}
const reader = generateCodeResponse.body?.getReader()
const decoder = new TextDecoder()
let result = ""
if (reader) {
while (true) {
const { done, value } = await reader.read()
if (done) break
result += decoder.decode(value, { stream: true })
}
}
// The result should now contain only the modified code
return { response: result.trim(), success: true }
} catch (e: any) {
console.error("Error generating code:", e)
return {
response: "Error generating code. Please try again.",
success: false,
}
}
}
}

View File

@ -1,6 +1,5 @@
import { Sandbox as E2BSandbox } from "e2b"
import { Socket } from "socket.io"
import { AIWorker } from "./AIWorker"
import { CONTAINER_TIMEOUT } from "./constants"
import { DokkuClient } from "./DokkuClient"
import { FileManager } from "./FileManager"
@ -29,7 +28,6 @@ function extractPortNumber(inputString: string): number | null {
}
type ServerContext = {
aiWorker: AIWorker
dokkuClient: DokkuClient | null
gitClient: SecureGitClient | null
}
@ -44,12 +42,11 @@ export class Sandbox {
// Server context:
dokkuClient: DokkuClient | null
gitClient: SecureGitClient | null
aiWorker: AIWorker
constructor(
sandboxId: string,
type: string,
{ aiWorker, dokkuClient, gitClient }: ServerContext
{ dokkuClient, gitClient }: ServerContext
) {
// Sandbox properties:
this.sandboxId = sandboxId
@ -58,7 +55,6 @@ export class Sandbox {
this.terminalManager = null
this.container = null
// Server context:
this.aiWorker = aiWorker
this.dokkuClient = dokkuClient
this.gitClient = gitClient
}
@ -240,22 +236,6 @@ export class Sandbox {
return this.terminalManager?.closeTerminal(id)
}
// Handle generating code
const handleGenerateCode: SocketHandler = ({
fileName,
code,
line,
instructions,
}: any) => {
return this.aiWorker.generateCode(
connection.userId,
fileName,
code,
line,
instructions
)
}
// Handle downloading files by download button
const handleDownloadFiles: SocketHandler = async () => {
if (!this.fileManager) throw Error("No file manager")
@ -284,7 +264,6 @@ export class Sandbox {
resizeTerminal: handleResizeTerminal,
terminalData: handleTerminalData,
closeTerminal: handleCloseTerminal,
generateCode: handleGenerateCode,
}
}
}

View File

@ -4,7 +4,6 @@ import express, { Express } from "express"
import fs from "fs"
import { createServer } from "http"
import { Server, Socket } from "socket.io"
import { AIWorker } from "./AIWorker"
import { ConnectionManager } from "./ConnectionManager"
import { DokkuClient } from "./DokkuClient"
@ -80,14 +79,6 @@ const gitClient =
)
: null
// Add this near the top of the file, after other initializations
const aiWorker = new AIWorker(
process.env.AI_WORKER_URL!,
process.env.CF_AI_KEY!,
process.env.DATABASE_WORKER_URL!,
process.env.WORKERS_KEY!
)
// Handle a client connecting to the server
io.on("connection", async (socket) => {
try {
@ -113,7 +104,6 @@ io.on("connection", async (socket) => {
const sandbox =
sandboxes[data.sandboxId] ??
new Sandbox(data.sandboxId, data.type, {
aiWorker,
dokkuClient,
gitClient,
})