diff options
Diffstat (limited to 'backend/instance/server.ts')
| -rw-r--r-- | backend/instance/server.ts | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/backend/instance/server.ts b/backend/instance/server.ts new file mode 100644 index 0000000..e41f91f --- /dev/null +++ b/backend/instance/server.ts @@ -0,0 +1,123 @@ +import express from 'express'; + +import * as api from './api-connection.js'; +import * as tools from './tools.js'; +import * as notes from './notes.js'; +import * as wget from './wget.js'; +import * as chat from './chat.js'; + +const app = express(); +app.use( express.json() ); + +var PORT = 3001; +var DOMAIN = 'http://localhost'; + +export function listen( port: number, domain: string ) { + PORT = port; + DOMAIN = domain; + + api.setStatus( { domain: `${DOMAIN}:${(port == 443 || port == 80)? '' : port}` } ); + + app.listen( PORT, () => { + console.log( `Server listening on ${DOMAIN}:${PORT}` ); + }); +} + +app.post( '/chat', async( req: any, res: any ) => { + let messages: chat.Msg[] | undefined = req.body.messages; + let options: chat.Options | undefined = req.body.options; + + if( !options || !messages ) + return res.status( 401 ).json( { status: 'error', msg: 'options not provided' } ); + if( api.status.isBusy ) + return res.status( 401 ).json( { status: 'busy', msg: 'please wait' } ); + + res.header( 'Transfer-Encoding', 'chunked' ); + api.serverNotify( { isBusy: true } ); + wget.resetUseCount(); + tools.resetUseCount(); + + let onChunk = ( chunk: string, isTool: boolean ) => { + const chatStream: chat.Stream = { + response: chunk, + status: 'ok', + done: false, + tool: !!isTool + }; + + res.write( JSON.stringify( chatStream ) + '\n' ); + }; + + try { + const notelog = notes.load( options.uuid ); + const chatRes = await chat.run( messages, options, false, notelog, onChunk ); + messages.push( chatRes ); + const stream: chat.Stream = { + status: 'ok', + done: false, + finalMsg: chatRes.content, + } + + if( chatRes.toolCall ) { + res.write( JSON.stringify( stream ) + '\n' ); + const toolRes = await tools.run( messages, options, chatRes.toolCall, notelog, onChunk ); + res.end( JSON.stringify( { status: 'ok', done: true, finalMsg: toolRes.content, title: chatRes.title } ) + "\n" ); + } else { + res.end( JSON.stringify( { status: 'ok', done: true, finalMsg: chatRes.content, title: chatRes.title } ) + "\n" ); + } + if( options.chatfile ) + chat.save( messages, options.chatfile ); + } catch( e: any ) { + console.log( e ); + res.end( JSON.stringify( { status: 'error', msg: e.message } ) ); + } + + api.serverNotify( { isBusy: false } ); +} ); + +app.post( '/generate', async( req: any, res: any ) => { + let { prompt, suffix, options } = req.body; + + if( api.status.isBusy ) + return res.status( 401 ).json( { status: 'busy', msg: 'please wait' } ); + if( !options ) + return res.status( 401 ).json( { status: 'error', msg: 'options not provided' } ); + + res.header( 'Transfer-Encoding', 'chunked' ); + api.serverNotify( { isBusy: true } ); + + let onChunk = ( chunk: string ) => { + const chatStream: chat.Stream = { + response: chunk, + status: 'ok', + done: false + }; + + res.write( JSON.stringify( chatStream ) + '\n' ); + } + + try { + const gen = await chat.generate( prompt, suffix, options, onChunk ); + const end: chat.Stream = { + status: 'ok', + done: true, + finalMsg: gen + }; + res.end( JSON.stringify( end ) ); + } catch( e: any ) { + console.log( e ); + res.end( JSON.stringify( { status: 'error', msg: e.message } ) ); + } + + api.serverNotify( { isBusy: false } ); +} ); + +// todo later +app.post( '/get-chat', async( _: any, res: any ) => { + return res.status( 400 ).json( { status: 'err', msg: 'not implemented' } ); +} ); + +// todo later +app.post( '/list-chats', async( _: any, res: any ) => { + return res.status( 400 ).json( { status: 'err', msg: 'not implemented' } ); +} ); |
