mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-04 14:57:42 +00:00
feat: default Enter to queueing during a run
This commit is contained in:
parent
5eb7115dd7
commit
6c0c3955e2
3 changed files with 39 additions and 18 deletions
|
|
@ -99,10 +99,10 @@ describe('useSteering', () => {
|
|||
});
|
||||
|
||||
describe('effectiveAction', () => {
|
||||
it('defaults to steer during an active agents run', () => {
|
||||
it('defaults to queue during an active agents run', () => {
|
||||
const { result } = setup();
|
||||
expect(result.current.duringRunActive).toBe(true);
|
||||
expect(result.current.effectiveAction).toBe('steer');
|
||||
expect(result.current.effectiveAction).toBe('queue');
|
||||
});
|
||||
|
||||
it('honors the queue preference while keeping the steer override available', () => {
|
||||
|
|
@ -591,7 +591,9 @@ describe('useSteering', () => {
|
|||
|
||||
describe('submitDuringRun', () => {
|
||||
it('routes to the steer POST with an optimistic sending chip', () => {
|
||||
const { result } = setup();
|
||||
const { result } = setup({}, ({ set }) => {
|
||||
set(store.duringRunDefaultAction, 'steer');
|
||||
});
|
||||
let consumed = false;
|
||||
act(() => {
|
||||
consumed = result.current.submitDuringRun('steer this');
|
||||
|
|
@ -817,7 +819,9 @@ describe('useSteering', () => {
|
|||
});
|
||||
|
||||
it('an ordinary steer does not preempt by default', () => {
|
||||
const { result } = setup();
|
||||
const { result } = setup({}, ({ set }) => {
|
||||
set(store.duringRunDefaultAction, 'steer');
|
||||
});
|
||||
act(() => {
|
||||
result.current.submitDuringRun('just steer');
|
||||
});
|
||||
|
|
@ -829,6 +833,7 @@ describe('useSteering', () => {
|
|||
|
||||
it('steerInterruptsByDefault makes the default Enter route preempt', () => {
|
||||
const { result } = setup({}, ({ set }) => {
|
||||
set(store.duringRunDefaultAction, 'steer');
|
||||
set(store.steerInterruptsByDefault, true);
|
||||
});
|
||||
act(() => {
|
||||
|
|
@ -1821,7 +1826,14 @@ describe('useSteering', () => {
|
|||
};
|
||||
const queuedFiles = [{ file_id: 'file-1', filepath: '/uploads/file-1.png', type: 'image/png' }];
|
||||
|
||||
function setupWithFiles(params: HookParams = {}, generationCreatedAt: number | null = 41) {
|
||||
/** Steering is gated on the active-generation epoch, so seed it by default
|
||||
* or every steer here is refused as pre-epoch. `null` seeds nothing, which
|
||||
* is the pre-epoch case itself; an initializer seeds the epoch and then
|
||||
* whatever else that test needs. */
|
||||
function setupWithFiles(
|
||||
params: HookParams = {},
|
||||
initialize?: ((snapshot: MutableSnapshot) => void) | null,
|
||||
) {
|
||||
const setFiles = jest.fn();
|
||||
const files = new Map([['file-1', composerFile]]) as unknown as NonNullable<
|
||||
Parameters<typeof useSteering>[0]['files']
|
||||
|
|
@ -1830,11 +1842,14 @@ describe('useSteering', () => {
|
|||
const stopGenerating = jest.fn();
|
||||
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
<RecoilRoot
|
||||
initializeState={({ set }) => {
|
||||
if (generationCreatedAt != null) {
|
||||
set(store.activeGenerationCreatedAtByConvoId(CONVO_ID), generationCreatedAt);
|
||||
}
|
||||
}}
|
||||
initializeState={
|
||||
initialize === null
|
||||
? undefined
|
||||
: (snapshot) => {
|
||||
snapshot.set(store.activeGenerationCreatedAtByConvoId(CONVO_ID), 41);
|
||||
initialize?.(snapshot);
|
||||
}
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</RecoilRoot>
|
||||
|
|
@ -1862,7 +1877,9 @@ describe('useSteering', () => {
|
|||
}
|
||||
|
||||
it('steers with the composer attachments as one unit', () => {
|
||||
const { result, setFiles } = setupWithFiles();
|
||||
const { result, setFiles } = setupWithFiles({}, ({ set }) => {
|
||||
set(store.duringRunDefaultAction, 'steer');
|
||||
});
|
||||
let consumed = false;
|
||||
act(() => {
|
||||
consumed = result.current.steering.submitDuringRun('look at this image');
|
||||
|
|
@ -1984,7 +2001,9 @@ describe('useSteering', () => {
|
|||
});
|
||||
|
||||
it('does not mark usage on the steer path (the 202 already marked)', () => {
|
||||
const { result } = setupWithFiles();
|
||||
const { result } = setupWithFiles({}, ({ set }) => {
|
||||
set(store.duringRunDefaultAction, 'steer');
|
||||
});
|
||||
act(() => {
|
||||
result.current.steering.submitDuringRun('steer with media');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -492,9 +492,9 @@
|
|||
"com_nav_delete_cache_storage": "Delete TTS cache storage",
|
||||
"com_nav_delete_data_info": "All your data will be deleted.",
|
||||
"com_nav_delete_warning": "WARNING: This will permanently delete your account.",
|
||||
"com_nav_during_run_action": "While generating, Enter will",
|
||||
"com_nav_during_run_action_queue": "Queue for after",
|
||||
"com_nav_during_run_action_steer": "Steer the response",
|
||||
"com_nav_during_run_action": "While a reply is generating, Enter will",
|
||||
"com_nav_during_run_action_queue": "Queue it",
|
||||
"com_nav_during_run_action_steer": "Send it into the reply",
|
||||
"com_nav_enable_cache_tts": "Enable cache TTS",
|
||||
"com_nav_enable_cloud_browser_voice": "Use cloud-based voices",
|
||||
"com_nav_engine": "Engine",
|
||||
|
|
@ -520,7 +520,7 @@
|
|||
"com_nav_info_balance": "Balance shows how many token credits you have left to use. Token credits translate to monetary value (e.g., 1000 credits = $0.001 USD)",
|
||||
"com_nav_info_code_background": "Code executions can run in the background by default: the conversation continues immediately while the code runs, and the model retrieves the result later with the background task tool. Output and generated files still attach to the original code run. Turn this off to require every code execution to finish before the conversation continues. Requires the app-level background tools capability.",
|
||||
"com_nav_info_default_temporary_chat": "When enabled, new chats will start with temporary chat mode activated by default. Temporary chats are not saved to your history.",
|
||||
"com_nav_info_during_run_action": "Choose what pressing Enter does while the assistant is still responding. \"Steer the response\" inserts your message into the current response at its next step; \"Queue for after\" sends it as a new turn once the response finishes. You can always override this per message from the send button.",
|
||||
"com_nav_info_during_run_action": "Queued messages send automatically when the reply finishes. Sending into the reply adds your message to the response the assistant is writing right now.",
|
||||
"com_nav_info_enter_to_send": "When enabled, pressing `ENTER` will send your message. When disabled, pressing Enter will add a new line, and you'll need to press `CTRL + ENTER` / `⌘ + ENTER` to send your message.",
|
||||
"com_nav_info_fork_change_default": "`Visible messages only` includes just the direct path to the selected message. `Include related branches` adds branches along the path. `Include all to/from here` includes all connected messages and branches.",
|
||||
"com_nav_info_fork_split_target_setting": "When enabled, forking will commence from the target message to the latest message in the conversation, according to the behavior selected.",
|
||||
|
|
|
|||
|
|
@ -30,10 +30,12 @@ const localStorageAtoms = {
|
|||
|
||||
// Chat settings
|
||||
enterToSend: atomWithLocalStorage('enterToSend', true),
|
||||
/** What Enter does while a run is generating: steer (inject mid-run) or queue (send after). */
|
||||
/** What Enter does while a reply is generating. Queue by default: injecting
|
||||
* into a reply the user is still reading is the surprising choice, so it is
|
||||
* the opt-in one. */
|
||||
duringRunDefaultAction: atomWithLocalStorage<'steer' | 'queue'>(
|
||||
'duringRunDefaultAction',
|
||||
'steer',
|
||||
'queue',
|
||||
),
|
||||
/**
|
||||
* Whether a steer interrupts generation at the next safe boundary instead of
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue