feat: add message queue functionality with auto-send and queue mode toggle
- Improved development server hot module replacement (HMR) by reusing OpenCode processes. - Introduced queued message mode with batching and idle auto-send, including support for attachments. - Added a toggle for queue mode in OpenChamber settings with persistence across sessions. - Updated various components to handle queued messages, including ChatInput and QueuedMessageChips. - Modified settings payload and desktop settings to include queue mode configuration. - Enhanced message sending logic to support additional parts for queued messages.
This commit is contained in:
@@ -332,6 +332,7 @@ export interface SettingsPayload {
|
||||
showReasoningTraces?: boolean;
|
||||
autoDeleteEnabled?: boolean;
|
||||
autoDeleteAfterDays?: number;
|
||||
queueModeEnabled?: boolean;
|
||||
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ export type DesktopSettings = {
|
||||
autoDeleteAfterDays?: number;
|
||||
defaultModel?: string; // format: "provider/model"
|
||||
defaultAgent?: string;
|
||||
queueModeEnabled?: boolean;
|
||||
};
|
||||
|
||||
export type DesktopSettingsApi = {
|
||||
|
||||
@@ -393,6 +393,16 @@ class OpencodeService {
|
||||
filename?: string;
|
||||
url: string;
|
||||
}>;
|
||||
/** Additional text/file parts to include (for batch sending queued messages) */
|
||||
additionalParts?: Array<{
|
||||
text: string;
|
||||
files?: Array<{
|
||||
type: 'file';
|
||||
mime: string;
|
||||
filename?: string;
|
||||
url: string;
|
||||
}>;
|
||||
}>;
|
||||
messageId?: string;
|
||||
agentMentions?: Array<{ name: string; source?: { value: string; start: number; end: number } }>;
|
||||
}): Promise<string> {
|
||||
@@ -433,6 +443,28 @@ class OpencodeService {
|
||||
});
|
||||
}
|
||||
|
||||
// Add additional parts (for batch/queued messages)
|
||||
if (params.additionalParts && params.additionalParts.length > 0) {
|
||||
for (const additional of params.additionalParts) {
|
||||
if (additional.text && additional.text.trim()) {
|
||||
parts.push({
|
||||
type: 'text',
|
||||
text: additional.text
|
||||
});
|
||||
}
|
||||
if (additional.files && additional.files.length > 0) {
|
||||
for (const file of additional.files) {
|
||||
parts.push({
|
||||
type: 'file',
|
||||
mime: file.mime,
|
||||
filename: file.filename,
|
||||
url: file.url
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (params.agentMentions && params.agentMentions.length > 0) {
|
||||
const [first] = params.agentMentions;
|
||||
if (first?.name) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { getDesktopSettings, updateDesktopSettings as updateDesktopSettingsApi, isDesktopRuntime } from '@/lib/desktop';
|
||||
import type { DesktopSettings } from '@/lib/desktop';
|
||||
import { useUIStore } from '@/stores/useUIStore';
|
||||
import { useMessageQueueStore } from '@/stores/messageQueueStore';
|
||||
import { loadAppearancePreferences, applyAppearancePreferences } from '@/lib/appearancePersistence';
|
||||
import { getRegisteredRuntimeAPIs } from '@/contexts/runtimeAPIRegistry';
|
||||
|
||||
@@ -55,6 +56,7 @@ const getRuntimeSettingsAPI = () => getRegisteredRuntimeAPIs()?.settings ?? null
|
||||
|
||||
const applyDesktopUiPreferences = (settings: DesktopSettings) => {
|
||||
const store = useUIStore.getState();
|
||||
const queueStore = useMessageQueueStore.getState();
|
||||
|
||||
if (typeof settings.showReasoningTraces === 'boolean' && settings.showReasoningTraces !== store.showReasoningTraces) {
|
||||
store.setShowReasoningTraces(settings.showReasoningTraces);
|
||||
@@ -68,6 +70,9 @@ const applyDesktopUiPreferences = (settings: DesktopSettings) => {
|
||||
store.setAutoDeleteAfterDays(normalized);
|
||||
}
|
||||
}
|
||||
if (typeof settings.queueModeEnabled === 'boolean' && settings.queueModeEnabled !== queueStore.queueModeEnabled) {
|
||||
queueStore.setQueueMode(settings.queueModeEnabled);
|
||||
}
|
||||
};
|
||||
|
||||
const sanitizeWebSettings = (payload: unknown): DesktopSettings | null => {
|
||||
@@ -131,6 +136,9 @@ const sanitizeWebSettings = (payload: unknown): DesktopSettings | null => {
|
||||
if (typeof candidate.defaultAgent === 'string' && candidate.defaultAgent.length > 0) {
|
||||
result.defaultAgent = candidate.defaultAgent;
|
||||
}
|
||||
if (typeof candidate.queueModeEnabled === 'boolean') {
|
||||
result.queueModeEnabled = candidate.queueModeEnabled;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user