@vincentbanana/bananacli 0.4.5 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/server/ui-server.js +18 -2
- package/dist/session/store.js +3 -2
- package/dist/ui/app.js +15 -2
- package/package.json +1 -1
package/dist/server/ui-server.js
CHANGED
|
@@ -81,6 +81,9 @@ export async function startUiServer(options) {
|
|
|
81
81
|
'多半是内核版本太旧或安装不完整,重新安装即可:npm install -g @vincentbanana/bananacli\n');
|
|
82
82
|
}
|
|
83
83
|
let turn = null;
|
|
84
|
+
// 当前会话记在服务进程内存里:新建对话后所有后续请求都认它,
|
|
85
|
+
// 不再依赖「磁盘上谁最新」这种容易串台的推断。
|
|
86
|
+
let activeId = null;
|
|
84
87
|
// 内嵌终端:不弹外部窗口,命令在当前工作区里执行,cd 之后的工作目录会被记住
|
|
85
88
|
let terminalCwd = null;
|
|
86
89
|
let terminalChild = null;
|
|
@@ -137,7 +140,11 @@ export async function startUiServer(options) {
|
|
|
137
140
|
return sendFile(res, 'style.css');
|
|
138
141
|
if (path === '/app.js')
|
|
139
142
|
return sendFile(res, 'app.js');
|
|
140
|
-
let session = turn?.session ??
|
|
143
|
+
let session = turn?.session ??
|
|
144
|
+
(activeId ? await store.load(activeId) : null) ??
|
|
145
|
+
(await store.lastActive().then(async (id) => (id ? await store.load(id) : null))) ??
|
|
146
|
+
store.create();
|
|
147
|
+
activeId = session.id;
|
|
141
148
|
if (path === '/api/info' && req.method === 'GET')
|
|
142
149
|
return json(res, 200, await info(session));
|
|
143
150
|
if (path === '/api/sessions' && req.method === 'GET')
|
|
@@ -207,6 +214,7 @@ export async function startUiServer(options) {
|
|
|
207
214
|
}
|
|
208
215
|
if (turn)
|
|
209
216
|
turn.session = session;
|
|
217
|
+
activeId = session.id;
|
|
210
218
|
return json(res, 200, { session: session.id, sessions: await listSessions(), info: await info(session) });
|
|
211
219
|
}
|
|
212
220
|
if (path === '/api/complete' && req.method === 'GET') {
|
|
@@ -320,7 +328,15 @@ export async function startUiServer(options) {
|
|
|
320
328
|
const body = await readJson(req);
|
|
321
329
|
if (turn)
|
|
322
330
|
return json(res, 409, { error: '当前正在跑一轮对话' });
|
|
323
|
-
|
|
331
|
+
// 前端会带上会话 id:以它为准,避免新建对话后又被解析回旧对话
|
|
332
|
+
let target = session;
|
|
333
|
+
if (body.session && body.session !== session.id) {
|
|
334
|
+
const found = await store.load(body.session);
|
|
335
|
+
if (found)
|
|
336
|
+
target = found;
|
|
337
|
+
}
|
|
338
|
+
activeId = target.id;
|
|
339
|
+
return chat(body, res, target);
|
|
324
340
|
}
|
|
325
341
|
if (path === '/api/terminal' && req.method === 'POST') {
|
|
326
342
|
const body = await readJson(req);
|
package/dist/session/store.js
CHANGED
|
@@ -106,7 +106,8 @@ export class SessionStore {
|
|
|
106
106
|
/** 返回最近一次更新且有内容的会话 id。 */
|
|
107
107
|
async lastActive() {
|
|
108
108
|
const sessions = await this.list();
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
// 必须用「最近更新的会话」,包括刚建好的空会话。
|
|
110
|
+
// 以前写的是「优先找有消息的会话」,结果新建对话后第一次发消息会被悄悄塞进上一个旧对话。
|
|
111
|
+
return sessions[0]?.id ?? null;
|
|
111
112
|
}
|
|
112
113
|
}
|
package/dist/ui/app.js
CHANGED
|
@@ -561,7 +561,7 @@ async function send() {
|
|
|
561
561
|
const res = await fetch(API + 'chat', {
|
|
562
562
|
method: 'POST',
|
|
563
563
|
headers: { 'content-type': 'application/json' },
|
|
564
|
-
body: JSON.stringify({ message: text, images }),
|
|
564
|
+
body: JSON.stringify({ message: text, images, session: state.info?.session?.id }),
|
|
565
565
|
signal: controller.signal,
|
|
566
566
|
});
|
|
567
567
|
if (!res.ok) throw new Error((await res.json().catch(() => ({}))).error ?? res.statusText);
|
|
@@ -1399,7 +1399,20 @@ function bind() {
|
|
|
1399
1399
|
hydrate();
|
|
1400
1400
|
loadTheme();
|
|
1401
1401
|
|
|
1402
|
-
$('newChat').addEventListener('click', () =>
|
|
1402
|
+
$('newChat').addEventListener('click', async () => {
|
|
1403
|
+
try {
|
|
1404
|
+
// 直接用返回的会话,不再 refresh:多一次 lastActive 解析就多一次串回旧对话的机会
|
|
1405
|
+
const result = await post('session', { action: 'new' });
|
|
1406
|
+
if (result?.info) state.info = result.info;
|
|
1407
|
+
if (result?.sessions) state.sessions = result.sessions;
|
|
1408
|
+
renderHeader();
|
|
1409
|
+
renderSidebar();
|
|
1410
|
+
renderThread();
|
|
1411
|
+
$('input').focus();
|
|
1412
|
+
} catch (error) {
|
|
1413
|
+
toast('新建对话失败:' + (error?.message ?? error));
|
|
1414
|
+
}
|
|
1415
|
+
});
|
|
1403
1416
|
$('abortBtn').addEventListener('click', async () => { controller?.abort(); await post('abort'); });
|
|
1404
1417
|
$('modelBtn').addEventListener('click', openSettings);
|
|
1405
1418
|
$('openSettings').addEventListener('click', openSettings);
|
package/package.json
CHANGED