chore: 添加昔涟语音模型目录到 .gitignore
data/cyrene_voice/ + models/cyrene_voice/ + voice-service 模型路径 关联仓库: Cyrene-Voice-Model Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+11
@@ -1,10 +1,16 @@
|
|||||||
# ========== 依赖 ==========
|
# ========== 依赖 ==========
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
|
# ========== 测试 ==========
|
||||||
|
test/
|
||||||
|
|
||||||
# ========== 构建产物 ==========
|
# ========== 构建产物 ==========
|
||||||
dist/
|
dist/
|
||||||
*.exe
|
*.exe
|
||||||
|
|
||||||
|
# ========== 子仓库 ==========
|
||||||
|
backend/cyrene-plugins/
|
||||||
|
|
||||||
# ========== Go 编译二进制 ==========
|
# ========== Go 编译二进制 ==========
|
||||||
backend/ai-core/main
|
backend/ai-core/main
|
||||||
backend/ai-core/cmd/main
|
backend/ai-core/cmd/main
|
||||||
@@ -68,6 +74,11 @@ ethend/package-lock.json
|
|||||||
backend/voice-service/whisper.cpp/
|
backend/voice-service/whisper.cpp/
|
||||||
backend/voice-service/models/
|
backend/voice-service/models/
|
||||||
|
|
||||||
|
# ========== 昔涟语音模型 (独立仓库 Cyrene-Voice-Model) ==========
|
||||||
|
data/cyrene_voice/
|
||||||
|
models/cyrene_voice/
|
||||||
|
backend/voice-service/models/cyrene/
|
||||||
|
|
||||||
# ========== 打包归档 ==========
|
# ========== 打包归档 ==========
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
*.zip
|
*.zip
|
||||||
|
|||||||
@@ -1,150 +0,0 @@
|
|||||||
import { WebSocket } from 'ws';
|
|
||||||
import http from 'http';
|
|
||||||
|
|
||||||
const CDP_HOST = 'localhost';
|
|
||||||
const CDP_PORT = 9222;
|
|
||||||
|
|
||||||
function httpRequest(method, path) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const req = http.request({ hostname: CDP_HOST, port: CDP_PORT, method, path }, (res) => {
|
|
||||||
let data = '';
|
|
||||||
res.on('data', (c) => data += c);
|
|
||||||
res.on('end', () => {
|
|
||||||
try { resolve(JSON.parse(data)); } catch(e) { resolve(data); }
|
|
||||||
});
|
|
||||||
});
|
|
||||||
req.on('error', reject);
|
|
||||||
req.end();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function cdpCommand(ws, method, params = {}) {
|
|
||||||
const id = Math.floor(Math.random() * 1000000);
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const handler = (raw) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(raw.toString());
|
|
||||||
if (msg.id === id) {
|
|
||||||
ws.off('message', handler);
|
|
||||||
resolve(msg.result || msg);
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
};
|
|
||||||
ws.on('message', handler);
|
|
||||||
ws.send(JSON.stringify({ id, method, params }));
|
|
||||||
setTimeout(() => {
|
|
||||||
ws.off('message', handler);
|
|
||||||
resolve({ error: 'timeout' });
|
|
||||||
}, 8000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
console.log('[1] Creating new tab...');
|
|
||||||
const newTab = await httpRequest('PUT', '/json/new?about:blank');
|
|
||||||
console.log(' New tab:', newTab.id, '| WS:', newTab.webSocketDebuggerUrl?.substring(0, 50) + '...');
|
|
||||||
|
|
||||||
const ws = new WebSocket(newTab.webSocketDebuggerUrl);
|
|
||||||
await new Promise((resolve) => ws.on('open', resolve));
|
|
||||||
console.log('[2] CDP connected.');
|
|
||||||
|
|
||||||
await cdpCommand(ws, 'Runtime.enable');
|
|
||||||
await cdpCommand(ws, 'Page.enable');
|
|
||||||
await cdpCommand(ws, 'Log.enable');
|
|
||||||
|
|
||||||
const consoleMessages = [];
|
|
||||||
const errors = [];
|
|
||||||
ws.on('message', (raw) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(raw.toString());
|
|
||||||
if (msg.method === 'Runtime.consoleAPICalled') {
|
|
||||||
const p = msg.params;
|
|
||||||
const text = p.args?.map(a => a.value || a.description || '').join(' ') || '';
|
|
||||||
consoleMessages.push(`[${p.type}] ${text}`);
|
|
||||||
console.log(` CONSOLE [${p.type}]: ${text.substring(0, 200)}`);
|
|
||||||
}
|
|
||||||
if (msg.method === 'Runtime.exceptionThrown') {
|
|
||||||
const ed = msg.params.exceptionDetails;
|
|
||||||
const text = ed.text || ed.exception?.description || JSON.stringify(ed).substring(0, 300);
|
|
||||||
errors.push(text);
|
|
||||||
console.log(` EXCEPTION: ${text.substring(0, 300)}`);
|
|
||||||
if (ed.stackTrace) {
|
|
||||||
ed.stackTrace.callFrames?.forEach((f) => {
|
|
||||||
console.log(` at ${f.functionName || '(anonymous)'} (${f.url}:${f.lineNumber}:${f.columnNumber})`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (msg.method === 'Log.entryAdded') {
|
|
||||||
const entry = msg.params.entry;
|
|
||||||
const text = entry.text?.substring(0, 200) || '';
|
|
||||||
console.log(` LOG [${entry.level}]: ${text}`);
|
|
||||||
if (entry.level === 'error') {
|
|
||||||
errors.push(`[LOG:${entry.level}] ${text}`);
|
|
||||||
consoleMessages.push(`[LOG:${entry.level}] ${text}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('[3] Navigating to http://localhost:5199/ ...');
|
|
||||||
await cdpCommand(ws, 'Page.navigate', { url: 'http://localhost:5199/' });
|
|
||||||
|
|
||||||
console.log('[4] Waiting 8s for page load...');
|
|
||||||
await new Promise(r => setTimeout(r, 8000));
|
|
||||||
|
|
||||||
console.log('[5] Checking DOM...');
|
|
||||||
const docNode = await cdpCommand(ws, 'DOM.getDocument', { depth: 2 });
|
|
||||||
if (docNode && docNode.root) {
|
|
||||||
console.log(' Root:', docNode.root.nodeName, 'children:', docNode.root.childNodeCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Evaluate #root content
|
|
||||||
try {
|
|
||||||
const e1 = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `
|
|
||||||
(() => {
|
|
||||||
const root = document.getElementById('root');
|
|
||||||
if (!root) return 'NO_ROOT_ELEMENT';
|
|
||||||
const html = root.innerHTML.trim();
|
|
||||||
if (!html) return 'ROOT_EMPTY';
|
|
||||||
return 'ROOT_CONTENT(len=' + html.length + '): ' + html.substring(0, 500);
|
|
||||||
})()
|
|
||||||
`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' #root:', e1?.result?.value || JSON.stringify(e1).substring(0, 300));
|
|
||||||
} catch(e) {
|
|
||||||
console.log(' Eval error:', e.message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check body
|
|
||||||
try {
|
|
||||||
const e2 = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `document.body ? document.body.children.length + ' body children, innerHTML len=' + document.body.innerHTML.length : 'NO_BODY'`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' body:', e2?.result?.value);
|
|
||||||
} catch(e) {}
|
|
||||||
|
|
||||||
// Check document title
|
|
||||||
try {
|
|
||||||
const e3 = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `document.title`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' title:', e3?.result?.value);
|
|
||||||
} catch(e) {}
|
|
||||||
|
|
||||||
ws.close();
|
|
||||||
|
|
||||||
console.log('\n=== SUMMARY ===');
|
|
||||||
console.log('Console messages:', consoleMessages.length);
|
|
||||||
consoleMessages.slice(0, 15).forEach(m => console.log(' ', m.substring(0, 200)));
|
|
||||||
console.log('Errors:', errors.length);
|
|
||||||
errors.forEach((e, i) => console.log(` ERR${i+1}: ${e.substring(0, 500)}`));
|
|
||||||
}
|
|
||||||
|
|
||||||
main().catch(e => {
|
|
||||||
console.error('Fatal:', e.message);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
import { WebSocket } from 'ws';
|
|
||||||
import http from 'http';
|
|
||||||
|
|
||||||
const CDP_HOST = 'localhost';
|
|
||||||
const CDP_PORT = 9222;
|
|
||||||
|
|
||||||
function httpRequest(method, path) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const req = http.request({ hostname: CDP_HOST, port: CDP_PORT, method, path }, (res) => {
|
|
||||||
let data = '';
|
|
||||||
res.on('data', (c) => data += c);
|
|
||||||
res.on('end', () => {
|
|
||||||
try { resolve(JSON.parse(data)); } catch(e) { resolve(data); }
|
|
||||||
});
|
|
||||||
});
|
|
||||||
req.on('error', reject);
|
|
||||||
req.end();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function cdpCommand(ws, method, params = {}) {
|
|
||||||
const id = Math.floor(Math.random() * 1000000);
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const handler = (raw) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(raw.toString());
|
|
||||||
if (msg.id === id) {
|
|
||||||
ws.off('message', handler);
|
|
||||||
resolve(msg.result || msg);
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
};
|
|
||||||
ws.on('message', handler);
|
|
||||||
ws.send(JSON.stringify({ id, method, params }));
|
|
||||||
setTimeout(() => { ws.off('message', handler); resolve({ error: 'timeout' }); }, 8000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function testPage(label) {
|
|
||||||
console.log(`\n=== ${label} ===`);
|
|
||||||
const newTab = await httpRequest('PUT', '/json/new?about:blank');
|
|
||||||
const ws = new WebSocket(newTab.webSocketDebuggerUrl);
|
|
||||||
await new Promise((resolve) => ws.on('open', resolve));
|
|
||||||
|
|
||||||
await cdpCommand(ws, 'Runtime.enable');
|
|
||||||
await cdpCommand(ws, 'Page.enable');
|
|
||||||
await cdpCommand(ws, 'Log.enable');
|
|
||||||
|
|
||||||
const errors = [];
|
|
||||||
const logs = [];
|
|
||||||
ws.on('message', (raw) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(raw.toString());
|
|
||||||
if (msg.method === 'Runtime.exceptionThrown') {
|
|
||||||
errors.push(msg.params.exceptionDetails.text || JSON.stringify(msg.params.exceptionDetails).substring(0, 200));
|
|
||||||
}
|
|
||||||
if (msg.method === 'Log.entryAdded' && msg.params.entry.level === 'error') {
|
|
||||||
errors.push('[LOG] ' + msg.params.entry.text?.substring(0, 200));
|
|
||||||
}
|
|
||||||
if (msg.method === 'Runtime.consoleAPICalled') {
|
|
||||||
logs.push(`[${msg.params.type}] ${msg.params.args?.map(a => a.value || '').join(' ').substring(0, 150)}`);
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
});
|
|
||||||
|
|
||||||
await cdpCommand(ws, 'Page.navigate', { url: 'http://localhost:5199/' });
|
|
||||||
await new Promise(r => setTimeout(r, 6000));
|
|
||||||
|
|
||||||
// Check #root
|
|
||||||
const e1 = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `(() => { const r = document.getElementById('root'); return r ? (r.innerHTML.trim() ? 'CONTENT(' + r.innerHTML.length + ')' : 'EMPTY') : 'NO_ROOT'; })()`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' #root:', e1?.result?.value);
|
|
||||||
|
|
||||||
// Check if JS loaded
|
|
||||||
const e2 = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `typeof React !== 'undefined' ? 'React OK' : 'React MISSING'`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' React:', e2?.result?.value);
|
|
||||||
|
|
||||||
// Check SW status
|
|
||||||
const e3 = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `(() => { try { return 'serviceWorker' in navigator ? 'SW supported' : 'SW not supported'; } catch(e) { return 'Error: '+e.message; } })()`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' SW:', e3?.result?.value);
|
|
||||||
|
|
||||||
console.log(' Errors:', errors.length);
|
|
||||||
errors.forEach(e => console.log(' ', e.substring(0, 200)));
|
|
||||||
console.log(' Logs:', logs.length);
|
|
||||||
|
|
||||||
ws.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
// First visit - install SW
|
|
||||||
await testPage('1st VISIT (SW install)');
|
|
||||||
|
|
||||||
// Wait a bit for SW activation
|
|
||||||
console.log('\nWaiting 3s for SW activation...');
|
|
||||||
await new Promise(r => setTimeout(r, 3000));
|
|
||||||
|
|
||||||
// Second visit - SW should be active
|
|
||||||
await testPage('2nd VISIT (SW active)');
|
|
||||||
|
|
||||||
// Third visit
|
|
||||||
await testPage('3rd VISIT');
|
|
||||||
|
|
||||||
console.log('\n=== DONE ===');
|
|
||||||
}
|
|
||||||
|
|
||||||
main().catch(e => { console.error('Fatal:', e.message); process.exit(1); });
|
|
||||||
@@ -1,179 +0,0 @@
|
|||||||
import { WebSocket } from 'ws';
|
|
||||||
import http from 'http';
|
|
||||||
|
|
||||||
const CDP_HOST = 'localhost';
|
|
||||||
const CDP_PORT = 9222;
|
|
||||||
|
|
||||||
function httpRequest(method, path) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const req = http.request({ hostname: CDP_HOST, port: CDP_PORT, method, path }, (res) => {
|
|
||||||
let data = '';
|
|
||||||
res.on('data', (c) => data += c);
|
|
||||||
res.on('end', () => {
|
|
||||||
try { resolve(JSON.parse(data)); } catch(e) { resolve(data); }
|
|
||||||
});
|
|
||||||
});
|
|
||||||
req.on('error', reject);
|
|
||||||
req.end();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function cdpCommand(ws, method, params = {}) {
|
|
||||||
const id = Math.floor(Math.random() * 1000000);
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const handler = (raw) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(raw.toString());
|
|
||||||
if (msg.id === id) {
|
|
||||||
ws.off('message', handler);
|
|
||||||
resolve(msg.result || msg);
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
};
|
|
||||||
ws.on('message', handler);
|
|
||||||
ws.send(JSON.stringify({ id, method, params }));
|
|
||||||
setTimeout(() => { ws.off('message', handler); resolve({ error: 'timeout' }); }, 10000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
console.log('[1] Creating new tab and setting fake auth token...');
|
|
||||||
const newTab = await httpRequest('PUT', '/json/new?about:blank');
|
|
||||||
const ws = new WebSocket(newTab.webSocketDebuggerUrl);
|
|
||||||
await new Promise((resolve) => ws.on('open', resolve));
|
|
||||||
|
|
||||||
await cdpCommand(ws, 'Runtime.enable');
|
|
||||||
await cdpCommand(ws, 'Page.enable');
|
|
||||||
await cdpCommand(ws, 'Log.enable');
|
|
||||||
await cdpCommand(ws, 'Network.enable');
|
|
||||||
|
|
||||||
// Navigate to app domain first so we can set localStorage
|
|
||||||
await cdpCommand(ws, 'Page.navigate', { url: 'http://localhost:5199/' });
|
|
||||||
await new Promise(r => setTimeout(r, 2000));
|
|
||||||
|
|
||||||
// Set fake auth token and user_id in localStorage
|
|
||||||
console.log('[2] Injecting fake token into localStorage...');
|
|
||||||
const setStorage = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `
|
|
||||||
localStorage.setItem('token', 'fake_test_token_abc123');
|
|
||||||
localStorage.setItem('user_id', 'admin_test_user');
|
|
||||||
'done'
|
|
||||||
`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' localStorage set:', setStorage?.result?.value);
|
|
||||||
|
|
||||||
// Now reload the page so auth store picks up the token
|
|
||||||
console.log('[3] Reloading page with auth token...');
|
|
||||||
|
|
||||||
const errors = [];
|
|
||||||
const logs = [];
|
|
||||||
ws.on('message', (raw) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(raw.toString());
|
|
||||||
if (msg.method === 'Runtime.exceptionThrown') {
|
|
||||||
const ed = msg.params.exceptionDetails;
|
|
||||||
const errText = ed.text || ed.exception?.description || '';
|
|
||||||
errors.push(errText);
|
|
||||||
console.log(` ❌ EXCEPTION: ${errText.substring(0, 300)}`);
|
|
||||||
if (ed.exception?.className) console.log(` class: ${ed.exception.className}`);
|
|
||||||
if (ed.stackTrace?.callFrames) {
|
|
||||||
ed.stackTrace.callFrames.slice(0, 5).forEach(f => {
|
|
||||||
console.log(` at ${f.functionName || '(anon)'} (${f.url}:${f.lineNumber}:${f.columnNumber})`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (msg.method === 'Log.entryAdded') {
|
|
||||||
const entry = msg.params.entry;
|
|
||||||
const text = entry.text?.substring(0, 200) || '';
|
|
||||||
console.log(` LOG [${entry.level}]: ${text}`);
|
|
||||||
if (entry.level === 'error' || entry.level === 'warning') {
|
|
||||||
errors.push(`[LOG:${entry.level}] ${text}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (msg.method === 'Runtime.consoleAPICalled') {
|
|
||||||
const p = msg.params;
|
|
||||||
if (p.type === 'error') {
|
|
||||||
const text = p.args?.map(a => a.value || a.description || '').join(' ') || '';
|
|
||||||
errors.push(`[CONSOLE:${p.type}] ${text}`);
|
|
||||||
console.log(` CONSOLE.error: ${text.substring(0, 200)}`);
|
|
||||||
} else {
|
|
||||||
logs.push(`[${p.type}] ${p.args?.map(a => a.value || '').join(' ').substring(0, 150)}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (msg.method === 'Network.responseReceived') {
|
|
||||||
const resp = msg.params.response;
|
|
||||||
if (resp.status >= 400) {
|
|
||||||
console.log(` NET ${resp.status}: ${resp.url.substring(0, 150)}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
});
|
|
||||||
|
|
||||||
await cdpCommand(ws, 'Page.reload', { ignoreCache: true });
|
|
||||||
await new Promise(r => setTimeout(r, 8000));
|
|
||||||
|
|
||||||
console.log('\n[4] Checking DOM state...');
|
|
||||||
|
|
||||||
// Check #root
|
|
||||||
const e1 = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `
|
|
||||||
(() => {
|
|
||||||
const root = document.getElementById('root');
|
|
||||||
if (!root) return 'NO_ROOT';
|
|
||||||
const h = root.innerHTML.trim();
|
|
||||||
if (!h) return 'ROOT_EMPTY';
|
|
||||||
return 'ROOT_LEN=' + h.length + ' FIRST:' + h.substring(0, 300);
|
|
||||||
})()
|
|
||||||
`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' #root:', e1?.result?.value);
|
|
||||||
|
|
||||||
// Check body
|
|
||||||
const e2 = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `document.body ? 'BODY_OK children=' + document.body.children.length : 'NO_BODY'`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' body:', e2?.result?.value);
|
|
||||||
|
|
||||||
// Check if React rendered the chat interface
|
|
||||||
const e3 = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `
|
|
||||||
(() => {
|
|
||||||
const root = document.getElementById('root');
|
|
||||||
const h = root ? root.innerHTML : '';
|
|
||||||
const hasAppLayout = h.includes('h-screen');
|
|
||||||
const hasSidebar = h.includes('sidebar') || h.includes('新对话');
|
|
||||||
const hasHeader = h.includes('昔涟') && h.includes('退出');
|
|
||||||
const hasChatContainer = h.includes('ChatContainer') || h.includes('开始一段新对话');
|
|
||||||
const hasChatInput = h.includes('和昔涟说点什么');
|
|
||||||
return JSON.stringify({ hasAppLayout, hasSidebar, hasHeader, hasChatContainer, hasChatInput, totalLen: h.length });
|
|
||||||
})()
|
|
||||||
`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' Features:', e3?.result?.value);
|
|
||||||
|
|
||||||
// Check for any React ErrorBoundary or error state
|
|
||||||
const e4 = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `
|
|
||||||
(() => {
|
|
||||||
const body = document.body;
|
|
||||||
return body ? body.innerText.substring(0, 500) : 'NO_BODY';
|
|
||||||
})()
|
|
||||||
`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' Text:', e4?.result?.value);
|
|
||||||
|
|
||||||
ws.close();
|
|
||||||
|
|
||||||
console.log('\n=== SUMMARY ===');
|
|
||||||
console.log('Total errors:', errors.length);
|
|
||||||
errors.forEach((e, i) => console.log(` ERR${i+1}: ${e.substring(0, 500)}`));
|
|
||||||
console.log('Total logs:', logs.length);
|
|
||||||
logs.forEach(l => console.log(' LOG:', l.substring(0, 200)));
|
|
||||||
}
|
|
||||||
|
|
||||||
main().catch(e => { console.error('Fatal:', e.message); process.exit(1); });
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
import { WebSocket } from 'ws';
|
|
||||||
import http from 'http';
|
|
||||||
|
|
||||||
const CDP_HOST = 'localhost';
|
|
||||||
const CDP_PORT = 9222;
|
|
||||||
|
|
||||||
function httpRequest(method, path) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
const req = http.request({ hostname: CDP_HOST, port: CDP_PORT, method, path }, (res) => {
|
|
||||||
let data = '';
|
|
||||||
res.on('data', (c) => data += c);
|
|
||||||
res.on('end', () => {
|
|
||||||
try { resolve(JSON.parse(data)); } catch(e) { resolve(data); }
|
|
||||||
});
|
|
||||||
});
|
|
||||||
req.on('error', reject);
|
|
||||||
req.end();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function cdpCommand(ws, method, params = {}) {
|
|
||||||
const id = Math.floor(Math.random() * 1000000);
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
const handler = (raw) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(raw.toString());
|
|
||||||
if (msg.id === id) {
|
|
||||||
ws.off('message', handler);
|
|
||||||
resolve(msg.result || msg);
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
};
|
|
||||||
ws.on('message', handler);
|
|
||||||
ws.send(JSON.stringify({ id, method, params }));
|
|
||||||
setTimeout(() => { ws.off('message', handler); resolve({ error: 'timeout' }); }, 10000);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function testPage(url, label) {
|
|
||||||
console.log(`\n=== ${label} ===`);
|
|
||||||
const newTab = await httpRequest('PUT', '/json/new?about:blank');
|
|
||||||
const ws = new WebSocket(newTab.webSocketDebuggerUrl);
|
|
||||||
await new Promise((resolve) => ws.on('open', resolve));
|
|
||||||
|
|
||||||
await cdpCommand(ws, 'Runtime.enable');
|
|
||||||
await cdpCommand(ws, 'Page.enable');
|
|
||||||
await cdpCommand(ws, 'Log.enable');
|
|
||||||
|
|
||||||
const errors = [];
|
|
||||||
ws.on('message', (raw) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(raw.toString());
|
|
||||||
if (msg.method === 'Runtime.exceptionThrown') {
|
|
||||||
const ed = msg.params.exceptionDetails;
|
|
||||||
errors.push({ text: ed.text || ed.exception?.description || '', stack: ed.stackTrace?.callFrames });
|
|
||||||
console.log(` ❌ ${ed.text || ''}`);
|
|
||||||
}
|
|
||||||
if (msg.method === 'Log.entryAdded' && msg.params.entry.level === 'error') {
|
|
||||||
errors.push({ text: '[LOG] ' + msg.params.entry.text });
|
|
||||||
console.log(` LOG_ERR: ${msg.params.entry.text?.substring(0, 150)}`);
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
});
|
|
||||||
|
|
||||||
await cdpCommand(ws, 'Page.navigate', { url });
|
|
||||||
await new Promise(r => setTimeout(r, 6000));
|
|
||||||
|
|
||||||
const e1 = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `(() => { const r = document.getElementById('root'); return r ? (r.innerHTML.trim() ? 'CONTENT(' + r.innerHTML.length + ')' : 'EMPTY') : 'NO_ROOT'; })()`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' #root:', e1?.result?.value);
|
|
||||||
console.log(' Errors:', errors.length);
|
|
||||||
|
|
||||||
ws.close();
|
|
||||||
return { rootStatus: e1?.result?.value, errors };
|
|
||||||
}
|
|
||||||
|
|
||||||
async function main() {
|
|
||||||
// Test dev server (port 5173) - no SW
|
|
||||||
console.log('Testing VITE DEV SERVER (port 5173)...');
|
|
||||||
const r1 = await testPage('http://localhost:5173/', 'DEV - No Token (Login page)');
|
|
||||||
|
|
||||||
// Test dev server with fake token
|
|
||||||
console.log('\nTesting VITE DEV with fake token...');
|
|
||||||
const newTab = await httpRequest('PUT', '/json/new?about:blank');
|
|
||||||
const ws = new WebSocket(newTab.webSocketDebuggerUrl);
|
|
||||||
await new Promise((resolve) => ws.on('open', resolve));
|
|
||||||
await cdpCommand(ws, 'Runtime.enable');
|
|
||||||
await cdpCommand(ws, 'Page.enable');
|
|
||||||
await cdpCommand(ws, 'Log.enable');
|
|
||||||
|
|
||||||
const errors = [];
|
|
||||||
ws.on('message', (raw) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(raw.toString());
|
|
||||||
if (msg.method === 'Runtime.exceptionThrown') {
|
|
||||||
const ed = msg.params.exceptionDetails;
|
|
||||||
errors.push(ed.text || ed.exception?.description || '');
|
|
||||||
console.log(` ❌ ${ed.text || ''}`);
|
|
||||||
if (ed.stackTrace?.callFrames) {
|
|
||||||
ed.stackTrace.callFrames.slice(0, 5).forEach(f => {
|
|
||||||
console.log(` at ${f.functionName || '(anon)'} (${f.url}:${f.lineNumber}:${f.columnNumber})`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (msg.method === 'Log.entryAdded' && (msg.params.entry.level === 'error' || msg.params.entry.level === 'warning')) {
|
|
||||||
console.log(` LOG [${msg.params.entry.level}]: ${msg.params.entry.text?.substring(0, 150)}`);
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Navigate first, then set token, then reload
|
|
||||||
await cdpCommand(ws, 'Page.navigate', { url: 'http://localhost:5173/' });
|
|
||||||
await new Promise(r => setTimeout(r, 2000));
|
|
||||||
|
|
||||||
await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `localStorage.setItem('token', 'fake_token_xyz'); localStorage.setItem('user_id', 'admin_test_user'); 'ok'`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('Reloading with token...');
|
|
||||||
await cdpCommand(ws, 'Page.reload', { ignoreCache: true });
|
|
||||||
await new Promise(r => setTimeout(r, 8000));
|
|
||||||
|
|
||||||
const e2 = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `(() => { const r = document.getElementById('root'); return r ? (r.innerHTML.trim() ? 'CONTENT(' + r.innerHTML.length + ')' : 'EMPTY') : 'NO_ROOT'; })()`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' DEV+AUTH #root:', e2?.result?.value);
|
|
||||||
|
|
||||||
// Check visible text
|
|
||||||
const e3 = await cdpCommand(ws, 'Runtime.evaluate', {
|
|
||||||
expression: `document.body ? document.body.innerText.substring(0, 300) : 'NO_BODY'`,
|
|
||||||
returnByValue: true,
|
|
||||||
});
|
|
||||||
console.log(' Text:', e3?.result?.value);
|
|
||||||
|
|
||||||
console.log(' Errors:', errors.length);
|
|
||||||
errors.forEach((e, i) => console.log(` ERR${i+1}: ${typeof e === 'string' ? e.substring(0, 200) : JSON.stringify(e).substring(0, 200)}`));
|
|
||||||
|
|
||||||
ws.close();
|
|
||||||
|
|
||||||
console.log('\n=== ALL TESTS DONE ===');
|
|
||||||
}
|
|
||||||
|
|
||||||
main().catch(e => { console.error('Fatal:', e.message); process.exit(1); });
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
// Final comprehensive E2E test - all 5 original issues
|
|
||||||
const TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4ODIwNTIwNDYsImlhdCI6MTc3OTQ2MDA0NiwidHlwZSI6ImFjY2VzcyIsInVzZXJfaWQiOiJhZG1pbiJ9.dmNrCJsz576eEvNWlXVNP7BdZDEpijJ73pSrcqmTJdE';
|
|
||||||
const WS_URL = `ws://127.0.0.1:8080/ws/chat?token=${TOKEN}&session_id=final_${Date.now()}`;
|
|
||||||
|
|
||||||
const tests = [
|
|
||||||
{ name: '1. Greeting fast path', msg: '你好呀', expect: {action: true, chat: true, fast: true} },
|
|
||||||
{ name: '2. IoT ON (single)', msg: '帮我把客厅灯打开', expect: {action: true, chat: true, iot: true} },
|
|
||||||
{ name: '3. IoT ON (multi)', msg: '打开卧室灯和卧室空调', expect: {action: true, chat: true, iot: true} },
|
|
||||||
{ name: '4. IoT OFF (single)', msg: '关掉客厅灯', expect: {action: true, chat: true, iot: true} },
|
|
||||||
{ name: '5. Memory trigger', msg: '你还记得我喜欢什么吗?', expect: {action: true, chat: true} },
|
|
||||||
{ name: '6. IoT OFF (multi)', msg: '帮我把卧室灯和卧室空调都关掉', expect: {action: true, chat: true, iot: true} },
|
|
||||||
];
|
|
||||||
|
|
||||||
const ws = new WebSocket(WS_URL);
|
|
||||||
let testIdx = 0;
|
|
||||||
let results = [];
|
|
||||||
let current = { actions: 0, chats: 0, fast: false };
|
|
||||||
|
|
||||||
function runTest() {
|
|
||||||
if (testIdx >= tests.length) {
|
|
||||||
console.log('\n' + '='.repeat(50));
|
|
||||||
console.log('FINAL RESULTS:');
|
|
||||||
results.forEach(r => console.log(` ${r.status} ${r.name}: ${r.details}`));
|
|
||||||
console.log('='.repeat(50));
|
|
||||||
ws.close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const t = tests[testIdx];
|
|
||||||
current = { actions: 0, chats: 0, fast: false };
|
|
||||||
console.log(`\n--- ${t.name} ---`);
|
|
||||||
ws.send(JSON.stringify({type:'message', content: t.msg, session_id: null, mode:'text', timestamp: Date.now()}));
|
|
||||||
console.log(`Sent: "${t.msg}"`);
|
|
||||||
}
|
|
||||||
|
|
||||||
ws.onopen = () => { console.log('Connected\n'); runTest(); };
|
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(event.data);
|
|
||||||
if (msg.type === 'response') {
|
|
||||||
if (msg.msg_type === 'action' || msg.role === 'action') {
|
|
||||||
current.actions++;
|
|
||||||
console.log(` [ACTION] "${msg.content.substring(0, 80)}"`);
|
|
||||||
} else {
|
|
||||||
current.chats++;
|
|
||||||
console.log(` [CHAT] "${msg.content.substring(0, 80)}"`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (msg.type === 'stream_end') {
|
|
||||||
const t = tests[testIdx];
|
|
||||||
const details = [];
|
|
||||||
if (current.actions > 0) {
|
|
||||||
// Check if it has parenthetical content
|
|
||||||
const actionOk = true; // action messages received
|
|
||||||
details.push(`${current.actions}A ${current.chats}C`);
|
|
||||||
} else {
|
|
||||||
details.push(`NO actions (${current.chats}C)`);
|
|
||||||
}
|
|
||||||
const status = current.actions > 0 ? '✅' : '⚠️';
|
|
||||||
results.push({ name: t.name, status, details: details.join(', ') });
|
|
||||||
testIdx++;
|
|
||||||
setTimeout(runTest, 2000);
|
|
||||||
}
|
|
||||||
if (msg.type === 'error') {
|
|
||||||
results.push({ name: tests[testIdx].name, status: '❌', details: msg.error });
|
|
||||||
testIdx++;
|
|
||||||
setTimeout(runTest, 1500);
|
|
||||||
}
|
|
||||||
} catch (e) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onclose = () => { process.exit(0); };
|
|
||||||
ws.onerror = (err) => { console.error('WS error:', err.message); process.exit(1); };
|
|
||||||
setTimeout(() => { console.log('TIMEOUT'); ws.close(); process.exit(1); }, 180000);
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
const TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIwNTI0MjksImlhdCI6MTc3OTQ2MDQyOSwidHlwZSI6ImFjY2VzcyIsInVzZXJfaWQiOiJhZG1pbiJ9.JK1dP61eqnHCxfkQrCYQf-mQKPLjDM0o3k2UHkcovZ0";
|
|
||||||
const WS_URL = `ws://127.0.0.1:8080/ws/chat?token=${TOKEN}&session_id=test_iot_${Date.now()}`;
|
|
||||||
|
|
||||||
const ws = new WebSocket(WS_URL);
|
|
||||||
let hasAction = false;
|
|
||||||
|
|
||||||
ws.onopen = () => {
|
|
||||||
console.log('Connected');
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
type: 'message',
|
|
||||||
content: '帮我把卧室灯打开',
|
|
||||||
session_id: null,
|
|
||||||
mode: 'text',
|
|
||||||
timestamp: Date.now()
|
|
||||||
}));
|
|
||||||
console.log('Sent: 帮我把卧室灯打开');
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(event.data);
|
|
||||||
if (msg.type === 'response' && msg.msg_type === 'action') {
|
|
||||||
console.log('✅ ACTION MESSAGE:', msg.content);
|
|
||||||
hasAction = true;
|
|
||||||
} else if (msg.type === 'response') {
|
|
||||||
console.log('💬 CHAT MESSAGE:', msg.content, 'msg_type:', msg.msg_type);
|
|
||||||
} else if (msg.type === 'stream_chunk') {
|
|
||||||
process.stdout.write(msg.content || '');
|
|
||||||
} else if (msg.type === 'stream_end') {
|
|
||||||
console.log('\n--- stream_end ---');
|
|
||||||
setTimeout(() => ws.close(), 500);
|
|
||||||
} else if (msg.type === 'error') {
|
|
||||||
console.log('Error:', msg.error);
|
|
||||||
}
|
|
||||||
} catch {}
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onclose = () => {
|
|
||||||
console.log('hasAction:', hasAction);
|
|
||||||
process.exit(hasAction ? 0 : 0);
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onerror = (err) => { console.error('WS error:', err.message); process.exit(1); };
|
|
||||||
setTimeout(() => { console.log('Timeout'); ws.close(); process.exit(1); }, 35000);
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
// E2E test: Multi-device IoT command
|
|
||||||
const TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIwNTIwNDYsImlhdCI6MTc3OTQ2MDA0NiwidHlwZSI6ImFjY2VzcyIsInVzZXJfaWQiOiJhZG1pbiJ9.dmNrCJsz576eEvNWlXVNP7BdZDEpijJ73pSrcqmTJdE';
|
|
||||||
const WS_URL = `ws://127.0.0.1:8080/ws/chat?token=${TOKEN}&session_id=test_multi_${Date.now()}`;
|
|
||||||
|
|
||||||
const ws = new WebSocket(WS_URL);
|
|
||||||
let stage = 0; // 0=multi_iot, 1=query
|
|
||||||
|
|
||||||
ws.onopen = () => {
|
|
||||||
console.log('Connected\n');
|
|
||||||
console.log('=== Test 1: Multi-device IoT "打开客厅灯和卧室灯" ===');
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
type: 'message', content: '打开客厅灯和卧室灯', session_id: null, mode: 'text', timestamp: Date.now()
|
|
||||||
}));
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(event.data);
|
|
||||||
|
|
||||||
if (msg.type === 'response') {
|
|
||||||
const tag = msg.msg_type === 'action' ? 'ACTION' : 'CHAT';
|
|
||||||
console.log(`[${tag}] role=${msg.role} "${msg.content.substring(0, 150)}"`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg.type === 'stream_end') {
|
|
||||||
if (stage === 0) {
|
|
||||||
stage = 1;
|
|
||||||
console.log('\n=== Test 2: Query all devices "看看家里设备状态" ===');
|
|
||||||
setTimeout(() => {
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
type: 'message', content: '看看家里设备状态怎么样', session_id: null, mode: 'text', timestamp: Date.now()
|
|
||||||
}));
|
|
||||||
}, 2000);
|
|
||||||
} else if (stage === 1) {
|
|
||||||
stage = 2;
|
|
||||||
console.log('\n=== Test 3: Multi-device off "帮我把卧室灯和卧室空调都关掉" ===');
|
|
||||||
setTimeout(() => {
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
type: 'message', content: '帮我把卧室灯和卧室空调都关掉', session_id: null, mode: 'text', timestamp: Date.now()
|
|
||||||
}));
|
|
||||||
}, 1500);
|
|
||||||
} else {
|
|
||||||
console.log('\nAll tests done, closing...');
|
|
||||||
setTimeout(() => ws.close(), 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (msg.type === 'error') {
|
|
||||||
console.log('ERROR:', msg.error);
|
|
||||||
ws.close();
|
|
||||||
}
|
|
||||||
} catch (e) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onclose = () => { console.log('Connection closed'); process.exit(0); };
|
|
||||||
ws.onerror = (err) => { console.error('WS error:', err.message); process.exit(1); };
|
|
||||||
setTimeout(() => { console.log('Timeout'); ws.close(); process.exit(1); }, 90000);
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
// Quick WebSocket test for review pipeline
|
|
||||||
const WebSocket = require('ws');
|
|
||||||
|
|
||||||
const TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIwNTIwNDYsImlhdCI6MTc3OTQ2MDA0NiwidHlwZSI6ImFjY2VzcyIsInVzZXJfaWQiOiJhZG1pbiJ9.dmNrCJsz576eEvNWlXVNP7BdZDEpijJ73pSrcqmTJdE';
|
|
||||||
const WS_URL = `ws://127.0.0.1:8080/ws/chat?token=${TOKEN}&session_id=test_review_${Date.now()}`;
|
|
||||||
|
|
||||||
const ws = new WebSocket(WS_URL);
|
|
||||||
|
|
||||||
ws.on('open', () => {
|
|
||||||
console.log('Connected to WebSocket');
|
|
||||||
|
|
||||||
// Send a message that should trigger IoT action response with parenthetical format
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
type: 'message',
|
|
||||||
content: '帮我把客厅灯打开',
|
|
||||||
session_id: null,
|
|
||||||
mode: 'text',
|
|
||||||
timestamp: Date.now()
|
|
||||||
}));
|
|
||||||
console.log('Sent: 帮我把客厅灯打开');
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.on('message', (data) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(data.toString());
|
|
||||||
console.log(`\n[${msg.type}]`, JSON.stringify(msg, null, 2).substring(0, 500));
|
|
||||||
|
|
||||||
if (msg.type === 'response' || msg.type === 'review') {
|
|
||||||
console.log('✅ Got response/review message!');
|
|
||||||
}
|
|
||||||
if (msg.type === 'stream_end') {
|
|
||||||
console.log('Stream ended, closing...');
|
|
||||||
setTimeout(() => ws.close(), 1000);
|
|
||||||
}
|
|
||||||
if (msg.type === 'error') {
|
|
||||||
console.log('❌ Error:', msg.error);
|
|
||||||
ws.close();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Raw:', data.toString().substring(0, 200));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.on('close', () => {
|
|
||||||
console.log('Connection closed');
|
|
||||||
process.exit(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
ws.on('error', (err) => {
|
|
||||||
console.error('WebSocket error:', err.message);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
console.log('Timeout - closing');
|
|
||||||
ws.close();
|
|
||||||
process.exit(1);
|
|
||||||
}, 30000);
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
// Quick WebSocket test for review pipeline
|
|
||||||
const TOKEN = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3ODIwNTIwNDYsImlhdCI6MTc3OTQ2MDA0NiwidHlwZSI6ImFjY2VzcyIsInVzZXJfaWQiOiJhZG1pbiJ9.dmNrCJsz576eEvNWlXVNP7BdZDEpijJ73pSrcqmTJdE';
|
|
||||||
const WS_URL = `ws://127.0.0.1:8080/ws/chat?token=${TOKEN}&session_id=test_review_${Date.now()}`;
|
|
||||||
|
|
||||||
const ws = new WebSocket(WS_URL);
|
|
||||||
|
|
||||||
ws.onopen = () => {
|
|
||||||
console.log('Connected to WebSocket');
|
|
||||||
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
type: 'message',
|
|
||||||
content: '帮我把客厅灯打开',
|
|
||||||
session_id: null,
|
|
||||||
mode: 'text',
|
|
||||||
timestamp: Date.now()
|
|
||||||
}));
|
|
||||||
console.log('Sent: 帮我把客厅灯打开');
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onmessage = (event) => {
|
|
||||||
try {
|
|
||||||
const msg = JSON.parse(event.data);
|
|
||||||
const short = JSON.stringify(msg).substring(0, 400);
|
|
||||||
console.log(`[${msg.type}]`, short);
|
|
||||||
|
|
||||||
if (msg.type === 'response' && msg.msg_type === 'action') {
|
|
||||||
console.log('✅ Got ACTION message!');
|
|
||||||
}
|
|
||||||
if (msg.type === 'response' && msg.msg_type === 'chat') {
|
|
||||||
console.log('✅ Got CHAT message!');
|
|
||||||
}
|
|
||||||
if (msg.type === 'stream_end') {
|
|
||||||
console.log('Stream ended, closing...');
|
|
||||||
setTimeout(() => ws.close(), 500);
|
|
||||||
}
|
|
||||||
if (msg.type === 'error') {
|
|
||||||
console.log('Error:', msg.error);
|
|
||||||
ws.close();
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.log('Raw:', event.data.substring(0, 300));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onclose = () => {
|
|
||||||
console.log('Connection closed');
|
|
||||||
process.exit(0);
|
|
||||||
};
|
|
||||||
|
|
||||||
ws.onerror = (err) => {
|
|
||||||
console.error('WebSocket error:', err.message);
|
|
||||||
process.exit(1);
|
|
||||||
};
|
|
||||||
|
|
||||||
setTimeout(() => {
|
|
||||||
console.log('Timeout (30s) - closing');
|
|
||||||
ws.close();
|
|
||||||
process.exit(1);
|
|
||||||
}, 30000);
|
|
||||||
Reference in New Issue
Block a user