refactor: update gateway agent session key handling and improve related logic

This commit is contained in:
Abhimanyu Saharan
2026-02-10 00:45:15 +05:30
parent 79f7ad8ba3
commit ba73ce8bfd
27 changed files with 233 additions and 208 deletions

View File

@@ -3498,7 +3498,7 @@ export const useUpdateAgentSoulApiV1AgentBoardsBoardIdAgentsAgentIdSoulPut = <
);
};
/**
* Route a lead's ask-user request through the gateway main agent.
* Route a lead's ask-user request through the dedicated gateway agent.
* @summary Ask User Via Gateway Main
*/
export type askUserViaGatewayMainApiV1AgentBoardsBoardIdGatewayMainAskUserPostResponse200 =

View File

@@ -275,7 +275,7 @@ export function useGetOnboardingApiV1BoardsBoardIdOnboardingGet<
}
/**
* Start onboarding and send instructions to the gateway main agent.
* Start onboarding and send instructions to the gateway agent.
* @summary Start Onboarding
*/
export type startOnboardingApiV1BoardsBoardIdOnboardingStartPostResponse200 = {
@@ -417,7 +417,7 @@ export const useStartOnboardingApiV1BoardsBoardIdOnboardingStartPost = <
);
};
/**
* Send a user onboarding answer to the gateway main agent.
* Send a user onboarding answer to the gateway agent.
* @summary Answer Onboarding
*/
export type answerOnboardingApiV1BoardsBoardIdOnboardingAnswerPostResponse200 =
@@ -567,7 +567,7 @@ export const useAnswerOnboardingApiV1BoardsBoardIdOnboardingAnswerPost = <
);
};
/**
* Store onboarding updates submitted by the gateway main agent.
* Store onboarding updates submitted by the gateway agent.
* @summary Agent Onboarding Update
*/
export type agentOnboardingUpdateApiV1BoardsBoardIdOnboardingAgentPostResponse200 =

View File

@@ -24,13 +24,13 @@ import type {
GatewayCommandsResponse,
GatewayCreate,
GatewayRead,
GatewayResolveQuery,
GatewaySessionHistoryResponse,
GatewaySessionMessageRequest,
GatewaySessionResponse,
GatewaySessionsResponse,
GatewayTemplatesSyncResult,
GatewayUpdate,
GatewaysStatusApiV1GatewaysStatusGetParams,
GatewaysStatusResponse,
GetGatewaySessionApiV1GatewaysSessionsSessionIdGetParams,
GetSessionHistoryApiV1GatewaysSessionsSessionIdHistoryGetParams,
@@ -74,36 +74,48 @@ export type gatewaysStatusApiV1GatewaysStatusGetResponse =
| gatewaysStatusApiV1GatewaysStatusGetResponseSuccess
| gatewaysStatusApiV1GatewaysStatusGetResponseError;
export const getGatewaysStatusApiV1GatewaysStatusGetUrl = () => {
return `/api/v1/gateways/status`;
export const getGatewaysStatusApiV1GatewaysStatusGetUrl = (
params?: GatewaysStatusApiV1GatewaysStatusGetParams,
) => {
const normalizedParams = new URLSearchParams();
Object.entries(params || {}).forEach(([key, value]) => {
if (value !== undefined) {
normalizedParams.append(key, value === null ? "null" : value.toString());
}
});
const stringifiedParams = normalizedParams.toString();
return stringifiedParams.length > 0
? `/api/v1/gateways/status?${stringifiedParams}`
: `/api/v1/gateways/status`;
};
export const gatewaysStatusApiV1GatewaysStatusGet = async (
gatewayResolveQuery: GatewayResolveQuery,
params?: GatewaysStatusApiV1GatewaysStatusGetParams,
options?: RequestInit,
): Promise<gatewaysStatusApiV1GatewaysStatusGetResponse> => {
return customFetch<gatewaysStatusApiV1GatewaysStatusGetResponse>(
getGatewaysStatusApiV1GatewaysStatusGetUrl(),
getGatewaysStatusApiV1GatewaysStatusGetUrl(params),
{
...options,
method: "GET",
headers: { "Content-Type": "application/json", ...options?.headers },
body: JSON.stringify(gatewayResolveQuery),
},
);
};
export const getGatewaysStatusApiV1GatewaysStatusGetQueryKey = (
gatewayResolveQuery?: GatewayResolveQuery,
params?: GatewaysStatusApiV1GatewaysStatusGetParams,
) => {
return [`/api/v1/gateways/status`, gatewayResolveQuery] as const;
return [`/api/v1/gateways/status`, ...(params ? [params] : [])] as const;
};
export const getGatewaysStatusApiV1GatewaysStatusGetQueryOptions = <
TData = Awaited<ReturnType<typeof gatewaysStatusApiV1GatewaysStatusGet>>,
TError = HTTPValidationError,
>(
gatewayResolveQuery: GatewayResolveQuery,
params?: GatewaysStatusApiV1GatewaysStatusGetParams,
options?: {
query?: Partial<
UseQueryOptions<
@@ -119,15 +131,12 @@ export const getGatewaysStatusApiV1GatewaysStatusGetQueryOptions = <
const queryKey =
queryOptions?.queryKey ??
getGatewaysStatusApiV1GatewaysStatusGetQueryKey(gatewayResolveQuery);
getGatewaysStatusApiV1GatewaysStatusGetQueryKey(params);
const queryFn: QueryFunction<
Awaited<ReturnType<typeof gatewaysStatusApiV1GatewaysStatusGet>>
> = ({ signal }) =>
gatewaysStatusApiV1GatewaysStatusGet(gatewayResolveQuery, {
signal,
...requestOptions,
});
gatewaysStatusApiV1GatewaysStatusGet(params, { signal, ...requestOptions });
return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
Awaited<ReturnType<typeof gatewaysStatusApiV1GatewaysStatusGet>>,
@@ -146,7 +155,7 @@ export function useGatewaysStatusApiV1GatewaysStatusGet<
TData = Awaited<ReturnType<typeof gatewaysStatusApiV1GatewaysStatusGet>>,
TError = HTTPValidationError,
>(
gatewayResolveQuery: GatewayResolveQuery,
params: undefined | GatewaysStatusApiV1GatewaysStatusGetParams,
options: {
query: Partial<
UseQueryOptions<
@@ -173,7 +182,7 @@ export function useGatewaysStatusApiV1GatewaysStatusGet<
TData = Awaited<ReturnType<typeof gatewaysStatusApiV1GatewaysStatusGet>>,
TError = HTTPValidationError,
>(
gatewayResolveQuery: GatewayResolveQuery,
params?: GatewaysStatusApiV1GatewaysStatusGetParams,
options?: {
query?: Partial<
UseQueryOptions<
@@ -200,7 +209,7 @@ export function useGatewaysStatusApiV1GatewaysStatusGet<
TData = Awaited<ReturnType<typeof gatewaysStatusApiV1GatewaysStatusGet>>,
TError = HTTPValidationError,
>(
gatewayResolveQuery: GatewayResolveQuery,
params?: GatewaysStatusApiV1GatewaysStatusGetParams,
options?: {
query?: Partial<
UseQueryOptions<
@@ -223,7 +232,7 @@ export function useGatewaysStatusApiV1GatewaysStatusGet<
TData = Awaited<ReturnType<typeof gatewaysStatusApiV1GatewaysStatusGet>>,
TError = HTTPValidationError,
>(
gatewayResolveQuery: GatewayResolveQuery,
params?: GatewaysStatusApiV1GatewaysStatusGetParams,
options?: {
query?: Partial<
UseQueryOptions<
@@ -239,7 +248,7 @@ export function useGatewaysStatusApiV1GatewaysStatusGet<
queryKey: DataTag<QueryKey, TData, TError>;
} {
const queryOptions = getGatewaysStatusApiV1GatewaysStatusGetQueryOptions(
gatewayResolveQuery,
params,
options,
);

View File

@@ -11,7 +11,6 @@
export interface GatewayCreate {
name: string;
url: string;
main_session_key: string;
workspace_root: string;
token?: string | null;
}

View File

@@ -11,11 +11,11 @@
export interface GatewayRead {
name: string;
url: string;
main_session_key: string;
workspace_root: string;
id: string;
organization_id: string;
token?: string | null;
main_session_key: string;
created_at: string;
updated_at: string;
}

View File

@@ -12,5 +12,4 @@ export interface GatewayResolveQuery {
board_id?: string | null;
gateway_url?: string | null;
gateway_token?: string | null;
gateway_main_session_key?: string | null;
}

View File

@@ -12,6 +12,5 @@ export interface GatewayUpdate {
name?: string | null;
url?: string | null;
token?: string | null;
main_session_key?: string | null;
workspace_root?: string | null;
}

View File

@@ -9,5 +9,4 @@ export type GatewaysStatusApiV1GatewaysStatusGetParams = {
board_id?: string | null;
gateway_url?: string | null;
gateway_token?: string | null;
gateway_main_session_key?: string | null;
};

View File

@@ -18,7 +18,6 @@ import type { GatewayUpdate } from "@/api/generated/model";
import { GatewayForm } from "@/components/gateways/GatewayForm";
import { DashboardPageLayout } from "@/components/templates/DashboardPageLayout";
import {
DEFAULT_MAIN_SESSION_KEY,
DEFAULT_WORKSPACE_ROOT,
checkGatewayConnection,
type GatewayCheckStatus,
@@ -41,9 +40,6 @@ export default function EditGatewayPage() {
const [gatewayToken, setGatewayToken] = useState<string | undefined>(
undefined,
);
const [mainSessionKey, setMainSessionKey] = useState<string | undefined>(
undefined,
);
const [workspaceRoot, setWorkspaceRoot] = useState<string | undefined>(
undefined,
);
@@ -86,10 +82,7 @@ export default function EditGatewayPage() {
const resolvedName = name ?? loadedGateway?.name ?? "";
const resolvedGatewayUrl = gatewayUrl ?? loadedGateway?.url ?? "";
const resolvedGatewayToken = gatewayToken ?? loadedGateway?.token ?? "";
const resolvedMainSessionKey =
mainSessionKey ??
loadedGateway?.main_session_key ??
DEFAULT_MAIN_SESSION_KEY;
const resolvedMainSessionKey = loadedGateway?.main_session_key ?? null;
const resolvedWorkspaceRoot =
workspaceRoot ?? loadedGateway?.workspace_root ?? DEFAULT_WORKSPACE_ROOT;
@@ -99,7 +92,6 @@ export default function EditGatewayPage() {
const canSubmit =
Boolean(resolvedName.trim()) &&
Boolean(resolvedGatewayUrl.trim()) &&
Boolean(resolvedMainSessionKey.trim()) &&
Boolean(resolvedWorkspaceRoot.trim()) &&
gatewayCheckStatus === "success";
@@ -117,7 +109,6 @@ export default function EditGatewayPage() {
const { ok, message } = await checkGatewayConnection({
gatewayUrl: resolvedGatewayUrl,
gatewayToken: resolvedGatewayToken,
mainSessionKey: resolvedMainSessionKey,
});
setGatewayCheckStatus(ok ? "success" : "error");
setGatewayCheckMessage(message);
@@ -138,10 +129,6 @@ export default function EditGatewayPage() {
setGatewayCheckMessage(gatewayValidation);
return;
}
if (!resolvedMainSessionKey.trim()) {
setError("Main session key is required.");
return;
}
if (!resolvedWorkspaceRoot.trim()) {
setError("Workspace root is required.");
return;
@@ -153,7 +140,6 @@ export default function EditGatewayPage() {
name: resolvedName.trim(),
url: resolvedGatewayUrl.trim(),
token: resolvedGatewayToken.trim() || null,
main_session_key: resolvedMainSessionKey.trim(),
workspace_root: resolvedWorkspaceRoot.trim(),
};
@@ -187,7 +173,6 @@ export default function EditGatewayPage() {
errorMessage={errorMessage}
isLoading={isLoading}
canSubmit={canSubmit}
mainSessionKeyPlaceholder={DEFAULT_MAIN_SESSION_KEY}
workspaceRootPlaceholder={DEFAULT_WORKSPACE_ROOT}
cancelLabel="Back"
submitLabel="Save changes"
@@ -207,11 +192,6 @@ export default function EditGatewayPage() {
setGatewayCheckStatus("idle");
setGatewayCheckMessage(null);
}}
onMainSessionKeyChange={(next) => {
setMainSessionKey(next);
setGatewayCheckStatus("idle");
setGatewayCheckMessage(null);
}}
onWorkspaceRootChange={setWorkspaceRoot}
/>
</DashboardPageLayout>

View File

@@ -67,7 +67,6 @@ export default function GatewayDetailPage() {
? {
gateway_url: gateway.url,
gateway_token: gateway.token ?? undefined,
gateway_main_session_key: gateway.main_session_key ?? undefined,
}
: {};

View File

@@ -13,7 +13,6 @@ import { useOrganizationMembership } from "@/lib/use-organization-membership";
import { GatewayForm } from "@/components/gateways/GatewayForm";
import { DashboardPageLayout } from "@/components/templates/DashboardPageLayout";
import {
DEFAULT_MAIN_SESSION_KEY,
DEFAULT_WORKSPACE_ROOT,
checkGatewayConnection,
type GatewayCheckStatus,
@@ -29,9 +28,6 @@ export default function NewGatewayPage() {
const [name, setName] = useState("");
const [gatewayUrl, setGatewayUrl] = useState("");
const [gatewayToken, setGatewayToken] = useState("");
const [mainSessionKey, setMainSessionKey] = useState(
DEFAULT_MAIN_SESSION_KEY,
);
const [workspaceRoot, setWorkspaceRoot] = useState(DEFAULT_WORKSPACE_ROOT);
const [gatewayUrlError, setGatewayUrlError] = useState<string | null>(null);
@@ -61,7 +57,6 @@ export default function NewGatewayPage() {
const canSubmit =
Boolean(name.trim()) &&
Boolean(gatewayUrl.trim()) &&
Boolean(mainSessionKey.trim()) &&
Boolean(workspaceRoot.trim()) &&
gatewayCheckStatus === "success";
@@ -79,7 +74,6 @@ export default function NewGatewayPage() {
const { ok, message } = await checkGatewayConnection({
gatewayUrl,
gatewayToken,
mainSessionKey,
});
setGatewayCheckStatus(ok ? "success" : "error");
setGatewayCheckMessage(message);
@@ -100,10 +94,6 @@ export default function NewGatewayPage() {
setGatewayCheckMessage(gatewayValidation);
return;
}
if (!mainSessionKey.trim()) {
setError("Main session key is required.");
return;
}
if (!workspaceRoot.trim()) {
setError("Workspace root is required.");
return;
@@ -115,7 +105,6 @@ export default function NewGatewayPage() {
name: name.trim(),
url: gatewayUrl.trim(),
token: gatewayToken.trim() || null,
main_session_key: mainSessionKey.trim(),
workspace_root: workspaceRoot.trim(),
},
});
@@ -136,7 +125,7 @@ export default function NewGatewayPage() {
name={name}
gatewayUrl={gatewayUrl}
gatewayToken={gatewayToken}
mainSessionKey={mainSessionKey}
mainSessionKey={null}
workspaceRoot={workspaceRoot}
gatewayUrlError={gatewayUrlError}
gatewayCheckStatus={gatewayCheckStatus}
@@ -144,7 +133,6 @@ export default function NewGatewayPage() {
errorMessage={error}
isLoading={isLoading}
canSubmit={canSubmit}
mainSessionKeyPlaceholder={DEFAULT_MAIN_SESSION_KEY}
workspaceRootPlaceholder={DEFAULT_WORKSPACE_ROOT}
cancelLabel="Cancel"
submitLabel="Create gateway"
@@ -164,11 +152,6 @@ export default function NewGatewayPage() {
setGatewayCheckStatus("idle");
setGatewayCheckMessage(null);
}}
onMainSessionKeyChange={(next) => {
setMainSessionKey(next);
setGatewayCheckStatus("idle");
setGatewayCheckMessage(null);
}}
onWorkspaceRootChange={setWorkspaceRoot}
/>
</DashboardPageLayout>

View File

@@ -89,24 +89,24 @@ export default function SettingsPage() {
const deleteAccountMutation = useDeleteMeApiV1UsersMeDelete<ApiError>({
mutation: {
onSuccess: async () => {
setDeleteError(null);
if (typeof window !== "undefined") {
const clerk = (window as Window & { Clerk?: ClerkGlobal }).Clerk;
if (clerk?.signOut) {
try {
await clerk.signOut({ redirectUrl: "/sign-in" });
return;
} catch {
// Fall through to local redirect.
onSuccess: async () => {
setDeleteError(null);
if (typeof window !== "undefined") {
const clerk = (window as Window & { Clerk?: ClerkGlobal }).Clerk;
if (clerk?.signOut) {
try {
await clerk.signOut({ redirectUrl: "/sign-in" });
return;
} catch {
// Fall through to local redirect.
}
}
}
}
router.replace("/sign-in");
},
onError: (error) => {
setDeleteError(error.message || "Unable to delete account.");
},
router.replace("/sign-in");
},
onError: (error) => {
setDeleteError(error.message || "Unable to delete account.");
},
},
});

View File

@@ -9,7 +9,7 @@ type GatewayFormProps = {
name: string;
gatewayUrl: string;
gatewayToken: string;
mainSessionKey: string;
mainSessionKey: string | null;
workspaceRoot: string;
gatewayUrlError: string | null;
gatewayCheckStatus: GatewayCheckStatus;
@@ -17,7 +17,6 @@ type GatewayFormProps = {
errorMessage: string | null;
isLoading: boolean;
canSubmit: boolean;
mainSessionKeyPlaceholder: string;
workspaceRootPlaceholder: string;
cancelLabel: string;
submitLabel: string;
@@ -28,7 +27,6 @@ type GatewayFormProps = {
onNameChange: (next: string) => void;
onGatewayUrlChange: (next: string) => void;
onGatewayTokenChange: (next: string) => void;
onMainSessionKeyChange: (next: string) => void;
onWorkspaceRootChange: (next: string) => void;
};
@@ -44,7 +42,6 @@ export function GatewayForm({
errorMessage,
isLoading,
canSubmit,
mainSessionKeyPlaceholder,
workspaceRootPlaceholder,
cancelLabel,
submitLabel,
@@ -55,7 +52,6 @@ export function GatewayForm({
onNameChange,
onGatewayUrlChange,
onGatewayTokenChange,
onMainSessionKeyChange,
onWorkspaceRootChange,
}: GatewayFormProps) {
return (
@@ -137,13 +133,12 @@ export function GatewayForm({
<div className="grid gap-6 md:grid-cols-2">
<div className="space-y-2">
<label className="text-sm font-medium text-slate-900">
Main session key <span className="text-red-500">*</span>
Main session key (read-only)
</label>
<Input
value={mainSessionKey}
onChange={(event) => onMainSessionKeyChange(event.target.value)}
placeholder={mainSessionKeyPlaceholder}
disabled={isLoading}
value={mainSessionKey ?? "Auto-generated by server"}
readOnly
disabled
/>
</div>
<div className="space-y-2">

View File

@@ -1,6 +1,5 @@
import { gatewaysStatusApiV1GatewaysStatusGet } from "@/api/generated/gateways/gateways";
export const DEFAULT_MAIN_SESSION_KEY = "agent:main:main";
export const DEFAULT_WORKSPACE_ROOT = "~/.openclaw";
export type GatewayCheckStatus = "idle" | "checking" | "success" | "error";
@@ -25,7 +24,6 @@ export const validateGatewayUrl = (value: string) => {
export async function checkGatewayConnection(params: {
gatewayUrl: string;
gatewayToken: string;
mainSessionKey: string;
}): Promise<{ ok: boolean; message: string }> {
try {
const requestParams: Record<string, string> = {
@@ -34,9 +32,6 @@ export async function checkGatewayConnection(params: {
if (params.gatewayToken.trim()) {
requestParams.gateway_token = params.gatewayToken.trim();
}
if (params.mainSessionKey.trim()) {
requestParams.gateway_main_session_key = params.mainSessionKey.trim();
}
const response = await gatewaysStatusApiV1GatewaysStatusGet(requestParams);
if (response.status !== 200) {