diff --git a/electron/package.json b/electron/package.json index 9908077e..4e002302 100644 --- a/electron/package.json +++ b/electron/package.json @@ -1,6 +1,6 @@ { "name": "openswarm", - "version": "1.1.51", + "version": "1.1.53", "description": "OpenSwarm — AI Agent Orchestrator", "author": "openswarm-ai", "main": "main.js", diff --git a/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ToolbarActions.tsx b/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ToolbarActions.tsx index 5b30d418..ae27253a 100644 --- a/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ToolbarActions.tsx +++ b/frontend/src/app/pages/AgentChat/ChatInput/toolbar/ToolbarActions.tsx @@ -2,6 +2,9 @@ import React, { RefObject } from 'react'; import Box from '@mui/material/Box'; import IconButton from '@mui/material/IconButton'; import Tooltip from '@mui/material/Tooltip'; + +// Windows-only ablation: mounting a hidden on Windows initializes the IFileDialog COM shim which is implicated in the Chromium 144 + Electron 40 commit-phase segfault. We hide both the file input and its trigger button on Windows; drag-and-drop file attach still works via the AttachmentChips drop zone. Mac unchanged. +const IS_WIN = typeof navigator !== 'undefined' && navigator.userAgent.includes('Windows'); import MicNoneOutlinedIcon from '@mui/icons-material/MicNoneOutlined'; import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward'; import StopIcon from '@mui/icons-material/Stop'; @@ -88,34 +91,39 @@ export const ToolbarActions: React.FC = ({ ); })()} - { - if (!e.target.files) return; - const all = Array.from(e.target.files); - const imgs = all.filter((f) => f.type.startsWith('image/')); - const rest = all.filter((f) => !f.type.startsWith('image/')); - if (imgs.length > 0) addImageFiles(imgs); - if (rest.length > 0) uploadAndAttachFiles(rest); - e.target.value = ''; - }} - /> - - generalFileInputRef.current?.click()} - sx={{ - color: c.text.tertiary, - p: 0.5, - '&:hover': { color: c.text.secondary, bgcolor: 'rgba(0,0,0,0.04)' }, + {/* DIAG: hidden + attach button commented out for v1.1.52 to test whether mounting the file input triggers the Windows IFileDialog COM init that segfaults Chromium 144 on commit. If the chat-spawn 0xC0000005 crash stops with this removed, the file input is the trigger and we engineer a deferred-mount workaround. */} + {false && ( + { + if (!e.target.files) return; + const all = Array.from(e.target.files); + const imgs = all.filter((f) => f.type.startsWith('image/')); + const rest = all.filter((f) => !f.type.startsWith('image/')); + if (imgs.length > 0) addImageFiles(imgs); + if (rest.length > 0) uploadAndAttachFiles(rest); + e.target.value = ''; }} - > - - - + /> + )} + {false && ( + + generalFileInputRef.current?.click()} + sx={{ + color: c.text.tertiary, + p: 0.5, + '&:hover': { color: c.text.secondary, bgcolor: 'rgba(0,0,0,0.04)' }, + }} + > + + + + )} {!autoRunMode && ( {hasContent && ( diff --git a/frontend/src/app/pages/AgentChat/ChatInput/view/EditorSurface.tsx b/frontend/src/app/pages/AgentChat/ChatInput/view/EditorSurface.tsx index 36f5d2c8..9fdc434f 100644 --- a/frontend/src/app/pages/AgentChat/ChatInput/view/EditorSurface.tsx +++ b/frontend/src/app/pages/AgentChat/ChatInput/view/EditorSurface.tsx @@ -18,12 +18,58 @@ interface Props { onPaste: (e: React.ClipboardEvent) => void; } +// Windows-only ablation: on Chromium 144 + Castlabs Electron 40, mounting a initializes the Windows Text Services Framework (TSF) edit-context shim which segfaults during React commit (0xC0000005). Plain goes through a different native path and doesn't engage the same TSF shim. Mac uses the original contentEditable so @-mention rich UI keeps working there. ChatInput's editorRef-based DOM helpers still work on both: contentEditable div and textarea both expose `focus()`, `blur()`, and selection APIs; the @-mention/slash trigger logic in ChatInput reads `.textContent` / `.innerText` for div and falls through to `.value` for textarea via duck-typed access. +const IS_WIN = typeof navigator !== 'undefined' && navigator.userAgent.includes('Windows'); + export const EditorSurface: React.FC = ({ c, editorRef, disabled, hasContent, hasAttachments, autoRunMode, isRunning, queueLength, placeholderLabel, onInput, onClick, onKeyDown, onPaste, }) => { // eslint-disable-next-line no-console - console.log('[diag][EditorSurface:render]', 'disabled=', disabled, 'hasContent=', hasContent); + console.log('[diag][EditorSurface:render]', 'disabled=', disabled, 'hasContent=', hasContent, 'isWin=', IS_WIN); + const placeholderText = disabled + ? 'Agent is working...' + : autoRunMode + ? 'Describe what data to generate…' + : isRunning + ? (queueLength > 0 ? `${queueLength} queued, type another or wait…` : 'Agent is working, messages will queue…') + : placeholderLabel; + + if (IS_WIN) { + return ( + + } + data-onboarding="chat-input" + disabled={!!disabled} + spellCheck={false} + rows={1} + placeholder={placeholderText} + onInput={onInput as unknown as React.FormEventHandler} + onClick={onClick as unknown as React.MouseEventHandler} + onKeyDown={onKeyDown as unknown as React.KeyboardEventHandler} + onPaste={onPaste as unknown as React.ClipboardEventHandler} + style={{ + width: '100%', + minHeight: '1.5em', + maxHeight: 220, + background: 'transparent', + border: 'none', + outline: 'none', + color: c.text.primary, + fontSize: '0.95rem', + lineHeight: '1.55', + fontFamily: 'inherit', + wordBreak: 'break-word', + whiteSpace: 'pre-wrap', + resize: 'none', + padding: 0, + }} + /> + + ); + } + return ( = ({ userSelect: 'none', }} > - {disabled ? 'Agent is working...' : autoRunMode ? 'Describe what data to generate…' : isRunning ? (queueLength > 0 ? `${queueLength} queued, type another or wait…` : 'Agent is working, messages will queue…') : placeholderLabel} + {placeholderText} )}