Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2,363 changes: 1,095 additions & 1,268 deletions ui/desktop/package-lock.json

Large diffs are not rendered by default.

72 changes: 36 additions & 36 deletions ui/desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,44 +39,44 @@
"start-alpha-gui": "ALPHA=true npm run start-gui"
},
"dependencies": {
"@ai-sdk/openai": "^2.0.52",
"@ai-sdk/openai": "^2.0.76",
"@ai-sdk/ui-utils": "^1.2.11",
"@mcp-ui/client": "^5.14.1",
"@mcp-ui/client": "^5.17.1",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-avatar": "^1.1.11",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-popover": "^1.1.15",
"@radix-ui/react-radio-group": "^1.3.8",
"@radix-ui/react-scroll-area": "^1.2.10",
"@radix-ui/react-select": "^2.2.6",
"@radix-ui/react-slot": "^1.2.3",
"@radix-ui/react-slot": "^1.2.4",
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/themes": "^3.2.1",
"@tanstack/react-form": "^1.23.7",
"@tanstack/react-form": "^1.27.0",
"@types/react-router-dom": "^5.3.3",
"ai": "^5.0.76",
"ai": "^5.0.106",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"compare-versions": "^6.1.1",
"cors": "^2.8.5",
"cronstrue": "^3.3.0",
"cronstrue": "^3.9.0",
"date-fns": "^4.1.0",
"dotenv": "^17.2.3",
"electron-log": "^5.4.3",
"electron-squirrel-startup": "^1.0.1",
"electron-updater": "^6.6.2",
"electron-window-state": "^5.0.3",
"express": "^5.1.0",
"express": "^5.2.1",
"katex": "^0.16.25",
"lodash": "^4.17.21",
"lucide-react": "^0.546.0",
"lucide-react": "^0.555.0",
"qrcode.react": "^4.2.0",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-icons": "^5.5.0",
"react-markdown": "^10.1.0",
"react-router-dom": "^7.9.4",
"react-router-dom": "^7.10.0",
"react-select": "^5.10.2",
"react-syntax-highlighter": "^16.1.0",
"react-toastify": "^11.0.5",
Expand All @@ -85,8 +85,8 @@
"remark-gfm": "^4.0.1",
"remark-math": "^6.0.0",
"split-type": "^0.3.4",
"swr": "^2.3.6",
"tailwind-merge": "^3.3.1",
"swr": "^2.3.7",
"tailwind-merge": "^3.4.0",
"tailwindcss-animate": "^1.0.7",
"tw-animate-css": "^1.4.0",
"unist-util-visit": "^5.0.0",
Expand All @@ -104,45 +104,45 @@
"@electron-forge/plugin-vite": "^7.10.2",
"@electron/fuses": "^1.8.0",
"@electron/remote": "^2.1.3",
"@eslint/js": "^9.33.0",
"@hey-api/openapi-ts": "^0.85.2",
"@modelcontextprotocol/sdk": "^1.20.1",
"@playwright/test": "^1.56.1",
"@eslint/js": "^9.39.1",
"@hey-api/openapi-ts": "^0.88.0",
"@modelcontextprotocol/sdk": "^1.24.0",
"@playwright/test": "^1.57.0",
"@tailwindcss/line-clamp": "^0.4.4",
"@tailwindcss/typography": "^0.5.19",
"@tailwindcss/vite": "^4.1.14",
"@tailwindcss/vite": "^4.1.17",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.0",
"@testing-library/user-event": "^14.6.1",
"@types/cors": "^2.8.19",
"@types/electron-squirrel-startup": "^1.0.2",
"@types/express": "^5.0.3",
"@types/lodash": "^4.17.20",
"@types/react": "^19.2.2",
"@types/react-dom": "^19.2.2",
"@types/express": "^5.0.6",
"@types/lodash": "^4.17.21",
"@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3",
"@types/react-syntax-highlighter": "^15.5.13",
"@types/yauzl": "^2.10.3",
"@typescript-eslint/eslint-plugin": "^8.39.1",
"@typescript-eslint/parser": "^8.39.1",
"@vitejs/plugin-react": "^5.0.4",
"@vitest/coverage-v8": "^3.2.4",
"@vitest/ui": "^3.2.4",
"autoprefixer": "^10.4.21",
"electron": "^38.3.0",
"@typescript-eslint/eslint-plugin": "^8.48.1",
"@typescript-eslint/parser": "^8.48.1",
"@vitejs/plugin-react": "^5.1.1",
"@vitest/coverage-v8": "^4.0.15",
"@vitest/ui": "^4.0.15",
"autoprefixer": "^10.4.22",
"electron": "^39.2.4",
"electron-devtools-installer": "^4.0.0",
"eslint": "^9.33.0",
"eslint": "^9.39.1",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"husky": "^9.1.7",
"jsdom": "^27.0.0",
"knip": "^5.66.0",
"lint-staged": "^16.2.4",
"jsdom": "^27.2.0",
"knip": "^5.71.0",
"lint-staged": "^16.2.7",
"postcss": "^8.5.6",
"prettier": "^3.6.2",
"tailwindcss": "^4.1.14",
"prettier": "^3.7.3",
"tailwindcss": "^4.1.17",
"typescript": "~5.9.3",
"vite": "^7.1.10",
"vitest": "^3.2.4"
"vite": "^7.2.6",
"vitest": "^4.0.15"
},
"keywords": [],
"license": "Apache-2.0",
Expand Down
35 changes: 34 additions & 1 deletion ui/desktop/src/api/client/client.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,40 @@ export const createClient = (config: Config = {}): Client => {
// fetch must be assigned here, otherwise it would throw the error:
// TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation
const _fetch = opts.fetch!;
let response = await _fetch(request);
let response: Response;

try {
response = await _fetch(request);
} catch (error) {
// Handle fetch exceptions (AbortError, network errors, etc.)
let finalError = error;

for (const fn of interceptors.error.fns) {
if (fn) {
finalError = (await fn(
error,
undefined as any,
request,
opts,
)) as unknown;
}
}

finalError = finalError || ({} as unknown);

if (opts.throwOnError) {
throw finalError;
}

// Return error response
return opts.responseStyle === 'data'
? undefined
: {
error: finalError,
request,
response: undefined as any,
};
}

for (const fn of interceptors.response.fns) {
if (fn) {
Expand Down
1 change: 0 additions & 1 deletion ui/desktop/src/api/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ export type {
Config,
CreateClientConfig,
Options,
OptionsLegacyParser,
RequestOptions,
RequestResult,
ResolvedRequestOptions,
Expand Down
31 changes: 2 additions & 29 deletions ui/desktop/src/api/client/types.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ type BuildUrlFn = <
url: string;
},
>(
options: Pick<TData, 'url'> & Options<TData>,
options: TData & Options<TData>,
) => string;

export type Client = CoreClient<
Expand Down Expand Up @@ -238,31 +238,4 @@ export type Options<
RequestOptions<TResponse, TResponseStyle, ThrowOnError>,
'body' | 'path' | 'query' | 'url'
> &
Omit<TData, 'url'>;

export type OptionsLegacyParser<
TData = unknown,
ThrowOnError extends boolean = boolean,
TResponseStyle extends ResponseStyle = 'fields',
> = TData extends { body?: any }
? TData extends { headers?: any }
? OmitKeys<
RequestOptions<unknown, TResponseStyle, ThrowOnError>,
'body' | 'headers' | 'url'
> &
TData
: OmitKeys<
RequestOptions<unknown, TResponseStyle, ThrowOnError>,
'body' | 'url'
> &
TData &
Pick<RequestOptions<unknown, TResponseStyle, ThrowOnError>, 'headers'>
: TData extends { headers?: any }
? OmitKeys<
RequestOptions<unknown, TResponseStyle, ThrowOnError>,
'headers' | 'url'
> &
TData &
Pick<RequestOptions<unknown, TResponseStyle, ThrowOnError>, 'body'>
: OmitKeys<RequestOptions<unknown, TResponseStyle, ThrowOnError>, 'url'> &
TData;
([TData] extends [never] ? unknown : Omit<TData, 'url'>);
17 changes: 9 additions & 8 deletions ui/desktop/src/api/client/utils.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import { getUrl } from '../core/utils.gen';
import type { Client, ClientOptions, Config, RequestOptions } from './types.gen';

export const createQuerySerializer = <T = unknown>({
allowReserved,
array,
object,
parameters = {},
...args
}: QuerySerializerOptions = {}) => {
const querySerializer = (queryParams: T) => {
const search: string[] = [];
Expand All @@ -26,29 +25,31 @@ export const createQuerySerializer = <T = unknown>({
continue;
}

const options = parameters[name] || args;

if (Array.isArray(value)) {
const serializedArray = serializeArrayParam({
allowReserved,
allowReserved: options.allowReserved,
explode: true,
name,
style: 'form',
value,
...array,
...options.array,
});
if (serializedArray) search.push(serializedArray);
} else if (typeof value === 'object') {
const serializedObject = serializeObjectParam({
allowReserved,
allowReserved: options.allowReserved,
explode: true,
name,
style: 'deepObject',
value: value as Record<string, unknown>,
...object,
...options.object,
});
if (serializedObject) search.push(serializedObject);
} else {
const serializedPrimitive = serializePrimitiveParam({
allowReserved,
allowReserved: options.allowReserved,
name,
value: value as string,
});
Expand Down
16 changes: 12 additions & 4 deletions ui/desktop/src/api/core/bodySerializer.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,19 @@ export type QuerySerializer = (query: Record<string, unknown>) => string;

export type BodySerializer = (body: any) => any;

export interface QuerySerializerOptions {
type QuerySerializerOptionsObject = {
allowReserved?: boolean;
array?: SerializerOptions<ArrayStyle>;
object?: SerializerOptions<ObjectStyle>;
}
array?: Partial<SerializerOptions<ArrayStyle>>;
object?: Partial<SerializerOptions<ObjectStyle>>;
};

export type QuerySerializerOptions = QuerySerializerOptionsObject & {
/**
* Per-parameter serialization overrides. When provided, these settings
* override the global array/object settings for specific parameter names.
*/
parameters?: Record<string, QuerySerializerOptionsObject>;
};

const serializeFormDataPair = (
data: FormData,
Expand Down
45 changes: 34 additions & 11 deletions ui/desktop/src/api/core/params.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@ export type Field =
*/
key?: string;
map?: string;
}
| {
/**
* Field name. This is the name we want the user to see and use.
*/
key: string;
/**
* Field mapped name. This is the name we want to use in the request.
* If `in` is omitted, `map` aliases `key` to the transport layer.
*/
map: Slot;
};

export interface Fields {
Expand All @@ -41,10 +52,14 @@ const extraPrefixes = Object.entries(extraPrefixesMap);

type KeyMap = Map<
string,
{
in: Slot;
map?: string;
}
| {
in: Slot;
map?: string;
}
| {
in?: never;
map: Slot;
}
>;

const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => {
Expand All @@ -60,6 +75,10 @@ const buildKeyMap = (fields: FieldsConfig, map?: KeyMap): KeyMap => {
map: config.map,
});
}
} else if ('key' in config) {
map.set(config.key, {
map: config.map,
});
} else if (config.args) {
buildKeyMap(config.args, map);
}
Expand Down Expand Up @@ -111,7 +130,9 @@ export const buildClientParams = (
if (config.key) {
const field = map.get(config.key)!;
const name = field.map || config.key;
(params[field.in] as Record<string, unknown>)[name] = arg;
if (field.in) {
(params[field.in] as Record<string, unknown>)[name] = arg;
}
} else {
params.body = arg;
}
Expand All @@ -120,8 +141,12 @@ export const buildClientParams = (
const field = map.get(key);

if (field) {
const name = field.map || key;
(params[field.in] as Record<string, unknown>)[name] = value;
if (field.in) {
const name = field.map || key;
(params[field.in] as Record<string, unknown>)[name] = value;
} else {
params[field.map] = value;
}
} else {
const extra = extraPrefixes.find(([prefix]) =>
key.startsWith(prefix),
Expand All @@ -132,10 +157,8 @@ export const buildClientParams = (
(params[slot] as Record<string, unknown>)[
key.slice(prefix.length)
] = value;
} else {
for (const [slot, allowed] of Object.entries(
config.allowExtra ?? {},
)) {
} else if ('allowExtra' in config && config.allowExtra) {
for (const [slot, allowed] of Object.entries(config.allowExtra)) {
if (allowed) {
(params[slot as Slot] as Record<string, unknown>)[key] = value;
break;
Expand Down
Loading
Loading