diff --git a/aha-ui/README.md b/aha-ui/README.md index 102e366..fefbccf 100644 --- a/aha-ui/README.md +++ b/aha-ui/README.md @@ -5,3 +5,8 @@ This template should help get you started developing with Tauri, React and Types ## Recommended IDE Setup - [VS Code](https://code.visualstudio.com/) + [Tauri](https://marketplace.visualstudio.com/items?itemName=tauri-apps.tauri-vscode) + [rust-analyzer](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer) + + + +ui 使用shadcn-admin ,基本上是直接粘贴过来的, +这个项目只有两个 \ No newline at end of file diff --git a/aha-ui/src/components/layout/data/sidebar-data.ts b/aha-ui/src/components/layout/data/sidebar-data.ts index f60021d..e99bcfc 100644 --- a/aha-ui/src/components/layout/data/sidebar-data.ts +++ b/aha-ui/src/components/layout/data/sidebar-data.ts @@ -1,6 +1,7 @@ import { Package, Play, + BookOpen, Settings, UserCog, Wrench, @@ -37,6 +38,11 @@ export const sidebarData: SidebarData = { url: '/launch', icon: Play, }, + { + title: '使用指南', + url: '/usage', + icon: BookOpen, + }, ], }, { diff --git a/aha-ui/src/features/usage/index.tsx b/aha-ui/src/features/usage/index.tsx new file mode 100644 index 0000000..7bf8aa9 --- /dev/null +++ b/aha-ui/src/features/usage/index.tsx @@ -0,0 +1,429 @@ +import { useState } from "react" +import { BookOpen, Copy, Check, Code, Terminal, FileType } from "lucide-react" +import { Card } from "@/components/ui/card" +import { Input } from "@/components/ui/input" +import { Label } from "@/components/ui/label" +import { Header } from "@/components/layout/header" +import { Main } from "@/components/layout/main" +import { ProfileDropdown } from "@/components/profile-dropdown" +import { ThemeSwitch } from "@/components/theme-switch" + +interface CodeBlockProps { + code: string + language?: string +} + +function CodeBlock({ code, language = "bash" }: CodeBlockProps) { + const [copied, setCopied] = useState(false) + + const handleCopy = async () => { + await navigator.clipboard.writeText(code) + setCopied(true) + setTimeout(() => setCopied(false), 2000) + } + + const langIcons: Record = { + bash: , + python: , + typescript: , + } + + return ( +
+
+
+ {langIcons[language] || null} + {language} +
+ +
+
+        {code}
+      
+
+ ) +} + +function ApiSection({ + title, + method, + path, + description, + children, +}: { + title: string + method: string + path: string + description: string + children: React.ReactNode +}) { + const methodColors: Record = { + GET: "bg-green-500/10 text-green-600 border-green-200 dark:border-green-800 dark:text-green-400", + POST: "bg-blue-500/10 text-blue-600 border-blue-200 dark:border-blue-800 dark:text-blue-400", + } + + return ( +
+

{title}

+

{description}

+
+ + {method} + + {path} +
+ {children} +
+ ) +} + +export function UsagePage() { + const [baseUrl, setBaseUrl] = useState("http://127.0.0.1:10100") + + return ( + <> +
+
+ + +
+
+ +
+
+

+ + API 使用指南 +

+

+ 如何通过 HTTP 接口调用本地模型推理服务 +

+
+ + {/* 服务地址配置 */} + +
+
+ + setBaseUrl(e.target.value)} + placeholder="http://127.0.0.1:10100" + /> +
+

+ 请确保服务已启动,地址与「启动服务」页面配置一致 +

+
+
+ +
+ {/* 1. 查看可用模型 */} + + +
+ + + +
+
+
+ + {/* 2. Chat Completions */} + + +
+ + + +
+ +
+

请求参数说明

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
参数类型说明
modelstring模型 ID
messagesarray对话消息列表
temperaturenumber采样温度 (0~2),默认 1.0
max_tokensnumber最大生成 token 数
streamboolean是否流式输出,默认 false
+
+
+
+ + {/* 3. 流式输出 */} + + +
+ + + +
+
+
+ + {/* 4. 使用 OpenAI SDK */} + +

使用 OpenAI SDK 调用

+

+ 由于服务兼容 OpenAI API 格式,你可以直接使用 OpenAI 官方 SDK,只需修改 base URL 即可。 +

+
+ + +
+
+ + {/* 5. 健康检查 */} + + + + + +
+
+ + ) +} diff --git a/aha-ui/src/routeTree.gen.ts b/aha-ui/src/routeTree.gen.ts index f9472c0..41674f7 100644 --- a/aha-ui/src/routeTree.gen.ts +++ b/aha-ui/src/routeTree.gen.ts @@ -11,6 +11,7 @@ import { Route as rootRouteImport } from './routes/__root' import { Route as AuthenticatedRouteRouteImport } from './routes/_authenticated/route' import { Route as AuthenticatedIndexRouteImport } from './routes/_authenticated/index' +import { Route as AuthenticatedUsageRouteImport } from './routes/_authenticated/usage' import { Route as AuthenticatedLaunchRouteImport } from './routes/_authenticated/launch' import { Route as errors503RouteImport } from './routes/(errors)/503' import { Route as errors500RouteImport } from './routes/(errors)/500' @@ -38,6 +39,11 @@ const AuthenticatedIndexRoute = AuthenticatedIndexRouteImport.update({ path: '/', getParentRoute: () => AuthenticatedRouteRoute, } as any) +const AuthenticatedUsageRoute = AuthenticatedUsageRouteImport.update({ + id: '/usage', + path: '/usage', + getParentRoute: () => AuthenticatedRouteRoute, +} as any) const AuthenticatedLaunchRoute = AuthenticatedLaunchRouteImport.update({ id: '/launch', path: '/launch', @@ -144,6 +150,7 @@ export interface FileRoutesByFullPath { '/500': typeof errors500Route '/503': typeof errors503Route '/launch': typeof AuthenticatedLaunchRoute + '/usage': typeof AuthenticatedUsageRoute '/settings/account': typeof AuthenticatedSettingsAccountRoute '/settings/appearance': typeof AuthenticatedSettingsAppearanceRoute '/settings/display': typeof AuthenticatedSettingsDisplayRoute @@ -162,6 +169,7 @@ export interface FileRoutesByTo { '/500': typeof errors500Route '/503': typeof errors503Route '/launch': typeof AuthenticatedLaunchRoute + '/usage': typeof AuthenticatedUsageRoute '/': typeof AuthenticatedIndexRoute '/settings/account': typeof AuthenticatedSettingsAccountRoute '/settings/appearance': typeof AuthenticatedSettingsAppearanceRoute @@ -184,6 +192,7 @@ export interface FileRoutesById { '/(errors)/500': typeof errors500Route '/(errors)/503': typeof errors503Route '/_authenticated/launch': typeof AuthenticatedLaunchRoute + '/_authenticated/usage': typeof AuthenticatedUsageRoute '/_authenticated/': typeof AuthenticatedIndexRoute '/_authenticated/settings/account': typeof AuthenticatedSettingsAccountRoute '/_authenticated/settings/appearance': typeof AuthenticatedSettingsAppearanceRoute @@ -207,6 +216,7 @@ export interface FileRouteTypes { | '/500' | '/503' | '/launch' + | '/usage' | '/settings/account' | '/settings/appearance' | '/settings/display' @@ -225,6 +235,7 @@ export interface FileRouteTypes { | '/500' | '/503' | '/launch' + | '/usage' | '/' | '/settings/account' | '/settings/appearance' @@ -246,6 +257,7 @@ export interface FileRouteTypes { | '/(errors)/500' | '/(errors)/503' | '/_authenticated/launch' + | '/_authenticated/usage' | '/_authenticated/' | '/_authenticated/settings/account' | '/_authenticated/settings/appearance' @@ -284,6 +296,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof AuthenticatedIndexRouteImport parentRoute: typeof AuthenticatedRouteRoute } + '/_authenticated/usage': { + id: '/_authenticated/usage' + path: '/usage' + fullPath: '/usage' + preLoaderRoute: typeof AuthenticatedUsageRouteImport + parentRoute: typeof AuthenticatedRouteRoute + } '/_authenticated/launch': { id: '/_authenticated/launch' path: '/launch' @@ -432,12 +451,14 @@ const AuthenticatedSettingsRouteRouteWithChildren = interface AuthenticatedRouteRouteChildren { AuthenticatedSettingsRouteRoute: typeof AuthenticatedSettingsRouteRouteWithChildren AuthenticatedLaunchRoute: typeof AuthenticatedLaunchRoute + AuthenticatedUsageRoute: typeof AuthenticatedUsageRoute AuthenticatedIndexRoute: typeof AuthenticatedIndexRoute } const AuthenticatedRouteRouteChildren: AuthenticatedRouteRouteChildren = { AuthenticatedSettingsRouteRoute: AuthenticatedSettingsRouteRouteWithChildren, AuthenticatedLaunchRoute: AuthenticatedLaunchRoute, + AuthenticatedUsageRoute: AuthenticatedUsageRoute, AuthenticatedIndexRoute: AuthenticatedIndexRoute, } diff --git a/aha-ui/src/routes/_authenticated/usage.tsx b/aha-ui/src/routes/_authenticated/usage.tsx new file mode 100644 index 0000000..66907c7 --- /dev/null +++ b/aha-ui/src/routes/_authenticated/usage.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from '@tanstack/react-router' +import { UsagePage } from '@/features/usage' + +export const Route = createFileRoute('/_authenticated/usage')({ + component: UsagePage, +})