mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-16 09:36:17 +08:00
566ff7470e
This PR contains the following updates: | Package | Change | Age | Adoption | Passing | Confidence | |---|---|---|---|---|---| | [oxlint](https://oxc.rs) ([source](https://redirect.github.com/oxc-project/oxc/tree/HEAD/npm/oxlint)) | [`0.16.11` -> `0.18.1`](https://renovatebot.com/diffs/npm/oxlint/0.16.11/0.18.1) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | [](https://docs.renovatebot.com/merge-confidence/) | --- ### Release Notes <details> <summary>oxc-project/oxc (oxlint)</summary> ### [`v0.18.1`](https://redirect.github.com/oxc-project/oxc/releases/tag/oxlint_v0.18.1): oxlint v0.18.1 [Compare Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v0.18.0...oxlint_v0.18.1) #### \[0.18.1] - 2025-06-09 ##### 🐛 Bug Fixes - [`6d68568`](https://redirect.github.com/oxc-project/oxc/commit/6d68568) linter: False negative in typescript/array-type ([#​11574](https://redirect.github.com/oxc-project/oxc/issues/11574)) (camc314) - [`6a856a0`](https://redirect.github.com/oxc-project/oxc/commit/6a856a0) linter/no-magic-numbers: Fix typo in error message ([#​11560](https://redirect.github.com/oxc-project/oxc/issues/11560)) (overlookmotel) - [`3952e01`](https://redirect.github.com/oxc-project/oxc/commit/3952e01) linter: False negative in jsx-a11y/aria-role ([#​11547](https://redirect.github.com/oxc-project/oxc/issues/11547)) (camc314) - [`b0e3e08`](https://redirect.github.com/oxc-project/oxc/commit/b0e3e08) linter: Misplaced quote in jsx-curly-brace-presence test case ([#​11546](https://redirect.github.com/oxc-project/oxc/issues/11546)) (camc314) - [`a833ed1`](https://redirect.github.com/oxc-project/oxc/commit/a833ed1) linter: Misplaced quote in anchor-is-valid test case ([#​11545](https://redirect.github.com/oxc-project/oxc/issues/11545)) (camc314) - [`4e53b80`](https://redirect.github.com/oxc-project/oxc/commit/4e53b80) linter: Misplaced backtick in exhaustive-deps test case ([#​11544](https://redirect.github.com/oxc-project/oxc/issues/11544)) (camc314) - [`e8a04b6`](https://redirect.github.com/oxc-project/oxc/commit/e8a04b6) linter: Misplaced backtick in no-object-constructor test case ([#​11543](https://redirect.github.com/oxc-project/oxc/issues/11543)) (camc314) - [`65311d0`](https://redirect.github.com/oxc-project/oxc/commit/65311d0) linter: Remove duplicate rule/scope from diagnostic ([#​11531](https://redirect.github.com/oxc-project/oxc/issues/11531)) (camc314) ##### 🚜 Refactor - [`7ab84c2`](https://redirect.github.com/oxc-project/oxc/commit/7ab84c2) editor: Use pattern for textDocument filter ([#​11559](https://redirect.github.com/oxc-project/oxc/issues/11559)) (Sysix) - [`9b475ad`](https://redirect.github.com/oxc-project/oxc/commit/9b475ad) linter: Use one instance of rope per file ([#​11552](https://redirect.github.com/oxc-project/oxc/issues/11552)) (Sysix) ##### 📚 Documentation - [`e13ed51`](https://redirect.github.com/oxc-project/oxc/commit/e13ed51) editor/vscode: Fix typo in README ([#​11572](https://redirect.github.com/oxc-project/oxc/issues/11572)) (David) - [`fa924ab`](https://redirect.github.com/oxc-project/oxc/commit/fa924ab) linter: Cleanup docs for multiple linter rules ([#​11551](https://redirect.github.com/oxc-project/oxc/issues/11551)) (Ulrich Stark) ##### ⚡ Performance - [`7bf25cb`](https://redirect.github.com/oxc-project/oxc/commit/7bf25cb) language_server: Transform `MessageWithPosition` to `Diagnostic` with less allocations ([#​11561](https://redirect.github.com/oxc-project/oxc/issues/11561)) (Sysix) ### [`v0.18.0`](https://redirect.github.com/oxc-project/oxc/releases/tag/oxlint_v0.18.0): oxlint v0.18.0 [Compare Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v0.17.0...oxlint_v0.18.0) #### \[0.18.0] - 2025-06-06 - [`bd9dd88`](https://redirect.github.com/oxc-project/oxc/commit/bd9dd88) linter: \[**BREAKING**] Add more info to json reporter ([#​11524](https://redirect.github.com/oxc-project/oxc/issues/11524)) (camc314) ##### Features - [`825d40c`](https://redirect.github.com/oxc-project/oxc/commit/825d40c) linter: Fix casing in unicorn/no-useless-promise-resolve-reject ([#​11528](https://redirect.github.com/oxc-project/oxc/issues/11528)) (camc314) - [`2faee3d`](https://redirect.github.com/oxc-project/oxc/commit/2faee3d) linter: Fix grammer in react/exhaustive-deps ([#​11527](https://redirect.github.com/oxc-project/oxc/issues/11527)) (camc314) ##### Bug Fixes - [`1a71d7c`](https://redirect.github.com/oxc-project/oxc/commit/1a71d7c) linter: Misplaced backtick in unicorn/no-array-for-each diagnostic ([#​11529](https://redirect.github.com/oxc-project/oxc/issues/11529)) (camc314) - [`7430b14`](https://redirect.github.com/oxc-project/oxc/commit/7430b14) linter: Grammer in jest/valid-expect diagnostic ([#​11522](https://redirect.github.com/oxc-project/oxc/issues/11522)) (camc314) - [`b92ac41`](https://redirect.github.com/oxc-project/oxc/commit/b92ac41) linter: Grammer in eslint/no-redeclare diagnostic ([#​11521](https://redirect.github.com/oxc-project/oxc/issues/11521)) (camc314) - [`17883e3`](https://redirect.github.com/oxc-project/oxc/commit/17883e3) linter: Improve eslint/no-unsafe-negation diagnostic ([#​11520](https://redirect.github.com/oxc-project/oxc/issues/11520)) (camc314) - [`8c89937`](https://redirect.github.com/oxc-project/oxc/commit/8c89937) linter: Improve eslint/no-shadow-restricted-names diagnostic ([#​11519](https://redirect.github.com/oxc-project/oxc/issues/11519)) (camc314) - [`3f0d889`](https://redirect.github.com/oxc-project/oxc/commit/3f0d889) linter: Add missing article to oxc/bad-array-method-on-arguments diagnostic ([#​11518](https://redirect.github.com/oxc-project/oxc/issues/11518)) (camc314) - [`cf0c24c`](https://redirect.github.com/oxc-project/oxc/commit/cf0c24c) linter: Improve message in react/prefer-es6-class diagnostic ([#​11516](https://redirect.github.com/oxc-project/oxc/issues/11516)) (camc314) - [`91855df`](https://redirect.github.com/oxc-project/oxc/commit/91855df) linter: Fix message in react/rules-of-hooks diagnostic ([#​11515](https://redirect.github.com/oxc-project/oxc/issues/11515)) (camc314) - [`b272194`](https://redirect.github.com/oxc-project/oxc/commit/b272194) linter: Misplaced backtick in jest/no-conditional-expect diagnostic ([#​11514](https://redirect.github.com/oxc-project/oxc/issues/11514)) (camc314) - [`3403303`](https://redirect.github.com/oxc-project/oxc/commit/3403303) linter: Misplaced backtick in unicorn/prefer-dom-node-dataset diagnostic ([#​11513](https://redirect.github.com/oxc-project/oxc/issues/11513)) (camc314) - [`d5ca872`](https://redirect.github.com/oxc-project/oxc/commit/d5ca872) linter: Misplaced backtick in eslint/radix diagnostic ([#​11512](https://redirect.github.com/oxc-project/oxc/issues/11512)) (camc314) - [`2dcf8be`](https://redirect.github.com/oxc-project/oxc/commit/2dcf8be) linter: Improve diagnostic message when function name is referenced ([#​11509](https://redirect.github.com/oxc-project/oxc/issues/11509)) (camc314) - [`0de0c9c`](https://redirect.github.com/oxc-project/oxc/commit/0de0c9c) linter: Improve diagnostic message for no-unsafe-declaration-merging ([#​11508](https://redirect.github.com/oxc-project/oxc/issues/11508)) (camc314) - [`0946dac`](https://redirect.github.com/oxc-project/oxc/commit/0946dac) linter: Correctly inherit categories when plugins are enabled ([#​11353](https://redirect.github.com/oxc-project/oxc/issues/11353)) (Cameron) - [`510c1c6`](https://redirect.github.com/oxc-project/oxc/commit/510c1c6) linter: Add missing `allowArrowFunctions` option for eslint/func-style ([#​11455](https://redirect.github.com/oxc-project/oxc/issues/11455)) (yefan) - [`c77787c`](https://redirect.github.com/oxc-project/oxc/commit/c77787c) linter: Improve `eslint/no-loss-of-precision` ([#​11437](https://redirect.github.com/oxc-project/oxc/issues/11437)) (magic-akari) - [`11d4523`](https://redirect.github.com/oxc-project/oxc/commit/11d4523) linter: False positive in react/exhaustive-deps ([#​11438](https://redirect.github.com/oxc-project/oxc/issues/11438)) (camc314) - [`616b613`](https://redirect.github.com/oxc-project/oxc/commit/616b613) linter/switch-case-braces: Align the logic with `unicorn` ([#​11405](https://redirect.github.com/oxc-project/oxc/issues/11405)) (shulaoda) ##### Refactor - [`db0b099`](https://redirect.github.com/oxc-project/oxc/commit/db0b099) language_server: Convert only once uri to path when creating `ServerLinter` ([#​11503](https://redirect.github.com/oxc-project/oxc/issues/11503)) (Sysix) - [`ccceb52`](https://redirect.github.com/oxc-project/oxc/commit/ccceb52) language_server: Simplify `workspace/didChangeConfiguration` call ([#​11462](https://redirect.github.com/oxc-project/oxc/issues/11462)) (Sysix) - [`0fdc51e`](https://redirect.github.com/oxc-project/oxc/commit/0fdc51e) linter: Simplify `OxlintRules::override_rules` ([#​11510](https://redirect.github.com/oxc-project/oxc/issues/11510)) (camc314) ##### Testing - [`2ba2893`](https://redirect.github.com/oxc-project/oxc/commit/2ba2893) editor: Fix test for auto `fixAll` on save ([#​11448](https://redirect.github.com/oxc-project/oxc/issues/11448)) (Sysix) ### [`v0.17.0`](https://redirect.github.com/oxc-project/oxc/releases/tag/oxlint_v0.17.0): oxlint v0.17.0 [Compare Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v0.16.12...oxlint_v0.17.0) #### \[0.17.0] - 2025-05-30 - [`ead5309`](https://redirect.github.com/oxc-project/oxc/commit/ead5309) linter: \[**BREAKING**] Remove react from default plugin set ([#​11382](https://redirect.github.com/oxc-project/oxc/issues/11382)) (camc314) ##### Features - [`2d25bd8`](https://redirect.github.com/oxc-project/oxc/commit/2d25bd8) linter: Remove `unicorn/no-for-loop` over `typescript/prefer-for-of` ([#​11354](https://redirect.github.com/oxc-project/oxc/issues/11354)) (camc314) - [`bbb7eb1`](https://redirect.github.com/oxc-project/oxc/commit/bbb7eb1) linter: Add auto-fix to react/forward-ref-uses-ref ([#​11342](https://redirect.github.com/oxc-project/oxc/issues/11342)) (yefan) - [`590c27b`](https://redirect.github.com/oxc-project/oxc/commit/590c27b) linter: Add auto-fix to unicorn/no-await-expression-member ([#​11306](https://redirect.github.com/oxc-project/oxc/issues/11306)) (yefan) - [`7824f01`](https://redirect.github.com/oxc-project/oxc/commit/7824f01) linter: Implement suggestion for `jsx/no-useless-fragment` ([#​10800](https://redirect.github.com/oxc-project/oxc/issues/10800)) (Cam McHenry) - [`2083d33`](https://redirect.github.com/oxc-project/oxc/commit/2083d33) linter/language_server: Add second editor suggestion for `react/forward-ref-uses-ref` ([#​11375](https://redirect.github.com/oxc-project/oxc/issues/11375)) (Sysix) ##### Bug Fixes - [`f6424dd`](https://redirect.github.com/oxc-project/oxc/commit/f6424dd) linter: Reflect react plugin is disabled by default in cli ([#​11397](https://redirect.github.com/oxc-project/oxc/issues/11397)) (camc314) - [`25ecbfe`](https://redirect.github.com/oxc-project/oxc/commit/25ecbfe) linter: Remove use of `FrameworkFlags::React` to decide whether rules should run ([#​11383](https://redirect.github.com/oxc-project/oxc/issues/11383)) (camc314) - [`0d240e4`](https://redirect.github.com/oxc-project/oxc/commit/0d240e4) linter: False positive in react/exhaustive-deps with default formal parameter ([#​11395](https://redirect.github.com/oxc-project/oxc/issues/11395)) (camc314) - [`c91697e`](https://redirect.github.com/oxc-project/oxc/commit/c91697e) linter: Fix panic in multi byte char in `TryFrom` aria ([#​11350](https://redirect.github.com/oxc-project/oxc/issues/11350)) (camc314) - [`9798ef1`](https://redirect.github.com/oxc-project/oxc/commit/9798ef1) linter: Stack overflow in no-async-endpoint-handlers ([#​11317](https://redirect.github.com/oxc-project/oxc/issues/11317)) (camc314) - [`348ad97`](https://redirect.github.com/oxc-project/oxc/commit/348ad97) linter: Skip no-unused-vars on astro files ([#​11303](https://redirect.github.com/oxc-project/oxc/issues/11303)) (camc314) - [`183d7f0`](https://redirect.github.com/oxc-project/oxc/commit/183d7f0) linter: Make `jest/no-large-snapshots` error easier to comprehend ([#​11294](https://redirect.github.com/oxc-project/oxc/issues/11294)) (Ulrich Stark) - [`4e606a5`](https://redirect.github.com/oxc-project/oxc/commit/4e606a5) linter: Improve `jest/no-large-snapshots` ([#​11291](https://redirect.github.com/oxc-project/oxc/issues/11291)) (Ulrich Stark) - [`14f790f`](https://redirect.github.com/oxc-project/oxc/commit/14f790f) linter: Improve `jest/no-restricted-matchers` ([#​11292](https://redirect.github.com/oxc-project/oxc/issues/11292)) (Ulrich Stark) - [`a2c82be`](https://redirect.github.com/oxc-project/oxc/commit/a2c82be) linter/block-scoped-var: Better diagnostic messages ([#​11290](https://redirect.github.com/oxc-project/oxc/issues/11290)) (DonIsaac) - [`19772e5`](https://redirect.github.com/oxc-project/oxc/commit/19772e5) linter/no-unused-vars: Panic when variable is redeclared as function in same scope ([#​11280](https://redirect.github.com/oxc-project/oxc/issues/11280)) (Dunqing) - [`7af5bb1`](https://redirect.github.com/oxc-project/oxc/commit/7af5bb1) oxc_language_server: Include save option for text document sync capability ([#​11297](https://redirect.github.com/oxc-project/oxc/issues/11297)) (Nicholas Rayburn) ##### Performance - [`0ed6c1a`](https://redirect.github.com/oxc-project/oxc/commit/0ed6c1a) language_server: Use `Arc<RwLock>` instead of `Mutex` for workspace workers ([#​11328](https://redirect.github.com/oxc-project/oxc/issues/11328)) (Sysix) - [`a0ee946`](https://redirect.github.com/oxc-project/oxc/commit/a0ee946) linter: Reduce code size in `globals` ([#​11333](https://redirect.github.com/oxc-project/oxc/issues/11333)) (shulaoda) - [`c90c5e9`](https://redirect.github.com/oxc-project/oxc/commit/c90c5e9) linter/no-unused-vars: Simplify checking self call usage ([#​11281](https://redirect.github.com/oxc-project/oxc/issues/11281)) (Dunqing) ##### Documentation - [`eae51ca`](https://redirect.github.com/oxc-project/oxc/commit/eae51ca) linter: Clarify jsdoc/check-tag-names configuration ([#​11394](https://redirect.github.com/oxc-project/oxc/issues/11394)) (Rägnar O'ock) - [`cd354d4`](https://redirect.github.com/oxc-project/oxc/commit/cd354d4) oxlint: Remove incorrect doc comment ([#​11326](https://redirect.github.com/oxc-project/oxc/issues/11326)) (camc314) ##### Refactor - [`42738f0`](https://redirect.github.com/oxc-project/oxc/commit/42738f0) linter: Shorten code of match arms ([#​11389](https://redirect.github.com/oxc-project/oxc/issues/11389)) (Ulrich Stark) - [`8a34447`](https://redirect.github.com/oxc-project/oxc/commit/8a34447) linter: Improve `unicorn/text-encoding-identifier-case` ([#​11386](https://redirect.github.com/oxc-project/oxc/issues/11386)) (shulaoda) - [`eaa605e`](https://redirect.github.com/oxc-project/oxc/commit/eaa605e) linter: Avoid some `Arc::clone` in linter runtime ([#​11388](https://redirect.github.com/oxc-project/oxc/issues/11388)) (Boshen) - [`1cd8b9c`](https://redirect.github.com/oxc-project/oxc/commit/1cd8b9c) linter: Fixes in `react/forward-ref-uses-ref` are suggestions ([#​11376](https://redirect.github.com/oxc-project/oxc/issues/11376)) (Sysix) - [`50ef691`](https://redirect.github.com/oxc-project/oxc/commit/50ef691) linter: Add `diagnostics_with_multiple_fixes` to `LintContext` ([#​11357](https://redirect.github.com/oxc-project/oxc/issues/11357)) (Sysix) - [`606bb34`](https://redirect.github.com/oxc-project/oxc/commit/606bb34) linter: Accept `PossibleFixes` instead of `Fix` for `Messages` ([#​11295](https://redirect.github.com/oxc-project/oxc/issues/11295)) (Sysix) - [`042a3f3`](https://redirect.github.com/oxc-project/oxc/commit/042a3f3) linter: Use `PossibleFixes` instead of `Option<Fix>` ([#​11284](https://redirect.github.com/oxc-project/oxc/issues/11284)) (Sysix) - [`ffcfb46`](https://redirect.github.com/oxc-project/oxc/commit/ffcfb46) linter: Improve `unicorn/throw-new-error` ([#​11364](https://redirect.github.com/oxc-project/oxc/issues/11364)) (shulaoda) - [`8fb55c3`](https://redirect.github.com/oxc-project/oxc/commit/8fb55c3) linter: Cleanup docs and simplify code of `eslint/no-fallthrough` ([#​11331](https://redirect.github.com/oxc-project/oxc/issues/11331)) (Ulrich Stark) - [`e2f0f0a`](https://redirect.github.com/oxc-project/oxc/commit/e2f0f0a) linter: Improve docs and simplify code of `eslint/no-duplicate-imports` ([#​11320](https://redirect.github.com/oxc-project/oxc/issues/11320)) (Ulrich Stark) - [`b53b053`](https://redirect.github.com/oxc-project/oxc/commit/b53b053) linter: Simplify accessing span of NameSpan ([#​11305](https://redirect.github.com/oxc-project/oxc/issues/11305)) (Ulrich Stark) - [`4bc2650`](https://redirect.github.com/oxc-project/oxc/commit/4bc2650) linter: Improve `eslint/no-void` ([#​11285](https://redirect.github.com/oxc-project/oxc/issues/11285)) (shulaoda) ##### Styling - [`49b664c`](https://redirect.github.com/oxc-project/oxc/commit/49b664c) linter: Remove needless newline in `declare_oxc_lint` ([#​11400](https://redirect.github.com/oxc-project/oxc/issues/11400)) (camc314) ##### Testing - [`c4f64aa`](https://redirect.github.com/oxc-project/oxc/commit/c4f64aa) linter: Explicitly disable correctness for clarity ([#​11327](https://redirect.github.com/oxc-project/oxc/issues/11327)) (camc314) - [`a404b2c`](https://redirect.github.com/oxc-project/oxc/commit/a404b2c) linter: `eslint/no-duplicate-imports` shouldn't report the same span ([#​11324](https://redirect.github.com/oxc-project/oxc/issues/11324)) (Ulrich Stark) ### [`v0.16.12`](https://redirect.github.com/oxc-project/oxc/blob/HEAD/npm/oxlint/CHANGELOG.md#01612---2025-05-25) [Compare Source](https://redirect.github.com/oxc-project/oxc/compare/oxlint_v0.16.11...oxlint_v0.16.12) ##### Features - [`6a7018e`](https://redirect.github.com/oxc-project/oxc/commit/6a7018e) linter: Generate stricter json schema for lint plugins ([#​11219](https://redirect.github.com/oxc-project/oxc/issues/11219)) (camc314) ##### Bug Fixes - [`e8470d9`](https://redirect.github.com/oxc-project/oxc/commit/e8470d9) linter: Delay merging of oxlintrc configs ([#​10835](https://redirect.github.com/oxc-project/oxc/issues/10835)) (camc314) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/toeverything/AFFiNE). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC4xNi4wIiwidXBkYXRlZEluVmVyIjoiNDAuNTAuMCIsInRhcmdldEJyYW5jaCI6ImNhbmFyeSIsImxhYmVscyI6WyJkZXBlbmRlbmNpZXMiXX0=--> <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **Refactor** - Simplified array element retrieval across multiple components and utilities by replacing `.filter(...)[0]` with `.find(...)` or `.findLast(...)`, improving code readability and efficiency. - Improved JSX structure in the audio player component by nesting elements directly rather than using a `children` prop. - Enhanced code organization in the modal container by repositioning functions and updating dependency arrays for better maintainability. - Added a comment to disable a specific lint rule in a React hook for clarity. - **Chores** - Updated the `oxlint` development dependency to allow for newer compatible versions. - **Tests** - Refactored test setup logic for more direct and clear retrieval of test data. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: LongYinan <lynweklm@gmail.com>
372 lines
9.8 KiB
TypeScript
372 lines
9.8 KiB
TypeScript
import {
|
|
config as falConfig,
|
|
stream as falStream,
|
|
} from '@fal-ai/serverless-client';
|
|
import { Injectable } from '@nestjs/common';
|
|
import { z, ZodType } from 'zod';
|
|
|
|
import {
|
|
CopilotPromptInvalid,
|
|
CopilotProviderSideError,
|
|
metrics,
|
|
UserFriendlyError,
|
|
} from '../../../base';
|
|
import { CopilotProvider } from './provider';
|
|
import type {
|
|
CopilotChatOptions,
|
|
CopilotImageOptions,
|
|
ModelConditions,
|
|
PromptMessage,
|
|
} from './types';
|
|
import { CopilotProviderType, ModelInputType, ModelOutputType } from './types';
|
|
|
|
export type FalConfig = {
|
|
apiKey: string;
|
|
};
|
|
|
|
const FalImageSchema = z
|
|
.object({
|
|
url: z.string(),
|
|
seed: z.number().nullable().optional(),
|
|
content_type: z.string(),
|
|
file_name: z.string().nullable().optional(),
|
|
file_size: z.number().nullable().optional(),
|
|
width: z.number(),
|
|
height: z.number(),
|
|
})
|
|
.optional();
|
|
|
|
type FalImage = z.infer<typeof FalImageSchema>;
|
|
|
|
const FalResponseSchema = z.object({
|
|
detail: z
|
|
.union([
|
|
z.array(z.object({ type: z.string(), msg: z.string() })),
|
|
z.string(),
|
|
])
|
|
.optional(),
|
|
images: z.array(FalImageSchema).nullable().optional(),
|
|
image: FalImageSchema.nullable().optional(),
|
|
output: z.string().nullable().optional(),
|
|
});
|
|
|
|
type FalResponse = z.infer<typeof FalResponseSchema>;
|
|
|
|
const FalStreamOutputSchema = z.object({
|
|
type: z.literal('output'),
|
|
output: FalResponseSchema,
|
|
});
|
|
|
|
type FalPrompt = {
|
|
model_name?: string;
|
|
image_url?: string;
|
|
prompt?: string;
|
|
loras?: { path: string; scale?: number }[];
|
|
controlnets?: {
|
|
image_url: string;
|
|
start_percentage?: number;
|
|
end_percentage?: number;
|
|
}[];
|
|
};
|
|
|
|
@Injectable()
|
|
export class FalProvider extends CopilotProvider<FalConfig> {
|
|
override type = CopilotProviderType.FAL;
|
|
|
|
override readonly models = [
|
|
// image to image models
|
|
{
|
|
id: 'lcm-sd15-i2i',
|
|
capabilities: [
|
|
{
|
|
input: [ModelInputType.Image],
|
|
output: [ModelOutputType.Image],
|
|
defaultForOutputType: true,
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'clarity-upscaler',
|
|
capabilities: [
|
|
{
|
|
input: [ModelInputType.Image],
|
|
output: [ModelOutputType.Image],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'face-to-sticker',
|
|
capabilities: [
|
|
{
|
|
input: [ModelInputType.Image],
|
|
output: [ModelOutputType.Image],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'imageutils/rembg',
|
|
capabilities: [
|
|
{
|
|
input: [ModelInputType.Image],
|
|
output: [ModelOutputType.Image],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'workflowutils/teed',
|
|
capabilities: [
|
|
{
|
|
input: [ModelInputType.Image],
|
|
output: [ModelOutputType.Image],
|
|
},
|
|
],
|
|
},
|
|
{
|
|
id: 'lora/image-to-image',
|
|
capabilities: [
|
|
{
|
|
input: [ModelInputType.Image],
|
|
output: [ModelOutputType.Image],
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
override configured(): boolean {
|
|
return !!this.config.apiKey;
|
|
}
|
|
|
|
protected override setup() {
|
|
super.setup();
|
|
falConfig({ credentials: this.config.apiKey });
|
|
}
|
|
|
|
private extractArray<T>(value: T | T[] | undefined): T[] {
|
|
if (Array.isArray(value)) return value;
|
|
return value ? [value] : [];
|
|
}
|
|
|
|
private extractPrompt(
|
|
message?: PromptMessage,
|
|
options: CopilotImageOptions = {}
|
|
): FalPrompt {
|
|
if (!message) throw new CopilotPromptInvalid('Prompt is empty');
|
|
const { content, attachments, params } = message;
|
|
// prompt attachments require at least one
|
|
if (!content && (!Array.isArray(attachments) || !attachments.length)) {
|
|
throw new CopilotPromptInvalid('Prompt or Attachments is empty');
|
|
}
|
|
if (Array.isArray(attachments) && attachments.length > 1) {
|
|
throw new CopilotPromptInvalid('Only one attachment is allowed');
|
|
}
|
|
const lora = [
|
|
...this.extractArray(params?.lora),
|
|
...this.extractArray(options.loras),
|
|
].filter(
|
|
(v): v is { path: string; scale?: number } =>
|
|
!!v && typeof v === 'object' && typeof v.path === 'string'
|
|
);
|
|
const controlnets = this.extractArray(params?.controlnets).filter(
|
|
(v): v is { image_url: string } =>
|
|
!!v && typeof v === 'object' && typeof v.image_url === 'string'
|
|
);
|
|
return {
|
|
model_name: options.modelName || undefined,
|
|
image_url: attachments
|
|
?.map(v =>
|
|
typeof v === 'string'
|
|
? v
|
|
: v.mimeType.startsWith('image/')
|
|
? v.attachment
|
|
: undefined
|
|
)
|
|
.find(v => !!v),
|
|
prompt: content.trim(),
|
|
loras: lora.length ? lora : undefined,
|
|
controlnets: controlnets.length ? controlnets : undefined,
|
|
};
|
|
}
|
|
|
|
private extractFalError(
|
|
resp: FalResponse,
|
|
message?: string
|
|
): CopilotProviderSideError {
|
|
if (Array.isArray(resp.detail) && resp.detail.length) {
|
|
const error = resp.detail[0].msg;
|
|
return new CopilotProviderSideError({
|
|
provider: this.type,
|
|
kind: resp.detail[0].type,
|
|
message: message ? `${message}: ${error}` : error,
|
|
});
|
|
} else if (typeof resp.detail === 'string') {
|
|
const error = resp.detail;
|
|
return new CopilotProviderSideError({
|
|
provider: this.type,
|
|
kind: resp.detail,
|
|
message: message ? `${message}: ${error}` : error,
|
|
});
|
|
}
|
|
return new CopilotProviderSideError({
|
|
provider: this.type,
|
|
kind: 'unknown',
|
|
message: 'No content generated',
|
|
});
|
|
}
|
|
|
|
private handleError(e: any) {
|
|
if (e instanceof UserFriendlyError) {
|
|
// pass through user friendly errors
|
|
return e;
|
|
} else {
|
|
const error = new CopilotProviderSideError({
|
|
provider: this.type,
|
|
kind: 'unexpected_response',
|
|
message: e?.message || 'Unexpected fal response',
|
|
});
|
|
return error;
|
|
}
|
|
}
|
|
|
|
private parseSchema<R>(schema: ZodType<R>, data: unknown): R {
|
|
const result = schema.safeParse(data);
|
|
if (result.success) return result.data;
|
|
const errors = JSON.stringify(result.error.errors);
|
|
throw new CopilotProviderSideError({
|
|
provider: this.type,
|
|
kind: 'unexpected_response',
|
|
message: `Unexpected fal response: ${errors}`,
|
|
});
|
|
}
|
|
|
|
async text(
|
|
cond: ModelConditions,
|
|
messages: PromptMessage[],
|
|
options: CopilotChatOptions = {}
|
|
): Promise<string> {
|
|
const model = this.selectModel(cond);
|
|
|
|
try {
|
|
metrics.ai.counter('chat_text_calls').add(1, { model: model.id });
|
|
|
|
// by default, image prompt assumes there is only one message
|
|
const prompt = this.extractPrompt(messages[messages.length - 1]);
|
|
|
|
const response = await fetch(`https://fal.run/fal-ai/${model.id}`, {
|
|
method: 'POST',
|
|
headers: {
|
|
Authorization: `key ${this.config.apiKey}`,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
...prompt,
|
|
sync_mode: true,
|
|
enable_safety_checks: false,
|
|
}),
|
|
signal: options.signal,
|
|
});
|
|
|
|
const data = this.parseSchema(FalResponseSchema, await response.json());
|
|
if (!data.output) {
|
|
throw this.extractFalError(data, 'Failed to generate text');
|
|
}
|
|
return data.output;
|
|
} catch (e: any) {
|
|
metrics.ai.counter('chat_text_errors').add(1, { model: model.id });
|
|
throw this.handleError(e);
|
|
}
|
|
}
|
|
|
|
async *streamText(
|
|
cond: ModelConditions,
|
|
messages: PromptMessage[],
|
|
options: CopilotChatOptions | CopilotImageOptions = {}
|
|
): AsyncIterable<string> {
|
|
const model = this.selectModel(cond);
|
|
|
|
try {
|
|
metrics.ai.counter('chat_text_stream_calls').add(1, { model: model.id });
|
|
const result = await this.text(cond, messages, options);
|
|
|
|
yield result;
|
|
} catch (e) {
|
|
metrics.ai.counter('chat_text_stream_errors').add(1, { model: model.id });
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
override async *streamImages(
|
|
cond: ModelConditions,
|
|
messages: PromptMessage[],
|
|
options: CopilotImageOptions = {}
|
|
): AsyncIterable<string> {
|
|
const model = this.selectModel({
|
|
...cond,
|
|
outputType: ModelOutputType.Image,
|
|
});
|
|
|
|
try {
|
|
metrics.ai
|
|
.counter('generate_images_stream_calls')
|
|
.add(1, { model: model.id });
|
|
|
|
// by default, image prompt assumes there is only one message
|
|
const prompt = this.extractPrompt(
|
|
messages[messages.length - 1],
|
|
options as CopilotImageOptions
|
|
);
|
|
|
|
let data: FalResponse;
|
|
if (model.id.startsWith('workflows/')) {
|
|
const stream = await falStream(model.id, { input: prompt });
|
|
data = this.parseSchema(
|
|
FalStreamOutputSchema,
|
|
await stream.done()
|
|
).output;
|
|
} else {
|
|
const response = await fetch(`https://fal.run/fal-ai/${model.id}`, {
|
|
method: 'POST',
|
|
headers: {
|
|
Authorization: `key ${this.config.apiKey}`,
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
...prompt,
|
|
sync_mode: true,
|
|
seed: (options as CopilotImageOptions)?.seed || 42,
|
|
enable_safety_checks: false,
|
|
}),
|
|
signal: options.signal,
|
|
});
|
|
data = this.parseSchema(FalResponseSchema, await response.json());
|
|
}
|
|
|
|
if (!data.images?.length && !data.image?.url) {
|
|
throw this.extractFalError(data, 'Failed to generate images');
|
|
}
|
|
|
|
if (data.image?.url) {
|
|
yield data.image.url;
|
|
return;
|
|
}
|
|
|
|
const imageUrls =
|
|
data.images
|
|
?.filter((image): image is NonNullable<FalImage> => !!image)
|
|
.map(image => image.url) || [];
|
|
|
|
for (const url of imageUrls) {
|
|
yield url;
|
|
if (options.signal?.aborted) {
|
|
break;
|
|
}
|
|
}
|
|
return;
|
|
} catch (e) {
|
|
metrics.ai
|
|
.counter('generate_images_stream_errors')
|
|
.add(1, { model: model.id });
|
|
throw this.handleError(e);
|
|
}
|
|
}
|
|
}
|