mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
refactor: upgrade claude-code-acp to v0.8.3 and optimize agent initialization flow
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useMemo } from "react";
|
||||
import { View, Text, ActivityIndicator } from "react-native";
|
||||
import { useLocalSearchParams } from "expo-router";
|
||||
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
||||
@@ -18,7 +18,6 @@ export default function AgentScreen() {
|
||||
const { id } = useLocalSearchParams<{ id: string }>();
|
||||
const { agents, agentStreamState, pendingPermissions, respondToPermission, initializeAgent } = useSession();
|
||||
const { registerFooterControls, unregisterFooterControls } = useFooterControls();
|
||||
const [isContentReady, setIsContentReady] = useState(false);
|
||||
|
||||
// Keyboard animation
|
||||
const { height: keyboardHeight } = useReanimatedKeyboardAnimation();
|
||||
@@ -38,6 +37,9 @@ export default function AgentScreen() {
|
||||
Array.from(pendingPermissions.entries()).filter(([_, perm]) => perm.agentId === id)
|
||||
);
|
||||
|
||||
// Agent is initializing if we don't have stream state yet
|
||||
const isInitializing = id ? !agentStreamState.has(id) : false;
|
||||
|
||||
useEffect(() => {
|
||||
if (!id) {
|
||||
return;
|
||||
@@ -50,39 +52,8 @@ export default function AgentScreen() {
|
||||
return <AgentInputArea agentId={id} />;
|
||||
}, [id]);
|
||||
|
||||
// Defer heavy rendering to next frame for faster initial paint
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
let frameId: number | null = null;
|
||||
let timeoutId: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
const markReady = () => {
|
||||
if (isMounted) {
|
||||
setIsContentReady(true);
|
||||
}
|
||||
};
|
||||
|
||||
if (typeof requestAnimationFrame === "function") {
|
||||
frameId = requestAnimationFrame(markReady);
|
||||
} else {
|
||||
timeoutId = setTimeout(markReady, 0);
|
||||
}
|
||||
|
||||
return () => {
|
||||
isMounted = false;
|
||||
|
||||
if (frameId !== null && typeof cancelAnimationFrame === "function") {
|
||||
cancelAnimationFrame(frameId);
|
||||
}
|
||||
|
||||
if (timeoutId !== null) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!agentControls || !agent || !isContentReady) {
|
||||
if (!agentControls || !agent || isInitializing) {
|
||||
unregisterFooterControls();
|
||||
return;
|
||||
}
|
||||
@@ -92,7 +63,7 @@ export default function AgentScreen() {
|
||||
return () => {
|
||||
unregisterFooterControls();
|
||||
};
|
||||
}, [agentControls, agent, isContentReady, registerFooterControls, unregisterFooterControls]);
|
||||
}, [agentControls, agent, isInitializing, registerFooterControls, unregisterFooterControls]);
|
||||
|
||||
if (!agent) {
|
||||
return (
|
||||
@@ -112,7 +83,12 @@ export default function AgentScreen() {
|
||||
|
||||
{/* Content Area with Keyboard Animation */}
|
||||
<ReanimatedAnimated.View style={[styles.content, animatedKeyboardStyle]}>
|
||||
{isContentReady ? (
|
||||
{isInitializing ? (
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color={theme.colors.primary} />
|
||||
<Text style={styles.loadingText}>Loading agent...</Text>
|
||||
</View>
|
||||
) : (
|
||||
<>
|
||||
<AgentStreamView
|
||||
agentId={id!}
|
||||
@@ -129,10 +105,6 @@ export default function AgentScreen() {
|
||||
<AgentStatusBar agentId={id!} />
|
||||
</View>
|
||||
</>
|
||||
) : (
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color={theme.colors.primary} />
|
||||
</View>
|
||||
)}
|
||||
</ReanimatedAnimated.View>
|
||||
</View>
|
||||
@@ -154,6 +126,11 @@ const styles = StyleSheet.create((theme) => ({
|
||||
flex: 1,
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
gap: 16,
|
||||
},
|
||||
loadingText: {
|
||||
fontSize: theme.fontSize.base,
|
||||
color: theme.colors.mutedForeground,
|
||||
},
|
||||
errorContainer: {
|
||||
flex: 1,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useRef, useState, useCallback } from 'react';
|
||||
import { useEffect, useRef, useState, useCallback, useMemo } from 'react';
|
||||
import type {
|
||||
WSInboundMessage,
|
||||
WSOutboundMessage,
|
||||
@@ -150,12 +150,15 @@ export function useWebSocket(url: string, conversationId?: string | null): UseWe
|
||||
[send]
|
||||
);
|
||||
|
||||
return {
|
||||
isConnected,
|
||||
conversationId: currentConversationId,
|
||||
send,
|
||||
on,
|
||||
sendPing,
|
||||
sendUserMessage,
|
||||
};
|
||||
return useMemo(
|
||||
() => ({
|
||||
isConnected,
|
||||
conversationId: currentConversationId,
|
||||
send,
|
||||
on,
|
||||
sendPing,
|
||||
sendUserMessage,
|
||||
}),
|
||||
[isConnected, currentConversationId, send, on, sendPing, sendUserMessage]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -53,5 +53,16 @@
|
||||
},
|
||||
"createdAt": "2025-10-25T12:44:52.183Z",
|
||||
"cwd": "/Users/moboudra/dev/faro/main"
|
||||
},
|
||||
{
|
||||
"id": "415c2eb6-6649-4f3f-aee5-acc3d6b2cfd4",
|
||||
"title": "Agent 415c2eb6",
|
||||
"sessionId": "019a1c5a-0929-76de-ad58-1b80fa056209",
|
||||
"options": {
|
||||
"type": "claude",
|
||||
"sessionId": null
|
||||
},
|
||||
"createdAt": "2025-10-25T17:10:52.912Z",
|
||||
"cwd": "/Users/moboudra/dev/faro/main"
|
||||
}
|
||||
]
|
||||
@@ -18,7 +18,7 @@
|
||||
"dependencies": {
|
||||
"@agentclientprotocol/sdk": "^0.4.9",
|
||||
"@ai-sdk/openai": "^2.0.52",
|
||||
"@boudra/claude-code-acp": "^0.8.2",
|
||||
"@boudra/claude-code-acp": "^0.8.3",
|
||||
"@deepgram/sdk": "^3.4.0",
|
||||
"@modelcontextprotocol/sdk": "^1.20.1",
|
||||
"@openrouter/ai-sdk-provider": "^1.2.0",
|
||||
|
||||
@@ -923,12 +923,7 @@ export class Session {
|
||||
private async sendSessionState(): Promise<void> {
|
||||
try {
|
||||
// Get live agents with session modes
|
||||
const agents = this.agentManager?.listAgents() || [];
|
||||
|
||||
// Subscribe to all existing agents so future updates stream through
|
||||
for (const agent of agents) {
|
||||
this.subscribeToAgent(agent.id);
|
||||
}
|
||||
const agents = this.agentManager.listAgents();
|
||||
|
||||
// Get live commands from terminal manager
|
||||
let commands: any[] = [];
|
||||
|
||||
Reference in New Issue
Block a user