summaryrefslogtreecommitdiff
path: root/backend/instance/server.ts
diff options
context:
space:
mode:
Diffstat (limited to 'backend/instance/server.ts')
-rw-r--r--backend/instance/server.ts123
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' } );
+} );