feat(frontend): 手工合并 layout、脚本与上传接口
This commit is contained in:
parent
e6183e84fc
commit
c67dad6db5
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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={{
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue