chore: linting

This commit is contained in:
DESKTOP-RTLN3BA\$punk 2026-07-24 14:30:46 -07:00
parent 8d1e2a5134
commit 4a727a2c57
41 changed files with 114 additions and 133 deletions

View file

@ -51,8 +51,7 @@ from app.gateway.inbox_worker import (
start_gateway_inbox_worker,
stop_gateway_inbox_worker,
)
from app.observability import analytics as ph_analytics
from app.observability import metrics as ot_metrics
from app.observability import analytics as ph_analytics, metrics as ot_metrics
from app.observability.bootstrap import init_otel, shutdown_otel
from app.rate_limiter import get_real_client_ip, limiter
from app.routes import router as crud_router
@ -843,11 +842,7 @@ class PatApiAnalyticsMiddleware(BaseHTTPMiddleware):
response = await call_next(request)
with contextlib.suppress(Exception):
ctx = getattr(request.state, "auth_context", None)
if (
ctx is not None
and ctx.method == "pat"
and ph_analytics.is_enabled()
):
if ctx is not None and ctx.method == "pat" and ph_analytics.is_enabled():
# Use the route *template* (e.g. /documents/{id}) to keep the
# ``route`` property low-cardinality; fall back to the raw path.
route = request.scope.get("route")

View file

@ -41,9 +41,7 @@ def _capture_run_outcome(run: AutomationRun, status: str) -> None:
"status": status,
"trigger_type": run.trigger.type.value if run.trigger else None,
},
groups={"workspace": str(workspace_id)}
if workspace_id is not None
else None,
groups={"workspace": str(workspace_id)} if workspace_id is not None else None,
)

View file

@ -132,7 +132,9 @@ def _breadcrumbs(product: dict[str, Any]) -> list[str]:
path = dig(product, "category", "path")
if not isinstance(path, list):
return []
return [node["name"] for node in path if isinstance(node, dict) and node.get("name")]
return [
node["name"] for node in path if isinstance(node, dict) and node.get("name")
]
def _reviews_sample(

View file

@ -14,16 +14,16 @@ from fastapi.responses import StreamingResponse
from pydantic import BaseModel, Field
from app.config import config
from app.observability import analytics as ph_analytics
from app.tasks.chat.streaming.flows.shared.analytics import (
build_llm_callback_handler,
)
from app.etl_pipeline.file_classifier import (
DIRECT_CONVERT_EXTENSIONS,
PLAINTEXT_EXTENSIONS,
)
from app.observability import analytics as ph_analytics
from app.rate_limiter import limiter
from app.tasks.chat.streaming.errors.classifier import classify_stream_exception
from app.tasks.chat.streaming.flows.shared.analytics import (
build_llm_callback_handler,
)
logger = logging.getLogger(__name__)

View file

@ -17,7 +17,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from app.auth.context import AuthContext
from app.observability import analytics as ph_analytics
from app.config import config
from app.db import (
ImageGeneration,
@ -27,6 +26,7 @@ from app.db import (
WorkspaceMembership,
get_async_session,
)
from app.observability import analytics as ph_analytics
from app.schemas import (
ImageGenerationCreate,
ImageGenerationListRead,

View file

@ -45,8 +45,11 @@ from app.db import (
get_async_session,
)
from app.notifications.service import NotificationService
from app.observability import analytics as ph_analytics
from app.observability import metrics as ot_metrics, otel as ot
from app.observability import (
analytics as ph_analytics,
metrics as ot_metrics,
otel as ot,
)
from app.schemas import (
GoogleDriveIndexRequest,
MCPConnectorCreate,

View file

@ -247,9 +247,7 @@ async def build_export_zip(
suffix = used_paths[file_path]
base_name = f"{base_name}_{suffix}"
file_path = (
f"{dir_path}/{base_name}.md"
if dir_path
else f"{base_name}.md"
f"{dir_path}/{base_name}.md" if dir_path else f"{base_name}.md"
)
used_paths[file_path] = used_paths.get(file_path, 0) + 1

View file

@ -37,6 +37,8 @@ from app.services.okf.validator import (
__all__ = [
"INDEX_FILENAME",
"LOG_FILENAME",
"RECOMMENDED_FRONTMATTER_KEYS",
"REQUIRED_FRONTMATTER_KEYS",
"ConceptRef",
"LogEntry",
"SubdirRef",
@ -44,13 +46,11 @@ __all__ = [
"document_to_concept",
"folder_to_index",
"folder_to_log",
"render_frontmatter",
"is_conformant_concept",
"okf_resource",
"okf_type",
"RECOMMENDED_FRONTMATTER_KEYS",
"REQUIRED_FRONTMATTER_KEYS",
"is_conformant_concept",
"parse_frontmatter",
"render_frontmatter",
"validate_bundle",
"validate_concept",
]

View file

@ -49,7 +49,11 @@ def build_frontmatter(document: Document) -> dict[str, Any]:
Only ``type`` is required; recommended keys are included only when we have a
value. Insertion order is preserved in the emitted YAML.
"""
metadata = document.document_metadata if isinstance(document.document_metadata, dict) else {}
metadata = (
document.document_metadata
if isinstance(document.document_metadata, dict)
else {}
)
frontmatter: dict[str, Any] = {"type": okf_type(document.document_type)}

View file

@ -50,7 +50,9 @@ OKF_TYPE_BY_DOCUMENT_TYPE: dict[DocumentType, str] = {
}
def _coerce_document_type(document_type: DocumentType | str | None) -> DocumentType | None:
def _coerce_document_type(
document_type: DocumentType | str | None,
) -> DocumentType | None:
if document_type is None:
return None
try:

View file

@ -9,8 +9,11 @@ from collections.abc import Awaitable, Callable
from celery import current_task
from app.celery_app import celery_app
from app.observability import analytics as ph_analytics
from app.observability import metrics as ot_metrics, otel as ot
from app.observability import (
analytics as ph_analytics,
metrics as ot_metrics,
otel as ot,
)
from app.tasks.celery_tasks import (
get_celery_session_maker,
run_async_celery_task as _run_async_celery_task,

View file

@ -10,8 +10,7 @@ from uuid import UUID
from app.celery_app import celery_app
from app.config import config
from app.notifications.service import NotificationService
from app.observability import analytics as ph_analytics
from app.observability import metrics as ot_metrics
from app.observability import analytics as ph_analytics, metrics as ot_metrics
from app.services.task_logging_service import TaskLoggingService
from app.tasks.celery_tasks import get_celery_session_maker, run_async_celery_task
from app.tasks.connector_indexers.local_folder_indexer import (

View file

@ -68,6 +68,10 @@ from app.tasks.chat.streaming.flows.new_chat.title_gen import (
maybe_emit_title_update,
spawn_title_task,
)
from app.tasks.chat.streaming.flows.shared.analytics import (
build_llm_callback_handler,
capture_chat_turn_completed,
)
from app.tasks.chat.streaming.flows.shared.assistant_finalize import (
finalize_assistant_message,
)
@ -97,10 +101,6 @@ from app.tasks.chat.streaming.flows.shared.rate_limit_recovery import (
log_rate_limit_recovered,
reroute_to_next_auto_pin,
)
from app.tasks.chat.streaming.flows.shared.analytics import (
build_llm_callback_handler,
capture_chat_turn_completed,
)
from app.tasks.chat.streaming.flows.shared.span import (
close_chat_request_span,
open_chat_request_span,

View file

@ -47,6 +47,10 @@ from app.tasks.chat.streaming.flows.resume_chat.resume_routing import (
from app.tasks.chat.streaming.flows.resume_chat.runtime_context import (
build_resume_chat_runtime_context,
)
from app.tasks.chat.streaming.flows.shared.analytics import (
build_llm_callback_handler,
capture_chat_turn_completed,
)
from app.tasks.chat.streaming.flows.shared.assistant_finalize import (
finalize_assistant_message,
)
@ -76,10 +80,6 @@ from app.tasks.chat.streaming.flows.shared.rate_limit_recovery import (
log_rate_limit_recovered,
reroute_to_next_auto_pin,
)
from app.tasks.chat.streaming.flows.shared.analytics import (
build_llm_callback_handler,
capture_chat_turn_completed,
)
from app.tasks.chat.streaming.flows.shared.span import (
close_chat_request_span,
open_chat_request_span,

View file

@ -105,9 +105,7 @@ def capture_chat_turn_completed(
groups = {"workspace": str(workspace_id)}
if auth_context is not None:
analytics.capture_for(
auth_context, "chat_turn_completed", props, groups=groups
)
analytics.capture_for(auth_context, "chat_turn_completed", props, groups=groups)
else:
analytics.capture(
"chat_turn_completed",

View file

@ -20,7 +20,6 @@ from sqlalchemy.ext.asyncio import AsyncSession
from app.auth.context import AuthContext
from app.auth.session_cookies import access_expires_at, write_session
from app.config import config
from app.observability import analytics as ph_analytics
from app.db import (
Prompt,
User,
@ -32,6 +31,7 @@ from app.db import (
get_default_roles_config,
get_user_db,
)
from app.observability import analytics as ph_analytics
from app.prompts.system_defaults import SYSTEM_PROMPT_DEFAULTS
from app.utils.pat import PAT_PREFIX, maybe_touch_last_used, resolve_pat
from app.utils.refresh_tokens import create_refresh_token
@ -353,6 +353,7 @@ async def get_auth_context(
FastAPI-Users still handles JWT mechanics; PATs are resolved here so RBAC
receives the full SurfSense principal instead of a bare User.
"""
def _stash(ctx: AuthContext) -> AuthContext:
# Expose the resolved principal on request.state so downstream
# middleware (e.g. PostHog pat_api_request attribution) can read it

View file

@ -75,9 +75,7 @@ async def step1_search(sess, state: dict) -> bool:
)
for it in items[:5]:
print(f" - {it.get('jobKey')} | {it.get('title')} @ {it.get('company')}")
state["job_url"] = next(
(it["jobUrl"] for it in items if it.get("jobUrl")), None
)
state["job_url"] = next((it["jobUrl"] for it in items if it.get("jobUrl")), None)
return _check("search returned jobs", len(items) > 0, f"{len(items)} jobs")

View file

@ -52,12 +52,20 @@ async def test_export_bundle_is_okf_conformant(
await db_session.flush()
await _add_doc(
db_session, workspace=db_workspace, user=db_user,
title="Root Note", folder_id=None, uid="okf-export-root",
db_session,
workspace=db_workspace,
user=db_user,
title="Root Note",
folder_id=None,
uid="okf-export-root",
)
await _add_doc(
db_session, workspace=db_workspace, user=db_user,
title="Nested Note", folder_id=folder.id, uid="okf-export-nested",
db_session,
workspace=db_workspace,
user=db_user,
title="Nested Note",
folder_id=folder.id,
uid="okf-export-nested",
)
result = await build_export_zip(db_session, db_workspace.id)

View file

@ -56,9 +56,7 @@ async def _roundtrip(
@pytest_asyncio.fixture
async def research_folder(
db_session: AsyncSession, db_workspace: Workspace
) -> Folder:
async def research_folder(db_session: AsyncSession, db_workspace: Workspace) -> Folder:
folder = Folder(name="Research", position="0", workspace_id=db_workspace.id)
db_session.add(folder)
await db_session.flush()

View file

@ -85,9 +85,7 @@ class TestConceptIdentityRoundTrip:
def test_folder_nested_document_roundtrips(self):
index = PathIndex(folder_paths={5: f"{DOCUMENTS_ROOT}/Research/AI"})
path = doc_to_virtual_path(
doc_id=2, title="My Note", folder_id=5, index=index
)
path = doc_to_virtual_path(doc_id=2, title="My Note", folder_id=5, index=index)
assert path == f"{DOCUMENTS_ROOT}/Research/AI/My Note.xml"
folder_parts, title = parse_documents_path(path)
assert folder_parts == ["Research", "AI"]
@ -97,9 +95,7 @@ class TestConceptIdentityRoundTrip:
# Second doc with the same title gets a " (<id>)" suffix; parsing the
# path must strip the disambiguator and recover the original title.
index = PathIndex(occupants={f"{DOCUMENTS_ROOT}/Hello.xml": 7})
path = doc_to_virtual_path(
doc_id=8, title="Hello", folder_id=None, index=index
)
path = doc_to_virtual_path(doc_id=8, title="Hello", folder_id=None, index=index)
assert path == f"{DOCUMENTS_ROOT}/Hello (8).xml"
folder_parts, title = parse_documents_path(path)
assert folder_parts == []

View file

@ -47,7 +47,9 @@ async def test_community_only_scrapes_listing(monkeypatch):
assert [i["id"] for i in items] == ["movies", "movies-p1"]
@pytest.mark.parametrize("raw", ["movies", "r/movies", "/r/movies/", " movies ", "R/movies"])
@pytest.mark.parametrize(
"raw", ["movies", "r/movies", "/r/movies/", " movies ", "R/movies"]
)
async def test_community_name_normalized(monkeypatch, raw):
seen: list[str] = []
monkeypatch.setattr(scraper, "_subreddit_flow", _fake_subreddit_flow(seen))

View file

@ -62,7 +62,9 @@ def test_validator_rejects_non_conformant_documents() -> None:
def test_folder_index_groups_by_type_and_lists_subdirs() -> None:
index = folder_to_index(
concepts=[
ConceptRef(title="Orders", filename="orders.md", type="Note", description="x"),
ConceptRef(
title="Orders", filename="orders.md", type="Note", description="x"
),
],
subdirectories=[SubdirRef(name="tables", description="Table docs")],
)
@ -114,11 +116,7 @@ def test_export_index_files_include_root_version_and_ancestors() -> None:
# A concept nested two levels deep, with no direct docs in the middle dir.
files = dict(
_build_index_files(
{
"Research/AI": [
ConceptRef(title="Note", filename="note.md", type="Note")
]
}
{"Research/AI": [ConceptRef(title="Note", filename="note.md", type="Note")]}
)
)

View file

@ -93,8 +93,10 @@ def register(mcp: FastMCP, client: SurfSenseClient, context: WorkspaceContext) -
] = False,
country_code: Annotated[
str | None,
Field(description="Two-letter delivery country for localized pricing, "
"e.g. 'us'."),
Field(
description="Two-letter delivery country for localized pricing, "
"e.g. 'us'."
),
] = None,
zip_code: Annotated[
str | None,

View file

@ -56,7 +56,9 @@ def register(mcp: FastMCP, client: SurfSenseClient, context: WorkspaceContext) -
] = None,
country: Annotated[
str,
Field(description="Country code selecting the Indeed domain, e.g. 'us', 'gb'."),
Field(
description="Country code selecting the Indeed domain, e.g. 'us', 'gb'."
),
] = "us",
location: Annotated[
str | None,

View file

@ -42,7 +42,9 @@ def register(mcp: FastMCP, client: SurfSenseClient, context: WorkspaceContext) -
] = None,
max_items: Annotated[
int,
Field(ge=1, le=100, description="Max products per search term or listing URL."),
Field(
ge=1, le=100, description="Max products per search term or listing URL."
),
] = 10,
include_details: Annotated[
bool,

View file

@ -178,8 +178,7 @@ export default function NewChatPage() {
const hasLiveStream = !!streamState && streamState.messages.length > 0;
const isActiveThreadHydrated = hydratedMessagesRef.current.threadId === activeThreadId;
const shouldHideStaleMessages = !!activeThreadId && !hasLiveStream && !isActiveThreadHydrated;
const isThreadMessagesLoading =
shouldHideStaleMessages && !threadMessagesQuery.error;
const isThreadMessagesLoading = shouldHideStaleMessages && !threadMessagesQuery.error;
const runtimeMessages = shouldHideStaleMessages ? EMPTY_MESSAGES : displayMessages;
// Live collaboration: sync session state and messages via Zero. Kept on the

View file

@ -2,9 +2,7 @@ import { atom, type Getter, type Setter } from "jotai";
import { rightPanelCollapsedAtom, rightPanelTabAtom } from "@/atoms/layout/right-panel.atom";
/** The source the citation panel is showing: a KB chunk or a scraper run. */
export type CitationTarget =
| { kind: "chunk"; chunkId: number }
| { kind: "run"; runId: string };
export type CitationTarget = { kind: "chunk"; chunkId: number } | { kind: "run"; runId: string };
interface CitationPanelState {
isOpen: boolean;

View file

@ -285,7 +285,11 @@ export const pruneMissingChatTabsAtom = atom(null, (get, set, missingChatIds: Se
}
const activeWasPruned = state.tabs.some(
(t) => t.id === state.activeTabId && t.type === "chat" && t.entityId !== null && missingChatIds.has(t.entityId)
(t) =>
t.id === state.activeTabId &&
t.type === "chat" &&
t.entityId !== null &&
missingChatIds.has(t.entityId)
);
const newActiveId = activeWasPruned
? remaining[Math.min(firstMissingIdx, remaining.length - 1)].id

View file

@ -74,7 +74,8 @@ type Screen =
| { kind: "tools" }
| { kind: "toolGroup"; label: string };
const ROW = "flex w-full items-center gap-3 px-4 py-3 text-sm hover:bg-accent hover:text-accent-foreground transition-colors";
const ROW =
"flex w-full items-center gap-3 px-4 py-3 text-sm hover:bg-accent hover:text-accent-foreground transition-colors";
export function ComposerAddMenuDrawer({
trigger,
@ -156,11 +157,7 @@ export function ComposerAddMenuDrawer({
<Upload className="size-4 shrink-0 text-muted-foreground" />
<span className="flex-1 text-left">Upload Files</span>
</button>
<button
type="button"
className={ROW}
onClick={() => push({ kind: "connectors" })}
>
<button type="button" className={ROW} onClick={() => push({ kind: "connectors" })}>
<Unplug className="size-4 shrink-0 text-muted-foreground" />
<span className="flex-1 text-left">MCP Connectors</span>
<ChevronRight className="size-4 shrink-0 text-muted-foreground" />

View file

@ -266,11 +266,7 @@ export const ConnectorEditView: FC<ConnectorEditViewProps> = ({
{/* Scrollable Content */}
<div className="flex-1 min-h-0 relative overflow-hidden">
<div
ref={scrollContainerRef}
className="h-full overflow-y-auto"
onScroll={handleScroll}
>
<div ref={scrollContainerRef} className="h-full overflow-y-auto" onScroll={handleScroll}>
<div className="space-y-6 pb-6 pt-2">
{/* Connector-specific configuration */}
{ConnectorConfigComponent && (

View file

@ -164,11 +164,7 @@ export const IndexingConfigurationView: FC<IndexingConfigurationViewProps> = ({
{/* Scrollable Content */}
<div className="flex-1 min-h-0 relative overflow-hidden">
<div
ref={scrollContainerRef}
className="h-full overflow-y-auto"
onScroll={handleScroll}
>
<div ref={scrollContainerRef} className="h-full overflow-y-auto" onScroll={handleScroll}>
<div className="space-y-6 pb-6 pt-2">
{/* Connector-specific configuration */}
{ConnectorConfigComponent && connector && (

View file

@ -29,8 +29,8 @@ import {
getConnectorTitle,
OAUTH_CONNECTORS,
} from "./constants/connector-constants";
import { type ConnectorRow, useConnectorRows } from "./hooks/use-connector-rows";
import { useConnectorDialog } from "./hooks/use-connector-dialog";
import { type ConnectorRow, useConnectorRows } from "./hooks/use-connector-rows";
import { AllConnectorsTab } from "./tabs/all-connectors-tab";
import { ConnectorAccountsListView } from "./views/connector-accounts-list-view";
import { YouTubeCrawlerView } from "./views/youtube-crawler-view";
@ -115,7 +115,9 @@ export function ConnectorsSection() {
} = useConnectorsSync(workspaceId);
const useSyncData = connectorsFromSync.length > 0 || (connectorsLoading && !connectorsError);
const connectors = (useSyncData ? connectorsFromSync : allConnectors || []) as SearchSourceConnector[];
const connectors = (
useSyncData ? connectorsFromSync : allConnectors || []
) as SearchSourceConnector[];
const refreshConnectors = async () => {
if (useSyncData) {
@ -174,9 +176,7 @@ export function ConnectorsSection() {
onManage={handleStartEdit}
onAddAccount={() => {
const oauthConnector =
OAUTH_CONNECTORS.find(
(c) => c.connectorType === viewingAccountsType.connectorType
) ||
OAUTH_CONNECTORS.find((c) => c.connectorType === viewingAccountsType.connectorType) ||
COMPOSIO_CONNECTORS.find(
(c) => c.connectorType === viewingAccountsType.connectorType
);

View file

@ -61,7 +61,8 @@ export function useConnectorRows(connectors: SearchSourceConnector[]) {
return groupConnectorsByType(connectors).map((row) => {
const ids = row.connectors.map((c) => c.id);
const syncing = ids.some(
(id) => indexingConnectorIds.has(id) || statusByConnectorId.get(id)?.status === "in_progress"
(id) =>
indexingConnectorIds.has(id) || statusByConnectorId.get(id)?.status === "in_progress"
);
const failedEntry = syncing
? undefined

View file

@ -152,15 +152,10 @@ interface ThreadProps {
}
export const Thread: FC<ThreadProps> = ({ hasActiveThread = false, isLoadingMessages = false }) => {
return (
<ThreadContent hasActiveThread={hasActiveThread} isLoadingMessages={isLoadingMessages} />
);
return <ThreadContent hasActiveThread={hasActiveThread} isLoadingMessages={isLoadingMessages} />;
};
const ThreadContent: FC<ThreadProps> = ({
hasActiveThread = false,
isLoadingMessages = false,
}) => {
const ThreadContent: FC<ThreadProps> = ({ hasActiveThread = false, isLoadingMessages = false }) => {
return (
<ThreadPrimitive.Root
className="aui-root aui-thread-root @container flex h-full min-h-0 flex-col bg-main-panel"

View file

@ -1,15 +1,7 @@
"use client";
import { useAtomValue, useSetAtom } from "jotai";
import {
Check,
Copy,
FileQuestionMark,
FileText,
Pencil,
RefreshCw,
XIcon,
} from "lucide-react";
import { Check, Copy, FileQuestionMark, FileText, Pencil, RefreshCw, XIcon } from "lucide-react";
import dynamic from "next/dynamic";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { toast } from "sonner";

View file

@ -658,8 +658,8 @@ export function HeroSection() {
>
SurfSense is the open-source NotebookLM alternative for AI agents, an open web
research platform with live data connectors. Your AI agents research the live web with
structured data from Reddit, YouTube, Instagram, TikTok, Amazon, Walmart, Google
Maps, Google Search, and any page on the open web.
structured data from Reddit, YouTube, Instagram, TikTok, Amazon, Walmart, Google Maps,
Google Search, and any page on the open web.
</p>
<div className="relative mb-4 flex w-full flex-col justify-center gap-y-2 sm:flex-row sm:justify-start sm:space-y-0 sm:space-x-4">

View file

@ -7,9 +7,9 @@ import { activeTabIdAtom } from "@/atoms/tabs/tabs.atom";
import { Logo } from "@/components/Logo";
import { Spinner } from "@/components/ui/spinner";
import { TooltipProvider } from "@/components/ui/tooltip";
import { type ResolvedTab, useResolvedTabs } from "@/hooks/use-resolved-tabs";
import { useIsMobile } from "@/hooks/use-mobile";
import { useElectronAPI } from "@/hooks/use-platform";
import { type ResolvedTab, useResolvedTabs } from "@/hooks/use-resolved-tabs";
import { cn } from "@/lib/utils";
import { SidebarProvider, useSidebarState } from "../../hooks";
import {

View file

@ -298,14 +298,8 @@ function AllChatsContent({ workspaceId, className }: AllChatsContentProps) {
{isLoading ? (
<div className="space-y-1">
{[75, 90, 55, 80, 65, 85].map((titleWidth) => (
<div
key={`skeleton-${titleWidth}`}
className="rounded-md px-3 py-1.5 md:py-2"
>
<Skeleton
className="h-4 rounded md:h-4.5"
style={{ width: `${titleWidth}%` }}
/>
<div key={`skeleton-${titleWidth}`} className="rounded-md px-3 py-1.5 md:py-2">
<Skeleton className="h-4 rounded md:h-4.5" style={{ width: `${titleWidth}%` }} />
</div>
))}
</div>
@ -419,7 +413,8 @@ function AllChatsContent({ workspaceId, className }: AllChatsContentProps) {
className={cn(
"pointer-events-auto absolute right-0 h-7 w-7 hover:bg-transparent",
openDropdownId === thread.id && "bg-accent hover:bg-accent",
openDropdownId !== thread.id && "opacity-0 group-hover/item:opacity-100"
openDropdownId !== thread.id &&
"opacity-0 group-hover/item:opacity-100"
)}
disabled={isBusy}
>

View file

@ -100,9 +100,7 @@ export function ModelsSelectionPanel({
variant="secondary"
size="sm"
className={`h-7 rounded-full px-3 text-xs ${
isActive
? "bg-brand text-white hover:bg-brand/90"
: "opacity-80"
isActive ? "bg-brand text-white hover:bg-brand/90" : "opacity-80"
}`}
onClick={() => setModelFilter(isActive ? null : filter.key)}
>

View file

@ -65,7 +65,8 @@ export const indeed: ConnectorPageContent = {
},
{
label: "Location",
description: "Formatted location, city, state, postal code, country, and remote or hybrid flags.",
description:
"Formatted location, city, state, postal code, country, and remote or hybrid flags.",
},
{
label: "Salary",
@ -157,8 +158,7 @@ export const indeed: ConnectorPageContent = {
},
schema: {
requestNote:
"Provide at least one source: urls or search_queries. Up to 20 sources per call.",
requestNote: "Provide at least one source: urls or search_queries. Up to 20 sources per call.",
request: [
{
name: "urls",

View file

@ -131,7 +131,8 @@ export const walmart: ConnectorPageContent = {
{
feature: "Reviews",
official: "A separate paid endpoint, often capped shallow",
surfsense: "A dedicated verb pages the full public review history with photos and seller replies",
surfsense:
"A dedicated verb pages the full public review history with photos and seller replies",
},
{
feature: "Data access",