Compare commits

...

53 Commits

Author SHA1 Message Date
Richard Kuo (Onyx)
7203cc76ba dead code 2025-06-13 15:45:41 -07:00
Richard Kuo (Onyx)
483a37354b remove commented code 2025-06-13 15:18:57 -07:00
Richard Kuo (Onyx)
3c8c1ab00d remove some dead code 2025-06-13 15:16:55 -07:00
Richard Kuo (Onyx)
7fd9a2cc96 remove commented code 2025-06-13 15:11:47 -07:00
Richard Kuo (Onyx)
2ca3c81ea4 ee for schema 2025-06-13 14:52:32 -07:00
Richard Kuo (Onyx)
0d90e285a4 more schema environment vars 2025-06-13 14:44:56 -07:00
Richard Kuo (Onyx)
d5394bcb88 install ee for schema generator 2025-06-13 14:29:30 -07:00
Richard Kuo (Onyx)
84b45c9366 add ee 2025-06-13 14:22:46 -07:00
Richard Kuo (Onyx)
dd8594031b fix import ordering so that env var applies 2025-06-13 14:16:15 -07:00
Richard Kuo (Onyx)
91a5e1c843 dump schema 2025-06-13 14:05:17 -07:00
Richard Kuo (Onyx)
eb0bb8a668 fix command line 2025-06-13 13:56:16 -07:00
Richard Kuo (Onyx)
59f4910fc6 print file sizes 2025-06-13 13:43:07 -07:00
Richard Kuo (Onyx)
a4edf73897 Merge branch 'main' of https://github.com/onyx-dot-app/onyx into feature/openapi-2 2025-06-13 13:31:35 -07:00
Richard Kuo (Onyx)
6361aad1b1 fix typo 2025-06-13 13:12:59 -07:00
Richard Kuo (Onyx)
4812be01bb tweaks to openapi generation 2025-06-13 13:12:43 -07:00
Richard Kuo (Onyx)
cca178c2fd add a check to enforce the openapi schema being in sync 2025-06-13 11:54:27 -07:00
Richard Kuo (Onyx)
762d03b764 check openapi schema into web 2025-06-13 11:22:43 -07:00
Richard Kuo (Onyx)
fc5c7644ca Revert "docker tweaks"
This reverts commit b4dd67ede1.
2025-06-13 10:56:11 -07:00
Richard Kuo (Onyx)
b4dd67ede1 docker tweaks 2025-06-12 11:21:16 -07:00
Richard Kuo (Onyx)
67216d8634 Merge branch 'main' of https://github.com/onyx-dot-app/onyx into feature/openapi-2 2025-06-11 17:45:08 -07:00
Richard Kuo (Onyx)
22d8c05225 fix working directory 2025-06-02 18:22:25 -07:00
Richard Kuo (Onyx)
05af5d08a9 try global vercel install 2025-06-02 16:56:07 -07:00
Richard Kuo (Onyx)
881f6abe1e npx? 2025-06-02 13:59:56 -07:00
Richard Kuo (Onyx)
fdad15eb22 try github action based vercel test 2025-06-02 13:48:44 -07:00
Richard Kuo (Onyx)
3b55284b76 update eslint parser and directives 2025-06-02 11:27:12 -07:00
Richard Kuo (Onyx)
e34ede8e81 Merge branch 'main' of https://github.com/onyx-dot-app/onyx into feature/openapi-2 2025-06-02 10:02:14 -07:00
Richard Kuo (Onyx)
6ef4f3325a add typescript client generation 2025-06-02 09:46:09 -07:00
Richard Kuo (Onyx)
f23ecb3683 Merge branch 'main' of https://github.com/onyx-dot-app/onyx into feature/openapi-2
# Conflicts:
#	.vscode/launch.template.jsonc
2025-05-30 17:15:51 -07:00
Richard Kuo (Onyx)
a46a397444 mvp of openapi client with orval 2025-05-15 18:16:45 -07:00
Richard Kuo (Onyx)
b6bb74dc90 modify tsconfig.json 2025-05-15 12:56:06 -07:00
Richard Kuo (Onyx)
5c95e8b066 add 2025-05-15 10:42:45 -07:00
Richard Kuo (Onyx)
11da426af0 add a comment 2025-05-15 09:28:56 -07:00
Richard Kuo (Onyx)
d9e239f07f use the config 2025-05-14 19:14:24 -07:00
Richard Kuo (Onyx)
d04f120556 add generated directory 2025-05-14 19:06:16 -07:00
Richard Kuo (Onyx)
46c49f6f43 more build fixes 2025-05-14 18:17:00 -07:00
Richard Kuo (Onyx)
c12cd29666 fix integration test 2025-05-14 17:24:31 -07:00
Richard Kuo (Onyx)
c08b8ee7a7 fix output dir 2025-05-14 17:15:42 -07:00
Richard Kuo (Onyx)
a82c28b8b5 try full path 2025-05-14 17:03:48 -07:00
Richard Kuo (Onyx)
719b587c03 set python path 2025-05-14 16:45:22 -07:00
Richard Kuo (Onyx)
7f45c4b10b fix script path 2025-05-14 16:35:03 -07:00
Richard Kuo (Onyx)
6ddb90661d fixes 2025-05-14 16:28:19 -07:00
Richard Kuo (Onyx)
68c54249fd first pass at making integration tests work 2025-05-14 16:12:50 -07:00
Richard Kuo (Onyx)
7a93cab338 local tests pass 2025-05-14 15:51:04 -07:00
Richard Kuo (Onyx)
be5336fc8f merge 2025-05-14 15:40:53 -07:00
Richard Kuo (Onyx)
4a44989850 fix mypy 2025-05-14 14:30:13 -07:00
Richard Kuo (Onyx)
f5bc749379 fix unused path param 2025-05-14 12:27:26 -07:00
Richard Kuo (Onyx)
f37dde0da2 update launch template 2025-05-14 11:31:22 -07:00
Richard Kuo (Onyx)
2e9151e6ed modify gitignore 2025-05-14 11:29:17 -07:00
Richard Kuo (Onyx)
b0b3101dd1 add readme 2025-05-14 11:28:58 -07:00
Richard Kuo (Onyx)
a662d0001b dedupe function names 2025-05-14 09:39:02 -07:00
Richard Kuo (Onyx)
36fed441cd send gitignore 2025-05-14 09:37:14 -07:00
Richard Kuo (Onyx)
6341149b05 fix app / app_fn 2025-05-13 16:51:47 -07:00
Richard Kuo (Onyx)
1e84e0f0d7 starting openapi support 2025-05-13 16:38:07 -07:00
25 changed files with 36117 additions and 147 deletions

View File

@@ -47,7 +47,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Docker meta
id: meta
uses: docker/metadata-action@v5

View File

@@ -52,7 +52,7 @@ jobs:
env:
PYTHONPATH: "."
run: |
python scripts/onyx_openapi_schema.py --filename generated/openapi.json
python scripts/onyx_openapi_schema.py -f generated/openapi.json
- name: Generate OpenAPI Python client
working-directory: ./backend

View File

@@ -31,6 +31,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
# we still install ee because the schema generator needs it
- name: Setup Python
uses: actions/setup-python@v5
with:
@@ -42,6 +43,7 @@ jobs:
- run: |
python -m pip install --upgrade pip
pip install --retries 5 --timeout 30 -r backend/requirements/default.txt
pip install --retries 5 --timeout 30 -r backend/requirements/ee.txt
pip install --retries 5 --timeout 30 -r backend/requirements/dev.txt
- name: Generate OpenAPI schema
@@ -49,7 +51,7 @@ jobs:
env:
PYTHONPATH: "."
run: |
python scripts/onyx_openapi_schema.py --filename generated/openapi.json
python scripts/onyx_openapi_schema.py -f generated/openapi.json
- name: Generate OpenAPI Python client
working-directory: ./backend

View File

@@ -42,9 +42,17 @@ jobs:
- run: |
python -m pip install --upgrade pip
pip install --retries 5 --timeout 30 -r backend/requirements/default.txt
pip install --retries 5 --timeout 30 -r backend/requirements/ee.txt
pip install --retries 5 --timeout 30 -r backend/requirements/dev.txt
pip install --retries 5 --timeout 30 -r backend/requirements/model_server.txt
- name: Generate OpenAPI schema
working-directory: ./backend
env:
PYTHONPATH: "."
run: |
python scripts/onyx_openapi_schema.py -f generated/openapi.json
- name: Setup node
uses: actions/setup-node@v4
with:
@@ -53,7 +61,7 @@ jobs:
- name: Install node dependencies
working-directory: ./web
run: npm ci
- name: Install playwright browsers
working-directory: ./web
run: npx playwright install --with-deps

View File

@@ -28,15 +28,25 @@ jobs:
- run: |
python -m pip install --upgrade pip
pip install --retries 5 --timeout 30 -r backend/requirements/default.txt
pip install --retries 5 --timeout 30 -r backend/requirements/ee.txt
pip install --retries 5 --timeout 30 -r backend/requirements/dev.txt
pip install --retries 5 --timeout 30 -r backend/requirements/model_server.txt
- name: Generate OpenAPI schema
- name: OpenAPI - Generate schema
working-directory: ./backend
env:
PYTHONPATH: "."
run: |
python scripts/onyx_openapi_schema.py --filename generated/openapi.json
python scripts/onyx_openapi_schema.py -f generated/openapi.json
- name: OpenAPI - Compare backend and web schemas
run: |
ls -l backend/generated/openapi.json
ls -l web/openapi/openapi.json
diff backend/generated/openapi.json web/openapi/openapi.json || {
echo "::error file=web/openapi/openapi.json is out of date. Please regenerate the schema."
exit 1
}
- name: Generate OpenAPI Python client
working-directory: ./backend
@@ -68,3 +78,10 @@ jobs:
run: |
cd backend
black --check .
- name: Upload OpenAPI schema
if: always()
uses: actions/upload-artifact@v4
with:
name: openapi-schema
path: ${{ github.workspace }}/backend/generated/openapi.json

54
.github/workflows/pr-vercel.yml vendored Normal file
View File

@@ -0,0 +1,54 @@
# https://vercel.com/guides/how-can-i-use-github-actions-with-vercel
name: Deploy Vercel Preview
on: push
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
jobs:
deploy:
name: Deploy
# See https://runs-on.com/runners/linux/
runs-on:
[
runs-on,
runner=8cpu-linux-x64,
disk=large,
"run-id=${{ github.run_id }}",
]
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup node
uses: actions/setup-node@v4
with:
node-version: 22
- name: Install node dependencies
working-directory: ./web
run: npm ci
- name: Generate OpenAPI TypeScript Client (orval)
working-directory: ./web
run: |
npx orval --config orval.config.js
# NOTE: Vercel pulls the working directory (web) from the project dashboard settings
- name: Install vercel globally
run: |
npm install --global vercel
- name: Pull Vercel Environment Information
run: vercel pull --yes --environment=preview --token=${{ secrets.VERCEL_TOKEN }}
- name: Build Project Artifacts
run: vercel build --token=${{ secrets.VERCEL_TOKEN }}
- name: Deploy Project Artifacts to Vercel
run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}

1
.gitignore vendored
View File

@@ -26,3 +26,4 @@ jira_test_env
/deployment/data/nginx/app.conf
*.sw?
/backend/tests/regression/answer_quality/search_test_config.yaml
/generated

View File

@@ -412,46 +412,47 @@
"group": "3"
}
},
{
// script to generate the openapi schema
"name": "Onyx OpenAPI Schema Generator",
"type": "debugpy",
"request": "launch",
"program": "scripts/onyx_openapi_schema.py",
"cwd": "${workspaceFolder}/backend",
"envFile": "${workspaceFolder}/.env",
"env": {
"PYTHONUNBUFFERED": "1",
"PYTHONPATH": "."
{
// script to generate the openapi schema
"name": "Onyx OpenAPI Schema Generator",
"type": "debugpy",
"request": "launch",
"program": "scripts/onyx_openapi_schema.py",
"cwd": "${workspaceFolder}/backend",
"envFile": "${workspaceFolder}/.env",
"env": {
"PYTHONUNBUFFERED": "1",
"PYTHONPATH": "."
},
"args": [
"-f",
"generated/openapi.json",
"../web/openapi/openapi.json",
]
},
"args": [
"--filename",
"generated/openapi.json",
]
},
{
// script to debug multi tenant db issues
"name": "Onyx DB Manager (Top Chunks)",
"type": "debugpy",
"request": "launch",
"program": "scripts/debugging/onyx_db.py",
"cwd": "${workspaceFolder}/backend",
"envFile": "${workspaceFolder}/.env",
"env": {
"PYTHONUNBUFFERED": "1",
"PYTHONPATH": "."
{
// script to debug multi tenant db issues
"name": "Onyx DB Manager (Top Chunks)",
"type": "debugpy",
"request": "launch",
"program": "scripts/debugging/onyx_db.py",
"cwd": "${workspaceFolder}/backend",
"envFile": "${workspaceFolder}/.env",
"env": {
"PYTHONUNBUFFERED": "1",
"PYTHONPATH": "."
},
"args": [
"--password",
"your_password_here",
"--port",
"5433",
"--report",
"top-chunks",
"--filename",
"generated/tenants_by_num_docs.csv"
]
},
"args": [
"--password",
"your_password_here",
"--port",
"5433",
"--report",
"top-chunks",
"--filename",
"generated/tenants_by_num_docs.csv"
]
},
{
"name": "Debug React Web App in Chrome",
"type": "chrome",

View File

@@ -1,6 +1,7 @@
{
"version": "2.0.0",
"tasks": [
/*
{
"type": "austin",
"label": "Profile celery beat",
@@ -20,6 +21,7 @@
"--loglevel=INFO"
]
},
*/
{
"type": "shell",
"label": "Generate Onyx OpenAPI Python client",

View File

@@ -354,7 +354,7 @@ class FailedConnectorIndexingStatus(BaseModel):
class ConnectorStatus(BaseModel):
"""
Represents the status of a connector,
including indexing status elated information
including indexing status related information
"""
cc_pair_id: int

View File

@@ -4,28 +4,35 @@
import argparse
import json
import os
from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi
from onyx.main import app as app_fn
# Force full enterprise edition schema to be generated
os.environ["ENABLE_PAID_ENTERPRISE_EDITION_FEATURES"] = "True"
# NOTE(rkuo): we're conditionally including endpoints based on auth type
# looks like a time bomb / bad design
os.environ["AUTH_TYPE"] = "basic"
if True: # noqa: E402
from onyx.main import app as app_fn
def go(filename: str) -> None:
with open(filename, "w") as f:
app: FastAPI = app_fn()
json.dump(
get_openapi(
title=app.title,
version=app.version,
openapi_version=app.openapi_version,
description=app.description,
routes=app.routes,
),
f,
)
print(f"Wrote OpenAPI schema to {filename}.")
def go(filenames: list[str]) -> None:
app: FastAPI = app_fn()
openapi_schema = get_openapi(
title=app.title,
version=app.version,
openapi_version=app.openapi_version,
description=app.description,
routes=app.routes,
)
for filename in filenames:
with open(filename, "w") as f:
json.dump(openapi_schema, f, indent=2)
print(f"Wrote OpenAPI schema to {filename}.")
def main() -> None:
@@ -33,11 +40,15 @@ def main() -> None:
description="Export OpenAPI schema for Onyx API (does not require starting API server)"
)
parser.add_argument(
"--filename", "-f", help="Filename to write to", default="openapi.json"
"--filenames",
"-f",
help="Filenames to write to. Can specify multiple delimited by spaces.",
nargs="+",
default=["openapi.json"],
)
args = parser.parse_args()
go(args.filename)
go(args.filenames)
if __name__ == "__main__":

2
generated/README.md Normal file
View File

@@ -0,0 +1,2 @@
- Generated Files
* Generated files live here.

View File

@@ -1,6 +1,7 @@
{
"extends": "next/core-web-vitals",
"plugins": ["unused-imports"],
"plugins": ["unused-imports", "@typescript-eslint"],
"parser": "@typescript-eslint/parser",
"rules": {
"@next/next/no-img-element": "off",
"react-hooks/exhaustive-deps": "off",
@@ -18,4 +19,4 @@
}
]
}
}
}

View File

@@ -26,6 +26,7 @@ COPY . .
# Install dependencies
RUN npm ci
RUN npx orval --config orval.config.js
# needed to get the `standalone` dir we expect later
ENV NEXT_PRIVATE_STANDALONE=true

2
web/openapi/README.md Normal file
View File

@@ -0,0 +1,2 @@
This openapi.json schema is generated from the backend directory and must be kept
in sync. GitHub build actions enforce this on pull requests.

33755
web/openapi/openapi.json Normal file

File diff suppressed because it is too large Load Diff

21
web/orval.config.js Normal file
View File

@@ -0,0 +1,21 @@
module.exports = {
onyx: {
input: {
target: "openapi/openapi.json",
},
output: {
mode: "tags-split",
target: "src/lib/generated/onyx-api/api.ts",
schemas: "src/lib/generated/onyx-api/model",
client: "swr",
httpClient: "fetch",
baseUrl: "http://localhost:3000",
override: {
mutator: {
path: "./src/lib/orvalFetcher.ts",
name: "orvalFetch",
},
},
},
},
};

2055
web/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -100,11 +100,14 @@
"@tailwindcss/typography": "^0.5.10",
"@types/chrome": "^0.0.287",
"@types/jest": "^29.5.14",
"@typescript-eslint/eslint-plugin": "^8.33.0",
"@typescript-eslint/parser": "^8.33.0",
"chromatic": "^11.25.2",
"eslint": "^8.57.1",
"eslint-config-next": "^14.1.0",
"eslint-plugin-unused-imports": "^4.1.4",
"jest": "^29.7.0",
"orval": "^7.9.0",
"prettier": "2.8.8",
"ts-jest": "^29.2.5",
"ts-unused-exports": "^11.0.1"

View File

@@ -12,7 +12,6 @@ import { Button } from "@/components/ui/button";
import { CCPairStatus, IndexAttemptStatus } from "@/components/Status";
import { timeAgo } from "@/lib/time";
import {
ConnectorIndexingStatus,
ConnectorSummary,
GroupedConnectorSummaries,
ValidSources,
@@ -42,6 +41,7 @@ import { TOGGLED_CONNECTORS_COOKIE_NAME } from "@/lib/constants";
import { usePaidEnterpriseFeaturesEnabled } from "@/components/settings/usePaidEnterpriseFeaturesEnabled";
import { ConnectorCredentialPairStatus } from "../../connector/[ccPairId]/types";
import { FilterComponent, FilterOptions } from "./FilterComponent";
import { ConnectorIndexingStatus } from "@/lib/generated/onyx-api/model";
function SummaryRow({
source,
@@ -122,7 +122,7 @@ function ConnectorRow({
invisible,
isEditable,
}: {
ccPairsIndexingStatus: ConnectorIndexingStatus<any, any>;
ccPairsIndexingStatus: ConnectorIndexingStatus;
invisible?: boolean;
isEditable: boolean;
}) {
@@ -182,7 +182,9 @@ border border-border dark:border-neutral-700
icon={FiRefreshCw}
>
Inherited from{" "}
{getSourceDisplayName(ccPairsIndexingStatus.connector.source)}
{getSourceDisplayName(
ccPairsIndexingStatus.connector.source as ValidSources
)}
</Badge>
) : (
<Badge variant={isEditable ? "private" : "default"} icon={FiLock}>
@@ -217,8 +219,8 @@ export function CCPairIndexingStatusTable({
ccPairsIndexingStatuses,
editableCcPairsIndexingStatuses,
}: {
ccPairsIndexingStatuses: ConnectorIndexingStatus<any, any>[];
editableCcPairsIndexingStatuses: ConnectorIndexingStatus<any, any>[];
ccPairsIndexingStatuses: ConnectorIndexingStatus[];
editableCcPairsIndexingStatuses: ConnectorIndexingStatus[];
}) {
const [searchTerm, setSearchTerm] = useState("");
@@ -258,12 +260,12 @@ export function CCPairIndexingStatusTable({
groupSummaries,
filteredGroupedStatuses,
} = useMemo(() => {
const grouped: Record<ValidSources, ConnectorIndexingStatus<any, any>[]> =
{} as Record<ValidSources, ConnectorIndexingStatus<any, any>[]>;
const grouped: Record<ValidSources, ConnectorIndexingStatus[]> =
{} as Record<ValidSources, ConnectorIndexingStatus[]>;
// First, add editable connectors
editableCcPairsIndexingStatuses.forEach((status) => {
const source = status.connector.source;
const source = status.connector.source as ValidSources;
if (!grouped[source]) {
grouped[source] = [];
}
@@ -272,7 +274,7 @@ export function CCPairIndexingStatusTable({
// Then, add non-editable connectors
ccPairsIndexingStatuses.forEach((status) => {
const source = status.connector.source;
const source = status.connector.source as ValidSources;
if (!grouped[source]) {
grouped[source] = [];
}
@@ -310,10 +312,8 @@ export function CCPairIndexingStatusTable({
});
// Apply filters to create filtered grouped statuses
const filteredGrouped: Record<
ValidSources,
ConnectorIndexingStatus<any, any>[]
> = {} as Record<ValidSources, ConnectorIndexingStatus<any, any>[]>;
const filteredGrouped: Record<ValidSources, ConnectorIndexingStatus[]> =
{} as Record<ValidSources, ConnectorIndexingStatus[]>;
sorted.forEach((source) => {
const statuses = grouped[source];
@@ -495,10 +495,9 @@ export function CCPairIndexingStatusTable({
},
refresh_freq: 86400,
prune_freq: null,
indexing_start: new Date("2023-07-01T12:00:00Z"),
indexing_start: new Date("2023-07-01T12:00:00Z").toString(),
id: 1,
credential_ids: [],
access_type: "public",
time_created: "2023-07-01T12:00:00Z",
time_updated: "2023-07-01T12:00:00Z",
},
@@ -520,6 +519,8 @@ export function CCPairIndexingStatusTable({
latest_index_attempt: null,
groups: [], // Add this line
in_repeated_error_state: false,
owner: "",
in_progress: false,
}}
isEditable={false}
/>

View File

@@ -6,22 +6,38 @@ import { CCPairIndexingStatusTable } from "./CCPairIndexingStatusTable";
import { AdminPageTitle } from "@/components/admin/Title";
import Link from "next/link";
import Text from "@/components/ui/text";
import { useConnectorCredentialIndexingStatus } from "@/lib/hooks";
import { usePopupFromQuery } from "@/components/popup/PopupFromQuery";
import { Button } from "@/components/ui/button";
import {
GetConnectorIndexingStatusQueryError,
GetConnectorIndexingStatusQueryResult,
useGetConnectorIndexingStatus,
} from "@/lib/generated/onyx-api/default/default";
import { HTTPValidationError } from "@/lib/generated/onyx-api/model";
function Main() {
const {
data: indexAttemptData,
isLoading: indexAttemptIsLoading,
error: indexAttemptError,
} = useConnectorCredentialIndexingStatus();
} = useGetConnectorIndexingStatus<HTTPValidationError>(undefined, {
swr: {
refreshInterval: 30000,
},
});
const {
data: editableIndexAttemptData,
isLoading: editableIndexAttemptIsLoading,
error: editableIndexAttemptError,
} = useConnectorCredentialIndexingStatus(undefined, true);
} = useGetConnectorIndexingStatus<HTTPValidationError>(
{ get_editable: true }, // or undefined if false
{
swr: {
refreshInterval: undefined,
},
}
);
if (indexAttemptIsLoading || editableIndexAttemptIsLoading) {
return <LoadingAnimation text="" />;
@@ -35,14 +51,46 @@ function Main() {
) {
return (
<div className="text-error">
{indexAttemptError?.info?.detail ||
editableIndexAttemptError?.info?.detail ||
{indexAttemptError?.detail?.[0]?.msg ||
editableIndexAttemptError?.detail?.[0]?.msg ||
"Error loading indexing history."}
</div>
);
}
if (indexAttemptData.length === 0) {
// Handle cases where data from SWR is unexpectedly undefined
if (!indexAttemptData || !editableIndexAttemptData) {
return (
<div className="text-error">
Indexing history data is not available. This is an unexpected state.
</div>
);
}
// Handle API errors returned in the response (e.g., status 422)
if (indexAttemptData.status !== 200) {
const apiError = indexAttemptData.data as HTTPValidationError;
const message =
apiError.detail?.[0]?.msg ||
`API error fetching primary indexing status (Status: ${indexAttemptData.status}).`;
return <div className="text-error">{message}</div>;
}
if (editableIndexAttemptData.status !== 200) {
const apiError = editableIndexAttemptData.data as HTTPValidationError;
const message =
apiError.detail?.[0]?.msg ||
`API error fetching editable indexing status (Status: ${editableIndexAttemptData.status}).`;
return <div className="text-error">{message}</div>;
}
// At this point, both API calls were successful (status 200)
// indexAttemptData.data is ConnectorIndexingStatus[]
// editableIndexAttemptData.data is ConnectorIndexingStatus[]
const actualIndexAttempts = indexAttemptData.data; // No `as ConnectorIndexingStatus[]` needed if TS infers correctly
const actualEditableIndexAttempts = editableIndexAttemptData.data;
if (actualIndexAttempts.length === 0) {
return (
<Text>
It looks like you don&apos;t have any connectors setup yet. Visit the{" "}
@@ -55,7 +103,7 @@ function Main() {
}
// sort by source name
indexAttemptData.sort((a, b) => {
actualIndexAttempts.sort((a, b) => {
if (a.connector.source < b.connector.source) {
return -1;
} else if (a.connector.source > b.connector.source) {
@@ -67,8 +115,8 @@ function Main() {
return (
<CCPairIndexingStatusTable
ccPairsIndexingStatuses={indexAttemptData}
editableCcPairsIndexingStatuses={editableIndexAttemptData}
ccPairsIndexingStatuses={actualIndexAttempts}
editableCcPairsIndexingStatuses={actualEditableIndexAttempts}
/>
);
}

View File

@@ -9,13 +9,14 @@ import {
FiMinus,
FiPauseCircle,
} from "react-icons/fi";
import { ConnectorCredentialPairStatus } from "@/app/admin/connector/[ccPairId]/types";
// import { ConnectorCredentialPairStatus } from "@/app/admin/connector/[ccPairId]/types";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import { ConnectorCredentialPairStatus } from "@/lib/generated/onyx-api/model/connectorCredentialPairStatus";
export function IndexAttemptStatus({
status,

View File

@@ -78,29 +78,8 @@ export const useObjectState = <T>(
return [state, set];
};
const INDEXING_STATUS_URL = "/api/manage/admin/connector/indexing-status";
const CONNECTOR_STATUS_URL = "/api/manage/admin/connector/status";
export const useConnectorCredentialIndexingStatus = (
refreshInterval = 30000, // 30 seconds
getEditable = false
) => {
const { mutate } = useSWRConfig();
const url = `${INDEXING_STATUS_URL}${
getEditable ? "?get_editable=true" : ""
}`;
const swrResponse = useSWR<ConnectorIndexingStatus<any, any>[]>(
url,
errorHandlingFetcher,
{ refreshInterval: refreshInterval }
);
return {
...swrResponse,
refreshIndexingStatus: () => mutate(url),
};
};
export const useConnectorStatus = (refreshInterval = 30000) => {
const { mutate } = useSWRConfig();
const url = CONNECTOR_STATUS_URL;

View File

@@ -0,0 +1,75 @@
// NOTE: Supports cases where `content-type` is other than `json`
const getBody = <T>(c: Response | Request): Promise<T> => {
const contentType = c.headers.get("content-type");
if (contentType && contentType.includes("application/json")) {
return c.json();
}
if (contentType && contentType.includes("application/pdf")) {
return c.blob() as Promise<T>;
}
return c.text() as Promise<T>;
};
// NOTE(rkuo): we must return a relative URL to get the routes working
const getUrl = (contextUrl: string): string => {
const url = new URL(contextUrl);
const pathname = url.pathname;
const search = url.search;
const baseUrl = "/api";
const requestUrl = `${baseUrl}${pathname}${search}`;
return requestUrl.toString();
};
// NOTE: Add headers
const getHeaders = (headers?: HeadersInit): HeadersInit => {
return {
...headers,
};
};
export const orvalFetch = async <T>(
url: string,
options: RequestInit
): Promise<T> => {
const isServer = typeof window === "undefined";
const requestUrl = getUrl(url);
const requestHeaders = getHeaders(options.headers);
let requestInit: RequestInit;
if (isServer) {
// Server-side: manually attach cookies
const { cookies } = require("next/headers");
// const cookieString = cookies().toString();
// console.log('Server-side cookies:', cookieString);
requestInit = {
...options,
headers: {
...requestHeaders,
Cookie: cookies().toString(), // Manually attach cookies on server
},
};
} else {
// Client-side: let browser handle cookies
// console.log('Client-side cookies available:', document.cookie ? 'Yes' : 'No');
requestInit = {
...options,
headers: requestHeaders,
credentials: "include", // Browser will automatically include cookies
};
}
// console.log('Request URL:', requestUrl);
// console.log('Request headers:', requestInit.headers);
const response = await fetch(requestUrl, requestInit);
const data = await getBody<T>(response);
return { status: response.status, data, headers: response.headers } as T;
};

View File

@@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "es5",
"target": "es6",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,