* feat: Implement Cortex server auto-restart and webview notification
Implements a robust auto-restart mechanism for the Cortex server (sidecar)
managed by the Tauri backend.
Key changes:
Backend (src-tauri):
- Modified `core/setup.rs` to:
- Loop sidecar spawning, attempting up to `MAX_RESTARTS` (5) times with a
`RESTART_DELAY_MS` (5 seconds) between attempts.
- Monitor the sidecar process for unexpected termination (crashes or
non-zero exit codes).
- Reset the restart attempt count to 0 in `AppState` upon a successful
server spawn.
- Emit a "cortex_max_restarts_reached" event to the webview if the
server fails to start after `MAX_RESTARTS`.
- Updated `core/state.rs` to include `cortex_restart_count: Arc<Mutex<u32>>`
in `AppState` to track restart attempts.
- Added a new Tauri command `reset_cortex_restart_count` in `core/cmd.rs`
to allow the webview (or other parts of the app) to reset this counter.
- Registered the new command and initialized the `cortex_restart_count`
in `lib.rs`.
Frontend (web-app):
- Created a new component `CortexFailureDialog.tsx` in
`src/containers/dialogs/` to:
- Listen for the "cortex_max_restarts_reached" event from Tauri.
- Display a dialog informing the user that the local AI engine (Cortex)
failed to start after multiple attempts.
- Offer options to "Contact Support" (opens jan.ai/support),
"Restart Jan" (invokes the `relaunch` Tauri command), or "Okay"
(dismisses the dialog).
- Integrated the `CortexFailureDialog` into the `RootLayout` in
`src/routes/__root.tsx` so it's globally available.
- Corrected button variants in `__root.tsx` to use `variant="default"`
with appropriate classNames for outline styling, resolving TypeScript
errors.
* refactor: Improve async handling and logging in setup_sidecar function
83 lines
2.7 KiB
TypeScript
83 lines
2.7 KiB
TypeScript
import { createRootRoute, Outlet, useRouterState } from '@tanstack/react-router'
|
|
// import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
|
|
|
|
import LeftPanel from '@/containers/LeftPanel'
|
|
import DialogAppUpdater from '@/containers/dialogs/AppUpdater'
|
|
import { CortexFailureDialog } from '@/containers/dialogs/CortexFailureDialog' // Added import
|
|
import { Fragment } from 'react/jsx-runtime'
|
|
import { AppearanceProvider } from '@/providers/AppearanceProvider'
|
|
import { ThemeProvider } from '@/providers/ThemeProvider'
|
|
import { KeyboardShortcutsProvider } from '@/providers/KeyboardShortcuts'
|
|
import { DataProvider } from '@/providers/DataProvider'
|
|
import { route } from '@/constants/routes'
|
|
import { ExtensionProvider } from '@/providers/ExtensionProvider'
|
|
import { ToasterProvider } from '@/providers/ToasterProvider'
|
|
|
|
export const Route = createRootRoute({
|
|
component: RootLayout,
|
|
})
|
|
|
|
const AppLayout = () => {
|
|
return (
|
|
<Fragment>
|
|
<KeyboardShortcutsProvider />
|
|
<main className="relative h-svh text-sm antialiased select-none bg-app">
|
|
{/* Fake absolute panel top to enable window drag */}
|
|
<div className="absolute w-full h-10 z-10" data-tauri-drag-region />
|
|
<DialogAppUpdater />
|
|
<div className="flex h-full">
|
|
{/* left content panel - only show if not logs route */}
|
|
<LeftPanel />
|
|
|
|
{/* Main content panel */}
|
|
<div className="h-full flex w-full p-1">
|
|
<div className="bg-main-view text-main-view-fg border border-main-view-fg/5 w-full rounded-lg overflow-hidden">
|
|
<Outlet />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</Fragment>
|
|
)
|
|
}
|
|
|
|
const LogsLayout = () => {
|
|
return (
|
|
<Fragment>
|
|
<main className="relative h-svh text-sm antialiased select-text bg-app">
|
|
<div className="flex h-full">
|
|
{/* Main content panel */}
|
|
<div className="h-full flex w-full">
|
|
<div className="bg-main-view text-main-view-fg border border-main-view-fg/5 w-full overflow-hidden">
|
|
<Outlet />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
</Fragment>
|
|
)
|
|
}
|
|
|
|
function RootLayout() {
|
|
const router = useRouterState()
|
|
|
|
const isLocalAPIServerLogsRoute =
|
|
router.location.pathname === route.localApiServerlogs ||
|
|
router.location.pathname === route.systemMonitor ||
|
|
router.location.pathname === route.appLogs
|
|
|
|
return (
|
|
<Fragment>
|
|
<ThemeProvider />
|
|
<AppearanceProvider />
|
|
<ToasterProvider />
|
|
<ExtensionProvider>
|
|
<DataProvider />
|
|
</ExtensionProvider>
|
|
{isLocalAPIServerLogsRoute ? <LogsLayout /> : <AppLayout />}
|
|
{/* <TanStackRouterDevtools position="bottom-right" /> */}
|
|
<CortexFailureDialog />
|
|
</Fragment>
|
|
)
|
|
}
|