chore: fixes

This commit is contained in:
Lluis Agusti
2026-02-13 00:43:37 +08:00
parent fd5d53bc90
commit fecd82cf90
7 changed files with 34 additions and 60 deletions

View File

@@ -4,7 +4,6 @@ import logging
from typing import Any
from backend.api.features.chat.model import ChatSession
from backend.api.features.library.db import add_generated_agent_image
from .agent_generator import (
AgentGeneratorNotConfiguredError,
@@ -318,19 +317,6 @@ class CreateAgentTool(BaseTool):
agent_json, user_id
)
# Generate image before returning so the URL is available in the response
image_url: str | None = None
try:
updated_agent = await add_generated_agent_image(
graph=created_graph,
user_id=user_id,
library_agent_id=library_agent.id,
)
if updated_agent and updated_agent.imageUrl:
image_url = updated_agent.imageUrl
except Exception as e:
logger.warning(f"Image generation failed, continuing without: {e}")
return AgentSavedResponse(
message=f"Agent '{created_graph.name}' has been saved to your library!",
agent_id=created_graph.id,
@@ -338,7 +324,6 @@ class CreateAgentTool(BaseTool):
library_agent_id=library_agent.id,
library_agent_link=f"/library/agents/{library_agent.id}",
agent_page_link=f"/build?flowID={created_graph.id}",
image_url=image_url,
session_id=session_id,
)
except Exception as e:

View File

@@ -277,7 +277,6 @@ class AgentSavedResponse(ToolResponseBase):
library_agent_id: str
library_agent_link: str
agent_page_link: str # Link to the agent builder/editor page
image_url: str | None = None
class ClarificationNeededResponse(ToolResponseBase):

View File

@@ -1,4 +1,5 @@
import { getV2GetSession } from "@/app/api/__generated__/endpoints/chat/chat";
import { getGetV2GetSessionQueryKey } from "@/app/api/__generated__/endpoints/chat/chat";
import { useQueryClient } from "@tanstack/react-query";
import type { UIDataTypes, UIMessage, UITools } from "ai";
import { useCallback, useEffect, useRef } from "react";
import { convertChatSessionMessagesToUiMessages } from "../helpers/convertChatSessionToUiMessages";
@@ -54,9 +55,6 @@ function safeParse(value: string): unknown {
*
* When the session data shows the tool output has changed (e.g. to
* agent_saved), it calls `setMessages` with the updated messages.
*
* Fetches session data directly (bypassing the shared React Query cache)
* so that polling never triggers the hydration effect in useCopilotPage.
*/
export function useLongRunningToolPolling(
sessionId: string | null,
@@ -67,6 +65,7 @@ export function useLongRunningToolPolling(
) => UIMessage<unknown, UIDataTypes, UITools>[],
) => void,
) {
const queryClient = useQueryClient();
const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);
const stopPolling = useCallback(() => {
@@ -79,34 +78,32 @@ export function useLongRunningToolPolling(
const poll = useCallback(async () => {
if (!sessionId) return;
try {
// Fetch directly instead of refetching the shared session query.
// Using refetchQueries updated the React Query cache which triggered
// the hydration effect in useCopilotPage, potentially overwriting
// useChat's internal message state and breaking subsequent sends.
const response = await getV2GetSession(sessionId);
// Invalidate the query cache so the next fetch gets fresh data
await queryClient.invalidateQueries({
queryKey: getGetV2GetSessionQueryKey(sessionId),
});
if (response.status !== 200) return;
// Fetch fresh session data
const data = queryClient.getQueryData<{
status: number;
data: { messages?: unknown[] };
}>(getGetV2GetSessionQueryKey(sessionId));
const data = response.data as { messages?: unknown[] };
if (!data.messages) return;
if (data?.status !== 200 || !data.data.messages) return;
const freshMessages = convertChatSessionMessagesToUiMessages(
sessionId,
data.messages,
);
const freshMessages = convertChatSessionMessagesToUiMessages(
sessionId,
data.data.messages,
);
if (!freshMessages || freshMessages.length === 0) return;
if (!freshMessages || freshMessages.length === 0) return;
// Update when the long-running tool completed
if (!hasOperatingTool(freshMessages)) {
setMessages(() => freshMessages);
stopPolling();
}
} catch {
// Network error — ignore and retry on next interval
// Update when the long-running tool completed
if (!hasOperatingTool(freshMessages)) {
setMessages(() => freshMessages);
stopPolling();
}
}, [sessionId, setMessages, stopPolling]);
}, [sessionId, queryClient, setMessages, stopPolling]);
useEffect(() => {
const shouldPoll = hasOperatingTool(messages);

View File

@@ -166,14 +166,6 @@ export function CreateAgentTool({ part }: Props) {
{isAgentSavedOutput(output) && (
<div className="rounded-xl border border-border/60 bg-card p-4 shadow-sm">
{output.image_url && (
// eslint-disable-next-line @next/next/no-img-element
<img
src={output.image_url}
alt={output.agent_name}
className="mb-3 h-40 w-full rounded-lg object-cover"
/>
)}
<div className="flex items-baseline gap-2">
<CheckFatIcon
size={18}

View File

@@ -6,10 +6,14 @@ export function MiniGame() {
const { canvasRef } = useMiniGame();
return (
<div className="w-full overflow-hidden rounded-md bg-background text-foreground">
<div
className="w-full overflow-hidden rounded-md bg-background text-foreground"
style={{ border: "1px solid #d17fff" }}
>
<canvas
ref={canvasRef}
className="block w-full"
tabIndex={0}
className="block w-full outline-none"
style={{ imageRendering: "pixelated" }}
/>
</div>

View File

@@ -17,7 +17,7 @@ const GROUND_PAD = 20;
const STORAGE_KEY = "copilot-minigame-highscore";
// Colors
const COLOR_BG = "#E0F2F19C";
const COLOR_BG = "#E8EAF6";
const COLOR_CHAR = "#263238";
const COLOR_BOSS = "#F50057";
@@ -531,6 +531,7 @@ export function useMiniGame() {
}
function onClick() {
canvas?.focus();
jump();
}
@@ -551,7 +552,7 @@ export function useMiniGame() {
rafRef.current = requestAnimationFrame(loop);
canvas.addEventListener("click", onClick);
window.addEventListener("keydown", onKey);
canvas.addEventListener("keydown", onKey);
const observer = new ResizeObserver((entries) => {
for (const entry of entries) {
@@ -569,7 +570,7 @@ export function useMiniGame() {
return () => {
cancelAnimationFrame(rafRef.current);
canvas.removeEventListener("click", onClick);
window.removeEventListener("keydown", onKey);
canvas.removeEventListener("keydown", onKey);
observer.disconnect();
};
}, []);

View File

@@ -6642,11 +6642,7 @@
"type": "string",
"title": "Library Agent Link"
},
"agent_page_link": { "type": "string", "title": "Agent Page Link" },
"image_url": {
"anyOf": [{ "type": "string" }, { "type": "null" }],
"title": "Image Url"
}
"agent_page_link": { "type": "string", "title": "Agent Page Link" }
},
"type": "object",
"required": [