Add showTypeModels setting
This commit is contained in:
@@ -724,6 +724,7 @@ export async function setAutogenerateQlPacks(choice: AutogenerateQLPacks) {
|
||||
const MODEL_SETTING = new Setting("model", ROOT_SETTING);
|
||||
const FLOW_GENERATION = new Setting("flowGeneration", MODEL_SETTING);
|
||||
const LLM_GENERATION = new Setting("llmGeneration", MODEL_SETTING);
|
||||
const SHOW_TYPE_MODELS = new Setting("showTypeModels", MODEL_SETTING);
|
||||
const LLM_GENERATION_BATCH_SIZE = new Setting(
|
||||
"llmGenerationBatchSize",
|
||||
MODEL_SETTING,
|
||||
@@ -743,6 +744,7 @@ const ENABLE_ACCESS_PATH_SUGGESTIONS = new Setting(
|
||||
export interface ModelConfig {
|
||||
flowGeneration: boolean;
|
||||
llmGeneration: boolean;
|
||||
showTypeModels: boolean;
|
||||
getExtensionsDirectory(languageId: string): string | undefined;
|
||||
enablePython: boolean;
|
||||
enableAccessPathSuggestions: boolean;
|
||||
@@ -761,6 +763,10 @@ export class ModelConfigListener extends ConfigListener implements ModelConfig {
|
||||
return !!LLM_GENERATION.getValue<boolean>();
|
||||
}
|
||||
|
||||
public get showTypeModels(): boolean {
|
||||
return !!SHOW_TYPE_MODELS.getValue<boolean>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Limits the number of candidates we send to the model in each request to avoid long requests.
|
||||
* Note that the model may return fewer than this number of candidates.
|
||||
|
||||
@@ -17,11 +17,35 @@ import type {
|
||||
import type { BaseLogger } from "../../common/logging";
|
||||
import type { AccessPathSuggestionRow } from "../suggestions";
|
||||
|
||||
// This is a subset of the model config that doesn't import the vscode module.
|
||||
// It only includes settings that are actually used.
|
||||
export type ModelConfig = {
|
||||
showTypeModels: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* This function creates a new model config object from the given model config object.
|
||||
* The new model config object is a deep copy of the given model config object.
|
||||
*
|
||||
* @param modelConfig The model config object to create a new model config object from.
|
||||
* In most cases, this is a `ModelConfigListener`.
|
||||
*/
|
||||
export function createModelConfig(modelConfig: ModelConfig): ModelConfig {
|
||||
return {
|
||||
showTypeModels: modelConfig.showTypeModels,
|
||||
};
|
||||
}
|
||||
|
||||
export const defaultModelConfig: ModelConfig = {
|
||||
showTypeModels: false,
|
||||
};
|
||||
|
||||
type GenerateMethodDefinition<T> = (method: T) => DataTuple[];
|
||||
type ReadModeledMethod = (row: DataTuple[]) => ModeledMethod;
|
||||
|
||||
type IsHiddenContext = {
|
||||
method: MethodDefinition;
|
||||
isCanary: boolean;
|
||||
config: ModelConfig;
|
||||
};
|
||||
|
||||
export type ModelsAsDataLanguagePredicate<T> = {
|
||||
|
||||
@@ -169,8 +169,7 @@ export const ruby: ModelsAsDataLanguage = {
|
||||
methodParameters: "",
|
||||
};
|
||||
},
|
||||
// Hide for all non-canary users
|
||||
isHidden: ({ isCanary }) => !isCanary,
|
||||
isHidden: ({ config }) => !config.showTypeModels,
|
||||
},
|
||||
},
|
||||
modelGeneration: {
|
||||
|
||||
@@ -11,11 +11,11 @@ import type { ModelingStore } from "../modeling-store";
|
||||
import { AbstractWebviewViewProvider } from "../../common/vscode/abstract-webview-view-provider";
|
||||
import { assertNever } from "../../common/helpers-pure";
|
||||
import type { ModelConfigListener } from "../../config";
|
||||
import { isCanary } from "../../config";
|
||||
import type { DatabaseItem } from "../../databases/local-databases";
|
||||
import type { ModelingEvents } from "../modeling-events";
|
||||
import type { QueryLanguage } from "../../common/query-language";
|
||||
import { tryGetQueryLanguage } from "../../common/query-language";
|
||||
import { createModelConfig } from "../languages";
|
||||
|
||||
export class MethodModelingViewProvider extends AbstractWebviewViewProvider<
|
||||
ToMethodModelingMessage,
|
||||
@@ -47,7 +47,7 @@ export class MethodModelingViewProvider extends AbstractWebviewViewProvider<
|
||||
t: "setMethodModelingPanelViewState",
|
||||
viewState: {
|
||||
language: this.language,
|
||||
isCanary: isCanary(),
|
||||
modelConfig: createModelConfig(this.modelConfig),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ import type { Method } from "./method";
|
||||
import type { ModeledMethod } from "./modeled-method";
|
||||
import type { ExtensionPack } from "./shared/extension-pack";
|
||||
import type { ModelConfigListener } from "../config";
|
||||
import { isCanary } from "../config";
|
||||
import { Mode } from "./shared/mode";
|
||||
import { loadModeledMethods, saveModeledMethods } from "./modeled-method-fs";
|
||||
import { pickExtensionPack } from "./extension-pack-picker";
|
||||
@@ -51,7 +50,7 @@ import { telemetryListener } from "../common/vscode/telemetry";
|
||||
import type { ModelingStore } from "./modeling-store";
|
||||
import type { ModelingEvents } from "./modeling-events";
|
||||
import type { ModelsAsDataLanguage } from "./languages";
|
||||
import { getModelsAsDataLanguage } from "./languages";
|
||||
import { createModelConfig, getModelsAsDataLanguage } from "./languages";
|
||||
import { runGenerateQueries } from "./generate";
|
||||
import { ResponseError } from "vscode-jsonrpc";
|
||||
import { LSPErrorCodes } from "vscode-languageclient";
|
||||
@@ -457,7 +456,7 @@ export class ModelEditorView extends AbstractWebview<
|
||||
mode: this.modelingStore.getMode(this.databaseItem),
|
||||
showModeSwitchButton,
|
||||
sourceArchiveAvailable,
|
||||
isCanary: isCanary(),
|
||||
modelConfig: createModelConfig(this.modelConfig),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { ExtensionPack } from "./extension-pack";
|
||||
import type { Mode } from "./mode";
|
||||
import type { QueryLanguage } from "../../common/query-language";
|
||||
import type { ModelConfig } from "../languages";
|
||||
|
||||
export interface ModelEditorViewState {
|
||||
extensionPack: ExtensionPack;
|
||||
@@ -11,10 +12,10 @@ export interface ModelEditorViewState {
|
||||
mode: Mode;
|
||||
showModeSwitchButton: boolean;
|
||||
sourceArchiveAvailable: boolean;
|
||||
isCanary: boolean;
|
||||
modelConfig: ModelConfig;
|
||||
}
|
||||
|
||||
export interface MethodModelingPanelViewState {
|
||||
language: QueryLanguage | undefined;
|
||||
isCanary: boolean;
|
||||
modelConfig: ModelConfig;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import { createSinkModeledMethod } from "../../../test/factories/model-editor/mo
|
||||
import { useState } from "react";
|
||||
import type { ModeledMethod } from "../../model-editor/modeled-method";
|
||||
import { QueryLanguage } from "../../common/query-language";
|
||||
import { defaultModelConfig } from "../../model-editor/languages";
|
||||
|
||||
export default {
|
||||
title: "Method Modeling/Method Modeling Inputs",
|
||||
@@ -34,7 +35,7 @@ const Template: StoryFn<typeof MethodModelingInputsComponent> = (args) => {
|
||||
language={QueryLanguage.Java}
|
||||
modeledMethod={m}
|
||||
onChange={onChange}
|
||||
isCanary={true}
|
||||
modelConfig={defaultModelConfig}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ import { VSCodeTag } from "@vscode/webview-ui-toolkit/react";
|
||||
import { ReviewInEditorButton } from "./ReviewInEditorButton";
|
||||
import { MultipleModeledMethodsPanel } from "./MultipleModeledMethodsPanel";
|
||||
import type { QueryLanguage } from "../../common/query-language";
|
||||
import type { ModelConfig } from "../../model-editor/languages";
|
||||
|
||||
const Container = styled.div`
|
||||
padding-top: 0.5rem;
|
||||
@@ -50,7 +51,7 @@ const UnsavedTag = ({ modelingStatus }: { modelingStatus: ModelingStatus }) => (
|
||||
|
||||
export type MethodModelingProps = {
|
||||
language: QueryLanguage;
|
||||
isCanary: boolean;
|
||||
modelConfig: ModelConfig;
|
||||
modelingStatus: ModelingStatus;
|
||||
method: Method;
|
||||
modeledMethods: ModeledMethod[];
|
||||
@@ -61,7 +62,7 @@ export type MethodModelingProps = {
|
||||
|
||||
export const MethodModeling = ({
|
||||
language,
|
||||
isCanary,
|
||||
modelConfig,
|
||||
modelingStatus,
|
||||
modeledMethods,
|
||||
method,
|
||||
@@ -82,7 +83,7 @@ export const MethodModeling = ({
|
||||
</DependencyContainer>
|
||||
<MultipleModeledMethodsPanel
|
||||
language={language}
|
||||
isCanary={isCanary}
|
||||
modelConfig={modelConfig}
|
||||
method={method}
|
||||
modeledMethods={modeledMethods}
|
||||
isModelingInProgress={isModelingInProgress}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { ModelOutputDropdown } from "../model-editor/ModelOutputDropdown";
|
||||
import { ModelKindDropdown } from "../model-editor/ModelKindDropdown";
|
||||
import { InProgressDropdown } from "../model-editor/InProgressDropdown";
|
||||
import type { QueryLanguage } from "../../common/query-language";
|
||||
import type { ModelConfig } from "../../model-editor/languages";
|
||||
|
||||
const Container = styled.div`
|
||||
padding-top: 0.5rem;
|
||||
@@ -24,7 +25,7 @@ const Name = styled.span`
|
||||
|
||||
export type MethodModelingInputsProps = {
|
||||
language: QueryLanguage;
|
||||
isCanary: boolean;
|
||||
modelConfig: ModelConfig;
|
||||
method: Method;
|
||||
modeledMethod: ModeledMethod | undefined;
|
||||
modelPending: boolean;
|
||||
@@ -34,7 +35,7 @@ export type MethodModelingInputsProps = {
|
||||
|
||||
export const MethodModelingInputs = ({
|
||||
language,
|
||||
isCanary,
|
||||
modelConfig,
|
||||
method,
|
||||
modeledMethod,
|
||||
modelPending,
|
||||
@@ -57,7 +58,7 @@ export const MethodModelingInputs = ({
|
||||
{isModelingInProgress ? (
|
||||
<InProgressDropdown />
|
||||
) : (
|
||||
<ModelTypeDropdown isCanary={isCanary} {...inputProps} />
|
||||
<ModelTypeDropdown modelConfig={modelConfig} {...inputProps} />
|
||||
)}
|
||||
</Input>
|
||||
</Container>
|
||||
|
||||
@@ -11,6 +11,7 @@ import { NotInModelingMode } from "./NotInModelingMode";
|
||||
import { NoMethodSelected } from "./NoMethodSelected";
|
||||
import type { MethodModelingPanelViewState } from "../../model-editor/shared/view-state";
|
||||
import { MethodAlreadyModeled } from "./MethodAlreadyModeled";
|
||||
import { defaultModelConfig } from "../../model-editor/languages";
|
||||
|
||||
type Props = {
|
||||
initialViewState?: MethodModelingPanelViewState;
|
||||
@@ -116,7 +117,7 @@ export function MethodModelingView({
|
||||
return (
|
||||
<MethodModeling
|
||||
language={viewState?.language}
|
||||
isCanary={viewState?.isCanary ?? false}
|
||||
modelConfig={viewState?.modelConfig ?? defaultModelConfig}
|
||||
modelingStatus={modelingStatus}
|
||||
method={method}
|
||||
modeledMethods={modeledMethods}
|
||||
|
||||
@@ -16,10 +16,11 @@ import type { QueryLanguage } from "../../common/query-language";
|
||||
import { createEmptyModeledMethod } from "../../model-editor/modeled-method-empty";
|
||||
import { sendTelemetry } from "../common/telemetry";
|
||||
import type { ModelingStatus } from "../../model-editor/shared/modeling-status";
|
||||
import type { ModelConfig } from "../../model-editor/languages";
|
||||
|
||||
export type MultipleModeledMethodsPanelProps = {
|
||||
language: QueryLanguage;
|
||||
isCanary: boolean;
|
||||
modelConfig: ModelConfig;
|
||||
method: Method;
|
||||
modeledMethods: ModeledMethod[];
|
||||
modelingStatus: ModelingStatus;
|
||||
@@ -62,7 +63,7 @@ const ModificationActions = styled.div`
|
||||
|
||||
export const MultipleModeledMethodsPanel = ({
|
||||
language,
|
||||
isCanary,
|
||||
modelConfig,
|
||||
method,
|
||||
modeledMethods,
|
||||
modelingStatus,
|
||||
@@ -159,7 +160,7 @@ export const MultipleModeledMethodsPanel = ({
|
||||
{modeledMethods.length > 0 ? (
|
||||
<MethodModelingInputs
|
||||
language={language}
|
||||
isCanary={isCanary}
|
||||
modelConfig={modelConfig}
|
||||
method={method}
|
||||
modeledMethod={modeledMethods[selectedIndex]}
|
||||
modelPending={isModelPending(
|
||||
@@ -173,7 +174,7 @@ export const MultipleModeledMethodsPanel = ({
|
||||
) : (
|
||||
<MethodModelingInputs
|
||||
language={language}
|
||||
isCanary={isCanary}
|
||||
modelConfig={modelConfig}
|
||||
method={method}
|
||||
modeledMethod={undefined}
|
||||
modelPending={isModelPending(
|
||||
|
||||
@@ -4,6 +4,7 @@ import { MethodModeling } from "../MethodModeling";
|
||||
import { createMethod } from "../../../../test/factories/model-editor/method-factories";
|
||||
import { createSinkModeledMethod } from "../../../../test/factories/model-editor/modeled-method-factories";
|
||||
import { QueryLanguage } from "../../../common/query-language";
|
||||
import { defaultModelConfig } from "../../../model-editor/languages";
|
||||
|
||||
describe(MethodModeling.name, () => {
|
||||
const render = (props: MethodModelingProps) =>
|
||||
@@ -18,7 +19,7 @@ describe(MethodModeling.name, () => {
|
||||
|
||||
render({
|
||||
language: QueryLanguage.Java,
|
||||
isCanary: false,
|
||||
modelConfig: defaultModelConfig,
|
||||
modelingStatus: "saved",
|
||||
method,
|
||||
modeledMethods: [modeledMethod],
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
} from "../../../../test/factories/model-editor/modeled-method-factories";
|
||||
import { QueryLanguage } from "../../../common/query-language";
|
||||
import { createEmptyModeledMethod } from "../../../model-editor/modeled-method-empty";
|
||||
import { defaultModelConfig } from "../../../model-editor/languages";
|
||||
|
||||
describe(MethodModelingInputs.name, () => {
|
||||
const render = (props: MethodModelingInputsProps) =>
|
||||
@@ -19,7 +20,7 @@ describe(MethodModelingInputs.name, () => {
|
||||
const modeledMethod = createSinkModeledMethod();
|
||||
const modelPending = false;
|
||||
const isModelingInProgress = false;
|
||||
const isCanary = false;
|
||||
const modelConfig = defaultModelConfig;
|
||||
const onChange = jest.fn();
|
||||
|
||||
it("renders the method modeling inputs", () => {
|
||||
@@ -29,7 +30,7 @@ describe(MethodModelingInputs.name, () => {
|
||||
modeledMethod,
|
||||
modelPending,
|
||||
isModelingInProgress,
|
||||
isCanary,
|
||||
modelConfig,
|
||||
onChange,
|
||||
});
|
||||
|
||||
@@ -57,7 +58,7 @@ describe(MethodModelingInputs.name, () => {
|
||||
modeledMethod,
|
||||
modelPending,
|
||||
isModelingInProgress,
|
||||
isCanary,
|
||||
modelConfig,
|
||||
onChange,
|
||||
});
|
||||
|
||||
@@ -81,7 +82,7 @@ describe(MethodModelingInputs.name, () => {
|
||||
modeledMethod,
|
||||
modelPending,
|
||||
isModelingInProgress,
|
||||
isCanary,
|
||||
modelConfig,
|
||||
onChange,
|
||||
});
|
||||
|
||||
@@ -97,7 +98,7 @@ describe(MethodModelingInputs.name, () => {
|
||||
modeledMethod={updatedModeledMethod}
|
||||
modelPending={modelPending}
|
||||
isModelingInProgress={isModelingInProgress}
|
||||
isCanary={isCanary}
|
||||
modelConfig={modelConfig}
|
||||
onChange={onChange}
|
||||
/>,
|
||||
);
|
||||
@@ -128,7 +129,7 @@ describe(MethodModelingInputs.name, () => {
|
||||
modeledMethod,
|
||||
modelPending,
|
||||
isModelingInProgress: true,
|
||||
isCanary,
|
||||
modelConfig,
|
||||
onChange,
|
||||
});
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import { userEvent } from "@testing-library/user-event";
|
||||
import type { ModeledMethod } from "../../../model-editor/modeled-method";
|
||||
import { QueryLanguage } from "../../../common/query-language";
|
||||
import type { ModelingStatus } from "../../../model-editor/shared/modeling-status";
|
||||
import { defaultModelConfig } from "../../../model-editor/languages";
|
||||
|
||||
describe(MultipleModeledMethodsPanel.name, () => {
|
||||
const language = QueryLanguage.Java;
|
||||
@@ -19,14 +20,14 @@ describe(MultipleModeledMethodsPanel.name, () => {
|
||||
const isProcessedByAutoModel = false;
|
||||
const modelingStatus: ModelingStatus = "unmodeled";
|
||||
const onChange = jest.fn<void, [string, ModeledMethod[]]>();
|
||||
const isCanary = false;
|
||||
const modelConfig = defaultModelConfig;
|
||||
|
||||
const baseProps = {
|
||||
language,
|
||||
method,
|
||||
modelingStatus,
|
||||
isModelingInProgress,
|
||||
isCanary,
|
||||
modelConfig,
|
||||
isProcessedByAutoModel,
|
||||
onChange,
|
||||
};
|
||||
|
||||
@@ -211,7 +211,7 @@ const ModelableMethodRow = forwardRef<HTMLElement | undefined, MethodRowProps>(
|
||||
|
||||
return !predicate.isHidden?.({
|
||||
method,
|
||||
isCanary: viewState.isCanary,
|
||||
config: viewState.modelConfig,
|
||||
});
|
||||
}),
|
||||
method,
|
||||
@@ -298,7 +298,7 @@ const ModelableMethodRow = forwardRef<HTMLElement | undefined, MethodRowProps>(
|
||||
<DataGridCell>
|
||||
<ModelTypeDropdown
|
||||
language={viewState.language}
|
||||
isCanary={viewState.isCanary}
|
||||
modelConfig={viewState.modelConfig}
|
||||
method={method}
|
||||
modeledMethod={modeledMethod}
|
||||
modelPending={modelPending}
|
||||
|
||||
@@ -10,13 +10,16 @@ import { createEmptyModeledMethod } from "../../model-editor/modeled-method-empt
|
||||
import type { Mutable } from "../../common/mutable";
|
||||
import { ReadonlyDropdown } from "../common/ReadonlyDropdown";
|
||||
import type { QueryLanguage } from "../../common/query-language";
|
||||
import type { ModelsAsDataLanguagePredicates } from "../../model-editor/languages";
|
||||
import type {
|
||||
ModelConfig,
|
||||
ModelsAsDataLanguagePredicates,
|
||||
} from "../../model-editor/languages";
|
||||
import { getModelsAsDataLanguage } from "../../model-editor/languages";
|
||||
import { InputDropdown } from "./InputDropdown";
|
||||
|
||||
type Props = {
|
||||
language: QueryLanguage;
|
||||
isCanary: boolean;
|
||||
modelConfig: ModelConfig;
|
||||
method: Method;
|
||||
modeledMethod: ModeledMethod | undefined;
|
||||
modelPending: boolean;
|
||||
@@ -35,7 +38,7 @@ type Option = { value: ModeledMethodType; label: string };
|
||||
|
||||
export const ModelTypeDropdown = ({
|
||||
language,
|
||||
isCanary,
|
||||
modelConfig,
|
||||
method,
|
||||
modeledMethod,
|
||||
modelPending,
|
||||
@@ -57,7 +60,10 @@ export const ModelTypeDropdown = ({
|
||||
return null;
|
||||
}
|
||||
|
||||
if (predicate.isHidden && predicate.isHidden({ method, isCanary })) {
|
||||
if (
|
||||
predicate.isHidden &&
|
||||
predicate.isHidden({ method, config: modelConfig })
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -70,7 +76,7 @@ export const ModelTypeDropdown = ({
|
||||
];
|
||||
|
||||
return baseOptions;
|
||||
}, [language, isCanary, method]);
|
||||
}, [language, modelConfig, method]);
|
||||
|
||||
const handleChange = useCallback(
|
||||
(e: ChangeEvent<HTMLSelectElement>) => {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { createNoneModeledMethod } from "../../../../test/factories/model-editor
|
||||
import { QueryLanguage } from "../../../common/query-language";
|
||||
import { ModelTypeDropdown } from "../ModelTypeDropdown";
|
||||
import { createMethod } from "../../../../test/factories/model-editor/method-factories";
|
||||
import { defaultModelConfig } from "../../../model-editor/languages";
|
||||
|
||||
describe(ModelTypeDropdown.name, () => {
|
||||
const onChange = jest.fn();
|
||||
@@ -23,7 +24,7 @@ describe(ModelTypeDropdown.name, () => {
|
||||
modelPending={false}
|
||||
onChange={onChange}
|
||||
method={method}
|
||||
isCanary={false}
|
||||
modelConfig={defaultModelConfig}
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -46,7 +47,10 @@ describe(ModelTypeDropdown.name, () => {
|
||||
modelPending={false}
|
||||
onChange={onChange}
|
||||
method={method}
|
||||
isCanary={true}
|
||||
modelConfig={{
|
||||
...defaultModelConfig,
|
||||
showTypeModels: true,
|
||||
}}
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -69,7 +73,7 @@ describe(ModelTypeDropdown.name, () => {
|
||||
modelPending={false}
|
||||
onChange={onChange}
|
||||
method={method}
|
||||
isCanary={false}
|
||||
modelConfig={defaultModelConfig}
|
||||
/>,
|
||||
);
|
||||
|
||||
@@ -89,7 +93,7 @@ describe(ModelTypeDropdown.name, () => {
|
||||
modelPending={false}
|
||||
onChange={onChange}
|
||||
method={method}
|
||||
isCanary={false}
|
||||
modelConfig={defaultModelConfig}
|
||||
/>,
|
||||
);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { ModelEditorViewState } from "../../../src/model-editor/shared/view
|
||||
import { Mode } from "../../../src/model-editor/shared/mode";
|
||||
import { createMockExtensionPack } from "./extension-pack";
|
||||
import { QueryLanguage } from "../../../src/common/query-language";
|
||||
import { defaultModelConfig } from "../../../src/model-editor/languages";
|
||||
|
||||
export function createMockModelEditorViewState(
|
||||
data: Partial<ModelEditorViewState> = {},
|
||||
@@ -15,7 +16,7 @@ export function createMockModelEditorViewState(
|
||||
showModeSwitchButton: true,
|
||||
extensionPack: createMockExtensionPack(),
|
||||
sourceArchiveAvailable: true,
|
||||
isCanary: false,
|
||||
modelConfig: defaultModelConfig,
|
||||
...data,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user