mirror of
https://github.com/leon-ai/leon.git
synced 2024-10-05 13:47:49 +03:00
feat(server): preparing LLM TCP server loading
This commit is contained in:
parent
1c0c8080bf
commit
49ac3218f7
@ -7,14 +7,14 @@ import prettyBytes from 'pretty-bytes'
|
||||
|
||||
import {
|
||||
PYTHON_BRIDGE_SRC_PATH,
|
||||
TCP_SERVER_SRC_PATH,
|
||||
PYTHON_TCP_SERVER_SRC_PATH,
|
||||
BINARIES_FOLDER_NAME,
|
||||
NODEJS_BRIDGE_DIST_PATH,
|
||||
PYTHON_BRIDGE_DIST_PATH,
|
||||
TCP_SERVER_DIST_PATH,
|
||||
PYTHON_TCP_SERVER_DIST_PATH,
|
||||
NODEJS_BRIDGE_BIN_NAME,
|
||||
PYTHON_BRIDGE_BIN_NAME,
|
||||
TCP_SERVER_BIN_NAME,
|
||||
PYTHON_TCP_SERVER_BIN_NAME,
|
||||
NODEJS_BRIDGE_ROOT_PATH
|
||||
} from '@/constants'
|
||||
import { OSTypes } from '@/types'
|
||||
@ -48,13 +48,13 @@ BUILD_TARGETS.set('python-bridge', {
|
||||
dotVenvPath: path.join(PYTHON_BRIDGE_SRC_PATH, '.venv')
|
||||
})
|
||||
BUILD_TARGETS.set('tcp-server', {
|
||||
name: 'TCP server',
|
||||
name: 'Python TCP server',
|
||||
needsPythonEnv: true,
|
||||
pipfilePath: path.join(TCP_SERVER_SRC_PATH, 'Pipfile'),
|
||||
setupFilePath: path.join(TCP_SERVER_SRC_PATH, 'setup.py'),
|
||||
distPath: TCP_SERVER_DIST_PATH,
|
||||
archiveName: `${TCP_SERVER_BIN_NAME}-${BINARIES_FOLDER_NAME}.zip`,
|
||||
dotVenvPath: path.join(TCP_SERVER_SRC_PATH, '.venv')
|
||||
pipfilePath: path.join(PYTHON_TCP_SERVER_SRC_PATH, 'Pipfile'),
|
||||
setupFilePath: path.join(PYTHON_TCP_SERVER_SRC_PATH, 'setup.py'),
|
||||
distPath: PYTHON_TCP_SERVER_DIST_PATH,
|
||||
archiveName: `${PYTHON_TCP_SERVER_BIN_NAME}-${BINARIES_FOLDER_NAME}.zip`,
|
||||
dotVenvPath: path.join(PYTHON_TCP_SERVER_SRC_PATH, '.venv')
|
||||
})
|
||||
;(async () => {
|
||||
LoaderHelper.start()
|
||||
|
@ -18,8 +18,8 @@ import {
|
||||
LEON_VERSION,
|
||||
NODEJS_BRIDGE_BIN_PATH,
|
||||
PYTHON_BRIDGE_BIN_PATH,
|
||||
TCP_SERVER_BIN_PATH,
|
||||
TCP_SERVER_VERSION,
|
||||
PYTHON_TCP_SERVER_BIN_PATH,
|
||||
PYTHON_TCP_SERVER_VERSION,
|
||||
NODEJS_BRIDGE_VERSION,
|
||||
PYTHON_BRIDGE_VERSION,
|
||||
INSTANCE_ID
|
||||
@ -50,8 +50,8 @@ dotenv.config()
|
||||
can_run: { title: 'Run', type: 'error', v: true },
|
||||
can_run_skill: { title: 'Run skills', type: 'error', v: true },
|
||||
can_text: { title: 'Reply you by texting', type: 'error', v: true },
|
||||
can_start_tcp_server: {
|
||||
title: 'Start the TCP server',
|
||||
can_start_python_tcp_server: {
|
||||
title: 'Start the Python TCP server',
|
||||
type: 'error',
|
||||
v: true
|
||||
},
|
||||
@ -118,7 +118,7 @@ dotenv.config()
|
||||
output: null,
|
||||
error: null
|
||||
},
|
||||
tcpServer: {
|
||||
pythonTCPServer: {
|
||||
version: null,
|
||||
startTime: null,
|
||||
command: null,
|
||||
@ -286,39 +286,39 @@ dotenv.config()
|
||||
}
|
||||
|
||||
/**
|
||||
* TCP server startup checking
|
||||
* Python TCP server startup checking
|
||||
*/
|
||||
|
||||
LogHelper.success(`TCP server version: ${TCP_SERVER_VERSION}`)
|
||||
reportDataInput.tcpServer.version = TCP_SERVER_VERSION
|
||||
LogHelper.success(`Python TCP server version: ${PYTHON_TCP_SERVER_VERSION}`)
|
||||
reportDataInput.pythonTCPServer.version = PYTHON_TCP_SERVER_VERSION
|
||||
|
||||
LogHelper.info('Starting the TCP server...')
|
||||
LogHelper.info('Starting the Python TCP server...')
|
||||
|
||||
const tcpServerCommand = `${TCP_SERVER_BIN_PATH} en`
|
||||
const tcpServerStart = Date.now()
|
||||
const p = spawn(tcpServerCommand, { shell: true })
|
||||
const pythonTCPServerCommand = `${PYTHON_TCP_SERVER_BIN_PATH} en`
|
||||
const pythonTCPServerStart = Date.now()
|
||||
const p = spawn(pythonTCPServerCommand, { shell: true })
|
||||
const ignoredWarnings = [
|
||||
'UserWarning: Unable to retrieve source for @torch.jit._overload function'
|
||||
]
|
||||
|
||||
LogHelper.info(tcpServerCommand)
|
||||
reportDataInput.tcpServer.command = tcpServerCommand
|
||||
LogHelper.info(pythonTCPServerCommand)
|
||||
reportDataInput.pythonTCPServer.command = pythonTCPServerCommand
|
||||
|
||||
if (osInfo.platform === 'darwin') {
|
||||
LogHelper.info(
|
||||
'For the first start, it may take a few minutes to cold start the TCP server on macOS. No worries it is a one-time thing'
|
||||
'For the first start, it may take a few minutes to cold start the Python TCP server on macOS. No worries it is a one-time thing'
|
||||
)
|
||||
}
|
||||
|
||||
let tcpServerOutput = ''
|
||||
let pythonTCPServerOutput = ''
|
||||
|
||||
p.stdout.on('data', (data) => {
|
||||
const newData = data.toString()
|
||||
tcpServerOutput += newData
|
||||
pythonTCPServerOutput += newData
|
||||
|
||||
if (newData?.toLowerCase().includes('waiting for')) {
|
||||
kill(p.pid)
|
||||
LogHelper.success('The TCP server can successfully start')
|
||||
LogHelper.success('The Python TCP server can successfully start')
|
||||
}
|
||||
})
|
||||
|
||||
@ -327,10 +327,10 @@ dotenv.config()
|
||||
|
||||
// Ignore given warnings on stderr output
|
||||
if (!ignoredWarnings.some((w) => newData.includes(w))) {
|
||||
tcpServerOutput += newData
|
||||
report.can_start_tcp_server.v = false
|
||||
reportDataInput.tcpServer.error = newData
|
||||
LogHelper.error(`Cannot start the TCP server: ${newData}`)
|
||||
pythonTCPServerOutput += newData
|
||||
report.can_start_python_tcp_server.v = false
|
||||
reportDataInput.pythonTCPServer.error = newData
|
||||
LogHelper.error(`Cannot start the Python TCP server: ${newData}`)
|
||||
}
|
||||
})
|
||||
|
||||
@ -339,18 +339,20 @@ dotenv.config()
|
||||
setTimeout(() => {
|
||||
kill(p.pid)
|
||||
|
||||
const error = `The TCP server timed out after ${timeout}ms`
|
||||
const error = `The Python TCP server timed out after ${timeout}ms`
|
||||
LogHelper.error(error)
|
||||
reportDataInput.tcpServer.error = error
|
||||
report.can_start_tcp_server.v = false
|
||||
reportDataInput.pythonTCPServer.error = error
|
||||
report.can_start_python_tcp_server.v = false
|
||||
}, timeout)
|
||||
|
||||
p.stdout.on('end', async () => {
|
||||
const tcpServerEnd = Date.now()
|
||||
reportDataInput.tcpServer.output = tcpServerOutput
|
||||
reportDataInput.tcpServer.startTime = `${tcpServerEnd - tcpServerStart}ms`
|
||||
const pythonTCPServerEnd = Date.now()
|
||||
reportDataInput.pythonTCPServer.output = pythonTCPServerOutput
|
||||
reportDataInput.pythonTCPServer.startTime = `${
|
||||
pythonTCPServerEnd - pythonTCPServerStart
|
||||
}ms`
|
||||
LogHelper.info(
|
||||
`TCP server startup time: ${reportDataInput.tcpServer.startTime}\n`
|
||||
`Python TCP server startup time: ${reportDataInput.pythonTCPServer.startTime}\n`
|
||||
)
|
||||
|
||||
/**
|
||||
@ -564,7 +566,7 @@ dotenv.config()
|
||||
report.can_run.v &&
|
||||
report.can_run_skill.v &&
|
||||
report.can_text.v &&
|
||||
report.can_start_tcp_server.v
|
||||
report.can_start_python_tcp_server.v
|
||||
) {
|
||||
LogHelper.success('Hooray! Leon can run correctly')
|
||||
LogHelper.info(
|
||||
|
@ -6,7 +6,7 @@ import { command } from 'execa'
|
||||
import {
|
||||
NODEJS_BRIDGE_SRC_PATH,
|
||||
PYTHON_BRIDGE_SRC_PATH,
|
||||
TCP_SERVER_SRC_PATH
|
||||
PYTHON_TCP_SERVER_SRC_PATH
|
||||
} from '@/constants'
|
||||
import { LogHelper } from '@/helpers/log-helper'
|
||||
import { LoaderHelper } from '@/helpers/loader-helper'
|
||||
@ -29,7 +29,7 @@ BUILD_TARGETS.set('python-bridge', {
|
||||
})
|
||||
BUILD_TARGETS.set('tcp-server', {
|
||||
workflowFileName: 'pre-release-tcp-server.yml',
|
||||
versionFilePath: path.join(TCP_SERVER_SRC_PATH, 'version.py')
|
||||
versionFilePath: path.join(PYTHON_TCP_SERVER_SRC_PATH, 'version.py')
|
||||
})
|
||||
;(async () => {
|
||||
LoaderHelper.start()
|
||||
|
@ -81,7 +81,6 @@ async function downloadLLM() {
|
||||
await stream.promises.finished(llmWriter)
|
||||
|
||||
LogHelper.success(`${LLM_NAME_WITH_VERSION} downloaded`)
|
||||
|
||||
LogHelper.success(`${LLM_NAME_WITH_VERSION} ready`)
|
||||
} else {
|
||||
LogHelper.success(
|
||||
|
@ -21,7 +21,10 @@ export const BINARIES_FOLDER_NAME = SystemHelper.getBinariesFolderName()
|
||||
export const BRIDGES_PATH = path.join(process.cwd(), 'bridges')
|
||||
export const NODEJS_BRIDGE_ROOT_PATH = path.join(BRIDGES_PATH, 'nodejs')
|
||||
export const PYTHON_BRIDGE_ROOT_PATH = path.join(BRIDGES_PATH, 'python')
|
||||
export const TCP_SERVER_ROOT_PATH = path.join(process.cwd(), 'tcp_server')
|
||||
export const PYTHON_TCP_SERVER_ROOT_PATH = path.join(
|
||||
process.cwd(),
|
||||
'tcp_server'
|
||||
)
|
||||
|
||||
export const NODEJS_BRIDGE_DIST_PATH = path.join(
|
||||
NODEJS_BRIDGE_ROOT_PATH,
|
||||
@ -31,11 +34,17 @@ export const PYTHON_BRIDGE_DIST_PATH = path.join(
|
||||
PYTHON_BRIDGE_ROOT_PATH,
|
||||
'dist'
|
||||
)
|
||||
export const TCP_SERVER_DIST_PATH = path.join(TCP_SERVER_ROOT_PATH, 'dist')
|
||||
export const PYTHON_TCP_SERVER_DIST_PATH = path.join(
|
||||
PYTHON_TCP_SERVER_ROOT_PATH,
|
||||
'dist'
|
||||
)
|
||||
|
||||
export const NODEJS_BRIDGE_SRC_PATH = path.join(NODEJS_BRIDGE_ROOT_PATH, 'src')
|
||||
export const PYTHON_BRIDGE_SRC_PATH = path.join(PYTHON_BRIDGE_ROOT_PATH, 'src')
|
||||
export const TCP_SERVER_SRC_PATH = path.join(TCP_SERVER_ROOT_PATH, 'src')
|
||||
export const PYTHON_TCP_SERVER_SRC_PATH = path.join(
|
||||
PYTHON_TCP_SERVER_ROOT_PATH,
|
||||
'src'
|
||||
)
|
||||
|
||||
const NODEJS_BRIDGE_VERSION_FILE_PATH = path.join(
|
||||
NODEJS_BRIDGE_SRC_PATH,
|
||||
@ -45,8 +54,8 @@ const PYTHON_BRIDGE_VERSION_FILE_PATH = path.join(
|
||||
PYTHON_BRIDGE_SRC_PATH,
|
||||
'version.py'
|
||||
)
|
||||
const TCP_SERVER_VERSION_FILE_PATH = path.join(
|
||||
TCP_SERVER_SRC_PATH,
|
||||
const PYTHON_TCP_SERVER_VERSION_FILE_PATH = path.join(
|
||||
PYTHON_TCP_SERVER_SRC_PATH,
|
||||
'version.py'
|
||||
)
|
||||
export const [, NODEJS_BRIDGE_VERSION] = fs
|
||||
@ -55,18 +64,18 @@ export const [, NODEJS_BRIDGE_VERSION] = fs
|
||||
export const [, PYTHON_BRIDGE_VERSION] = fs
|
||||
.readFileSync(PYTHON_BRIDGE_VERSION_FILE_PATH, 'utf8')
|
||||
.split("'")
|
||||
export const [, TCP_SERVER_VERSION] = fs
|
||||
.readFileSync(TCP_SERVER_VERSION_FILE_PATH, 'utf8')
|
||||
export const [, PYTHON_TCP_SERVER_VERSION] = fs
|
||||
.readFileSync(PYTHON_TCP_SERVER_VERSION_FILE_PATH, 'utf8')
|
||||
.split("'")
|
||||
|
||||
export const NODEJS_BRIDGE_BIN_NAME = 'leon-nodejs-bridge.js'
|
||||
export const PYTHON_BRIDGE_BIN_NAME = 'leon-python-bridge'
|
||||
export const TCP_SERVER_BIN_NAME = 'leon-tcp-server'
|
||||
export const PYTHON_TCP_SERVER_BIN_NAME = 'leon-tcp-server'
|
||||
|
||||
export const TCP_SERVER_BIN_PATH = path.join(
|
||||
TCP_SERVER_DIST_PATH,
|
||||
export const PYTHON_TCP_SERVER_BIN_PATH = path.join(
|
||||
PYTHON_TCP_SERVER_DIST_PATH,
|
||||
BINARIES_FOLDER_NAME,
|
||||
TCP_SERVER_BIN_NAME
|
||||
PYTHON_TCP_SERVER_BIN_NAME
|
||||
)
|
||||
export const PYTHON_BRIDGE_BIN_PATH = path.join(
|
||||
PYTHON_BRIDGE_DIST_PATH,
|
||||
@ -121,8 +130,12 @@ export const HAS_OVER_HTTP = process.env['LEON_OVER_HTTP'] === 'true'
|
||||
export const HTTP_API_KEY = process.env['LEON_HTTP_API_KEY']
|
||||
export const HTTP_API_LANG = process.env['LEON_HTTP_API_LANG']
|
||||
|
||||
export const TCP_SERVER_HOST = process.env['LEON_PY_TCP_SERVER_HOST']
|
||||
export const TCP_SERVER_PORT = Number(process.env['LEON_PY_TCP_SERVER_PORT'])
|
||||
export const PYTHON_TCP_SERVER_HOST = process.env['LEON_PY_TCP_SERVER_HOST']
|
||||
export const PYTHON_TCP_SERVER_PORT = Number(
|
||||
process.env['LEON_PY_TCP_SERVER_PORT']
|
||||
)
|
||||
export const LLM_TCP_SERVER_HOST = '0.0.0.0'
|
||||
export const LLM_TCP_SERVER_PORT = 52420
|
||||
|
||||
export const IS_TELEMETRY_ENABLED = process.env['LEON_TELEMETRY'] === 'true'
|
||||
|
||||
|
@ -22,7 +22,7 @@ import {
|
||||
STT_PROVIDER,
|
||||
TTS_PROVIDER
|
||||
} from '@/constants'
|
||||
import { TCP_CLIENT } from '@/core'
|
||||
import { PYTHON_TCP_CLIENT } from '@/core'
|
||||
import Nlu from '@/core/nlu'
|
||||
import Brain from '@/core/brain'
|
||||
import Asr from '@/core/asr/asr'
|
||||
@ -221,10 +221,10 @@ server.handleOnConnection = (socket) => {
|
||||
const provider = await addProvider(socket.id)
|
||||
|
||||
// Check whether the TCP client is connected to the TCP server
|
||||
if (TCP_CLIENT.isConnected) {
|
||||
if (PYTHON_TCP_CLIENT.isConnected) {
|
||||
socket.emit('ready')
|
||||
} else {
|
||||
TCP_CLIENT.ee.on('connected', () => {
|
||||
PYTHON_TCP_CLIENT.ee.on('connected', () => {
|
||||
socket.emit('ready')
|
||||
})
|
||||
}
|
||||
|
@ -1,4 +1,11 @@
|
||||
import { HOST, PORT, TCP_SERVER_HOST, TCP_SERVER_PORT } from '@/constants'
|
||||
import {
|
||||
HOST,
|
||||
PORT,
|
||||
PYTHON_TCP_SERVER_HOST,
|
||||
PYTHON_TCP_SERVER_PORT,
|
||||
LLM_TCP_SERVER_HOST,
|
||||
LLM_TCP_SERVER_PORT
|
||||
} from '@/constants'
|
||||
import TCPClient from '@/core/tcp-client'
|
||||
import HTTPServer from '@/core/http-server/http-server'
|
||||
import SocketServer from '@/core/socket-server'
|
||||
@ -11,13 +18,23 @@ import NaturalLanguageUnderstanding from '@/core/nlp/nlu/nlu'
|
||||
import Brain from '@/core/brain/brain'
|
||||
|
||||
/**
|
||||
* Register core singletons
|
||||
* Register core nodes
|
||||
*/
|
||||
|
||||
export const TCP_CLIENT = new TCPClient(
|
||||
String(TCP_SERVER_HOST),
|
||||
TCP_SERVER_PORT
|
||||
export const PYTHON_TCP_CLIENT = new TCPClient(
|
||||
'Python',
|
||||
String(PYTHON_TCP_SERVER_HOST),
|
||||
PYTHON_TCP_SERVER_PORT
|
||||
)
|
||||
export const LLM_TCP_CLIENT = new LLMTCPClient(
|
||||
'LLM',
|
||||
LLM_TCP_SERVER_HOST,
|
||||
LLM_TCP_SERVER_PORT
|
||||
)
|
||||
|
||||
/**
|
||||
* Register core singletons
|
||||
*/
|
||||
|
||||
export const HTTP_SERVER = new HTTPServer(String(HOST), PORT)
|
||||
|
||||
|
13
server/src/core/llm-tcp-server/llm-tcp-server.ts
Normal file
13
server/src/core/llm-tcp-server/llm-tcp-server.ts
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Duties:
|
||||
*
|
||||
* Custom NER
|
||||
* Summarization
|
||||
* Translation
|
||||
* More accurate NLU (per domain list vs per skill list) / Utterance shortener or paraphraser
|
||||
* Knowledge base / RAG
|
||||
* Question answering
|
||||
* Sentiment analysis
|
||||
* Chit chat
|
||||
* Intent fallback
|
||||
*/
|
@ -13,7 +13,7 @@ import type {
|
||||
SkillCustomRegexEntityTypeSchema,
|
||||
SkillCustomTrimEntityTypeSchema
|
||||
} from '@/schemas/skill-schemas'
|
||||
import { BRAIN, MODEL_LOADER, TCP_CLIENT } from '@/core'
|
||||
import { BRAIN, MODEL_LOADER, PYTHON_TCP_CLIENT } from '@/core'
|
||||
import { LogHelper } from '@/helpers/log-helper'
|
||||
import { StringHelper } from '@/helpers/string-helper'
|
||||
import { SkillDomainHelper } from '@/helpers/skill-domain-helper'
|
||||
@ -197,10 +197,13 @@ export default class NER {
|
||||
resolve(spacyEntities)
|
||||
}
|
||||
|
||||
TCP_CLIENT.ee.removeAllListeners()
|
||||
TCP_CLIENT.ee.on('spacy-entities-received', spacyEntitiesReceivedHandler)
|
||||
PYTHON_TCP_CLIENT.ee.removeAllListeners()
|
||||
PYTHON_TCP_CLIENT.ee.on(
|
||||
'spacy-entities-received',
|
||||
spacyEntitiesReceivedHandler
|
||||
)
|
||||
|
||||
TCP_CLIENT.emit('get-spacy-entities', utterance)
|
||||
PYTHON_TCP_CLIENT.emit('get-spacy-entities', utterance)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -14,8 +14,14 @@ import type {
|
||||
NLUResult
|
||||
} from '@/core/nlp/types'
|
||||
import { langs } from '@@/core/langs.json'
|
||||
import { TCP_SERVER_BIN_PATH } from '@/constants'
|
||||
import { TCP_CLIENT, BRAIN, SOCKET_SERVER, MODEL_LOADER, NER } from '@/core'
|
||||
import { PYTHON_TCP_SERVER_BIN_PATH } from '@/constants'
|
||||
import {
|
||||
PYTHON_TCP_CLIENT,
|
||||
BRAIN,
|
||||
SOCKET_SERVER,
|
||||
MODEL_LOADER,
|
||||
NER
|
||||
} from '@/core'
|
||||
import { LogHelper } from '@/helpers/log-helper'
|
||||
import { LangHelper } from '@/helpers/lang-helper'
|
||||
import { ActionLoop } from '@/core/nlp/nlu/action-loop'
|
||||
@ -70,14 +76,17 @@ export default class NLU {
|
||||
BRAIN.talk(`${BRAIN.wernicke('random_language_switch')}.`, true)
|
||||
|
||||
// Recreate a new TCP server process and reconnect the TCP client
|
||||
kill(global.tcpServerProcess.pid as number, () => {
|
||||
global.tcpServerProcess = spawn(`${TCP_SERVER_BIN_PATH} ${locale}`, {
|
||||
shell: true
|
||||
})
|
||||
kill(global.pythonTCPServerProcess.pid as number, () => {
|
||||
global.pythonTCPServerProcess = spawn(
|
||||
`${PYTHON_TCP_SERVER_BIN_PATH} ${locale}`,
|
||||
{
|
||||
shell: true
|
||||
}
|
||||
)
|
||||
|
||||
TCP_CLIENT.connect()
|
||||
TCP_CLIENT.ee.removeListener('connected', connectedHandler)
|
||||
TCP_CLIENT.ee.on('connected', connectedHandler)
|
||||
PYTHON_TCP_CLIENT.connect()
|
||||
PYTHON_TCP_CLIENT.ee.removeListener('connected', connectedHandler)
|
||||
PYTHON_TCP_CLIENT.ee.on('connected', connectedHandler)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import { Server as SocketIOServer, Socket } from 'socket.io'
|
||||
import { LANG, HAS_STT, HAS_TTS, IS_DEVELOPMENT_ENV } from '@/constants'
|
||||
import {
|
||||
HTTP_SERVER,
|
||||
TCP_CLIENT,
|
||||
PYTHON_TCP_CLIENT,
|
||||
ASR,
|
||||
STT,
|
||||
TTS,
|
||||
@ -86,11 +86,11 @@ export default class SocketServer {
|
||||
// TODO
|
||||
// const provider = await addProvider(socket.id)
|
||||
|
||||
// Check whether the TCP client is connected to the TCP server
|
||||
if (TCP_CLIENT.isConnected) {
|
||||
// Check whether the Python TCP client is connected to the Python TCP server
|
||||
if (PYTHON_TCP_CLIENT.isConnected) {
|
||||
this.socket?.emit('ready')
|
||||
} else {
|
||||
TCP_CLIENT.ee.on('connected', () => {
|
||||
PYTHON_TCP_CLIENT.ee.on('connected', () => {
|
||||
this.socket?.emit('ready')
|
||||
})
|
||||
}
|
||||
|
@ -15,10 +15,9 @@ interface ChunkData {
|
||||
topic: string
|
||||
data: unknown
|
||||
}
|
||||
type TCPClientName = 'Python' | 'LLM'
|
||||
|
||||
export default class TCPClient {
|
||||
private static instance: TCPClient
|
||||
|
||||
private reconnectCounter = 0
|
||||
private tcpSocket = new Net.Socket()
|
||||
private _isConnected = false
|
||||
@ -34,23 +33,21 @@ export default class TCPClient {
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly name: TCPClientName,
|
||||
private readonly host: string,
|
||||
private readonly port: number
|
||||
) {
|
||||
if (!TCPClient.instance) {
|
||||
LogHelper.title('TCP Client')
|
||||
LogHelper.success('New instance')
|
||||
|
||||
TCPClient.instance = this
|
||||
}
|
||||
LogHelper.title(`${name} TCP Client`)
|
||||
LogHelper.success('New instance')
|
||||
|
||||
this.name = name
|
||||
this.host = host
|
||||
this.port = port
|
||||
|
||||
this.tcpSocket.on('connect', () => {
|
||||
LogHelper.title('TCP Client')
|
||||
LogHelper.title(`${this.name} TCP Client`)
|
||||
LogHelper.success(
|
||||
`Connected to the TCP server tcp://${this.host}:${this.port}`
|
||||
`Connected to the ${this.name} TCP server tcp://${this.host}:${this.port}`
|
||||
)
|
||||
|
||||
this.reconnectCounter = 0
|
||||
@ -59,7 +56,7 @@ export default class TCPClient {
|
||||
})
|
||||
|
||||
this.tcpSocket.on('data', (chunk: ChunkData) => {
|
||||
LogHelper.title('TCP Client')
|
||||
LogHelper.title(`${this.name} TCP Client`)
|
||||
LogHelper.info(`Received data: ${String(chunk)}`)
|
||||
|
||||
const data = JSON.parse(String(chunk))
|
||||
@ -67,7 +64,7 @@ export default class TCPClient {
|
||||
})
|
||||
|
||||
this.tcpSocket.on('error', (err: NodeJS.ErrnoException) => {
|
||||
LogHelper.title('TCP Client')
|
||||
LogHelper.title(`${this.name} TCP Client`)
|
||||
|
||||
if (err.code === 'ECONNREFUSED') {
|
||||
this.reconnectCounter += 1
|
||||
@ -75,17 +72,17 @@ export default class TCPClient {
|
||||
const { type: osType } = SystemHelper.getInformation()
|
||||
|
||||
if (this.reconnectCounter >= RETRIES_NB) {
|
||||
LogHelper.error('Failed to connect to the TCP server')
|
||||
LogHelper.error(`Failed to connect to the ${this.name} TCP server`)
|
||||
this.tcpSocket.end()
|
||||
}
|
||||
|
||||
if (this.reconnectCounter >= 1) {
|
||||
LogHelper.info('Trying to connect to the TCP server...')
|
||||
LogHelper.info(`Trying to connect to the ${this.name} TCP server...`)
|
||||
|
||||
if (this.reconnectCounter >= 5) {
|
||||
if (osType === OSTypes.MacOS) {
|
||||
LogHelper.warning(
|
||||
'The cold start of the TCP server can take a few more seconds on macOS. It should be a one-time thing, no worries'
|
||||
`The cold start of the ${this.name} TCP server can take a few more seconds on macOS. It should be a one-time thing, no worries`
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -95,15 +92,17 @@ export default class TCPClient {
|
||||
}, INTERVAL * this.reconnectCounter)
|
||||
}
|
||||
} else {
|
||||
LogHelper.error(`Failed to connect to the TCP server: ${err}`)
|
||||
LogHelper.error(
|
||||
`Failed to connect to the ${this.name} TCP server: ${err}`
|
||||
)
|
||||
}
|
||||
|
||||
this._isConnected = false
|
||||
})
|
||||
|
||||
this.tcpSocket.on('end', () => {
|
||||
LogHelper.title('TCP Client')
|
||||
LogHelper.success('Disconnected from the TCP server')
|
||||
LogHelper.title(`${this.name} TCP Client`)
|
||||
LogHelper.success(`Disconnected from the ${this.name} TCP server`)
|
||||
|
||||
this._isConnected = false
|
||||
})
|
||||
|
5
server/src/global.d.ts
vendored
5
server/src/global.d.ts
vendored
@ -1,12 +1,9 @@
|
||||
import type { ChildProcessWithoutNullStreams } from 'node:child_process'
|
||||
|
||||
import TCPClient from '@/core/tcp-client'
|
||||
|
||||
declare global {
|
||||
/* eslint-disable no-var */
|
||||
|
||||
var tcpServerProcess: ChildProcessWithoutNullStreams
|
||||
var tcpClient: TCPClient
|
||||
var pythonTCPServerProcess: ChildProcessWithoutNullStreams
|
||||
}
|
||||
|
||||
export {}
|
||||
|
@ -5,26 +5,26 @@ import {
|
||||
IS_DEVELOPMENT_ENV,
|
||||
IS_TELEMETRY_ENABLED,
|
||||
LANG as LEON_LANG,
|
||||
TCP_SERVER_BIN_PATH
|
||||
PYTHON_TCP_SERVER_BIN_PATH
|
||||
} from '@/constants'
|
||||
import { TCP_CLIENT, HTTP_SERVER, SOCKET_SERVER } from '@/core'
|
||||
import { PYTHON_TCP_CLIENT, HTTP_SERVER, SOCKET_SERVER } from '@/core'
|
||||
import { Telemetry } from '@/telemetry'
|
||||
import { LangHelper } from '@/helpers/lang-helper'
|
||||
import { LogHelper } from '@/helpers/log-helper'
|
||||
;(async (): Promise<void> => {
|
||||
process.title = 'leon'
|
||||
|
||||
// Start the TCP server
|
||||
global.tcpServerProcess = spawn(
|
||||
`${TCP_SERVER_BIN_PATH} ${LangHelper.getShortCode(LEON_LANG)}`,
|
||||
// Start the Python TCP server
|
||||
global.pythonTCPServerProcess = spawn(
|
||||
`${PYTHON_TCP_SERVER_BIN_PATH} ${LangHelper.getShortCode(LEON_LANG)}`,
|
||||
{
|
||||
shell: true,
|
||||
detached: IS_DEVELOPMENT_ENV
|
||||
}
|
||||
)
|
||||
|
||||
// Connect the TCP client to the TCP server
|
||||
TCP_CLIENT.connect()
|
||||
// Connect the Python TCP client to the Python TCP server
|
||||
PYTHON_TCP_CLIENT.connect()
|
||||
|
||||
// Start the HTTP server
|
||||
await HTTP_SERVER.init()
|
||||
@ -65,7 +65,7 @@ import { LogHelper } from '@/helpers/log-helper'
|
||||
process.on(eventType, () => {
|
||||
Telemetry.stop()
|
||||
|
||||
global.tcpServerProcess.kill()
|
||||
global.pythonTCPServerProcess.kill()
|
||||
|
||||
setTimeout(() => {
|
||||
process.exit(0)
|
||||
|
@ -126,6 +126,18 @@
|
||||
"[Add|Append] @todos"
|
||||
],
|
||||
"entities": [
|
||||
{
|
||||
"type": "llm",
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"list_name": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "trim",
|
||||
"name": "todos",
|
||||
|
Loading…
Reference in New Issue
Block a user