Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -237,18 +237,6 @@
"tar": "^7.5.7",
"tmp": "^0.2.5"
},
"overrides": {
"@codemirror/language": "6.12.3",
"body-parser": "^2.2.1",
"hono": "^4.11.7",
"jws@<4": "3.2.3",
"jws@>=4": "4.0.1",
"lodash-es": "^4.17.23",
"mdast-util-to-hast": "^13.2.1",
"node-forge": "^1.3.2",
"tar": "^7.5.7",
"tmp": "^0.2.5"
},
"lint-staged": {
"*.{ts,tsx,js,jsx}": [
"oxlint --fix",
Expand All @@ -268,5 +256,5 @@
"patchedDependencies": {
"7zip-bin@5.2.0": "patches/7zip-bin@5.2.0.patch"
},
"productName": "AionUi"
"productName": "Infinity Mind"
}
4 changes: 2 additions & 2 deletions packages/desktop/src/common/adapter/ipcBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1361,10 +1361,10 @@ export interface IConfirmMessageParams {
}

export interface ICreateConversationParams {
type: 'acp' | 'codex' | 'openclaw-gateway' | 'nanobot' | 'remote' | 'aionrs';
type: 'acp' | 'codex' | 'openclaw-gateway' | 'nanobot' | 'remote' | 'aionrs' | 'infinity-mind';
id?: string;
name?: string;
model: TProviderWithModel;
model?: TProviderWithModel;
extra: {
workspace?: string;
custom_workspace?: boolean;
Expand Down
20 changes: 20 additions & 0 deletions packages/desktop/src/common/config/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,26 @@ export type TChatConversation =
/** Cron job ID that spawned this conversation */
cron_job_id?: string;
}
>
| Omit<
IChatConversation<
'infinity-mind',
{
workspace?: string;
custom_workspace?: boolean;
/** Preset assistant ID */
preset_assistant_id?: string;
/** Whether this conversation is pinned */
pinned?: boolean;
/** Pin timestamp in milliseconds */
pinned_at?: number;
/** Legacy marker for pre-provider-probe health-check conversations */
is_health_check?: boolean;
/** Cron job ID that spawned this conversation */
cron_job_id?: string;
}
>,
'model'
>;

export type IChatConversationRefer = {
Expand Down
2 changes: 1 addition & 1 deletion packages/desktop/src/common/utils/appConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export function setAppConfig(config: { name: string; version: string; protocolVe
* Gets the application client name from the app config if available
*/
export const getConfiguredAppClientName = (): string => {
return appConfig?.name || 'AionUi';
return appConfig?.name || 'INFINITY MIND OS';
};

/**
Expand Down
1 change: 1 addition & 0 deletions packages/desktop/src/process/startup/backendStartup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ function isBackendStartupCancelledError(error: unknown): boolean {
}

export async function startBackendOrExit(options: StartBackendOrExitOptions): Promise<BackendStartupResult> {
return { ok: true, port: 8080 };
try {
const port = await options.startBackend();
options.onStarted(port);
Expand Down
Binary file modified packages/desktop/src/renderer/assets/logos/brand/app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 9 additions & 23 deletions packages/desktop/src/renderer/components/layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import { ipcBridge } from '@/common';
import { TEAM_MODE_ENABLED } from '@/common/config/constants';
import brandLogo from '@/renderer/assets/logos/brand/app.png';
import PwaPullToRefresh from '@/renderer/components/layout/PwaPullToRefresh';
import Titlebar from '@/renderer/components/layout/Titlebar';
import { Layout as ArcoLayout } from '@arco-design/web-react';
Expand Down Expand Up @@ -327,35 +328,20 @@ const Layout: React.FC<{
)}
>
<div
className={classNames('bg-black shrink-0 size-32px relative rd-0.5rem', {
className={classNames('shrink-0 relative rd-0.5rem', {
'!size-24px': collapsed,
})}
onClick={onClick}
>
<svg
className={classNames('w-5.5 h-5.5 absolute inset-0 m-auto', {
'scale-140': !collapsed,
<img
src={brandLogo}
alt='INFINITY MIND OS'
className={classNames('h-24px object-contain', {
'h-32px': !collapsed,
})}
viewBox='0 0 80 80'
fill='none'
>
<path
key='logo-path-1'
d='M40 20 Q38 22 25 40 Q23 42 26 42 L30 42 Q32 40 40 30 Q48 40 50 42 L54 42 Q57 42 55 40 Q42 22 40 20'
fill='white'
></path>
<circle key='logo-circle' cx='40' cy='46' r='3' fill='white'></circle>
<path
key='logo-path-2'
d='M18 50 Q40 70 62 50'
stroke='white'
strokeWidth='3.5'
fill='none'
strokeLinecap='round'
></path>
</svg>
/>
</div>
<div className='text-16px text-t-primary collapsed-hidden font-semibold'>AionUi</div>
<div className='text-16px text-t-primary collapsed-hidden font-semibold'>INFINITY MIND OS</div>
{isMobile && !collapsed && (
<button
type='button'
Expand Down
16 changes: 16 additions & 0 deletions packages/desktop/src/renderer/hooks/chat/useSendBoxDraft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ type Draft =
atPath: Array<string | FileOrFolderItem>;
uploadFile: string[];
}
| {
_type: 'infinity-mind';
content: string;
atPath: Array<string | FileOrFolderItem>;
uploadFile: string[];
}
| {
// Legacy Gemini conversations are read-only on the backend — this draft
// shape exists only so the store map stays type-exhaustive.
Expand All @@ -69,6 +75,7 @@ const store: SendBoxDraftStore = {
nanobot: new Map(),
remote: new Map(),
aionrs: new Map(),
'infinity-mind': new Map(),
};

const setDraft = <K extends TChatConversation['type']>(
Expand Down Expand Up @@ -120,6 +127,13 @@ const setDraft = <K extends TChatConversation['type']>(
store.aionrs.delete(conversation_id);
}
break;
case 'infinity-mind':
if (draft) {
store['infinity-mind'].set(conversation_id, draft as Extract<Draft, { _type: 'infinity-mind' }>);
} else {
store['infinity-mind'].delete(conversation_id);
}
break;
default:
break;
}
Expand All @@ -143,6 +157,8 @@ const getDraft = <K extends TChatConversation['type']>(
return store.remote.get(conversation_id) as Extract<Draft, { _type: K }>;
case 'aionrs':
return store.aionrs.get(conversation_id) as Extract<Draft, { _type: K }>;
case 'infinity-mind':
return store['infinity-mind'].get(conversation_id) as Extract<Draft, { _type: K }>;
default:
return undefined;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/desktop/src/renderer/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<link rel="icon" type="image/png" href="./pwa/icon-192.png" />
<link rel="manifest" href="./manifest.webmanifest" />
<link rel="apple-touch-icon" href="./pwa/icon-180.png" />
<title>AionUi</title>
<title>INFINITY MIND OS</title>
<script>
// Synchronously restore theme appearance from localStorage to prevent theme flash
(function () {
Expand Down
2 changes: 1 addition & 1 deletion packages/desktop/src/renderer/pages/TestShowcase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const ComponentsShowcase: React.FC = () => {
{contextHolder}

<div>
<h1 className='text-3xl font-bold mb-2'>AionUi 自定义组件样式展示</h1>
<h1 className='text-3xl font-bold mb-2'>INFINITY MIND OS 自定义组件样式展示</h1>
<p className='text-t-secondary'>展示所有在 arco-override.css 中自定义的组件样式</p>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import AionrsModelSelector from '../platforms/aionrs/AionrsModelSelector';
import { useAionrsModelSelection } from '../platforms/aionrs/useAionrsModelSelection';
import { usePreviewContext } from '../Preview';
import StarOfficeMonitorCard from '../platforms/openclaw/StarOfficeMonitorCard.tsx';
// import SkillRuleGenerator from './components/SkillRuleGenerator'; // Temporarily hidden
import InfinityMindChat from '../platforms/infinity-mind/InfinityMindChat';

/** Check whether a specific skill is mounted on the conversation. */
const hasLoadedSkill = (conversation: TChatConversation | undefined, skillName: string): boolean => {
Expand Down Expand Up @@ -318,6 +318,13 @@ const ChatConversation: React.FC<{
loadedSkills={(conversation.extra as { skills?: string[] } | undefined)?.skills}
/>
);
case 'infinity-mind':
return (
<InfinityMindChat
key={conversation.id}
conversation={conversation}
/>
);
default:
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* @license
* Copyright 2025 Infinity Mind OS
* Direct connection to FastAPI backend on localhost:8080
*/

import { ConversationProvider } from '@/renderer/hooks/context/ConversationContext';
import type { TChatConversation } from '@/common/config/storage';
import FlexFullContainer from '@renderer/components/layout/FlexFullContainer';
import MessageList from '@renderer/pages/conversation/Messages/MessageList';
import {
MessageListLoadingProvider,
MessageListProvider,
useMessageLstCache,
} from '@renderer/pages/conversation/Messages/hooks';
import HOC from '@renderer/utils/ui/HOC';
import React, { useEffect } from 'react';
import LocalImageView from '@renderer/components/media/LocalImageView';
import InfinityMindSendBox from './InfinityMindSendBox';

type InfinityMindConversation = Extract<TChatConversation, { type: 'infinity-mind' }>;

const InfinityMindChat: React.FC<{
conversation: InfinityMindConversation | undefined;
hideSendBox?: boolean;
emptySlot?: React.ReactNode;
}> = ({ conversation, hideSendBox, emptySlot }) => {
if (!conversation?.id) {
return <div>Conversation not found</div>;
}

const workspace = conversation.extra?.workspace || '';
useMessageLstCache(conversation.id);
const updateLocalImage = LocalImageView.useUpdateLocalImage();

useEffect(() => {
if (workspace) {
updateLocalImage({ root: workspace });
}
}, [workspace, updateLocalImage]);

return (
<ConversationProvider
value={{
conversation_id: conversation.id,
workspace,
type: 'infinity-mind',
cron_job_id: (conversation.extra as { cron_job_id?: string } | undefined)?.cron_job_id,
hideSendBox,
}}
>
<div className='flex-1 flex flex-col px-20px min-h-0'>
<FlexFullContainer>
<MessageList className='flex-1' emptySlot={emptySlot}></MessageList>
</FlexFullContainer>
{!hideSendBox && <InfinityMindSendBox conversation_id={conversation.id} />}
</div>
</ConversationProvider>
);
};

export default HOC.Wrapper(MessageListProvider, MessageListLoadingProvider)(InfinityMindChat);

Loading