Switch to fastify + add model CRUD impl

This commit is contained in:
Linh Tran 2023-12-01 23:02:35 +07:00
parent 1bf75cfd05
commit f5c19bccc5
11 changed files with 154 additions and 63 deletions

View File

View File

View File

@ -1,28 +1,17 @@
import express from 'express' import fastify from 'fastify'
import bodyParser from 'body-parser'
import fs from 'fs'
import v1API from './v1' import v1API from './v1'
const JAN_API_PORT = 1337; const JAN_API_PORT = 1337;
const server = fastify()
const server = express()
server.use(bodyParser.urlencoded())
server.use(bodyParser.json())
const USER_ROOT_DIR = '.data' const USER_ROOT_DIR = '.data'
server.use("/v1", v1API) server.register(v1API, {prefix: "/api/v1"})
// server.post("fs", (req, res) => {
// let op = req.body.op;
// switch(op){
// case 'readFile':
// fs.readFile(req.body.path, ()=>{})
// case 'writeFile':
// fs.writeFile(req.body.path, Buffer.from(req.body.data, "base64"), ()=>{})
// }
// })
server.listen(JAN_API_PORT, () => { server.listen({
console.log(`JAN API listening at: http://localhost:${JAN_API_PORT}`); port: JAN_API_PORT,
host: "0.0.0.0"
}).then(()=>{
console.log(`JAN API listening at: http://0.0.0.0:${JAN_API_PORT}`);
}) })

View File

@ -75,6 +75,7 @@
"@typescript-eslint/eslint-plugin": "^6.7.3", "@typescript-eslint/eslint-plugin": "^6.7.3",
"@typescript-eslint/parser": "^6.7.3", "@typescript-eslint/parser": "^6.7.3",
"eslint-plugin-react": "^7.33.2", "eslint-plugin-react": "^7.33.2",
"fastify": "^4.24.3",
"nodemon": "^3.0.1", "nodemon": "^3.0.1",
"run-script-os": "^1.1.6" "run-script-os": "^1.1.6"
}, },

View File

@ -1,5 +1,8 @@
import { Request, Response } from 'express' import { FastifyInstance, FastifyPluginAsync, FastifyPluginOptions } from 'fastify'
export default function route(req: Request, res: Response){
const router: FastifyPluginAsync = async (app: FastifyInstance, opts: FastifyPluginOptions) => {
//TODO: Add controllers for assistants here
// app.get("/", controller)
// app.post("/", controller)
} }
export default router;

View File

@ -1,5 +1,11 @@
import { Request, Response } from 'express' import { FastifyInstance, FastifyPluginAsync, FastifyPluginOptions } from 'fastify'
export default function route(req: Request, res: Response){ const router: FastifyPluginAsync = async (app: FastifyInstance, opts: FastifyPluginOptions) => {
//TODO: Add controllers for here
// app.get("/", controller)
app.post("/", (req, res) => {
req.body
})
} }
export default router;

View File

@ -1,20 +1,37 @@
import { Request, Response } from 'express'
import assistantsAPI from './assistants' import assistantsAPI from './assistants'
import chatCompletionAPI from './chat' import chatCompletionAPI from './chat'
import modelsAPI from './models' import modelsAPI from './models'
import threadsAPI from './threads' import threadsAPI from './threads'
export default function route(req: Request, res: Response){ import { FastifyInstance, FastifyPluginAsync } from 'fastify'
console.log(req.path.split("/")[1])
switch (req.path.split("/")[1]){ const router: FastifyPluginAsync = async (app: FastifyInstance, opts) => {
case 'assistants': app.register(
assistantsAPI(req, res) assistantsAPI,
case 'chat': {
chatCompletionAPI(req, res) prefix: "/assisstants"
case 'models':
modelsAPI(req, res)
case 'threads':
threadsAPI(req, res)
} }
)
app.register(
chatCompletionAPI,
{
prefix: "/chat/completion"
}
)
app.register(
modelsAPI,
{
prefix: "/models"
}
)
app.register(
threadsAPI,
{
prefix: "/threads"
}
)
} }
export default router;

View File

@ -1,5 +1,23 @@
import { Request, Response } from 'express' import { RouteHandlerMethod, FastifyRequest, FastifyReply } from 'fastify'
import { MODEL_FOLDER_PATH } from "./index"
import fs from 'fs/promises'
export default function controller(req: Request, res: Response){ const controller: RouteHandlerMethod = async (req: FastifyRequest, res: FastifyReply) => {
//TODO: download models impl
//Mirror logic from JanModelExtension.downloadModel?
let model = req.body.model;
// Fetching logic
// const directoryPath = join(MODEL_FOLDER_PATH, model.id)
// await fs.mkdir(directoryPath)
// const path = join(directoryPath, model.id)
// downloadFile(model.source_url, path)
// TODO: Different model downloader from different model vendor
res.status(200).send({
status: "Ok"
})
} }
export default controller;

View File

@ -1,18 +1,61 @@
import { Request, Response } from 'express'
import downloadModelController from './downloadModel' export const MODEL_FOLDER_PATH = "./data/models"
export const _modelMetadataFileName = 'model.json'
function getModelController(req: Request, res: Response){ import fs from 'fs/promises'
import { Model } from '@janhq/core'
import { join } from 'path'
} // map string => model object
let modelIndex = new Map<String, Model>();
export default function route(req: Request, res: Response){ async function buildModelIndex(){
switch(req.method){ let modelIds = await fs.readdir(MODEL_FOLDER_PATH);
case 'get': // TODO: read modelFolders to get model info, mirror JanModelExtension?
getModelController(req, res) try{
break; for(let modelId in modelIds){
case 'post': let path = join(MODEL_FOLDER_PATH, modelId)
downloadModelController(req, res) let fileData = await fs.readFile(join(path, _modelMetadataFileName))
break; modelIndex.set(modelId, JSON.parse(fileData.toString("utf-8")) as Model)
}
}
catch(err){
console.error("build model index failed. ", err);
} }
} }
buildModelIndex()
import { FastifyInstance, FastifyPluginAsync, FastifyPluginOptions } from 'fastify'
import downloadModelController from './downloadModel'
import { startModel, stopModel } from './modelOp'
const router: FastifyPluginAsync = async (app: FastifyInstance, opts: FastifyPluginOptions) => {
//TODO: Add controllers declaration here
///////////// CRUD ////////////////
// Model listing
app.get("/", async (req, res) => {
res.status(200).send(
modelIndex.values()
)
})
// Retrieve model info
app.get("/:id", (req, res) => {
res.status(200).send(
modelIndex.get(req.params.id)
)
})
// Delete model
app.delete("/:id", (req, res) => {
modelIndex.delete(req.params)
// TODO: delete on disk
})
///////////// Other ops ////////////////
app.post("/", downloadModelController)
app.put("/start", startModel)
app.put("/stop", stopModel)
}
export default router;

View File

@ -0,0 +1,11 @@
import {FastifyRequest, FastifyReply} from 'fastify'
export async function startModel(req: FastifyRequest, res: FastifyReply): Promise<void> {
}
export async function stopModel(req: FastifyRequest, res: FastifyReply): Promise<void> {
}

View File

@ -1,5 +1,8 @@
import { Request, Response } from 'express' import { FastifyInstance, FastifyPluginAsync, FastifyPluginOptions } from 'fastify'
export default function route(req: Request, res: Response){ const router: FastifyPluginAsync = async (app: FastifyInstance, opts: FastifyPluginOptions) => {
//TODO: Add controllers declaration here
// app.get()
} }
export default router;