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:
duanshuwen
2026-04-17 21:32:06 +08:00
parent eca70425cf
commit e9f3a29886
33 changed files with 1526 additions and 2428 deletions

View File

@@ -0,0 +1,92 @@
export const DEFAULT_AGENT_ID = 'main';
export const DEFAULT_MAIN_SESSION_SUFFIX = 'main';
export interface AgentSummary {
id: string;
name: string;
isDefault: boolean;
providerAccountId: string | null;
modelRef: string | null;
modelDisplay: string;
mainSessionKey: string;
vendorId?: string | null;
source?: 'synthetic-main' | 'provider-account';
}
export interface AgentsSnapshot {
agents: AgentSummary[];
defaultAgentId: string;
defaultProviderAccountId: string | null;
defaultModelRef: string | null;
mainSessionSuffix: string;
configuredChannelTypes: string[];
channelOwners: Record<string, string>;
channelAccountOwners: Record<string, string>;
}
export interface ParsedSessionKey {
sessionKey: string;
agentId: string;
sessionId: string;
isAgentSession: boolean;
}
export function normalizeAgentId(value: string | null | undefined): string {
const normalized = String(value ?? '').trim().toLowerCase();
return normalized || DEFAULT_AGENT_ID;
}
export function normalizeSessionSuffix(value: string | null | undefined): string {
const normalized = String(value ?? '').trim().toLowerCase();
return normalized || DEFAULT_MAIN_SESSION_SUFFIX;
}
export function buildAgentSessionKey(agentId: string, sessionId: string): string {
return `agent:${normalizeAgentId(agentId)}:${normalizeSessionSuffix(sessionId)}`;
}
export function buildMainSessionKey(
agentId: string,
sessionId = DEFAULT_MAIN_SESSION_SUFFIX,
): string {
return buildAgentSessionKey(agentId, sessionId);
}
export function parseSessionKey(sessionKey: string): ParsedSessionKey {
const trimmed = String(sessionKey ?? '').trim();
if (trimmed.startsWith('agent:')) {
const parts = trimmed.split(':');
const agentId = normalizeAgentId(parts[1]);
const sessionId = normalizeSessionSuffix(parts.slice(2).join(':'));
return {
sessionKey: buildAgentSessionKey(agentId, sessionId),
agentId,
sessionId,
isAgentSession: true,
};
}
if (trimmed.startsWith('local:')) {
const parts = trimmed.split(':');
const agentId = normalizeAgentId(parts[1]);
const sessionId = normalizeSessionSuffix(parts.slice(2).join(':'));
return {
sessionKey: buildAgentSessionKey(agentId, sessionId),
agentId,
sessionId,
isAgentSession: true,
};
}
return {
sessionKey: trimmed,
agentId: DEFAULT_AGENT_ID,
sessionId: normalizeSessionSuffix(trimmed),
isAgentSession: false,
};
}
export function normalizeAgentSessionKey(sessionKey: string): string {
return parseSessionKey(sessionKey).sessionKey;
}