feat: implement OpenClaw process owner and runtime path utilities
- Add OpenClawProcessOwner class to manage the lifecycle of the OpenClaw process. - Introduce utility functions for managing OpenClaw runtime paths. - Update session store to normalize agent session keys and migrate existing keys. - Refactor main process to handle local provider API routing through a new dispatch function. - Enhance token usage writer to utilize a new session key parsing function. - Create agents management store to handle agent data and interactions. - Update chat store to integrate agent selection and session management. - Introduce AgentsSection component for displaying agent information in the UI. - Refactor HomePage to support agent selection and display current agent. - Update routing to reflect new agents page structure.
This commit is contained in:
@@ -15,11 +15,13 @@ import {
|
||||
import { IPC_EVENTS } from '../../lib/constants';
|
||||
import { invokeIpc } from '../../lib/host-api';
|
||||
import {
|
||||
agentsStore,
|
||||
channelStore,
|
||||
chatStore,
|
||||
getCompletedTasks,
|
||||
getPendingTasks,
|
||||
taskStore,
|
||||
useAgentsStore,
|
||||
useChannelStore,
|
||||
useChatStore,
|
||||
useTaskStore,
|
||||
@@ -147,6 +149,7 @@ function mapMessages(messages: RawMessage[], streamingMessage: RawMessage | null
|
||||
}
|
||||
|
||||
export default function HomePage() {
|
||||
const agentsState = useAgentsStore();
|
||||
const chat = useChatStore();
|
||||
const taskState = useTaskStore();
|
||||
const channelState = useChannelStore();
|
||||
@@ -158,6 +161,7 @@ export default function HomePage() {
|
||||
const [addChannelDialogOpen, setAddChannelDialogOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
void agentsStore.init();
|
||||
void chatStore.init();
|
||||
void taskStore.init();
|
||||
void channelStore.init();
|
||||
@@ -208,6 +212,10 @@ export default function HomePage() {
|
||||
const latestTask = currentTaskSource[0];
|
||||
|
||||
const visibleMessages = mapMessages(chat.messages, chat.streamingMessage);
|
||||
const selectedAgentId = agentsState.agents.some((agent) => agent.id === chat.currentAgentId)
|
||||
? chat.currentAgentId
|
||||
: agentsState.defaultAgentId;
|
||||
const currentAgent = agentsState.agents.find((agent) => agent.id === selectedAgentId) || null;
|
||||
|
||||
async function handleSendMessage(): Promise<void> {
|
||||
const sent = await chatStore.sendMessage(inputMessage, attachments);
|
||||
@@ -279,7 +287,7 @@ export default function HomePage() {
|
||||
loading={!chat.initialized}
|
||||
selectedConversationId={chat.currentSessionKey}
|
||||
onNewChat={() => {
|
||||
void chatStore.newSession();
|
||||
void chatStore.newSession(selectedAgentId || undefined);
|
||||
}}
|
||||
onSelectConversation={(conversationId) => {
|
||||
chatStore.switchSession(conversationId);
|
||||
@@ -307,18 +315,39 @@ export default function HomePage() {
|
||||
<h2 className="text-base font-semibold text-[#171717] dark:text-gray-100">智能对话</h2>
|
||||
<div className="mt-1 text-xs text-[#99A0AE] dark:text-gray-500">
|
||||
网关状态:{chat.gatewayStatus === 'connected' ? '已连接' : chat.gatewayStatus === 'reconnecting' ? '重连中' : '未连接'}
|
||||
{currentAgent ? ` · 当前代理:${currentAgent.name}` : ''}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-full border border-[#E5E8EE] px-3 py-1.5 text-xs text-[#525866] transition-colors hover:border-[#2B7FFF] hover:text-[#2B7FFF] dark:border-[#2a2a2d] dark:text-gray-300"
|
||||
onClick={() => {
|
||||
void chatStore.loadSessions();
|
||||
void chatStore.loadHistory();
|
||||
}}
|
||||
>
|
||||
刷新会话
|
||||
</button>
|
||||
<div className="flex items-center gap-3">
|
||||
<label className="flex items-center gap-2 text-xs text-[#525866] dark:text-gray-300">
|
||||
<span>代理</span>
|
||||
<select
|
||||
className="rounded-full border border-[#E5E8EE] bg-white px-3 py-1.5 text-xs text-[#525866] outline-none transition-colors hover:border-[#2B7FFF] dark:border-[#2a2a2d] dark:bg-[#232327] dark:text-gray-300"
|
||||
disabled={agentsState.loading || agentsState.agents.length === 0}
|
||||
value={selectedAgentId}
|
||||
onChange={(event) => {
|
||||
chatStore.selectAgent(event.target.value);
|
||||
}}
|
||||
>
|
||||
{agentsState.agents.map((agent) => (
|
||||
<option key={agent.id} value={agent.id}>
|
||||
{agent.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
<button
|
||||
type="button"
|
||||
className="rounded-full border border-[#E5E8EE] px-3 py-1.5 text-xs text-[#525866] transition-colors hover:border-[#2B7FFF] hover:text-[#2B7FFF] dark:border-[#2a2a2d] dark:text-gray-300"
|
||||
onClick={() => {
|
||||
void agentsStore.load();
|
||||
void chatStore.loadSessions();
|
||||
void chatStore.loadHistory();
|
||||
}}
|
||||
>
|
||||
刷新会话
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex min-h-0 flex-1 flex-col">
|
||||
|
||||
Reference in New Issue
Block a user