fix(ai): register chart tool for electron auto skills

This commit is contained in:
digua committed 2026-06-05 11:12:42 +08:00
1 parent f825c0734b
commit 9b1f359699
12 files changed
+164 -18

No files matched your search

+17 -2
View File
@@ -11,7 +11,7 @@ const path = require('node:path')
const fs = require('node:fs')
const os = require('node:os')
const net = require('node:net')
const electron = require('electron')
const { createRequire } = require('node:module')
const DEFAULT_START_PORT = 9222
const DEFAULT_MAX_PORT_RETRIES = 100
@@ -127,6 +127,20 @@ function releaseReservation(reservationServer) {
safeCloseServer(reservationServer)
}
function resolveElectronExecutable(deps = {}) {
if (deps.electronPath) return deps.electronPath
const desktopPackageJson = path.resolve(__dirname, '../../../apps/desktop/package.json')
const requireElectron = deps.requireElectron || createRequire(desktopPackageJson)
try {
const electronModule = requireElectron('electron')
return typeof electronModule === 'string' ? electronModule : ''
} catch (error) {
throw new Error(`[AppLauncher] 无法解析 Electron 可执行文件: ${error.message}`)
}
}
/**
* 启动 Electron 应用
*/
@@ -172,7 +186,7 @@ async function launchApp(options = {}, deps = {}) {
throw new Error(`[AppLauncher] 应用目录不存在: ${appPath}`)
}
const electronExe = typeof electron === 'string' ? electron : ''
const electronExe = resolveElectronExecutable(deps)
if (!electronExe || !fsImpl.existsSync(electronExe)) {
throw new Error(`Electron 可执行文件不存在: ${electronExe}`)
@@ -261,5 +275,6 @@ module.exports = {
findAvailablePortWithReservation,
terminateProcess,
releaseReservation,
resolveElectronExecutable,
},
}
+3 -1
View File
@@ -74,6 +74,7 @@ test('findAvailablePortWithReservation 达到最大重试会抛错', async () =>
})
test('launchApp 支持 startPort 并正确注入 TEST_MODE 环境', async () => {
const fakeElectronPath = '/tmp/fake-electron'
const captured = {
startPort: null,
spawnCmd: null,
@@ -108,6 +109,7 @@ test('launchApp 支持 startPort 并正确注入 TEST_MODE 环境', async () =>
mkdirSync: () => {},
},
sleepFn: async () => {},
electronPath: fakeElectronPath,
findPortFn: async (startPort) => {
captured.startPort = startPort
return {
@@ -130,7 +132,7 @@ test('launchApp 支持 startPort 并正确注入 TEST_MODE 环境', async () =>
assert.equal(captured.startPort, 9900)
assert.equal(captured.reservationClosed, true)
assert.match(captured.spawnCmd, /electron(\.cmd|\.exe)?$/)
assert.equal(captured.spawnCmd, fakeElectronPath)
assert.deepEqual(captured.spawnArgs, ['--remote-debugging-port=9901', captured.spawnArgs[1]])
assert.equal(captured.spawnEnv.TEST_MODE, 'true')
assert.match(captured.spawnEnv.CHATLAB_E2E_USER_DATA_DIR, /chatlab-e2e-9901$/)
+12 -1
View File
@@ -6,7 +6,7 @@ const fs = require('node:fs')
const path = require('node:path')
const os = require('node:os')
const http = require('node:http')
const Database = require('better-sqlite3')
const { createRequire } = require('node:module')
const { launchApp } = require('../helpers/app-launcher')
@@ -114,6 +114,15 @@ const CONVERSATION_ID = 'conv_chart_smoke'
const CONVERSATION_TITLE = 'Chart replay smoke'
const CHART_TITLE = 'Selected members smoke'
let Database = null
function getDatabaseConstructor() {
if (Database) return Database
const nodeRuntimePackageJson = path.resolve(__dirname, '../../../packages/node-runtime/package.json')
Database = createRequire(nodeRuntimePackageJson)('better-sqlite3')
return Database
}
function resolveNativeBinding() {
if (process.env.CHATLAB_TEST_SQLITE_NATIVE_BINDING) {
return process.env.CHATLAB_TEST_SQLITE_NATIVE_BINDING
@@ -135,6 +144,7 @@ function ensureDir(dir) {
}
function seedChatSessionDb(chatDataDir) {
const Database = getDatabaseConstructor()
const dbDir = path.join(chatDataDir, 'databases')
ensureDir(dbDir)
const db = new Database(path.join(dbDir, `${SESSION_ID}.db`), {
@@ -183,6 +193,7 @@ function seedChatSessionDb(chatDataDir) {
}
function seedAiConversationDb(homeDir) {
const Database = getDatabaseConstructor()
const aiDir = path.join(homeDir, '.chatlab', 'ai')
ensureDir(aiDir)
const db = new Database(path.join(aiDir, 'conversations.db'), {