
بوابة مفتوحة المصدر تؤمّن وتحكم وتراقب استدعاءات أدوات MCP الخاصة بوكلاء الذكاء الاصطناعي وحركة مرور LLM، مع مصادقة بمفتاح API ولوحة تحكم إدارية للمراقبة.
لوحة تحكم لبوابة وكيل الذكاء الاصطناعي Tuskira. React 19 + Vite + TypeScript (صارم) + Tailwind CSS 4 + shadcn/ui.
يتطلب Node 26+ وnpm 11+ (بدون pnpm).
npm install
npm run dev
يعمل خادم التطوير على تمرير الطلبات من /api إلى http://localhost:8081 (انظر vite.config.ts)، لذا
شغّل البوابة على المنفذ :8081 إلى جانب واجهة المستخدم. سجّل الدخول عند /login باستخدام مفتاح API
(gk_…) صادر عن البوابة.
من جذر المستودع يمكنك بدلاً من ذلك تشغيل:
make ui-install
make ui-dev
npm run build
يُصدر حزمة إنتاج إلى dist/. في بيئة الإنتاج، تخدم البوابة نفسها هذه الحزمة على المسار / عبر المنفذ :8081، لذا يتواصل التطبيق مع واجهة API من نفس الأصل — دون الحاجة إلى وكيل.
make ui-build # from the repo root
وحدة التحكم مُحزَّمة أيضًا باسم @tuskira/gateway-web، لذا يمكنك تركيب صفحاتها
داخل تطبيق React الخاص بك. الحزمة ليست على سجل npm. كل إصدار من GitHub
يحملها كملف tarball، ونسختها تطابق دائمًا وسم إصدار البوابة. تُعد React
وReact DOM وReact Router (react-router-dom 7) وTanStack Query 5 تبعيات نظيرة؛
وكل ما عدا ذلك يُثبَّت مع الحزمة.
npm install https://github.com/Tuskira/ai-agent-gateway/releases/download/v<version>/tuskira-gateway-web-<version>.tgz \
react react-dom react-router-dom @tanstack/react-query
npm يسجّل تجزئة سلامة tarball في package-lock.json.
import {
AppShell, AuthProvider, RequireAuth, LoginPage, Toaster, TooltipProvider,
configureGateway, gatewayPageRoutes,
} from '@tuskira/gateway-web'
import '@tuskira/gateway-web/style.css' // Tailwind output + design tokens
import '@tuskira/gateway-web/fonts.css' // optional: self-hosted Inter / JetBrains Mono
configureGateway({
apiBase: '/gw/api/v1', // default '/api/v1'
mcpBase: 'https://gw.example.com/mcp', // default: guessed from the page origin
onUnauthenticated: () => router.navigate('/login'), // default: window.location.assign('/login')
})
const router = createBrowserRouter(
[
{ path: '/login', element: <LoginPage /> },
{ element: <RequireAuth />, children: [{ element: <AppShell />, children: gatewayPageRoutes() }] },
],
{ basename: '/gateway' },
)
ضع الراوتر داخل QueryClientProvider وAuthProvider وTooltipProvider، واعرض
<Toaster /> مرة واحدة، كما يفعل src/App.tsx. تُرجع gatewayRoutes() الشجرة الكاملة
(تسجيل الدخول، والمستندات، وتغيير كلمة المرور، والصدفة، وإعادة التوجيه الشاملة) إذا أردت أن تمتلك
لوحة التحكم الراوتر بأكمله. لا يُدعم سوى ما تصدّره @tuskira/gateway-web؛ لا تستورد من src/.
مرّر extension لوضع مجموعات الشريط الجانبي وصفحاتك الخاصة داخل صدفة لوحة التحكم و
حارس تسجيل الدخول:
gatewayRoutes({ extension: { navGroups: [...], routes: [...] } })
import { Plug } from 'lucide-react'
import { AppShell, gatewayPageRoutes, type ConsoleExtension } from '@tuskira/gateway-web'
const extension: ConsoleExtension = {
navGroups: [
// New group, placed before the core "Observe" group (appended without `before`).
{ label: 'Billing', before: 'Observe', items: [
{ label: 'Invoices', path: '/invoices', icon: Plug, description: 'Invoices and usage.' },
] },
// Same label as a core group: the items are added to that group.
{ label: 'Access', items: [
{ label: 'Audit', path: '/audit', icon: Plug, description: 'Audit trail.' },
] },
],
routes: [
{ path: '/invoices', Component: InvoicesPage },
{ path: '/audit', Component: AuditPage },
],
}
// Own router: pass the extension to both the routes and the shell.
{ element: <AppShell extension={extension} />, children: gatewayPageRoutes(extension) }
gatewayRoutes({ extension }) يفعل الاثنين نيابةً عنك. عنصر تنقّل ليس لمساره أي مسار يعرض
عنصر نائب "قريبًا". اضبط end: true على عنصر يكون مساره بادئة لمسارات عناصر أخرى
حتى يكون نشطًا على مساره الخاص فقط.
يجب أن يصل المتصفح إلى واجهة برمجة تطبيقات البوابة على المسار الذي تضبطه كـ apiBase. عندما يقدّم
التطبيق المضيف وحدة التحكم، أضف قاعدة وكيل عكسي تعيد توجيه /api/v1/* (أو مسار apiBase
الخاص بك، معاد كتابته إلى /api/v1) إلى البوابة على المنفذ 8081. حافظ على المسار، وجميع ترويسات الطلب
والاستجابة (Authorization، X-CSRF-Token، X-Gateway-Acting-Tenant) و
ملفات تعريف الارتباط دون تغيير، وإلا ستفشل عمليات تسجيل الدخول وفحوصات CSRF.
ابنِ الحزمة باستخدام npm run build:lib، الذي يكتب dist-lib/ (index.js، types/،
style.css، fonts.css). ثم ينتج npm pack ملف tarball؛ ويرفقه سير عمل الإصدار بـ GitHub release عند كل وسم v*.
npm run lint # eslint
npm run typecheck # tsc --noEmit (project references)
npm run test # vitest
npm run format:check # prettier --check
npx shadcn@latest add <component>
يستهدف ملف components.json في هذا المشروع قالب Vite، وأساس radix، ولون
الأساس neutral، ومتغيرات CSS للتنسيق، مع توجيه الاسم المستعار للاستيراد @/*
إلى src/*. تُكتب المكوّنات الجديدة في src/components/ui/.
ملف tokens.json (في جذر المستودع) هو المصدر الوحيد للحقيقة لنظام التصميم —
الألوان، والتباعد، وأنصاف الأقطار، والظلال، والخطوط. شغّل npm run gen:tokens بعد
تعديله لإعادة التوليد:
src/styles/tokens.css — الرموز الخام كخصائص CSS مخصصة (:root للقيم
الفاتحة، و.dark للتجاوزات الداكنة)، مع الحفاظ على أسماء الرموز الخاصة
بالمصمم (--indigo-9، --sev-high، --r-4، --shadow-1، ...).src/styles/tokens.ts — نفس مقاييس الألوان الفئوية (colors.indigo،
colors.slate، colors.sev، colors.status، colors.brand) بالإضافة إلى fonts
وradii وshadows، للمستهلكين غير الخاصين بـ CSS (مثل ألوان سلاسل recharts).يربط src/index.css المتغيرات الدلالية الخاصة بـ shadcn (--background، --primary،
--sidebar، ...) بهذه الرموز، ويسجّل مدخلات @theme الخاصة بـ Tailwind v4 بحيث
تكون الأدوات المساعدة مثل bg-indigo-9 وtext-text-muted وborder-border-strong وshadow-1
وrounded-r-4 وfont-mono متاحة في أي مكان في التطبيق. لا تُعدّل يدويًا
src/styles/tokens.css / src/styles/tokens.ts — إذ يستبدلها
المولّد. يؤكد src/test/tokens.test.ts أن لكل مدخل في tokens.ts إعلانًا مطابقًا
في tokens.css.