Changeset 0.22.7 (#149)

This commit is contained in:
2026-03-04 10:44:42 +00:00
parent d8e0664fa3
commit 389e47b0f9
62 changed files with 6820 additions and 1476 deletions

View File

@@ -77,7 +77,7 @@ const ChatInput = {
// Hide the textarea, create CM6 editor in its place
this._textarea.style.display = 'none';
this._editor = CM.chatInput(wrap, {
placeholder: 'Send a message...',
placeholder: 'Type a message\u2026',
onSubmit: () => sendMessage(),
onChange: () => {
updateInputTokens();
@@ -240,7 +240,7 @@ async function selectChat(chatId) {
}
}
// Restore the last-used model/preset for this chat
// Restore the last-used model/persona for this chat
_restoreChatModel(chatId, chat);
// Load multi-model roster for @mention routing (v0.20.0)
@@ -286,7 +286,7 @@ function updateChatTokenCount() {
}
}
// ── Per-Chat Model/Preset Persistence ────────
// ── Per-Chat Model/Persona Persistence ────────
// Server-side: saved in channel.settings.last_selector_id (JSONB merge).
// localStorage used as write-through cache for instant restore without
// waiting for the channel list API call.
@@ -345,7 +345,7 @@ function _restoreChatModel(chatId, chat) {
// 4. Fall back to channel's base model ID (match by baseModelId)
if (chat?.model) {
const match = App.models.find(m => m.baseModelId === chat.model && !m.isPreset && !m.hidden);
const match = App.models.find(m => m.baseModelId === chat.model && !m.isPersona && !m.hidden);
if (match) {
UI.setModelValue(match.id, match.name + (match.provider ? ` (${match.provider})` : ''));
return;
@@ -513,9 +513,9 @@ async function sendMessage() {
const selectedId = UI.getModelValue();
const modelInfo = App.findModel(selectedId);
// For presets, send the base model ID; for regular models, send the model ID
// For personas, send the base model ID; for regular models, send the model ID
const model = modelInfo?.baseModelId || selectedId;
const presetId = modelInfo?.isPreset ? modelInfo.presetId : null;
const personaId = modelInfo?.isPersona ? modelInfo.personaId : null;
if (!App.currentChatId) {
try {
@@ -554,7 +554,7 @@ async function sendMessage() {
UI.setGenerating(true);
try {
const resp = await API.streamCompletion(App.currentChatId, text, model, App.abortController.signal, modelInfo?.configId, presetId, attachmentIds,
const resp = await API.streamCompletion(App.currentChatId, text, model, App.abortController.signal, modelInfo?.configId, personaId, attachmentIds,
typeof ToolsToggle !== 'undefined' ? ToolsToggle.getDisabledTools() : []);
await UI.streamResponse(resp, chat.messages, modelInfo?.name);
@@ -562,7 +562,7 @@ async function sendMessage() {
await reloadActivePath();
UI.showRegenerate(true);
// Persist the model/preset selection for this chat
// Persist the model/persona selection for this chat
_saveChatModel(App.currentChatId);
// Auto-name: title the chat after first assistant response (v0.17.0)
@@ -636,7 +636,7 @@ async function regenerateMessage(messageId) {
const selectedId = UI.getModelValue();
const modelInfo = App.findModel(selectedId);
const model = modelInfo?.baseModelId || selectedId;
const presetId = modelInfo?.isPreset ? modelInfo.presetId : null;
const personaId = modelInfo?.isPersona ? modelInfo.personaId : null;
// Truncate display to the parent of the message being regenerated.
// This makes the stream appear in the correct position — as a fresh
@@ -657,7 +657,7 @@ async function regenerateMessage(messageId) {
try {
const resp = await API.streamRegenerate(
App.currentChatId, messageId, App.abortController.signal,
model, presetId, modelInfo?.configId,
model, personaId, modelInfo?.configId,
typeof ToolsToggle !== 'undefined' ? ToolsToggle.getDisabledTools() : []
);
await UI.streamResponse(resp, chat?.messages || [], modelInfo?.name);
@@ -721,7 +721,7 @@ async function submitEdit(messageId, newContent) {
const selectedId = UI.getModelValue();
const modelInfo = App.findModel(selectedId);
const model = modelInfo?.baseModelId || selectedId;
const presetId = modelInfo?.isPreset ? modelInfo.presetId : null;
const personaId = modelInfo?.isPersona ? modelInfo.personaId : null;
App.isGenerating = true;
App.abortController = new AbortController();
@@ -742,7 +742,7 @@ async function submitEdit(messageId, newContent) {
// message that streamCompletion would create.
const resp = await API.streamRegenerate(
App.currentChatId, editResp.id, App.abortController.signal,
model, presetId, modelInfo?.configId,
model, personaId, modelInfo?.configId,
typeof ToolsToggle !== 'undefined' ? ToolsToggle.getDisabledTools() : []
);
await UI.streamResponse(resp, chat?.messages || [], modelInfo?.name);
@@ -875,7 +875,7 @@ function _initChatListeners() {
localStorage.setItem('sb_sidebar', '1');
});
document.getElementById('fetchModelsBtn')?.addEventListener('click', async () => {
await fetchModels();
await fetchModelsAndUpdateUI();
const visible = App.models.filter(m => !m.hidden).length;
UI.toast(`Loaded ${visible} model${visible !== 1 ? 's' : ''}`, 'success');
});