From 627c8c692e82809fa6314200436572dd9b3212dd Mon Sep 17 00:00:00 2001 From: Omar Shaikh Date: Tue, 7 Apr 2026 21:31:52 -0700 Subject: [PATCH 1/2] update the model dropdown --- .../renderer/components/shared/ModelDropdown.tsx | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/client/renderer/components/shared/ModelDropdown.tsx b/src/client/renderer/components/shared/ModelDropdown.tsx index 9b0e937..501e757 100644 --- a/src/client/renderer/components/shared/ModelDropdown.tsx +++ b/src/client/renderer/components/shared/ModelDropdown.tsx @@ -6,18 +6,15 @@ export interface ModelOption { } export const LLM_MODELS: ModelOption[] = [ - { value: "gemini/gemini-3-flash-preview", label: "Gemini 3 Flash Preview" }, { value: "gemini/gemini-3.1-flash-lite-preview", label: "Gemini 3.1 Flash-Lite Preview" }, - { value: "anthropic/claude-haiku-4-5", label: "Claude Haiku 4.5" }, - { value: "anthropic/claude-sonnet-4-6", label: "Claude Sonnet 4.6" }, - { value: "anthropic/claude-opus-4-6", label: "Claude Opus 4.6" }, + { value: "openai/gpt-5.2-nano", label: "OpenAI GPT-5.2 Nano" }, + { value: "openai/gpt-4.1-nano", label: "OpenAI GPT-4.1 Nano" }, ]; export const TADA_MODELS: ModelOption[] = [ - { value: "gemini/gemini-3.1-flash-lite-preview", label: "Gemini 3.1 Flash-Lite Preview" }, - { value: "anthropic/claude-haiku-4-5", label: "Claude Haiku 4.5" }, - { value: "anthropic/claude-sonnet-4-6", label: "Claude Sonnet 4.6" }, - { value: "anthropic/claude-opus-4-6", label: "Claude Opus 4.6" }, + { value: "gemini/gemini-3.1-flash-lite-preview", label: "Gemini 3.1 Flash-Lite Preview" }, + { value: "openai/gpt-5.2-nano", label: "OpenAI GPT-5.2 Nano" }, + { value: "openai/gpt-4.1-nano", label: "OpenAI GPT-4.1 Nano" }, ]; export const TINKER_MODELS: ModelOption[] = [ From ec526a074fe7f66ec14fd04624d1451a915242bf Mon Sep 17 00:00:00 2001 From: Omar Shaikh Date: Tue, 7 Apr 2026 22:35:26 -0700 Subject: [PATCH 2/2] lots of updates --- site/src/App.tsx | 2 +- site/src/main.tsx | 2 +- src/apps/moments/discovery.py | 4 +- src/apps/moments/scheduler.py | 3 +- src/client/renderer/App.tsx | 5 +- src/client/renderer/components/Sidebar.tsx | 16 +- .../renderer/components/UpdateBanner.tsx | 2 + .../components/connectors/ConnectorItem.tsx | 2 +- .../components/dashboard/PipelineTile.tsx | 1 + .../components/dashboard/PredictionCard.tsx | 2 + .../components/dashboard/RewardsChart.tsx | 1 + .../components/modals/PermissionModal.tsx | 2 +- .../components/onboarding/Onboarding.tsx | 36 ++++- .../renderer/components/overlay/Overlay.tsx | 2 +- .../components/shared/AdvancedLLMSection.tsx | 3 +- .../components/shared/CollapsibleSection.tsx | 3 +- .../components/shared/ModelDropdown.tsx | 2 +- .../components/views/ConnectorsView.tsx | 6 +- .../components/views/DashboardView.tsx | 6 +- .../components/views/SettingsView.tsx | 143 ++++++++++-------- .../renderer/components/views/TadaView.tsx | 2 +- .../components/views/UserModelView.tsx | 2 +- src/client/renderer/context/AppContext.tsx | 2 +- src/client/renderer/featureFlags.ts | 36 +++++ src/client/renderer/main.tsx | 1 + src/client/renderer/onboarding-main.tsx | 1 + src/client/renderer/overlay-main.tsx | 1 + src/connectors/service.py | 7 + src/server/app.py | 12 +- src/server/config.py | 7 +- src/server/feature_flags.py | 33 ++++ src/server/routes/settings.py | 3 +- tada-config.defaults.json | 18 ++- 33 files changed, 268 insertions(+), 100 deletions(-) create mode 100644 src/client/renderer/featureFlags.ts create mode 100644 src/server/feature_flags.py diff --git a/site/src/App.tsx b/site/src/App.tsx index 521d28f..a6aeea9 100644 --- a/site/src/App.tsx +++ b/site/src/App.tsx @@ -1,4 +1,4 @@ -import { type ReactNode, useEffect, useState } from "react"; +import React, { type ReactNode, useEffect, useState } from "react"; const REPO = "GeneralUserModels/tada"; const RELEASE_URL = `https://github.com/${REPO}/releases/latest`; diff --git a/site/src/main.tsx b/site/src/main.tsx index bd4d570..423ec24 100644 --- a/site/src/main.tsx +++ b/site/src/main.tsx @@ -1,4 +1,4 @@ -import { StrictMode } from "react"; +import React, { StrictMode } from "react"; import { createRoot } from "react-dom/client"; import { App } from "./App"; import "./App.css"; diff --git a/src/apps/moments/discovery.py b/src/apps/moments/discovery.py index 671120f..9075ee8 100644 --- a/src/apps/moments/discovery.py +++ b/src/apps/moments/discovery.py @@ -7,6 +7,8 @@ from datetime import datetime from pathlib import Path +from server.feature_flags import is_enabled + logger = logging.getLogger(__name__) @@ -100,7 +102,7 @@ async def run_moments_discovery(state) -> None: logger.info("Next discovery run at %s (in %.0fs)", next_run, delay) await asyncio.sleep(delay) - if not state.config.moments_enabled: + if not (is_enabled(state.config, "moments") and state.config.moments_enabled): continue cfg = state.config diff --git a/src/apps/moments/scheduler.py b/src/apps/moments/scheduler.py index 4284331..da921d3 100644 --- a/src/apps/moments/scheduler.py +++ b/src/apps/moments/scheduler.py @@ -12,6 +12,7 @@ from apps.moments.execute import run as execute_moment, _parse_frontmatter as parse_frontmatter from apps.moments.state import load_state +from server.feature_flags import is_enabled logger = logging.getLogger(__name__) @@ -138,7 +139,7 @@ async def run_moments_scheduler(state) -> None: try: await asyncio.sleep(SCAN_INTERVAL) - if not state.config.moments_enabled: + if not (is_enabled(state.config, "moments") and state.config.moments_enabled): continue cfg = state.config diff --git a/src/client/renderer/App.tsx b/src/client/renderer/App.tsx index 0046904..31020ca 100644 --- a/src/client/renderer/App.tsx +++ b/src/client/renderer/App.tsx @@ -1,4 +1,6 @@ +import React from "react"; import { useAppContext } from "./context/AppContext"; +import { useFeatureFlag } from "./featureFlags"; import { Sidebar } from "./components/Sidebar"; import { ConnectorsView } from "./components/views/ConnectorsView"; import { UserModelView } from "./components/views/UserModelView"; @@ -8,6 +10,7 @@ import { UpdateBanner } from "./components/UpdateBanner"; export function App() { const { state, dispatch } = useAppContext(); + const momentsEnabled = useFeatureFlag("moments"); const navigate = (view: typeof state.activeView) => { dispatch({ type: "NAVIGATE", view }); @@ -30,7 +33,7 @@ export function App() { /> )} {state.activeView === "connectors" && } - {state.activeView === "tada" && } + {state.activeView === "tada" && momentsEnabled && } {state.activeView === "usermodel" && } {state.activeView === "settings" && } diff --git a/src/client/renderer/components/Sidebar.tsx b/src/client/renderer/components/Sidebar.tsx index dbfe03a..d18e222 100644 --- a/src/client/renderer/components/Sidebar.tsx +++ b/src/client/renderer/components/Sidebar.tsx @@ -1,4 +1,6 @@ +import React from "react"; import { ActiveView } from "../context/AppContext"; +import { useFeatureFlags, getFlag } from "../featureFlags"; interface Props { activeView: ActiveView; @@ -48,7 +50,19 @@ const navItems: { view: ActiveView; label: string; icon: JSX.Element }[] = [ }, ]; +const FLAG_FOR_VIEW: Partial> = { + tada: "moments", +}; + export function Sidebar({ activeView, connected, onNavigate }: Props) { + const featureFlags = useFeatureFlags(); + + const visibleItems = navItems.filter(({ view }) => { + const flag = FLAG_FOR_VIEW[view]; + if (flag && !getFlag(featureFlags, flag)) return false; + return true; + }); + return (