feat(chat): persist more composer input history with global or session scope; recallable with up/down arrow keys (#3035)

* feat(chat): persist input history

* feat(settings): configure input history scope

* fix(web): keep input history validation packaged

* fix(chat): preserve input history across tabs

* fix(settings): restore prompt history limit

* fix(settings): keep history deletion warning visible

* fix(i18n): restore Turkish Git empty state translations

---------

Co-authored-by: Bohdan Triapitsyn <artmore@protonmail.com>
This commit is contained in:
Matt Visnovsky
2026-09-05 19:19:03 +03:00
committed by GitHub
co-authored by Bohdan Triapitsyn
parent 29480383cc
commit 1d6b15bc04
49 changed files with 3353 additions and 458 deletions
@@ -1,3 +1,4 @@
import { createInputHistoryIdentity, createInputHistorySubmission, useInputHistoryStore } from './useInputHistoryStore';
import { create } from 'zustand';
import { devtools, persist } from 'zustand/middleware';
import { z } from 'zod';
@@ -548,6 +549,8 @@ export const useMessageQueueStore = create<MessageQueueStore>()(
set((state) => removeMessageLocally(state, key, id));
throw new Error('A queued message needs a provider and model to be delivered later.');
}
const historyIdentity = createInputHistoryIdentity(target.runtimeKey, target.directory, target.sessionId);
const historySubmission = createInputHistorySubmission(message.content, message.attachments ?? []);
try {
const result = await requestJson(serverSessionResponseSchema, `${sessionPath(target.sessionId)}/items`, jsonInit('POST', {
directory: target.directory,
@@ -556,6 +559,9 @@ export const useMessageQueueStore = create<MessageQueueStore>()(
// The optimistic entry is replaced by the server's copy of the queue.
set((state) => removeMessageLocally(state, key, id));
applyServerSession(result.session, result.revision, target.runtimeKey);
if (historyIdentity) {
useInputHistoryStore.getState().appendSubmissions(historyIdentity, [historySubmission]);
}
} catch (error) {
set((state) => removeMessageLocally(state, key, id));
throw error;