Skip to content

Commit

Permalink
quivr addon frontend (#4648)
Browse files Browse the repository at this point in the history
  • Loading branch information
Feroze Mohideen authored May 15, 2024
1 parent 5c0ddac commit d195078
Show file tree
Hide file tree
Showing 7 changed files with 337 additions and 0 deletions.
Binary file added dashboard/src/assets/quivr.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
60 changes: 60 additions & 0 deletions dashboard/src/lib/addons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Mezmo,
Newrelic,
Postgres,
Quivr,
Redis,
Tailscale,
} from "@porter-dev/api-contracts/src/porter/v1/addons_pb";
Expand All @@ -20,6 +21,7 @@ import { metabaseConfigValidator } from "./metabase";
import { mezmoConfigValidator } from "./mezmo";
import { newrelicConfigValidator } from "./newrelic";
import { defaultPostgresAddon, postgresConfigValidator } from "./postgres";
import { quivrConfigValidator } from "./quivr";
import { redisConfigValidator } from "./redis";
import { tailscaleConfigValidator } from "./tailscale";
import {
Expand All @@ -28,6 +30,7 @@ import {
ADDON_TEMPLATE_MEZMO,
ADDON_TEMPLATE_NEWRELIC,
ADDON_TEMPLATE_POSTGRES,
ADDON_TEMPLATE_QUIVR,
ADDON_TEMPLATE_REDIS,
ADDON_TEMPLATE_TAILSCALE,
type AddonTemplate,
Expand Down Expand Up @@ -55,6 +58,7 @@ export const clientAddonValidator = z.object({
metabaseConfigValidator,
newrelicConfigValidator,
tailscaleConfigValidator,
quivrConfigValidator,
]),
});
export type ClientAddonType = z.infer<
Expand Down Expand Up @@ -153,6 +157,16 @@ export function defaultClientAddon(
}),
template: ADDON_TEMPLATE_TAILSCALE,
}))
.with("quivr", () => ({
...clientAddonValidator.parse({
expanded: true,
name: { readOnly: false, value: "quivr" },
config: quivrConfigValidator.parse({
type: "quivr",
}),
}),
template: ADDON_TEMPLATE_QUIVR,
}))
.exhaustive();
}

Expand All @@ -165,6 +179,7 @@ function addonTypeEnumProto(type: ClientAddon["config"]["type"]): AddonType {
.with("metabase", () => AddonType.METABASE)
.with("newrelic", () => AddonType.NEWRELIC)
.with("tailscale", () => AddonType.TAILSCALE)
.with("quivr", () => AddonType.QUIVR)
.exhaustive();
}

Expand Down Expand Up @@ -254,6 +269,31 @@ export function clientAddonToProto(
}),
case: "tailscale" as const,
}))
.with({ type: "quivr" }, (data) => ({
value: new Quivr({
ingressEnabled: data.exposedToExternalTraffic,
domains: [
{
name: data.customDomain,
type: DomainType.UNSPECIFIED,
},
{
name: data.porterDomain,
type: DomainType.PORTER,
},
// if not exposed, remove all domains
].filter((d) => d.name !== "" && data.exposedToExternalTraffic),
openaiApiKey: data.openAiApiKey,
supabaseUrl: data.supabaseUrl,
supabaseServiceKey: data.supabaseServiceKey,
pgDatabaseUrl: data.pgDatabaseUrl,
jwtSecretKey: data.jwtSecretKey,
quivrDomain: data.quivrDomain,
anthropicApiKey: data.anthropicApiKey,
cohereApiKey: data.cohereApiKey,
}),
case: "quivr" as const,
}))
.exhaustive();

const proto = new Addon({
Expand Down Expand Up @@ -365,6 +405,25 @@ export function clientAddonFromProto({
authKey: data.value.authKey ?? "",
subnetRoutes: data.value.subnetRoutes.map((r) => ({ route: r })),
}))
.with({ case: "quivr" }, (data) => ({
type: "quivr" as const,
exposedToExternalTraffic: data.value.ingressEnabled ?? false,
porterDomain:
data.value.domains.find((domain) => domain.type === DomainType.PORTER)
?.name ?? "",
customDomain:
data.value.domains.find(
(domain) => domain.type === DomainType.UNSPECIFIED
)?.name ?? "",
openAiApiKey: data.value.openaiApiKey ?? "",
supabaseUrl: data.value.supabaseUrl ?? "",
supabaseServiceKey: data.value.supabaseServiceKey ?? "",
pgDatabaseUrl: data.value.pgDatabaseUrl ?? "",
jwtSecretKey: data.value.jwtSecretKey ?? "",
quivrDomain: data.value.quivrDomain ?? "",
anthropicApiKey: data.value.anthropicApiKey ?? "",
cohereApiKey: data.value.cohereApiKey ?? "",
}))
.exhaustive();

const template = match(addon.config)
Expand All @@ -375,6 +434,7 @@ export function clientAddonFromProto({
.with({ case: "metabase" }, () => ADDON_TEMPLATE_METABASE)
.with({ case: "newrelic" }, () => ADDON_TEMPLATE_NEWRELIC)
.with({ case: "tailscale" }, () => ADDON_TEMPLATE_TAILSCALE)
.with({ case: "quivr" }, () => ADDON_TEMPLATE_QUIVR)
.exhaustive();

const clientAddon = {
Expand Down
20 changes: 20 additions & 0 deletions dashboard/src/lib/addons/quivr.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { z } from "zod";

export const quivrConfigValidator = z.object({
type: z.literal("quivr"),
exposedToExternalTraffic: z.boolean().default(true),
porterDomain: z.string().default(""),
customDomain: z.string().default(""),
openAiApiKey: z.string().nonempty().default("*******"),
supabaseUrl: z.string().nonempty().default("https://*******.supabase.co"),
supabaseServiceKey: z.string().nonempty().default("*******"),
pgDatabaseUrl: z
.string()
.nonempty()
.default("postgres://postgres:postgres@localhost:5432/quivr"),
jwtSecretKey: z.string().nonempty().default("*******"),
quivrDomain: z.string().nonempty().default("https://*******.quivr.co"),
anthropicApiKey: z.string().nonempty().default("*******"),
cohereApiKey: z.string().nonempty().default("*******"),
});
export type QuivrConfigValidator = z.infer<typeof quivrConfigValidator>;
44 changes: 44 additions & 0 deletions dashboard/src/lib/addons/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import DatadogForm from "main/home/add-on-dashboard/datadog/DatadogForm";
import MetabaseForm from "main/home/add-on-dashboard/metabase/MetabaseForm";
import MezmoForm from "main/home/add-on-dashboard/mezmo/MezmoForm";
import NewRelicForm from "main/home/add-on-dashboard/newrelic/NewRelicForm";
import QuivrForm from "main/home/add-on-dashboard/quivr/QuivrForm";
import TailscaleForm from "main/home/add-on-dashboard/tailscale/TailscaleForm";
import TailscaleOverview from "main/home/add-on-dashboard/tailscale/TailscaleOverview";

import quivr from "assets/quivr.png";

import { type ClientAddon, type ClientAddonType } from ".";

export type AddonTemplateTag =
Expand Down Expand Up @@ -279,11 +282,52 @@ export const ADDON_TEMPLATE_TAILSCALE: AddonTemplate<"tailscale"> = {
},
};

export const ADDON_TEMPLATE_QUIVR: AddonTemplate<"quivr"> = {
type: "quivr",
displayName: "Quivr",
description: "Your second brain, empowered by generative AI",
icon: quivr,
tags: ["Analytics"],
tabs: [
{
name: "configuration",
displayName: "Configuration",
component: QuivrForm,
},
{
name: "logs",
displayName: "Logs",
component: Logs,
isOnlyForPorterOperators: true,
},
{
name: "settings",
displayName: "Settings",
component: Settings,
},
],
defaultValues: {
type: "quivr",
exposedToExternalTraffic: true,
porterDomain: "",
customDomain: "",
openAiApiKey: "",
supabaseUrl: "",
supabaseServiceKey: "",
pgDatabaseUrl: "",
jwtSecretKey: "",
quivrDomain: "https://chat.quivr.com",
anthropicApiKey: "",
cohereApiKey: "",
},
};

export const SUPPORTED_ADDON_TEMPLATES: Array<AddonTemplate<ClientAddonType>> =
[
ADDON_TEMPLATE_DATADOG,
ADDON_TEMPLATE_MEZMO,
ADDON_TEMPLATE_METABASE,
// ADDON_TEMPLATE_NEWRELIC,
ADDON_TEMPLATE_TAILSCALE,
ADDON_TEMPLATE_QUIVR,
];
3 changes: 3 additions & 0 deletions dashboard/src/main/home/add-on-dashboard/AddonHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ const AddonHeader: React.FC = () => {
.with({ type: "metabase" }, (config) => {
return config.customDomain || config.porterDomain;
})
.with({ type: "quivr" }, (config) => {
return config.customDomain || config.porterDomain;
})
.otherwise(() => "");
}, [addon]);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import DatadogForm from "../datadog/DatadogForm";
import MetabaseForm from "../metabase/MetabaseForm";
import MezmoForm from "../mezmo/MezmoForm";
import NewRelicForm from "../newrelic/NewRelicForm";
import QuivrForm from "../quivr/QuivrForm";
import TailscaleForm from "../tailscale/TailscaleForm";

type Props = {
Expand All @@ -20,6 +21,7 @@ const Configuration: React.FC<Props> = ({ type }) => {
.with("metabase", () => <MetabaseForm />)
.with("newrelic", () => <NewRelicForm />)
.with("tailscale", () => <TailscaleForm />)
.with("quivr", () => <QuivrForm />)
.otherwise(() => null);
};

Expand Down
Loading

0 comments on commit d195078

Please sign in to comment.