Merge pull request #803 from janhq/768-fs-adapter-calling-server-api-for-handling-fs
feat: boilerplate for express server localhost 1337
This commit is contained in:
commit
2627d95ef0
1
server/.gitignore
vendored
Normal file
1
server/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
data
|
||||||
0
server/data/.gitkeep
Normal file
0
server/data/.gitkeep
Normal file
0
server/data/models/.gitkeep
Normal file
0
server/data/models/.gitkeep
Normal file
0
server/data/threads/.gitkeep
Normal file
0
server/data/threads/.gitkeep
Normal file
BIN
server/icons/icon.png
Normal file
BIN
server/icons/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
0
server/lib/.gitkeep
Normal file
0
server/lib/.gitkeep
Normal file
19
server/main.ts
Normal file
19
server/main.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import fastify from 'fastify'
|
||||||
|
import dotenv from 'dotenv'
|
||||||
|
import v1API from './v1'
|
||||||
|
const server = fastify()
|
||||||
|
|
||||||
|
dotenv.config()
|
||||||
|
server.register(v1API, {prefix: "/api/v1"})
|
||||||
|
|
||||||
|
|
||||||
|
const JAN_API_PORT = Number.parseInt(process.env.JAN_API_PORT || '1337')
|
||||||
|
const JAN_API_HOST = process.env.JAN_API_HOST || "0.0.0.0"
|
||||||
|
|
||||||
|
server.listen({
|
||||||
|
port: JAN_API_PORT,
|
||||||
|
host: JAN_API_HOST
|
||||||
|
}).then(() => {
|
||||||
|
console.log(`JAN API listening at: http://${JAN_API_HOST}:${JAN_API_PORT}`);
|
||||||
|
})
|
||||||
|
|
||||||
5
server/nodemon.json
Normal file
5
server/nodemon.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"watch": ["main.ts", "v1"],
|
||||||
|
"ext": "ts, json",
|
||||||
|
"exec": "tsc && node ./build/main.js"
|
||||||
|
}
|
||||||
32
server/package.json
Normal file
32
server/package.json
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"name": "jan-server",
|
||||||
|
"version": "0.1.3",
|
||||||
|
"main": "./build/main.js",
|
||||||
|
"author": "Jan <service@jan.ai>",
|
||||||
|
"license": "AGPL-3.0",
|
||||||
|
"homepage": "https://jan.ai",
|
||||||
|
"description": "Use offline LLMs with your own data. Run open source models like Llama2 or Falcon on your internal computers/servers.",
|
||||||
|
"build": "",
|
||||||
|
"scripts": {
|
||||||
|
"lint": "eslint . --ext \".js,.jsx,.ts,.tsx\"",
|
||||||
|
"test:e2e": "playwright test --workers=1",
|
||||||
|
"dev": "nodemon .",
|
||||||
|
"build": "tsc"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/body-parser": "^1.19.5",
|
||||||
|
"@types/npmcli__arborist": "^5.6.4",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^6.7.3",
|
||||||
|
"@typescript-eslint/parser": "^6.7.3",
|
||||||
|
"dotenv": "^16.3.1",
|
||||||
|
"eslint-plugin-react": "^7.33.2",
|
||||||
|
"fastify": "^4.24.3",
|
||||||
|
"nodemon": "^3.0.1",
|
||||||
|
"run-script-os": "^1.1.6"
|
||||||
|
},
|
||||||
|
"installConfig": {
|
||||||
|
"hoistingLimits": "workspaces"
|
||||||
|
}
|
||||||
|
}
|
||||||
22
server/tsconfig.json
Normal file
22
server/tsconfig.json
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"module": "commonjs",
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true,
|
||||||
|
"outDir": "./build",
|
||||||
|
"rootDir": "./",
|
||||||
|
"noEmitOnError": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"paths": { "*": ["node_modules/*"] },
|
||||||
|
"typeRoots": ["node_modules/@types"]
|
||||||
|
},
|
||||||
|
// "sourceMap": true,
|
||||||
|
|
||||||
|
"include": ["./**/*.ts"],
|
||||||
|
"exclude": ["core", "build", "dist", "tests", "node_modules"]
|
||||||
|
}
|
||||||
8
server/v1/assistants/index.ts
Normal file
8
server/v1/assistants/index.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { FastifyInstance, FastifyPluginAsync, FastifyPluginOptions } from 'fastify'
|
||||||
|
|
||||||
|
const router: FastifyPluginAsync = async (app: FastifyInstance, opts: FastifyPluginOptions) => {
|
||||||
|
//TODO: Add controllers for assistants here
|
||||||
|
// app.get("/", controller)
|
||||||
|
// app.post("/", controller)
|
||||||
|
}
|
||||||
|
export default router;
|
||||||
11
server/v1/chat/index.ts
Normal file
11
server/v1/chat/index.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { FastifyInstance, FastifyPluginAsync, FastifyPluginOptions } from 'fastify'
|
||||||
|
|
||||||
|
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;
|
||||||
37
server/v1/index.ts
Normal file
37
server/v1/index.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import assistantsAPI from './assistants'
|
||||||
|
import chatCompletionAPI from './chat'
|
||||||
|
import modelsAPI from './models'
|
||||||
|
import threadsAPI from './threads'
|
||||||
|
|
||||||
|
import { FastifyInstance, FastifyPluginAsync } from 'fastify'
|
||||||
|
|
||||||
|
const router: FastifyPluginAsync = async (app: FastifyInstance, opts) => {
|
||||||
|
app.register(
|
||||||
|
assistantsAPI,
|
||||||
|
{
|
||||||
|
prefix: "/assistants"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
app.register(
|
||||||
|
chatCompletionAPI,
|
||||||
|
{
|
||||||
|
prefix: "/chat/completion"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
app.register(
|
||||||
|
modelsAPI,
|
||||||
|
{
|
||||||
|
prefix: "/models"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
app.register(
|
||||||
|
threadsAPI,
|
||||||
|
{
|
||||||
|
prefix: "/threads"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default router;
|
||||||
23
server/v1/models/downloadModel.ts
Normal file
23
server/v1/models/downloadModel.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { RouteHandlerMethod, FastifyRequest, FastifyReply } from 'fastify'
|
||||||
|
import { MODEL_FOLDER_PATH } from "./index"
|
||||||
|
import fs from 'fs/promises'
|
||||||
|
|
||||||
|
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;
|
||||||
61
server/v1/models/index.ts
Normal file
61
server/v1/models/index.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
|
||||||
|
export const MODEL_FOLDER_PATH = "./data/models"
|
||||||
|
export const _modelMetadataFileName = 'model.json'
|
||||||
|
|
||||||
|
import fs from 'fs/promises'
|
||||||
|
import { Model } from '@janhq/core'
|
||||||
|
import { join } from 'path'
|
||||||
|
|
||||||
|
// map string => model object
|
||||||
|
let modelIndex = new Map<String, Model>();
|
||||||
|
async function buildModelIndex(){
|
||||||
|
let modelIds = await fs.readdir(MODEL_FOLDER_PATH);
|
||||||
|
// TODO: read modelFolders to get model info, mirror JanModelExtension?
|
||||||
|
try{
|
||||||
|
for(let modelId in modelIds){
|
||||||
|
let path = join(MODEL_FOLDER_PATH, modelId)
|
||||||
|
let fileData = await fs.readFile(join(path, _modelMetadataFileName))
|
||||||
|
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;
|
||||||
11
server/v1/models/modelOp.ts
Normal file
11
server/v1/models/modelOp.ts
Normal 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> {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
8
server/v1/threads/index.ts
Normal file
8
server/v1/threads/index.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { FastifyInstance, FastifyPluginAsync, FastifyPluginOptions } from 'fastify'
|
||||||
|
|
||||||
|
const router: FastifyPluginAsync = async (app: FastifyInstance, opts: FastifyPluginOptions) => {
|
||||||
|
//TODO: Add controllers declaration here
|
||||||
|
|
||||||
|
// app.get()
|
||||||
|
}
|
||||||
|
export default router;
|
||||||
Loading…
x
Reference in New Issue
Block a user