refactor: centralize host route builders and add dedicated new-agent route

This commit is contained in:
Mohamed Boudra
2026-03-04 15:09:06 +07:00
parent 92991ffdb8
commit f47ea7afe5
17 changed files with 231 additions and 193 deletions
@@ -60,6 +60,7 @@ import { shouldClearAgentAttentionOnView } from "@/utils/agent-attention";
import type { DaemonClient } from "@server/client/daemon-client";
import { useExplorerOpenGesture } from "@/hooks/use-explorer-open-gesture";
import type { ExplorerCheckoutContext } from "@/stores/panel-store";
import { buildHostRootRoute } from "@/utils/host-routes";
const EMPTY_STREAM_ITEMS: StreamItem[] = [];
const IS_DEV = Boolean((globalThis as { __DEV__?: boolean }).__DEV__);
@@ -528,7 +529,7 @@ function AgentScreenContent({
return;
}
hasRedirectedArchivedAgentRef.current = true;
const route: Href = `/h/${encodeURIComponent(serverId)}` as Href;
const route: Href = buildHostRootRoute(serverId) as Href;
router.replace(route);
}, [agent?.archivedAt, resolvedAgentId, router, serverId]);
+2 -1
View File
@@ -5,6 +5,7 @@ import { BackHeader } from "@/components/headers/back-header";
import { AgentList } from "@/components/agent-list";
import { useAllAgentsList } from "@/hooks/use-all-agents-list";
import { router } from "expo-router";
import { buildHostRootRoute } from "@/utils/host-routes";
export function AgentsScreen({ serverId }: { serverId: string }) {
const { agents, isRevalidating, refreshAll } = useAllAgentsList({
@@ -43,7 +44,7 @@ export function AgentsScreen({ serverId }: { serverId: string }) {
<View style={styles.container}>
<BackHeader
title="All agents"
onBack={() => router.replace(`/h/${encodeURIComponent(serverId)}` as any)}
onBack={() => router.replace(buildHostRootRoute(serverId) as any)}
/>
<AgentList
agents={sortedAgents}
@@ -1,9 +1,11 @@
import { useCallback, useEffect, useMemo, useReducer } from "react";
import { useCallback, useEffect, useMemo, useReducer, useRef } from "react";
import { Keyboard, Platform, ScrollView, Text, View } from "react-native";
import { StyleSheet } from "react-native-unistyles";
import { AgentInputArea } from "@/components/agent-input-area";
import { AgentConfigRow } from "@/components/agent-form/agent-form-dropdowns";
import { FileDropZone } from "@/components/file-drop-zone";
import { AgentStreamView } from "@/components/agent-stream-view";
import type { ImageAttachment } from "@/components/message-input";
import { MAX_CONTENT_WIDTH } from "@/constants/layout";
import { useAgentFormState } from "@/hooks/use-agent-form-state";
import { useHostRuntimeSession } from "@/runtime/host-runtime";
@@ -63,6 +65,7 @@ export function WorkspaceDraftAgentTab({
onCreated,
}: WorkspaceDraftAgentTabProps) {
const { client, isConnected } = useHostRuntimeSession(serverId);
const addImagesRef = useRef<((images: ImageAttachment[]) => void) | null>(null);
const setPendingCreateAttempt = useCreateFlowStore((state) => state.setPending);
const updatePendingAgentId = useCreateFlowStore((state) => state.updateAgentId);
@@ -322,64 +325,75 @@ export function WorkspaceDraftAgentTab({
workspaceId,
]);
const handleFilesDropped = useCallback((files: ImageAttachment[]) => {
addImagesRef.current?.(files);
}, []);
const handleAddImagesCallback = useCallback((addImages: (images: ImageAttachment[]) => void) => {
addImagesRef.current = addImages;
}, []);
return (
<View style={styles.container}>
<View style={styles.contentContainer}>
{machine.tag === "creating" && draftAgent ? (
<View style={styles.streamContainer}>
<AgentStreamView
agentId={tabId}
serverId={serverId}
agent={draftAgent}
streamItems={optimisticStreamItems}
pendingPermissions={EMPTY_PENDING_PERMISSIONS}
/>
</View>
) : (
<ScrollView style={styles.scrollView} contentContainerStyle={styles.configScrollContent}>
<View style={styles.configSection}>
<AgentConfigRow
providerDefinitions={providerDefinitions}
selectedProvider={selectedProvider}
onSelectProvider={setProviderFromUser}
modeOptions={modeOptions}
selectedMode={selectedMode}
onSelectMode={setModeFromUser}
models={availableModels}
selectedModel={selectedModel}
onSelectModel={setModelFromUser}
isModelLoading={isModelLoading}
thinkingOptions={availableThinkingOptions}
selectedThinkingOptionId={selectedThinkingOptionId}
onSelectThinkingOption={setThinkingOptionFromUser}
disabled={isSubmitting}
<FileDropZone onFilesDropped={handleFilesDropped}>
<View style={styles.container}>
<View style={styles.contentContainer}>
{machine.tag === "creating" && draftAgent ? (
<View style={styles.streamContainer}>
<AgentStreamView
agentId={tabId}
serverId={serverId}
agent={draftAgent}
streamItems={optimisticStreamItems}
pendingPermissions={EMPTY_PENDING_PERMISSIONS}
/>
{formErrorMessage ? (
<View style={styles.errorContainer}>
<Text style={styles.errorText}>{formErrorMessage}</Text>
</View>
) : null}
</View>
</ScrollView>
)}
</View>
) : (
<ScrollView style={styles.scrollView} contentContainerStyle={styles.configScrollContent}>
<View style={styles.configSection}>
<AgentConfigRow
providerDefinitions={providerDefinitions}
selectedProvider={selectedProvider}
onSelectProvider={setProviderFromUser}
modeOptions={modeOptions}
selectedMode={selectedMode}
onSelectMode={setModeFromUser}
models={availableModels}
selectedModel={selectedModel}
onSelectModel={setModelFromUser}
isModelLoading={isModelLoading}
thinkingOptions={availableThinkingOptions}
selectedThinkingOptionId={selectedThinkingOptionId}
onSelectThinkingOption={setThinkingOptionFromUser}
disabled={isSubmitting}
/>
<View style={styles.inputAreaWrapper}>
<AgentInputArea
agentId={tabId}
serverId={serverId}
onSubmitMessage={handleCreateFromInput}
isSubmitLoading={isSubmitting}
blurOnSubmit={true}
value={promptValue}
onChangeText={(next) => dispatch({ type: "DRAFT_SET_PROMPT", text: next })}
autoFocus={machine.tag === "draft"}
commandDraftConfig={draftCommandConfig}
draftId={draftId}
/>
{formErrorMessage ? (
<View style={styles.errorContainer}>
<Text style={styles.errorText}>{formErrorMessage}</Text>
</View>
) : null}
</View>
</ScrollView>
)}
</View>
<View style={styles.inputAreaWrapper}>
<AgentInputArea
agentId={tabId}
serverId={serverId}
onSubmitMessage={handleCreateFromInput}
isSubmitLoading={isSubmitting}
blurOnSubmit={true}
value={promptValue}
onChangeText={(next) => dispatch({ type: "DRAFT_SET_PROMPT", text: next })}
autoFocus={machine.tag === "draft"}
onAddImages={handleAddImagesCallback}
commandDraftConfig={draftCommandConfig}
draftId={draftId}
/>
</View>
</View>
</View>
</FileDropZone>
);
}