diff --git a/components/canvas/CanvasChatPanel.tsx b/components/canvas/CanvasChatPanel.tsx
index 71d3d8b5e..a475ab9bb 100644
--- a/components/canvas/CanvasChatPanel.tsx
+++ b/components/canvas/CanvasChatPanel.tsx
@@ -1437,6 +1437,34 @@ function buildPreviewImageUrl(url: string, width: number): string {
});
}
+function ModelAvatarImage({
+ src,
+ alt,
+ className,
+ fallback,
+}: {
+ src: string;
+ alt: string;
+ className: string;
+ fallback: JSX.Element;
+}) {
+ const [loadFailed, setLoadFailed] = useState(false);
+ if (!src || loadFailed) {
+ return fallback;
+ }
+
+ return (
+
setLoadFailed(true)}
+ />
+ );
+}
+
const CANVAS_IMAGE_ANALYSIS_TITLE = "图片分析";
const CANVAS_IMAGE_DONE_SUMMARY = "已完成本次生成,如需微调可继续告诉我。";
const CANVAS_AGENT_SECTION_TITLES = new Set([
@@ -15115,17 +15143,22 @@ export function CanvasChatPanel({
)}
>
{model.avatarUrl ? (
-
{
- if (event.currentTarget.src !== model.avatarUrl) {
- event.currentTarget.src = model.avatarUrl || "";
- }
- }}
+ fallback={
+
+ {model.id === "auto" ? "A" : model.displayName.slice(0, 1)}
+
+ }
/>
) : (
{selectDisplayModel?.avatarUrl ? (
-
{
- if (event.currentTarget.src !== selectDisplayModel.avatarUrl) {
- event.currentTarget.src = selectDisplayModel.avatarUrl || "";
- }
- }}
+ fallback={
+
+ {(selectDisplayModel?.displayName || "A").slice(0, 1)}
+
+ }
/>
) : getToolbarItem("chatModelSelector").iconUrl ? (
(false);
+
+ if (!src || loadFailed) {
+ return fallback;
+ }
+
+ return (
+
setLoadFailed(true)}
+ />
+ );
+}
+
import { Trigger } from "@radix-ui/react-select";
import type { UIMessage } from "ai";
import equal from "fast-deep-equal";
@@ -2132,10 +2162,11 @@ function PureModelSelectorCompact({
title={readOnlyName}
>
{readOnlyAvatarUrl ? (
-
}
/>
) : (
@@ -2189,10 +2220,11 @@ function PureModelSelectorCompact({
variant="ghost"
>
{selectedModel?.avatarUrl ? (
-
}
/>
) : (
@@ -2227,10 +2259,26 @@ function PureModelSelectorCompact({
{model.avatarUrl ? (
-
+ {(() => {
+ if (isVideoProviderType(model)) {
+ return ;
+ }
+ if (isImageGenerationModel(model)) {
+ return ;
+ }
+ if ((model.providerType || "") === "system") {
+ return ;
+ }
+ return ;
+ })()}
+
+ }
/>
) : (
diff --git a/proxy.ts b/proxy.ts
index ab17ebb98..777dcba96 100644
--- a/proxy.ts
+++ b/proxy.ts
@@ -778,6 +778,11 @@ export async function proxy(request: NextRequest, event: NextFetchEvent) {
return NextResponse.next();
}
+ // 图片代理用于站内图片优化/转码,需支持未登录用户下的公开图片链接渲染。
+ if (pathname === "/api/image-proxy" && request.method === "GET") {
+ return NextResponse.next();
+ }
+
// 允许匿名访问新版首页灵感数据
if (pathname === "/api/featured" || pathname.startsWith("/api/featured/")) {
return NextResponse.next();