1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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' } );
} );
|