mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-04 13:22:41 +02:00
feat(story-3.5): add cloud-mode LLM model selection with token quota enforcement
Implement system-managed model catalog, subscription tier enforcement, atomic token quota tracking, and frontend cloud/self-hosted conditional rendering. Apply all 20 BMAD code review patches including security fixes (cross-user API key hijack), race condition mitigation (atomic SQL UPDATE), and SSE mid-stream quota error handling. Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
This commit is contained in:
parent
e7382b26de
commit
c1776b3ec8
19 changed files with 1003 additions and 34 deletions
|
|
@ -1,6 +1,8 @@
|
|||
"use client";
|
||||
|
||||
import { useCallback, useState } from "react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useSetAtom } from "jotai";
|
||||
import { selectedSystemModelIdAtom } from "@/atoms/new-llm-config/system-models-query.atoms";
|
||||
import { ImageConfigDialog } from "@/components/shared/image-config-dialog";
|
||||
import { ModelConfigDialog } from "@/components/shared/model-config-dialog";
|
||||
import { VisionConfigDialog } from "@/components/shared/vision-config-dialog";
|
||||
|
|
@ -12,7 +14,9 @@ import type {
|
|||
NewLLMConfigPublic,
|
||||
VisionLLMConfig,
|
||||
} from "@/contracts/types/new-llm-config.types";
|
||||
import { isCloud } from "@/lib/env-config";
|
||||
import { ModelSelector } from "./model-selector";
|
||||
import { SystemModelSelector } from "./system-model-selector";
|
||||
|
||||
interface ChatHeaderProps {
|
||||
searchSpaceId: number;
|
||||
|
|
@ -20,6 +24,12 @@ interface ChatHeaderProps {
|
|||
}
|
||||
|
||||
export function ChatHeader({ searchSpaceId, className }: ChatHeaderProps) {
|
||||
// Reset system model selection when search space changes
|
||||
const setSelectedSystemModelId = useSetAtom(selectedSystemModelIdAtom);
|
||||
useEffect(() => {
|
||||
setSelectedSystemModelId(null);
|
||||
}, [searchSpaceId, setSelectedSystemModelId]);
|
||||
|
||||
// LLM config dialog state
|
||||
const [dialogOpen, setDialogOpen] = useState(false);
|
||||
const [selectedConfig, setSelectedConfig] = useState<
|
||||
|
|
@ -115,15 +125,19 @@ export function ChatHeader({ searchSpaceId, className }: ChatHeaderProps) {
|
|||
|
||||
return (
|
||||
<div className="flex items-center gap-2">
|
||||
<ModelSelector
|
||||
onEditLLM={handleEditLLMConfig}
|
||||
onAddNewLLM={handleAddNewLLM}
|
||||
onEditImage={handleEditImageConfig}
|
||||
onAddNewImage={handleAddImageModel}
|
||||
onEditVision={handleEditVisionConfig}
|
||||
onAddNewVision={handleAddVisionModel}
|
||||
className={className}
|
||||
/>
|
||||
{isCloud() ? (
|
||||
<SystemModelSelector className={className} />
|
||||
) : (
|
||||
<ModelSelector
|
||||
onEditLLM={handleEditLLMConfig}
|
||||
onAddNewLLM={handleAddNewLLM}
|
||||
onEditImage={handleEditImageConfig}
|
||||
onAddNewImage={handleAddImageModel}
|
||||
onEditVision={handleEditVisionConfig}
|
||||
onAddNewVision={handleAddVisionModel}
|
||||
className={className}
|
||||
/>
|
||||
)}
|
||||
<ModelConfigDialog
|
||||
open={dialogOpen}
|
||||
onOpenChange={handleDialogClose}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue