feat(frontend): 手工合并 layout、脚本与上传接口

This commit is contained in:
肖应宇 2026-03-28 22:49:47 +08:00
parent e6183e84fc
commit c67dad6db5
4 changed files with 22 additions and 22 deletions

View File

@ -6,10 +6,11 @@
"scripts": { "scripts": {
"demo:save": "node scripts/save-demo.js", "demo:save": "node scripts/save-demo.js",
"build": "next build", "build": "next build",
"check": "next lint && tsc --noEmit", "check": "eslint . --ext .ts,.tsx && tsc --noEmit",
"dev": "next dev --turbo", "dev": "next dev --turbo",
"format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md}\"", "format": "prettier --write \"src/**/*.{ts,tsx,js,jsx,json,css,md}\"",
"format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,css,md}\"", "format:check": "prettier --check \"src/**/*.{ts,tsx,js,jsx,json,css,md}\"",
"format:write": "prettier --write .",
"lint": "eslint . --ext .ts,.tsx", "lint": "eslint . --ext .ts,.tsx",
"lint:fix": "eslint . --ext .ts,.tsx --fix", "lint:fix": "eslint . --ext .ts,.tsx --fix",
"preview": "next build && next start", "preview": "next build && next start",
@ -70,7 +71,7 @@
"marked": "^17.0.5", "marked": "^17.0.5",
"motion": "^12.26.2", "motion": "^12.26.2",
"nanoid": "^5.1.6", "nanoid": "^5.1.6",
"next": "^16.1.4", "next": "^16.1.7",
"next-themes": "^0.4.6", "next-themes": "^0.4.6",
"nuxt-og-image": "^5.1.13", "nuxt-og-image": "^5.1.13",
"ogl": "^1.0.11", "ogl": "^1.0.11",

View File

@ -2,7 +2,6 @@ import "@/styles/globals.css";
import "katex/dist/katex.min.css"; import "katex/dist/katex.min.css";
import { type Metadata } from "next"; import { type Metadata } from "next";
import { Geist } from "next/font/google";
import { ThemeProvider } from "@/components/theme-provider"; import { ThemeProvider } from "@/components/theme-provider";
import { I18nProvider } from "@/core/i18n/context"; import { I18nProvider } from "@/core/i18n/context";
@ -13,22 +12,12 @@ export const metadata: Metadata = {
description: "A LangChain-based framework for building super agents.", description: "A LangChain-based framework for building super agents.",
}; };
const geist = Geist({
subsets: ["latin"],
variable: "--font-geist-sans",
});
export default async function RootLayout({ export default async function RootLayout({
children, children,
}: Readonly<{ children: React.ReactNode }>) { }: Readonly<{ children: React.ReactNode }>) {
const locale = await detectLocaleServer(); const locale = await detectLocaleServer();
return ( return (
<html <html lang={locale} suppressContentEditableWarning suppressHydrationWarning>
lang={locale}
className={geist.variable + ""}
suppressContentEditableWarning
suppressHydrationWarning
>
<body> <body>
<ThemeProvider attribute="class" enableSystem disableTransitionOnChange> <ThemeProvider attribute="class" enableSystem disableTransitionOnChange>
<I18nProvider initialLocale={locale}>{children}</I18nProvider> <I18nProvider initialLocale={locale}>{children}</I18nProvider>

View File

@ -6,6 +6,7 @@ import { useCallback, useEffect, useLayoutEffect, useState } from "react";
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar"; import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
import { Toaster } from "@/components/ui/sonner"; import { Toaster } from "@/components/ui/sonner";
import { CommandPalette } from "@/components/workspace/command-palette";
import { WorkspaceSidebar } from "@/components/workspace/workspace-sidebar"; import { WorkspaceSidebar } from "@/components/workspace/workspace-sidebar";
import { getLocalSettings, useLocalSettings } from "@/core/settings"; import { getLocalSettings, useLocalSettings } from "@/core/settings";
@ -42,10 +43,10 @@ export default function WorkspaceLayout({
open={open} open={open}
onOpenChange={handleOpenChange} onOpenChange={handleOpenChange}
> >
{/* MARK: 生产环境下必须注释才能提交!!!! */} {!isSkillMode && <WorkspaceSidebar className="" />}
{/* {!isSkillMode && <WorkspaceSidebar className="" />} */}
<SidebarInset className="min-w-0">{children}</SidebarInset> <SidebarInset className="min-w-0">{children}</SidebarInset>
</SidebarProvider> </SidebarProvider>
<CommandPalette />
<Toaster <Toaster
position="top-center" position="top-center"
toastOptions={{ toastOptions={{

View File

@ -31,6 +31,16 @@ export interface ListFilesResponse {
export type UploadTarget = "skill"; export type UploadTarget = "skill";
async function readErrorDetail(
response: Response,
fallback: string,
): Promise<string> {
const error = await response
.json()
.catch(() => ({ detail: fallback }));
return error.detail ?? fallback;
}
/** /**
* Upload files to a thread * Upload files to a thread
*/ */
@ -58,10 +68,7 @@ export async function uploadFiles(
); );
if (!response.ok) { if (!response.ok) {
const error = await response throw new Error(await readErrorDetail(response, "Upload failed"));
.json()
.catch(() => ({ detail: "Upload failed" }));
throw new Error(error.detail ?? "Upload failed");
} }
return response.json(); return response.json();
@ -78,7 +85,9 @@ export async function listUploadedFiles(
); );
if (!response.ok) { if (!response.ok) {
throw new Error("Failed to list uploaded files"); throw new Error(
await readErrorDetail(response, "Failed to list uploaded files"),
);
} }
return response.json(); return response.json();
@ -99,7 +108,7 @@ export async function deleteUploadedFile(
); );
if (!response.ok) { if (!response.ok) {
throw new Error("Failed to delete file"); throw new Error(await readErrorDetail(response, "Failed to delete file"));
} }
return response.json(); return response.json();