mirror of
https://github.com/StanGirard/quivr.git
synced 2024-12-24 11:52:45 +03:00
feat: allow updating api brain definition (#1682)
Issue: https://github.com/StanGirard/quivr/issues/1683 Demo: https://github.com/StanGirard/quivr/assets/63923024/67cf2a0f-4cfe-420c-9181-baffaa584c78 https://github.com/StanGirard/quivr/assets/63923024/eee57598-1520-4c11-bd64-887869878f46
This commit is contained in:
parent
1a4c6c8741
commit
d9a72b368a
@ -54,6 +54,19 @@ class ApiBrainDefinitions(Repository):
|
|||||||
return None
|
return None
|
||||||
return ApiBrainDefinition(**response.data[0])
|
return ApiBrainDefinition(**response.data[0])
|
||||||
|
|
||||||
|
def update_api_brain_definition(
|
||||||
|
self, brain_id: UUID, api_brain_definition: ApiBrainDefinition
|
||||||
|
) -> Optional[ApiBrainDefinition]:
|
||||||
|
response = (
|
||||||
|
self.db.table("api_brain_definition")
|
||||||
|
.update(api_brain_definition.dict(exclude={"brain_id"}))
|
||||||
|
.filter("brain_id", "eq", str(brain_id))
|
||||||
|
.execute()
|
||||||
|
)
|
||||||
|
if len(response.data) == 0:
|
||||||
|
return None
|
||||||
|
return ApiBrainDefinition(**response.data[0])
|
||||||
|
|
||||||
def delete_api_brain_definition(self, brain_id: UUID) -> None:
|
def delete_api_brain_definition(self, brain_id: UUID) -> None:
|
||||||
self.db.table("api_brain_definition").delete().filter(
|
self.db.table("api_brain_definition").delete().filter(
|
||||||
"brain_id", "eq", str(brain_id)
|
"brain_id", "eq", str(brain_id)
|
||||||
|
@ -2,6 +2,7 @@ from typing import Optional
|
|||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
from logger import get_logger
|
from logger import get_logger
|
||||||
|
from models.ApiBrainDefinition import ApiBrainDefinition
|
||||||
from models.brain_entity import (
|
from models.brain_entity import (
|
||||||
BrainEntity,
|
BrainEntity,
|
||||||
BrainType,
|
BrainType,
|
||||||
@ -45,6 +46,7 @@ class BrainUpdatableProperties(BaseModel):
|
|||||||
max_tokens: Optional[int]
|
max_tokens: Optional[int]
|
||||||
status: Optional[str]
|
status: Optional[str]
|
||||||
prompt_id: Optional[UUID]
|
prompt_id: Optional[UUID]
|
||||||
|
brain_definition: Optional[ApiBrainDefinition]
|
||||||
|
|
||||||
def dict(self, *args, **kwargs):
|
def dict(self, *args, **kwargs):
|
||||||
brain_dict = super().dict(*args, **kwargs)
|
brain_dict = super().dict(*args, **kwargs)
|
||||||
|
@ -0,0 +1,13 @@
|
|||||||
|
from typing import Optional
|
||||||
|
from uuid import UUID
|
||||||
|
|
||||||
|
from models.ApiBrainDefinition import ApiBrainDefinition
|
||||||
|
from models.settings import get_supabase_db
|
||||||
|
|
||||||
|
|
||||||
|
def update_api_brain_definition(
|
||||||
|
brain_id: UUID, api_brain_definition: ApiBrainDefinition
|
||||||
|
) -> Optional[ApiBrainDefinition]:
|
||||||
|
supabase_db = get_supabase_db()
|
||||||
|
|
||||||
|
return supabase_db.update_api_brain_definition(brain_id, api_brain_definition)
|
@ -8,7 +8,7 @@ from repository.api_brain_definition.delete_api_brain_definition import (
|
|||||||
delete_api_brain_definition,
|
delete_api_brain_definition,
|
||||||
)
|
)
|
||||||
from repository.brain import get_brain_by_id
|
from repository.brain import get_brain_by_id
|
||||||
from repository.brain.delete_brain_secrets import delete_brain_secrets
|
from repository.brain.delete_brain_secrets import delete_brain_secrets_values
|
||||||
from repository.knowledge.remove_brain_all_knowledge import (
|
from repository.knowledge.remove_brain_all_knowledge import (
|
||||||
remove_brain_all_knowledge,
|
remove_brain_all_knowledge,
|
||||||
)
|
)
|
||||||
@ -22,7 +22,7 @@ def delete_brain(brain_id: UUID) -> dict[str, str]:
|
|||||||
raise HTTPException(status_code=404, detail="Brain not found.")
|
raise HTTPException(status_code=404, detail="Brain not found.")
|
||||||
|
|
||||||
if brain_to_delete.brain_type == BrainType.API:
|
if brain_to_delete.brain_type == BrainType.API:
|
||||||
delete_brain_secrets(
|
delete_brain_secrets_values(
|
||||||
brain_id=brain_id,
|
brain_id=brain_id,
|
||||||
)
|
)
|
||||||
delete_api_brain_definition(brain_id=brain_id)
|
delete_api_brain_definition(brain_id=brain_id)
|
||||||
|
@ -9,7 +9,7 @@ from repository.api_brain_definition.get_api_brain_definition import (
|
|||||||
from repository.external_api_secret import delete_secret
|
from repository.external_api_secret import delete_secret
|
||||||
|
|
||||||
|
|
||||||
def delete_brain_secrets(brain_id: UUID) -> None:
|
def delete_brain_secrets_values(brain_id: UUID) -> None:
|
||||||
supabase_db = get_supabase_db()
|
supabase_db = get_supabase_db()
|
||||||
|
|
||||||
brain_definition = get_api_brain_definition(brain_id=brain_id)
|
brain_definition = get_api_brain_definition(brain_id=brain_id)
|
||||||
|
@ -1,18 +1,77 @@
|
|||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
|
from fastapi import HTTPException
|
||||||
from models import BrainEntity, get_supabase_db
|
from models import BrainEntity, get_supabase_db
|
||||||
|
from models.brain_entity import BrainType
|
||||||
from models.databases.supabase.brains import BrainUpdatableProperties
|
from models.databases.supabase.brains import BrainUpdatableProperties
|
||||||
|
|
||||||
|
from repository.api_brain_definition.update_api_brain_definition import (
|
||||||
|
update_api_brain_definition,
|
||||||
|
)
|
||||||
|
from repository.brain.delete_brain_secrets import delete_brain_secrets_values
|
||||||
from repository.brain.update_brain_last_update_time import update_brain_last_update_time
|
from repository.brain.update_brain_last_update_time import update_brain_last_update_time
|
||||||
|
|
||||||
|
|
||||||
def update_brain_by_id(brain_id: UUID, brain: BrainUpdatableProperties) -> BrainEntity:
|
def update_brain_by_id(
|
||||||
|
brain_id: UUID, brain_new_values: BrainUpdatableProperties
|
||||||
|
) -> BrainEntity:
|
||||||
"""Update a prompt by id"""
|
"""Update a prompt by id"""
|
||||||
supabase_db = get_supabase_db()
|
supabase_db = get_supabase_db()
|
||||||
|
|
||||||
brain_update_answer = supabase_db.update_brain_by_id(brain_id, brain)
|
existing_brain = supabase_db.get_brain_by_id(brain_id)
|
||||||
|
|
||||||
|
if existing_brain is None:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail=f"Brain with id {brain_id} not found",
|
||||||
|
)
|
||||||
|
|
||||||
|
brain_update_answer = supabase_db.update_brain_by_id(
|
||||||
|
brain_id,
|
||||||
|
brain=BrainUpdatableProperties(
|
||||||
|
**brain_new_values.dict(exclude={"brain_definition"})
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
if brain_update_answer is None:
|
if brain_update_answer is None:
|
||||||
raise Exception("Brain not found")
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail=f"Brain with id {brain_id} not found",
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
brain_update_answer.brain_type == BrainType.API
|
||||||
|
and brain_new_values.brain_definition
|
||||||
|
):
|
||||||
|
existing_brain_secrets_definition = (
|
||||||
|
existing_brain.brain_definition.secrets
|
||||||
|
if existing_brain.brain_definition
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
brain_new_values_secrets_definition = (
|
||||||
|
brain_new_values.brain_definition.secrets
|
||||||
|
if brain_new_values.brain_definition
|
||||||
|
else None
|
||||||
|
)
|
||||||
|
should_remove_existing_secrets_values = (
|
||||||
|
existing_brain_secrets_definition
|
||||||
|
and brain_new_values_secrets_definition
|
||||||
|
and existing_brain_secrets_definition != brain_new_values_secrets_definition
|
||||||
|
)
|
||||||
|
|
||||||
|
if should_remove_existing_secrets_values:
|
||||||
|
delete_brain_secrets_values(brain_id=brain_id)
|
||||||
|
|
||||||
|
update_api_brain_definition(
|
||||||
|
brain_id,
|
||||||
|
api_brain_definition=brain_new_values.brain_definition,
|
||||||
|
)
|
||||||
|
|
||||||
|
if brain_update_answer is None:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=404,
|
||||||
|
detail=f"Brain with id {brain_id} not found",
|
||||||
|
)
|
||||||
|
|
||||||
update_brain_last_update_time(brain_id)
|
update_brain_last_update_time(brain_id)
|
||||||
return brain_update_answer
|
return brain_update_answer
|
||||||
|
@ -4,7 +4,7 @@ from repository.external_api_secret.create_secret import create_secret
|
|||||||
from repository.external_api_secret.delete_secret import delete_secret
|
from repository.external_api_secret.delete_secret import delete_secret
|
||||||
|
|
||||||
|
|
||||||
def update_secret(
|
def update_secret_value(
|
||||||
user_id: UUID,
|
user_id: UUID,
|
||||||
brain_id: UUID,
|
brain_id: UUID,
|
||||||
secret_name: str,
|
secret_name: str,
|
@ -26,7 +26,9 @@ from repository.brain import (
|
|||||||
update_brain_by_id,
|
update_brain_by_id,
|
||||||
)
|
)
|
||||||
from repository.brain.get_brain_for_user import get_brain_for_user
|
from repository.brain.get_brain_for_user import get_brain_for_user
|
||||||
from repository.external_api_secret.update_secret import update_secret
|
from repository.external_api_secret.update_secret_value import (
|
||||||
|
update_secret_value,
|
||||||
|
)
|
||||||
from repository.prompt import delete_prompt_by_id, get_prompt_by_id
|
from repository.prompt import delete_prompt_by_id, get_prompt_by_id
|
||||||
|
|
||||||
from routes.authorizations.brain_authorization import has_brain_authorization
|
from routes.authorizations.brain_authorization import has_brain_authorization
|
||||||
@ -156,7 +158,7 @@ async def update_existing_brain(
|
|||||||
|
|
||||||
|
|
||||||
@brain_router.put(
|
@brain_router.put(
|
||||||
"/brains/{brain_id}/secrets",
|
"/brains/{brain_id}/secrets-values",
|
||||||
dependencies=[
|
dependencies=[
|
||||||
Depends(AuthBearer()),
|
Depends(AuthBearer()),
|
||||||
],
|
],
|
||||||
@ -206,7 +208,7 @@ async def update_existing_brain_secrets(
|
|||||||
detail=f"Secret {key} is not a valid secret.",
|
detail=f"Secret {key} is not a valid secret.",
|
||||||
)
|
)
|
||||||
if value:
|
if value:
|
||||||
update_secret(
|
update_secret_value(
|
||||||
user_id=current_user.id,
|
user_id=current_user.id,
|
||||||
brain_id=brain_id,
|
brain_id=brain_id,
|
||||||
secret_name=key,
|
secret_name=key,
|
||||||
|
@ -6,16 +6,14 @@ import { useTranslation } from "react-i18next";
|
|||||||
import { FaSpinner } from "react-icons/fa";
|
import { FaSpinner } from "react-icons/fa";
|
||||||
|
|
||||||
import { Divider } from "@/lib/components/ui/Divider";
|
import { Divider } from "@/lib/components/ui/Divider";
|
||||||
import { defaultBrainConfig } from "@/lib/config/defaultBrainConfig";
|
import { Brain } from "@/lib/context/BrainProvider/types";
|
||||||
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
|
||||||
import { BrainConfig } from "@/lib/types/brainConfig";
|
|
||||||
|
|
||||||
import { GeneralInformation, ModelSelection, Prompt } from "./components";
|
import { GeneralInformation, ModelSelection, Prompt } from "./components";
|
||||||
import { AccessConfirmationModal } from "./components/PrivateAccessConfirmationModal/AccessConfirmationModal";
|
import { AccessConfirmationModal } from "./components/PrivateAccessConfirmationModal/AccessConfirmationModal";
|
||||||
import { useAccessConfirmationModal } from "./components/PrivateAccessConfirmationModal/hooks/useAccessConfirmationModal";
|
import { useAccessConfirmationModal } from "./components/PrivateAccessConfirmationModal/hooks/useAccessConfirmationModal";
|
||||||
|
import { usePermissionsController } from "./hooks/usePermissionsController";
|
||||||
import { UsePromptProps } from "./hooks/usePrompt";
|
import { UsePromptProps } from "./hooks/usePrompt";
|
||||||
import { useSettingsTab } from "./hooks/useSettingsTab";
|
import { useSettingsTab } from "./hooks/useSettingsTab";
|
||||||
import { getBrainPermissions } from "../../utils/getBrainPermissions";
|
|
||||||
|
|
||||||
type SettingsTabProps = {
|
type SettingsTabProps = {
|
||||||
brainId: UUID;
|
brainId: UUID;
|
||||||
@ -44,12 +42,9 @@ export const SettingsTabContent = ({
|
|||||||
const { onCancel, isAccessModalOpened, closeModal } =
|
const { onCancel, isAccessModalOpened, closeModal } =
|
||||||
useAccessConfirmationModal();
|
useAccessConfirmationModal();
|
||||||
|
|
||||||
const { allBrains } = useBrainContext();
|
|
||||||
|
|
||||||
const { hasEditRights, isOwnedByCurrentUser, isPublicBrain } =
|
const { hasEditRights, isOwnedByCurrentUser, isPublicBrain } =
|
||||||
getBrainPermissions({
|
usePermissionsController({
|
||||||
brainId,
|
brainId,
|
||||||
userAccessibleBrains: allBrains,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -57,7 +52,7 @@ export const SettingsTabContent = ({
|
|||||||
<form
|
<form
|
||||||
onSubmit={(e) => {
|
onSubmit={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
void handleSubmit(true);
|
void handleSubmit();
|
||||||
}}
|
}}
|
||||||
className="my-10 mb-0 flex flex-col items-center gap-2"
|
className="my-10 mb-0 flex flex-col items-center gap-2"
|
||||||
ref={formRef}
|
ref={formRef}
|
||||||
@ -103,9 +98,7 @@ export const SettingsTabContent = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const SettingsTab = ({ brainId }: SettingsTabProps): JSX.Element => {
|
export const SettingsTab = ({ brainId }: SettingsTabProps): JSX.Element => {
|
||||||
const methods = useForm<BrainConfig>({
|
const methods = useForm<Brain>();
|
||||||
defaultValues: defaultBrainConfig,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormProvider {...methods}>
|
<FormProvider {...methods}>
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
/* eslint max-lines:["error", 150] */
|
/* eslint max-lines:["error", 150] */
|
||||||
// TODO: useFormContext to avoid passing too many props
|
|
||||||
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
import { ApiRequestDefinition } from "@/lib/components/ApiRequestDefinition";
|
||||||
import Button from "@/lib/components/ui/Button";
|
import Button from "@/lib/components/ui/Button";
|
||||||
import { Chip } from "@/lib/components/ui/Chip";
|
import { Chip } from "@/lib/components/ui/Chip";
|
||||||
import Field from "@/lib/components/ui/Field";
|
import Field from "@/lib/components/ui/Field";
|
||||||
import { Radio } from "@/lib/components/ui/Radio";
|
import { Radio } from "@/lib/components/ui/Radio";
|
||||||
import { TextArea } from "@/lib/components/ui/TextArea";
|
import { TextArea } from "@/lib/components/ui/TextArea";
|
||||||
|
|
||||||
import { ApiBrainDefinition } from "./components/ApiBrainDefinition";
|
|
||||||
import { useGeneralInformation } from "./hooks/useGeneralInformation";
|
import { useGeneralInformation } from "./hooks/useGeneralInformation";
|
||||||
import { useBrainFormState } from "../../hooks/useBrainFormState";
|
import { useBrainFormState } from "../../hooks/useBrainFormState";
|
||||||
|
|
||||||
@ -97,10 +96,11 @@ export const GeneralInformation = (
|
|||||||
items={brainTypeOptions}
|
items={brainTypeOptions}
|
||||||
label={t("knowledge_source_label", { ns: "brain" })}
|
label={t("knowledge_source_label", { ns: "brain" })}
|
||||||
className="flex-1 justify-between w-[50%]"
|
className="flex-1 justify-between w-[50%]"
|
||||||
{...register("brain_type", { disabled: true })}
|
disabled={true}
|
||||||
|
{...register("brain_type")}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<ApiBrainDefinition />
|
<ApiRequestDefinition />
|
||||||
<TextArea
|
<TextArea
|
||||||
label={t("brainDescription", { ns: "brain" })}
|
label={t("brainDescription", { ns: "brain" })}
|
||||||
placeholder={t("brainDescriptionPlaceholder", { ns: "brain" })}
|
placeholder={t("brainDescriptionPlaceholder", { ns: "brain" })}
|
||||||
|
@ -1,95 +0,0 @@
|
|||||||
import { Fragment } from "react";
|
|
||||||
import { useTranslation } from "react-i18next";
|
|
||||||
|
|
||||||
import { useUrlBrain } from "@/lib/hooks/useBrainIdFromUrl";
|
|
||||||
|
|
||||||
export const ApiBrainDefinition = (): JSX.Element => {
|
|
||||||
const { brainDetails } = useUrlBrain();
|
|
||||||
const { t } = useTranslation(["external_api_definition"]);
|
|
||||||
|
|
||||||
if (brainDetails?.brain_type !== "api") {
|
|
||||||
return <Fragment />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="w-full">
|
|
||||||
<hr className="border-t border-gray-300 w-full mb-3" />
|
|
||||||
<div className="mb-2">
|
|
||||||
<p>
|
|
||||||
<span className="font-semibold">{t("url_placeholder")}</span>
|
|
||||||
<span className="ml-2">{brainDetails.brain_definition?.url}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="mb-2">
|
|
||||||
<p>
|
|
||||||
<span className="font-semibold">{t("method_label")}</span>
|
|
||||||
<span className="ml-2">{brainDetails.brain_definition?.method}</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{(brainDetails.brain_definition?.params.properties.length ?? 0) > 0 && (
|
|
||||||
<div className="mb-3">
|
|
||||||
<p>
|
|
||||||
<span className="font-bold mr-1">{t("params")}:</span>
|
|
||||||
<span>{t("paramsTabDescription")}</span>
|
|
||||||
</p>
|
|
||||||
{brainDetails.brain_definition?.params.properties.map((param) => (
|
|
||||||
<div key={param.name}>
|
|
||||||
<span className="mr-1">-</span>
|
|
||||||
<span className="font-semibold">{param.name}:</span>
|
|
||||||
<span className="ml-2">{param.type}</span>
|
|
||||||
<span className="ml-2">
|
|
||||||
{brainDetails.brain_definition?.params.required.includes(
|
|
||||||
param.name
|
|
||||||
) ?? false
|
|
||||||
? "- Required"
|
|
||||||
: " - Optional"}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{(brainDetails.brain_definition?.search_params.properties.length ?? 0) >
|
|
||||||
0 && (
|
|
||||||
<div className="mb-3">
|
|
||||||
<p>
|
|
||||||
<span className="font-bold mr-1">{t("searchParams")}:</span>
|
|
||||||
<span>{t("searchParamsTabDescription")}</span>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
{brainDetails.brain_definition?.search_params.properties.map(
|
|
||||||
(param) => (
|
|
||||||
<div key={param.name}>
|
|
||||||
<span className="mr-1">-</span>
|
|
||||||
<span className="font-semibold">{param.name}:</span>
|
|
||||||
<span className="ml-2">{param.type}</span>
|
|
||||||
<span className="ml-2">
|
|
||||||
{brainDetails.brain_definition?.search_params.required.includes(
|
|
||||||
param.name
|
|
||||||
) ?? false
|
|
||||||
? "- Required"
|
|
||||||
: " - Optional"}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{(brainDetails.brain_definition?.secrets?.length ?? 0) > 0 && (
|
|
||||||
<div className="mb-3">
|
|
||||||
<p>
|
|
||||||
<span className="font-bold mr-1">{t("secrets")}:</span>
|
|
||||||
<span>{t("secretsTabDescription")}</span>
|
|
||||||
</p>
|
|
||||||
{brainDetails.brain_definition?.secrets?.map((param) => (
|
|
||||||
<div key={param.name}>
|
|
||||||
<span className="mr-1">-</span>
|
|
||||||
<span className="font-bold">{param.name}:</span>
|
|
||||||
<span className="ml-2">{param.type}</span>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<hr className="border-t border-gray-300 w-full mt-5" />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
@ -23,7 +23,7 @@ export const useBrainFormState = () => {
|
|||||||
setValue,
|
setValue,
|
||||||
reset,
|
reset,
|
||||||
resetField,
|
resetField,
|
||||||
formState: { dirtyFields },
|
formState: { defaultValues, dirtyFields },
|
||||||
} = useFormContext<BrainConfig>();
|
} = useFormContext<BrainConfig>();
|
||||||
|
|
||||||
const { brain, refetchBrain } = useBrainFetcher({
|
const { brain, refetchBrain } = useBrainFetcher({
|
||||||
@ -54,8 +54,6 @@ export const useBrainFormState = () => {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// @ts-expect-error bad type inference from typescript
|
// @ts-expect-error bad type inference from typescript
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
if (Boolean(brain[key])) setValue(key, brain[key]);
|
if (Boolean(brain[key])) setValue(key, brain[key]);
|
||||||
@ -81,6 +79,7 @@ export const useBrainFormState = () => {
|
|||||||
isDefaultBrain,
|
isDefaultBrain,
|
||||||
promptId,
|
promptId,
|
||||||
openAiKey,
|
openAiKey,
|
||||||
|
defaultValues,
|
||||||
dirtyFields,
|
dirtyFields,
|
||||||
status,
|
status,
|
||||||
register,
|
register,
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
import { UUID } from "crypto";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import { useFormContext } from "react-hook-form";
|
||||||
|
|
||||||
|
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
||||||
|
|
||||||
|
import { getBrainPermissions } from "../../../utils/getBrainPermissions";
|
||||||
|
|
||||||
|
type UsePermissionsControllerProps = {
|
||||||
|
brainId: UUID;
|
||||||
|
};
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
|
export const usePermissionsController = ({
|
||||||
|
brainId,
|
||||||
|
}: UsePermissionsControllerProps) => {
|
||||||
|
const { allBrains } = useBrainContext();
|
||||||
|
|
||||||
|
const { setValue } = useFormContext<{
|
||||||
|
isApiDefinitionReadOnly: boolean;
|
||||||
|
isUpdatingApiDefinition: boolean;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const { hasEditRights, isOwnedByCurrentUser, isPublicBrain } =
|
||||||
|
getBrainPermissions({
|
||||||
|
brainId,
|
||||||
|
userAccessibleBrains: allBrains,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setValue("isApiDefinitionReadOnly", !hasEditRights);
|
||||||
|
setValue("isUpdatingApiDefinition", true);
|
||||||
|
}, [hasEditRights, setValue]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
hasEditRights,
|
||||||
|
isOwnedByCurrentUser,
|
||||||
|
isPublicBrain,
|
||||||
|
};
|
||||||
|
};
|
@ -29,15 +29,8 @@ export const useSettingsTab = ({ brainId }: UseSettingsTabProps) => {
|
|||||||
const { fetchAllBrains, fetchDefaultBrain } = useBrainContext();
|
const { fetchAllBrains, fetchDefaultBrain } = useBrainContext();
|
||||||
const { userData } = useUserData();
|
const { userData } = useUserData();
|
||||||
|
|
||||||
const {
|
const { getValues, maxTokens, setValue, openAiKey, model, isDefaultBrain } =
|
||||||
dirtyFields,
|
useBrainFormState();
|
||||||
getValues,
|
|
||||||
maxTokens,
|
|
||||||
setValue,
|
|
||||||
openAiKey,
|
|
||||||
model,
|
|
||||||
isDefaultBrain,
|
|
||||||
} = useBrainFormState();
|
|
||||||
|
|
||||||
const accessibleModels = getAccessibleModels({
|
const accessibleModels = getAccessibleModels({
|
||||||
openAiKey,
|
openAiKey,
|
||||||
@ -52,7 +45,7 @@ export const useSettingsTab = ({ brainId }: UseSettingsTabProps) => {
|
|||||||
const handleKeyPress = (event: KeyboardEvent) => {
|
const handleKeyPress = (event: KeyboardEvent) => {
|
||||||
if (event.key === "Enter") {
|
if (event.key === "Enter") {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
void handleSubmit(true);
|
void handleSubmit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,12 +86,8 @@ export const useSettingsTab = ({ brainId }: UseSettingsTabProps) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSubmit = async (checkDirty: boolean) => {
|
const handleSubmit = async () => {
|
||||||
const hasChanges = Object.keys(dirtyFields).length > 0;
|
const { name } = getValues();
|
||||||
if (!hasChanges && checkDirty) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const { name} = getValues();
|
|
||||||
|
|
||||||
checkBrainName(name, publish, t);
|
checkBrainName(name, publish, t);
|
||||||
|
|
||||||
|
@ -10,7 +10,11 @@ import {
|
|||||||
} from "@/lib/api/chat/chat.local";
|
} from "@/lib/api/chat/chat.local";
|
||||||
import { USER_DATA_KEY } from "@/lib/api/user/config";
|
import { USER_DATA_KEY } from "@/lib/api/user/config";
|
||||||
import { useUserApi } from "@/lib/api/user/useUserApi";
|
import { useUserApi } from "@/lib/api/user/useUserApi";
|
||||||
import { defaultBrainConfig } from "@/lib/config/defaultBrainConfig";
|
import {
|
||||||
|
defaultMaxTokens,
|
||||||
|
defaultModel,
|
||||||
|
defaultTemperature,
|
||||||
|
} from "@/lib/config/defaultBrainConfig";
|
||||||
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
import { useBrainContext } from "@/lib/context/BrainProvider/hooks/useBrainContext";
|
||||||
import { ChatConfig } from "@/lib/context/ChatProvider/types";
|
import { ChatConfig } from "@/lib/context/ChatProvider/types";
|
||||||
import { getAccessibleModels } from "@/lib/helpers/getAccessibleModels";
|
import { getAccessibleModels } from "@/lib/helpers/getAccessibleModels";
|
||||||
@ -28,13 +32,12 @@ export const useConfigModal = () => {
|
|||||||
queryKey: [USER_DATA_KEY],
|
queryKey: [USER_DATA_KEY],
|
||||||
queryFn: getUser,
|
queryFn: getUser,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const { register, watch, setValue } = useForm<ChatConfig>({
|
const { register, watch, setValue } = useForm<ChatConfig>({
|
||||||
defaultValues: {
|
defaultValues: {
|
||||||
model: defaultBrainConfig.model,
|
model: "gpt-3.5-turbo-16k",
|
||||||
temperature: defaultBrainConfig.temperature,
|
temperature: 0,
|
||||||
maxTokens: defaultBrainConfig.maxTokens,
|
maxTokens: 3000,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -61,15 +64,12 @@ export const useConfigModal = () => {
|
|||||||
if (relatedBrainConfig === undefined) {
|
if (relatedBrainConfig === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
setValue("model", relatedBrainConfig.model ?? defaultBrainConfig.model);
|
setValue("model", relatedBrainConfig.model ?? defaultModel);
|
||||||
setValue(
|
setValue(
|
||||||
"temperature",
|
"temperature",
|
||||||
relatedBrainConfig.temperature ?? defaultBrainConfig.temperature
|
relatedBrainConfig.temperature ?? defaultTemperature
|
||||||
);
|
|
||||||
setValue(
|
|
||||||
"maxTokens",
|
|
||||||
relatedBrainConfig.max_tokens ?? defaultBrainConfig.maxTokens
|
|
||||||
);
|
);
|
||||||
|
setValue("maxTokens", relatedBrainConfig.max_tokens ?? defaultMaxTokens);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -247,7 +247,7 @@ describe("useBrainApi", () => {
|
|||||||
await updateBrainSecrets(brainId, secrets);
|
await updateBrainSecrets(brainId, secrets);
|
||||||
expect(axiosPutMock).toHaveBeenCalledTimes(1);
|
expect(axiosPutMock).toHaveBeenCalledTimes(1);
|
||||||
expect(axiosPutMock).toHaveBeenCalledWith(
|
expect(axiosPutMock).toHaveBeenCalledWith(
|
||||||
`/brains/${brainId}/secrets`,
|
`/brains/${brainId}/secrets-values`,
|
||||||
secrets
|
secrets
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -149,5 +149,5 @@ export const updateBrainSecrets = async (
|
|||||||
secrets: Record<string, string>,
|
secrets: Record<string, string>,
|
||||||
axiosInstance: AxiosInstance
|
axiosInstance: AxiosInstance
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
await axiosInstance.put(`/brains/${brainId}/secrets`, secrets);
|
await axiosInstance.put(`/brains/${brainId}/secrets-values`, secrets);
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { UUID } from "crypto";
|
||||||
|
|
||||||
import { BrainRoleType } from "@/lib/components/BrainUsers/types";
|
import { BrainRoleType } from "@/lib/components/BrainUsers/types";
|
||||||
import { BrainStatus, BrainType, Model } from "@/lib/types/brainConfig";
|
import { BrainStatus, BrainType, Model } from "@/lib/types/brainConfig";
|
||||||
|
|
||||||
@ -28,6 +30,7 @@ export type ApiBrainDefinitionSecret = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type ApiBrainDefinition = {
|
export type ApiBrainDefinition = {
|
||||||
|
brain_id: UUID;
|
||||||
method: AllowedRequestMethod;
|
method: AllowedRequestMethod;
|
||||||
url: string;
|
url: string;
|
||||||
search_params: ApiBrainDefinitionSchema;
|
search_params: ApiBrainDefinitionSchema;
|
||||||
@ -44,7 +47,7 @@ export type CreateBrainInput = {
|
|||||||
max_tokens?: number;
|
max_tokens?: number;
|
||||||
prompt_id?: string | null;
|
prompt_id?: string | null;
|
||||||
brain_type?: BrainType;
|
brain_type?: BrainType;
|
||||||
brain_definition?: ApiBrainDefinition;
|
brain_definition?: Omit<ApiBrainDefinition, "brain_id">;
|
||||||
brain_secrets_values?: Record<string, string>;
|
brain_secrets_values?: Record<string, string>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,10 +11,10 @@ import { Modal } from "@/lib/components/ui/Modal";
|
|||||||
import { defineMaxTokens } from "@/lib/helpers/defineMaxTokens";
|
import { defineMaxTokens } from "@/lib/helpers/defineMaxTokens";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
import { ApiRequestDefinition } from "./components/ApiRequestDefinition";
|
|
||||||
import { PublicAccessConfirmationModal } from "./components/PublicAccessConfirmationModal";
|
import { PublicAccessConfirmationModal } from "./components/PublicAccessConfirmationModal";
|
||||||
import { useAddBrainConfig } from "./hooks/useAddBrainConfig";
|
import { useAddBrainConfig } from "./hooks/useAddBrainConfig";
|
||||||
import { useAddBrainConfigLabels } from "./hooks/useAddBrainConfigLabels";
|
import { useAddBrainConfigLabels } from "./hooks/useAddBrainConfigLabels";
|
||||||
|
import { ApiRequestDefinition } from "../../../ApiRequestDefinition";
|
||||||
import { Divider } from "../../../ui/Divider";
|
import { Divider } from "../../../ui/Divider";
|
||||||
import { Radio } from "../../../ui/Radio";
|
import { Radio } from "../../../ui/Radio";
|
||||||
import { TextArea } from "../../../ui/TextArea";
|
import { TextArea } from "../../../ui/TextArea";
|
||||||
@ -114,7 +114,6 @@ export const AddBrainConfig = ({
|
|||||||
<ApiRequestDefinition />
|
<ApiRequestDefinition />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
||||||
<fieldset className="w-full flex flex-col">
|
<fieldset className="w-full flex flex-col">
|
||||||
<label className="flex-1 text-sm" htmlFor="model">
|
<label className="flex-1 text-sm" htmlFor="model">
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
export const apiTabs = ["params", "searchParams", "secrets"] as const;
|
|
||||||
|
|
||||||
export type ApiTab = (typeof apiTabs)[number];
|
|
@ -3,20 +3,22 @@ import { Fragment } from "react";
|
|||||||
import { useFormContext } from "react-hook-form";
|
import { useFormContext } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
import { allowedRequestMethods, CreateBrainInput } from "@/lib/api/brain/types";
|
import { allowedRequestMethods } from "@/lib/api/brain/types";
|
||||||
|
|
||||||
import { BrainDefinitionTabTrigger } from "./components/BrainDefinitionTabTrigger";
|
import { BrainDefinitionTabTrigger } from "./components/BrainDefinitionTabTrigger";
|
||||||
import { ParamsDefinition } from "./components/ParamsDefinition/ParamsDefinition";
|
import { ParamsDefinition } from "./components/ParamsDefinition/ParamsDefinition";
|
||||||
import { SecretsDefinition } from "./components/SecretsDefinition/SecretsDefinition";
|
import { SecretsDefinition } from "./components/SecretsDefinition/SecretsDefinition";
|
||||||
import { useApiRequestDefinition } from "./hooks/useApiRequestDefinition";
|
import { useApiRequestDefinition } from "./hooks/useApiRequestDefinition";
|
||||||
|
import { ApiDefinitionContextType } from "./types";
|
||||||
|
|
||||||
export const ApiRequestDefinition = (): JSX.Element => {
|
export const ApiRequestDefinition = (): JSX.Element => {
|
||||||
const { selectedTab, setSelectedTab } = useApiRequestDefinition();
|
const { selectedTab, setSelectedTab } = useApiRequestDefinition();
|
||||||
const { t } = useTranslation(["external_api_definition"]);
|
const { t } = useTranslation(["external_api_definition"]);
|
||||||
|
|
||||||
const { watch, register } = useFormContext<CreateBrainInput>();
|
const { watch, register } = useFormContext<ApiDefinitionContextType>();
|
||||||
|
|
||||||
const brainType = watch("brain_type");
|
const brainType = watch("brain_type");
|
||||||
|
const readOnly = watch("isApiDefinitionReadOnly") ?? false;
|
||||||
|
|
||||||
if (brainType !== "api") {
|
if (brainType !== "api") {
|
||||||
return <Fragment />;
|
return <Fragment />;
|
||||||
@ -33,6 +35,7 @@ export const ApiRequestDefinition = (): JSX.Element => {
|
|||||||
<select
|
<select
|
||||||
className="block w-32 px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
|
className="block w-32 px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm focus:outline-none focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
|
||||||
defaultValue="GET"
|
defaultValue="GET"
|
||||||
|
disabled={readOnly}
|
||||||
{...register("brain_definition.method")}
|
{...register("brain_definition.method")}
|
||||||
>
|
>
|
||||||
{allowedMethodsOptions.map(({ label, value }) => (
|
{allowedMethodsOptions.map(({ label, value }) => (
|
||||||
@ -45,6 +48,7 @@ export const ApiRequestDefinition = (): JSX.Element => {
|
|||||||
<input
|
<input
|
||||||
className="flex-1 px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
|
className="flex-1 px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50"
|
||||||
placeholder="https://api.example.com/resource"
|
placeholder="https://api.example.com/resource"
|
||||||
|
disabled={readOnly}
|
||||||
{...register("brain_definition.url", { required: true })}
|
{...register("brain_definition.url", { required: true })}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
@ -22,7 +22,7 @@ export const ParamsDefinition = ({
|
|||||||
description,
|
description,
|
||||||
}: ParamsDefinitionProps): JSX.Element => {
|
}: ParamsDefinitionProps): JSX.Element => {
|
||||||
const { t } = useTranslation(["brain"]);
|
const { t } = useTranslation(["brain"]);
|
||||||
const { control, register } = useParamsDefinition({
|
const { control, register, isApiDefinitionReadOnly } = useParamsDefinition({
|
||||||
name,
|
name,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -61,6 +61,7 @@ export const ParamsDefinition = ({
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
append(defaultParamDefinitionRow);
|
append(defaultParamDefinitionRow);
|
||||||
}}
|
}}
|
||||||
|
disabled={isApiDefinitionReadOnly}
|
||||||
className="p-2"
|
className="p-2"
|
||||||
variant={"secondary"}
|
variant={"secondary"}
|
||||||
>
|
>
|
@ -1,7 +1,8 @@
|
|||||||
import { UseFormRegister } from "react-hook-form";
|
import { useFormContext, UseFormRegister } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { MdCancel } from "react-icons/md";
|
import { MdCancel } from "react-icons/md";
|
||||||
|
|
||||||
|
import { ApiDefinitionContextType } from "../../../types";
|
||||||
import { paramsNameStyle } from "../../styles";
|
import { paramsNameStyle } from "../../styles";
|
||||||
import { ParameterDefinition } from "../types";
|
import { ParameterDefinition } from "../types";
|
||||||
|
|
||||||
@ -23,6 +24,8 @@ export const ParamDefinitionRow = ({
|
|||||||
name,
|
name,
|
||||||
}: ParamDefinitionRowProps): JSX.Element => {
|
}: ParamDefinitionRowProps): JSX.Element => {
|
||||||
const { t } = useTranslation(["brain"]);
|
const { t } = useTranslation(["brain"]);
|
||||||
|
const { watch } = useFormContext<ApiDefinitionContextType>();
|
||||||
|
const isApiDefinitionReadOnly = watch("isApiDefinitionReadOnly") ?? false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-1 justify-between items-center py-4 border-b border-gray-300 relative gap-2">
|
<div className="flex flex-1 justify-between items-center py-4 border-b border-gray-300 relative gap-2">
|
||||||
@ -31,6 +34,7 @@ export const ParamDefinitionRow = ({
|
|||||||
type="text"
|
type="text"
|
||||||
className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block shadow-sm sm:text-sm border-gray-300 dark:bg-gray-800 dark:text-gray-100 rounded-md w-full outline-none"
|
className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block shadow-sm sm:text-sm border-gray-300 dark:bg-gray-800 dark:text-gray-100 rounded-md w-full outline-none"
|
||||||
placeholder={t("api_brain.name")}
|
placeholder={t("api_brain.name")}
|
||||||
|
disabled={isApiDefinitionReadOnly}
|
||||||
{...register(
|
{...register(
|
||||||
`${name}[${index}].name` as `${typeof name}.${number}.name`
|
`${name}[${index}].name` as `${typeof name}.${number}.name`
|
||||||
)}
|
)}
|
||||||
@ -42,6 +46,7 @@ export const ParamDefinitionRow = ({
|
|||||||
id={`description-${index}`}
|
id={`description-${index}`}
|
||||||
className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 dark:bg-gray-800 dark:text-gray-100 rounded-md outline-none"
|
className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 dark:bg-gray-800 dark:text-gray-100 rounded-md outline-none"
|
||||||
placeholder={t("api_brain.description")}
|
placeholder={t("api_brain.description")}
|
||||||
|
disabled={isApiDefinitionReadOnly}
|
||||||
{...register(
|
{...register(
|
||||||
`${name}[${index}].description` as `${typeof name}.${number}.description`
|
`${name}[${index}].description` as `${typeof name}.${number}.description`
|
||||||
)}
|
)}
|
||||||
@ -51,6 +56,7 @@ export const ParamDefinitionRow = ({
|
|||||||
<select
|
<select
|
||||||
id={`type-${index}`}
|
id={`type-${index}`}
|
||||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 dark:bg-gray-800 dark:text-gray-100 bg-white dark:border-gray-800 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
className="mt-1 block w-full py-2 px-3 border border-gray-300 dark:bg-gray-800 dark:text-gray-100 bg-white dark:border-gray-800 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
||||||
|
disabled={isApiDefinitionReadOnly}
|
||||||
{...register(
|
{...register(
|
||||||
`${name}[${index}].type` as `${typeof name}.${number}.type`
|
`${name}[${index}].type` as `${typeof name}.${number}.type`
|
||||||
)}
|
)}
|
||||||
@ -63,12 +69,14 @@ export const ParamDefinitionRow = ({
|
|||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
className="form-checkbox h-5 w-5 text-indigo-600 rounded focus:ring-2 focus:ring-indigo-400 outline-none"
|
className="form-checkbox h-5 w-5 text-indigo-600 rounded focus:ring-2 focus:ring-indigo-400 outline-none"
|
||||||
|
disabled={isApiDefinitionReadOnly}
|
||||||
{...register(`${name}[${index}].required`)}
|
{...register(`${name}[${index}].required`)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
disabled={isApiDefinitionReadOnly}
|
||||||
onClick={() => remove(index)}
|
onClick={() => remove(index)}
|
||||||
className="absolute right-0 text-red-500 bg-transparent border-none cursor-pointer"
|
className="absolute right-0 text-red-500 bg-transparent border-none cursor-pointer"
|
||||||
>
|
>
|
@ -2,7 +2,7 @@ import { useEffect } from "react";
|
|||||||
import { useForm, useFormContext, useWatch } from "react-hook-form";
|
import { useForm, useFormContext, useWatch } from "react-hook-form";
|
||||||
|
|
||||||
import { useParamsDefinitionDefaultValues } from "./useParamsDefinitionDefaultValues";
|
import { useParamsDefinitionDefaultValues } from "./useParamsDefinitionDefaultValues";
|
||||||
import { CreateBrainProps } from "../../../../../types";
|
import { ApiDefinitionContextType } from "../../../types";
|
||||||
import { ParameterDefinition } from "../types";
|
import { ParameterDefinition } from "../types";
|
||||||
import { mapParameterDefinitionToApiBrainDefinitionSchema } from "../utils/mapParameterDefinitionToApiBrainDefinitionSchema";
|
import { mapParameterDefinitionToApiBrainDefinitionSchema } from "../utils/mapParameterDefinitionToApiBrainDefinitionSchema";
|
||||||
|
|
||||||
@ -14,7 +14,8 @@ type UseParamsDefinitionProps = {
|
|||||||
export const useParamsDefinition = ({ name }: UseParamsDefinitionProps) => {
|
export const useParamsDefinition = ({ name }: UseParamsDefinitionProps) => {
|
||||||
const dataKey = `brain_definition.${name}` as const;
|
const dataKey = `brain_definition.${name}` as const;
|
||||||
|
|
||||||
const { setValue: setContextValue } = useFormContext<CreateBrainProps>();
|
const { setValue: setContextValue, watch: watchContextValue } =
|
||||||
|
useFormContext<ApiDefinitionContextType>();
|
||||||
|
|
||||||
const { defaultValues } = useParamsDefinitionDefaultValues({
|
const { defaultValues } = useParamsDefinitionDefaultValues({
|
||||||
dataKey,
|
dataKey,
|
||||||
@ -28,6 +29,9 @@ export const useParamsDefinition = ({ name }: UseParamsDefinitionProps) => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const isApiDefinitionReadOnly =
|
||||||
|
watchContextValue("isApiDefinitionReadOnly") ?? false;
|
||||||
|
|
||||||
const params = useWatch({
|
const params = useWatch({
|
||||||
control,
|
control,
|
||||||
name,
|
name,
|
||||||
@ -47,5 +51,6 @@ export const useParamsDefinition = ({ name }: UseParamsDefinitionProps) => {
|
|||||||
return {
|
return {
|
||||||
control,
|
control,
|
||||||
register,
|
register,
|
||||||
|
isApiDefinitionReadOnly,
|
||||||
};
|
};
|
||||||
};
|
};
|
@ -1,6 +1,6 @@
|
|||||||
import { useFormContext } from "react-hook-form";
|
import { useFormContext } from "react-hook-form";
|
||||||
|
|
||||||
import { CreateBrainProps } from "../../../../../types";
|
import { CreateBrainProps } from "../../../../AddBrainModal/components/AddBrainConfig/types";
|
||||||
import { defaultParamDefinitionRow } from "../config";
|
import { defaultParamDefinitionRow } from "../config";
|
||||||
import { mapApiBrainDefinitionSchemaToParameterDefinition } from "../utils/mapApiBrainDefinitionSchemaToParameterDefinition";
|
import { mapApiBrainDefinitionSchemaToParameterDefinition } from "../utils/mapApiBrainDefinitionSchemaToParameterDefinition";
|
||||||
|
|
@ -18,7 +18,12 @@ const paramsNameStyle = "flex flex-1 justify-center";
|
|||||||
export const SecretsDefinition = (): JSX.Element => {
|
export const SecretsDefinition = (): JSX.Element => {
|
||||||
const { t } = useTranslation(["brain", "external_api_definition"]);
|
const { t } = useTranslation(["brain", "external_api_definition"]);
|
||||||
|
|
||||||
const { control, register } = useSecretsDefinition();
|
const {
|
||||||
|
control,
|
||||||
|
register,
|
||||||
|
isApiDefinitionReadOnly,
|
||||||
|
isUpdatingApiDefinition,
|
||||||
|
} = useSecretsDefinition();
|
||||||
|
|
||||||
const { fields, append, remove } = useFieldArray({
|
const { fields, append, remove } = useFieldArray({
|
||||||
control,
|
control,
|
||||||
@ -38,7 +43,9 @@ export const SecretsDefinition = (): JSX.Element => {
|
|||||||
<div className={paramsNameStyle}>{t("api_brain.name")}</div>
|
<div className={paramsNameStyle}>{t("api_brain.name")}</div>
|
||||||
<div className={paramsNameStyle}>{t("api_brain.description")}</div>
|
<div className={paramsNameStyle}>{t("api_brain.description")}</div>
|
||||||
<div className={paramsNameStyle}>{t("api_brain.type")}</div>
|
<div className={paramsNameStyle}>{t("api_brain.type")}</div>
|
||||||
<div className={paramsNameStyle}>{t("api_brain.value")}</div>
|
{!isUpdatingApiDefinition && (
|
||||||
|
<div className={paramsNameStyle}>{t("api_brain.value")}</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{fields.map((field, index) => (
|
{fields.map((field, index) => (
|
||||||
@ -56,6 +63,7 @@ export const SecretsDefinition = (): JSX.Element => {
|
|||||||
append(defaultSecretDefinitionRow);
|
append(defaultSecretDefinitionRow);
|
||||||
}}
|
}}
|
||||||
className="p-2"
|
className="p-2"
|
||||||
|
disabled={isApiDefinitionReadOnly}
|
||||||
variant={"secondary"}
|
variant={"secondary"}
|
||||||
>
|
>
|
||||||
<MdAdd size={20} /> {t("api_brain.addRow")}
|
<MdAdd size={20} /> {t("api_brain.addRow")}
|
@ -1,7 +1,8 @@
|
|||||||
import { UseFormRegister } from "react-hook-form";
|
import { useFormContext, UseFormRegister } from "react-hook-form";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { MdCancel } from "react-icons/md";
|
import { MdCancel } from "react-icons/md";
|
||||||
|
|
||||||
|
import { ApiDefinitionContextType } from "../../../types";
|
||||||
import { paramsNameStyle } from "../../styles";
|
import { paramsNameStyle } from "../../styles";
|
||||||
import { brainSecretsSchemaDefinitionKeyInForm } from "../config";
|
import { brainSecretsSchemaDefinitionKeyInForm } from "../config";
|
||||||
import { SecretDefinition } from "../types";
|
import { SecretDefinition } from "../types";
|
||||||
@ -22,6 +23,9 @@ export const SecretDefinitionRow = ({
|
|||||||
register,
|
register,
|
||||||
}: SecretDefinitionRowProps): JSX.Element => {
|
}: SecretDefinitionRowProps): JSX.Element => {
|
||||||
const { t } = useTranslation(["brain"]);
|
const { t } = useTranslation(["brain"]);
|
||||||
|
const { watch } = useFormContext<ApiDefinitionContextType>();
|
||||||
|
const isApiDefinitionReadOnly = watch("isApiDefinitionReadOnly") ?? false;
|
||||||
|
const isUpdatingApiDefinition = watch("isUpdatingApiDefinition") ?? false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-1 justify-between items-center py-4 border-b border-gray-300 relative gap-2">
|
<div className="flex flex-1 justify-between items-center py-4 border-b border-gray-300 relative gap-2">
|
||||||
@ -30,6 +34,7 @@ export const SecretDefinitionRow = ({
|
|||||||
type="text"
|
type="text"
|
||||||
className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block shadow-sm sm:text-sm border-gray-300 dark:bg-gray-800 dark:text-gray-100 rounded-md w-full outline-none"
|
className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block shadow-sm sm:text-sm border-gray-300 dark:bg-gray-800 dark:text-gray-100 rounded-md w-full outline-none"
|
||||||
placeholder={t("api_brain.name")}
|
placeholder={t("api_brain.name")}
|
||||||
|
disabled={isApiDefinitionReadOnly}
|
||||||
{...register(
|
{...register(
|
||||||
`${brainSecretsSchemaDefinitionKeyInForm}.${index}.name`
|
`${brainSecretsSchemaDefinitionKeyInForm}.${index}.name`
|
||||||
)}
|
)}
|
||||||
@ -41,6 +46,7 @@ export const SecretDefinitionRow = ({
|
|||||||
id={`description-${index}`}
|
id={`description-${index}`}
|
||||||
className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 dark:bg-gray-800 dark:text-gray-100 rounded-md outline-none"
|
className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 dark:bg-gray-800 dark:text-gray-100 rounded-md outline-none"
|
||||||
placeholder={t("api_brain.description")}
|
placeholder={t("api_brain.description")}
|
||||||
|
disabled={isApiDefinitionReadOnly}
|
||||||
{...register(
|
{...register(
|
||||||
`${brainSecretsSchemaDefinitionKeyInForm}.${index}.description`
|
`${brainSecretsSchemaDefinitionKeyInForm}.${index}.description`
|
||||||
)}
|
)}
|
||||||
@ -50,6 +56,7 @@ export const SecretDefinitionRow = ({
|
|||||||
<select
|
<select
|
||||||
id={`type-${index}`}
|
id={`type-${index}`}
|
||||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 dark:bg-gray-800 dark:text-gray-100 bg-white dark:border-gray-800 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
className="mt-1 block w-full py-2 px-3 border border-gray-300 dark:bg-gray-800 dark:text-gray-100 bg-white dark:border-gray-800 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
||||||
|
disabled={isApiDefinitionReadOnly}
|
||||||
{...register(
|
{...register(
|
||||||
`${brainSecretsSchemaDefinitionKeyInForm}.${index}.type`
|
`${brainSecretsSchemaDefinitionKeyInForm}.${index}.type`
|
||||||
)}
|
)}
|
||||||
@ -58,20 +65,23 @@ export const SecretDefinitionRow = ({
|
|||||||
<option value="number">number</option>
|
<option value="number">number</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div className={paramsNameStyle}>
|
{!isUpdatingApiDefinition && (
|
||||||
<input
|
<div className={paramsNameStyle}>
|
||||||
type="text"
|
<input
|
||||||
className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 dark:bg-gray-800 dark:text-gray-100 rounded-md outline-none"
|
type="text"
|
||||||
placeholder={t("api_brain.value")}
|
className="mt-1 focus:ring-indigo-500 focus:border-indigo-500 block w-full shadow-sm sm:text-sm border-gray-300 dark:bg-gray-800 dark:text-gray-100 rounded-md outline-none"
|
||||||
{...register(
|
placeholder={t("api_brain.value")}
|
||||||
`${brainSecretsSchemaDefinitionKeyInForm}.${index}.value`
|
{...register(
|
||||||
)}
|
`${brainSecretsSchemaDefinitionKeyInForm}.${index}.value`
|
||||||
/>
|
)}
|
||||||
</div>
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => remove(index)}
|
onClick={() => remove(index)}
|
||||||
|
disabled={isApiDefinitionReadOnly}
|
||||||
className="absolute right-0 text-red-500 bg-transparent border-none cursor-pointer"
|
className="absolute right-0 text-red-500 bg-transparent border-none cursor-pointer"
|
||||||
>
|
>
|
||||||
<MdCancel />
|
<MdCancel />
|
@ -2,7 +2,7 @@ import { useEffect } from "react";
|
|||||||
import { useForm, useFormContext, useWatch } from "react-hook-form";
|
import { useForm, useFormContext, useWatch } from "react-hook-form";
|
||||||
|
|
||||||
import { useSecretsDefinitionDefaultValues } from "./useSecretsDefinitionDefaultValues";
|
import { useSecretsDefinitionDefaultValues } from "./useSecretsDefinitionDefaultValues";
|
||||||
import { CreateBrainProps } from "../../../../../types";
|
import { ApiDefinitionContextType } from "../../../types";
|
||||||
import {
|
import {
|
||||||
brainSecretsSchemaDefinitionKeyInForm,
|
brainSecretsSchemaDefinitionKeyInForm,
|
||||||
brainSecretsValueKeyInForm,
|
brainSecretsValueKeyInForm,
|
||||||
@ -12,7 +12,8 @@ import { mapSecretDefinitionToApiBrainSecretsDefinitionsAndValue } from "../util
|
|||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||||
export const useSecretsDefinition = () => {
|
export const useSecretsDefinition = () => {
|
||||||
const { setValue: setContextValue } = useFormContext<CreateBrainProps>();
|
const { setValue: setContextValue, watch: watchContextValue } =
|
||||||
|
useFormContext<ApiDefinitionContextType>();
|
||||||
const { defaultValues } = useSecretsDefinitionDefaultValues();
|
const { defaultValues } = useSecretsDefinitionDefaultValues();
|
||||||
|
|
||||||
const { register, control } = useForm<{
|
const { register, control } = useForm<{
|
||||||
@ -28,6 +29,11 @@ export const useSecretsDefinition = () => {
|
|||||||
name: brainSecretsSchemaDefinitionKeyInForm,
|
name: brainSecretsSchemaDefinitionKeyInForm,
|
||||||
}) as SecretDefinition[] | undefined;
|
}) as SecretDefinition[] | undefined;
|
||||||
|
|
||||||
|
const isApiDefinitionReadOnly =
|
||||||
|
watchContextValue("isApiDefinitionReadOnly") ?? false;
|
||||||
|
const isUpdatingApiDefinition =
|
||||||
|
watchContextValue("isUpdatingApiDefinition") ?? false;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (secretsDefinitionSchemas === undefined) {
|
if (secretsDefinitionSchemas === undefined) {
|
||||||
return;
|
return;
|
||||||
@ -50,5 +56,7 @@ export const useSecretsDefinition = () => {
|
|||||||
return {
|
return {
|
||||||
control,
|
control,
|
||||||
register,
|
register,
|
||||||
|
isApiDefinitionReadOnly,
|
||||||
|
isUpdatingApiDefinition,
|
||||||
};
|
};
|
||||||
};
|
};
|
@ -1,6 +1,6 @@
|
|||||||
import { useFormContext } from "react-hook-form";
|
import { useFormContext } from "react-hook-form";
|
||||||
|
|
||||||
import { CreateBrainProps } from "../../../../../types";
|
import { CreateBrainProps } from "../../../../AddBrainModal/components/AddBrainConfig/types";
|
||||||
import {
|
import {
|
||||||
brainSecretsValueKeyInForm,
|
brainSecretsValueKeyInForm,
|
||||||
defaultSecretDefinitionRow,
|
defaultSecretDefinitionRow,
|
10
frontend/lib/components/ApiRequestDefinition/types.ts
Normal file
10
frontend/lib/components/ApiRequestDefinition/types.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { CreateBrainInput } from "@/lib/api/brain/types";
|
||||||
|
|
||||||
|
export const apiTabs = ["params", "searchParams", "secrets"] as const;
|
||||||
|
|
||||||
|
export type ApiTab = (typeof apiTabs)[number];
|
||||||
|
|
||||||
|
export type ApiDefinitionContextType = CreateBrainInput & {
|
||||||
|
isApiDefinitionReadOnly?: boolean;
|
||||||
|
isUpdatingApiDefinition?: boolean;
|
||||||
|
};
|
@ -1,5 +1,5 @@
|
|||||||
import { CreateBrainInput } from "../api/brain/types";
|
import { CreateBrainInput } from "../api/brain/types";
|
||||||
import { BrainConfig } from "../types/brainConfig";
|
import { Model } from "../types/brainConfig";
|
||||||
|
|
||||||
export const addBrainDefaultValues: CreateBrainInput = {
|
export const addBrainDefaultValues: CreateBrainInput = {
|
||||||
model: "gpt-3.5-turbo",
|
model: "gpt-3.5-turbo",
|
||||||
@ -12,24 +12,6 @@ export const addBrainDefaultValues: CreateBrainInput = {
|
|||||||
brain_type: "doc",
|
brain_type: "doc",
|
||||||
};
|
};
|
||||||
|
|
||||||
export const defaultBrainConfig: BrainConfig = {
|
export const defaultModel: Model = "gpt-3.5-turbo";
|
||||||
model: "gpt-3.5-turbo",
|
export const defaultMaxTokens = 1000;
|
||||||
temperature: 0,
|
export const defaultTemperature = 0;
|
||||||
maxTokens: 1000,
|
|
||||||
keepLocal: true,
|
|
||||||
anthropicKey: undefined,
|
|
||||||
backendUrl: undefined,
|
|
||||||
openAiKey: undefined,
|
|
||||||
supabaseKey: undefined,
|
|
||||||
supabaseUrl: undefined,
|
|
||||||
prompt_id: undefined,
|
|
||||||
status: "private",
|
|
||||||
prompt: {
|
|
||||||
title: "",
|
|
||||||
content: "",
|
|
||||||
},
|
|
||||||
name: "",
|
|
||||||
description: "",
|
|
||||||
setDefault: false,
|
|
||||||
brain_type: "doc",
|
|
||||||
};
|
|
||||||
|
@ -3,7 +3,6 @@ import axios, { AxiosError, AxiosInstance } from "axios";
|
|||||||
import { useSupabase } from "@/lib/context/SupabaseProvider";
|
import { useSupabase } from "@/lib/context/SupabaseProvider";
|
||||||
|
|
||||||
import { DEFAULT_BACKEND_URL } from "../config/CONSTANTS";
|
import { DEFAULT_BACKEND_URL } from "../config/CONSTANTS";
|
||||||
import { defaultBrainConfig } from "../config/defaultBrainConfig";
|
|
||||||
|
|
||||||
const axiosInstance = axios.create({
|
const axiosInstance = axios.create({
|
||||||
baseURL: `${process.env.NEXT_PUBLIC_BACKEND_URL ?? DEFAULT_BACKEND_URL}`,
|
baseURL: `${process.env.NEXT_PUBLIC_BACKEND_URL ?? DEFAULT_BACKEND_URL}`,
|
||||||
@ -11,13 +10,10 @@ const axiosInstance = axios.create({
|
|||||||
|
|
||||||
export const useAxios = (): { axiosInstance: AxiosInstance } => {
|
export const useAxios = (): { axiosInstance: AxiosInstance } => {
|
||||||
const { session } = useSupabase();
|
const { session } = useSupabase();
|
||||||
const { backendUrl, openAiKey } = defaultBrainConfig;
|
|
||||||
axiosInstance.interceptors.request.clear();
|
axiosInstance.interceptors.request.clear();
|
||||||
axiosInstance.interceptors.request.use(
|
axiosInstance.interceptors.request.use(
|
||||||
(config) => {
|
(config) => {
|
||||||
config.headers["Authorization"] = `Bearer ${session?.access_token ?? ""}`;
|
config.headers["Authorization"] = `Bearer ${session?.access_token ?? ""}`;
|
||||||
config.headers["Openai-Api-Key"] = openAiKey;
|
|
||||||
config.baseURL = backendUrl ?? config.baseURL;
|
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
},
|
},
|
||||||
|
@ -13,7 +13,8 @@ export const useUrlBrain = () => {
|
|||||||
|
|
||||||
const brainId = params?.brainId as UUID | undefined;
|
const brainId = params?.brainId as UUID | undefined;
|
||||||
const correspondingBrain = allBrains.find((brain) => brain.id === brainId);
|
const correspondingBrain = allBrains.find((brain) => brain.id === brainId);
|
||||||
const { brain: brainDetails } = useBrainFetcher({
|
|
||||||
|
const { brain: brainDetails, refetchBrain } = useBrainFetcher({
|
||||||
brainId: brainId,
|
brainId: brainId,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -21,5 +22,6 @@ export const useUrlBrain = () => {
|
|||||||
brain: correspondingBrain,
|
brain: correspondingBrain,
|
||||||
brainId,
|
brainId,
|
||||||
brainDetails,
|
brainDetails,
|
||||||
|
refetchBrain,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -2,8 +2,6 @@ import { useEffect, useState } from "react";
|
|||||||
|
|
||||||
import { useSupabase } from "@/lib/context/SupabaseProvider";
|
import { useSupabase } from "@/lib/context/SupabaseProvider";
|
||||||
|
|
||||||
import { defaultBrainConfig } from "../config/defaultBrainConfig";
|
|
||||||
|
|
||||||
interface FetchInstance {
|
interface FetchInstance {
|
||||||
get: (url: string, headers?: HeadersInit) => Promise<Response>;
|
get: (url: string, headers?: HeadersInit) => Promise<Response>;
|
||||||
post: (
|
post: (
|
||||||
@ -30,12 +28,11 @@ const fetchInstance: FetchInstance = {
|
|||||||
|
|
||||||
export const useFetch = (): { fetchInstance: FetchInstance } => {
|
export const useFetch = (): { fetchInstance: FetchInstance } => {
|
||||||
const { session } = useSupabase();
|
const { session } = useSupabase();
|
||||||
const { backendUrl: configBackendUrl, openAiKey } = defaultBrainConfig;
|
|
||||||
|
|
||||||
const [instance, setInstance] = useState(fetchInstance);
|
const [instance, setInstance] = useState(fetchInstance);
|
||||||
|
|
||||||
const baseURL = `${process.env.NEXT_PUBLIC_BACKEND_URL ?? ""}`;
|
const baseURL = `${process.env.NEXT_PUBLIC_BACKEND_URL ?? ""}`;
|
||||||
const backendUrl = configBackendUrl ?? baseURL;
|
const backendUrl = baseURL;
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setInstance({
|
setInstance({
|
||||||
@ -43,29 +40,25 @@ export const useFetch = (): { fetchInstance: FetchInstance } => {
|
|||||||
get: async (url, headers) =>
|
get: async (url, headers) =>
|
||||||
fetchInstance.get(`${backendUrl}${url}`, {
|
fetchInstance.get(`${backendUrl}${url}`, {
|
||||||
Authorization: `Bearer ${session?.access_token ?? ""}`,
|
Authorization: `Bearer ${session?.access_token ?? ""}`,
|
||||||
"Openai-Api-Key": openAiKey ?? "",
|
|
||||||
...headers,
|
...headers,
|
||||||
}),
|
}),
|
||||||
post: async (url, body, headers) =>
|
post: async (url, body, headers) =>
|
||||||
fetchInstance.post(`${backendUrl}${url}`, body, {
|
fetchInstance.post(`${backendUrl}${url}`, body, {
|
||||||
Authorization: `Bearer ${session?.access_token ?? ""}`,
|
Authorization: `Bearer ${session?.access_token ?? ""}`,
|
||||||
"Openai-Api-Key": openAiKey ?? "",
|
|
||||||
...headers,
|
...headers,
|
||||||
}),
|
}),
|
||||||
put: async (url, body, headers) =>
|
put: async (url, body, headers) =>
|
||||||
fetchInstance.put(`${backendUrl}${url}`, body, {
|
fetchInstance.put(`${backendUrl}${url}`, body, {
|
||||||
Authorization: `Bearer ${session?.access_token ?? ""}`,
|
Authorization: `Bearer ${session?.access_token ?? ""}`,
|
||||||
"Openai-Api-Key": openAiKey ?? "",
|
|
||||||
...headers,
|
...headers,
|
||||||
}),
|
}),
|
||||||
delete: async (url, headers) =>
|
delete: async (url, headers) =>
|
||||||
fetchInstance.delete(`${backendUrl}${url}`, {
|
fetchInstance.delete(`${backendUrl}${url}`, {
|
||||||
Authorization: `Bearer ${session?.access_token ?? ""}`,
|
Authorization: `Bearer ${session?.access_token ?? ""}`,
|
||||||
"Openai-Api-Key": openAiKey ?? "",
|
|
||||||
...headers,
|
...headers,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}, [session, backendUrl, openAiKey]);
|
}, [session, backendUrl]);
|
||||||
|
|
||||||
return { fetchInstance: instance };
|
return { fetchInstance: instance };
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
import { UUID } from "crypto";
|
||||||
|
|
||||||
|
import { ApiBrainDefinition } from "../api/brain/types";
|
||||||
|
|
||||||
export const brainStatuses = ["private", "public"] as const;
|
export const brainStatuses = ["private", "public"] as const;
|
||||||
|
|
||||||
export type BrainStatus = (typeof brainStatuses)[number];
|
export type BrainStatus = (typeof brainStatuses)[number];
|
||||||
@ -8,7 +12,9 @@ export type BrainType = (typeof brainTypes)[number];
|
|||||||
|
|
||||||
export type Model = (typeof freeModels)[number];
|
export type Model = (typeof freeModels)[number];
|
||||||
|
|
||||||
|
// TODO: update this type to match the backend (antropic, openai and some other keys should be removed)
|
||||||
export type BrainConfig = {
|
export type BrainConfig = {
|
||||||
|
id: UUID;
|
||||||
model: Model;
|
model: Model;
|
||||||
temperature: number;
|
temperature: number;
|
||||||
maxTokens: number;
|
maxTokens: number;
|
||||||
@ -27,11 +33,8 @@ export type BrainConfig = {
|
|||||||
};
|
};
|
||||||
name: string;
|
name: string;
|
||||||
description: string;
|
description: string;
|
||||||
setDefault: boolean;
|
} & {
|
||||||
};
|
brain_definition?: ApiBrainDefinition;
|
||||||
|
|
||||||
export type BrainConfigContextType = {
|
|
||||||
config: BrainConfig;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const openAiFreeModels = ["gpt-3.5-turbo","gpt-3.5-turbo-1106", "gpt-3.5-turbo-16k"] as const;
|
export const openAiFreeModels = ["gpt-3.5-turbo","gpt-3.5-turbo-1106", "gpt-3.5-turbo-16k"] as const;
|
||||||
|
Loading…
Reference in New Issue
Block a user