Browse Source

UI: Fixed bugs change translate and add bedrock provider config settings

pull/13371/head
Artem Dzhereleiko 1 year ago
parent
commit
315fef0fc8
  1. 38
      ui-ngx/src/app/modules/home/components/ai-model/ai-model-dialog.component.html
  2. 7
      ui-ngx/src/app/modules/home/components/ai-model/ai-model-dialog.component.ts
  3. 8
      ui-ngx/src/app/modules/home/components/rule-node/external/ai-config.component.html
  4. 19
      ui-ngx/src/app/modules/home/components/rule-node/external/ai-config.component.ts
  5. 15
      ui-ngx/src/app/modules/home/pages/ai-model/ai-model-table-config.resolve.ts
  6. 2
      ui-ngx/src/app/shared/components/string-autocomplete.component.html
  7. 12
      ui-ngx/src/app/shared/models/ai-model.models.ts
  8. 28
      ui-ngx/src/assets/locale/locale.constant-en_US.json

38
ui-ngx/src/app/modules/home/components/ai-model/ai-model-dialog.component.html

@ -35,7 +35,7 @@
<mat-label translate>ai-models.name</mat-label> <mat-label translate>ai-models.name</mat-label>
<input matInput required formControlName="name"> <input matInput required formControlName="name">
<mat-hint></mat-hint> <mat-hint></mat-hint>
<mat-error *ngIf="aiModelForms.get('name').hasError('required')"> <mat-error *ngIf="aiModelForms.get('name').hasError('required') || aiModelForms.get('name').hasError('pattern')">
{{ 'ai-models.name-required' | translate }} {{ 'ai-models.name-required' | translate }}
</mat-error> </mat-error>
<mat-error *ngIf="aiModelForms.get('name').hasError('maxlength')"> <mat-error *ngIf="aiModelForms.get('name').hasError('maxlength')">
@ -49,7 +49,7 @@
<section class="tb-form-panel outlined no-border no-padding"> <section class="tb-form-panel outlined no-border no-padding">
<mat-form-field class="mat-block flex-1" appearance="outline"> <mat-form-field class="mat-block flex-1" appearance="outline">
<mat-label translate>ai-models.ai-provider</mat-label> <mat-label translate>ai-models.ai-provider</mat-label>
<mat-select required formControlName="provider"> <mat-select formControlName="provider">
<mat-option *ngFor="let provider of providerMap" [value]="provider"> <mat-option *ngFor="let provider of providerMap" [value]="provider">
{{providerTranslationMap.get(provider) | translate}} {{providerTranslationMap.get(provider) | translate}}
</mat-option> </mat-option>
@ -122,6 +122,34 @@
</mat-error> </mat-error>
</mat-form-field> </mat-form-field>
} }
@if (providerFieldsList.includes('region')) {
<mat-form-field class="mat-block flex-1" appearance="outline" subscriptSizing="dynamic">
<mat-label translate>ai-models.region</mat-label>
<input required matInput formControlName="region">
<mat-error *ngIf="aiModelForms.get('configuration').get('providerConfig').get('region').hasError('required')">
{{ 'ai-models.region-required' | translate }}
</mat-error>
</mat-form-field>
}
@if (providerFieldsList.includes('accessKeyId')) {
<mat-form-field class="mat-block flex-1" appearance="outline" subscriptSizing="dynamic">
<mat-label translate>ai-models.access-key-id</mat-label>
<input required matInput formControlName="accessKeyId">
<mat-error *ngIf="aiModelForms.get('configuration').get('providerConfig').get('accessKeyId').hasError('required')">
{{ 'ai-models.access-key-id-required' | translate }}
</mat-error>
</mat-form-field>
}
@if (providerFieldsList.includes('secretAccessKey')) {
<mat-form-field class="mat-block flex-1" appearance="outline">
<mat-label translate>ai-models.secret-access-key</mat-label>
<input type="password" required matInput formControlName="secretAccessKey">
<tb-toggle-password matSuffix></tb-toggle-password>
<mat-error *ngIf="aiModelForms.get('configuration').get('providerConfig').get('secretAccessKey').hasError('required')">
{{ 'ai-models.secret-access-key-required' | translate }}
</mat-error>
</mat-form-field>
}
</div> </div>
</section> </section>
</section> </section>
@ -222,8 +250,8 @@
} }
@if (modelFieldsList.includes('maxOutputTokens')) { @if (modelFieldsList.includes('maxOutputTokens')) {
<div class="tb-form-row space-between"> <div class="tb-form-row space-between">
<div tb-hint-tooltip-icon="{{ 'ai-models.max-output-token-hint' | translate }}"> <div tb-hint-tooltip-icon="{{ 'ai-models.max-output-tokens-hint' | translate }}">
{{ 'ai-models.max-output-token' | translate }} {{ 'ai-models.max-output-tokens' | translate }}
</div> </div>
<mat-form-field appearance="outline" class="number" subscriptSizing="dynamic"> <mat-form-field appearance="outline" class="number" subscriptSizing="dynamic">
<input matInput formControlName="maxOutputTokens" <input matInput formControlName="maxOutputTokens"
@ -231,7 +259,7 @@
<mat-icon matSuffix <mat-icon matSuffix
matTooltipPosition="above" matTooltipPosition="above"
matTooltipClass="tb-error-tooltip" matTooltipClass="tb-error-tooltip"
[matTooltip]="'ai-models.max-output-token-min' | translate" [matTooltip]="'ai-models.max-output-tokens-min' | translate"
*ngIf="aiModelForms.get('configuration').get('maxOutputTokens').hasError('min')" *ngIf="aiModelForms.get('configuration').get('maxOutputTokens').hasError('min')"
class="tb-error"> class="tb-error">
warning warning

7
ui-ngx/src/app/modules/home/components/ai-model/ai-model-dialog.component.ts

@ -83,10 +83,10 @@ export class AIModelDialogComponent extends DialogComponent<AIModelDialogCompone
this.provider = this.data.AIModel ? this.data.AIModel.configuration.provider : AiProvider.OPENAI; this.provider = this.data.AIModel ? this.data.AIModel.configuration.provider : AiProvider.OPENAI;
this.aiModelForms = this.fb.group({ this.aiModelForms = this.fb.group({
name: [this.data.AIModel ? this.data.AIModel.name : '', [Validators.required, Validators.maxLength(255)]], name: [this.data.AIModel ? this.data.AIModel.name : '', [Validators.required, Validators.maxLength(255), Validators.pattern(/.*\S.*/)]],
modelType: [ModelType.CHAT], modelType: [ModelType.CHAT],
configuration: this.fb.group({ configuration: this.fb.group({
provider: [this.provider, [Validators.required]], provider: [this.provider, []],
providerConfig: this.fb.group({ providerConfig: this.fb.group({
apiKey: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.apiKey : '', [Validators.required]], apiKey: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.apiKey : '', [Validators.required]],
personalAccessToken: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.personalAccessToken : '', [Validators.required]], personalAccessToken: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.personalAccessToken : '', [Validators.required]],
@ -96,6 +96,9 @@ export class AIModelDialogComponent extends DialogComponent<AIModelDialogCompone
location: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.location : '', [Validators.required]], location: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.location : '', [Validators.required]],
serviceAccountKey: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.serviceAccountKey : '', [Validators.required]], serviceAccountKey: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.serviceAccountKey : '', [Validators.required]],
fileName: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.fileName : '', [Validators.required]], fileName: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.fileName : '', [Validators.required]],
region: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.region : '', [Validators.required]],
accessKeyId: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.accessKeyId : '', [Validators.required]],
secretAccessKey: [this.data.AIModel ? this.data.AIModel.configuration.providerConfig?.secretAccessKey : '', [Validators.required]],
}), }),
modelId: [this.data.AIModel ? this.data.AIModel.configuration?.modelId : '', [Validators.required]], modelId: [this.data.AIModel ? this.data.AIModel.configuration?.modelId : '', [Validators.required]],
temperature: [this.data.AIModel ? this.data.AIModel.configuration?.temperature : null, [Validators.min(0)]], temperature: [this.data.AIModel ? this.data.AIModel.configuration?.temperature : null, [Validators.min(0)]],

8
ui-ngx/src/app/modules/home/components/rule-node/external/ai-config.component.html

@ -26,7 +26,7 @@
useFullEntityId useFullEntityId
required required
appearance="outline" appearance="outline"
labelText="ai-models.ai-model" labelText="rule-node-config.ai.model"
(entityChanged)="onEntityChange($event)" (entityChanged)="onEntityChange($event)"
[entityType]="entityType.AI_MODEL" [entityType]="entityType.AI_MODEL"
(createNew)="createModelAi('modelId')" (createNew)="createModelAi('modelId')"
@ -76,10 +76,10 @@
<div class="tb-form-panel stroked" formGroupName="responseFormat"> <div class="tb-form-panel stroked" formGroupName="responseFormat">
<div class="flex flex-row items-center justify-between xs:flex-col xs:items-start xs:gap-3"> <div class="flex flex-row items-center justify-between xs:flex-col xs:items-start xs:gap-3">
<div class="tb-form-panel-title" tb-hint-tooltip-icon="{{ 'rule-node-config.ai.response-format-hint' | translate }}"> <div class="tb-form-panel-title" tb-hint-tooltip-icon="{{ getResponseFormatHint }}">
{{ 'rule-node-config.ai.response-format' | translate }} {{ 'rule-node-config.ai.response-format' | translate }}
</div> </div>
<tb-toggle-select formControlName="type"> <tb-toggle-select formControlName="type" [disabled]="disabledResponseFormatType">
<tb-toggle-option [value]="responseFormat.TEXT">{{ 'rule-node-config.ai.response-text' | translate }}</tb-toggle-option> <tb-toggle-option [value]="responseFormat.TEXT">{{ 'rule-node-config.ai.response-text' | translate }}</tb-toggle-option>
<tb-toggle-option [value]="responseFormat.JSON">{{ 'rule-node-config.ai.response-json' | translate }}</tb-toggle-option> <tb-toggle-option [value]="responseFormat.JSON">{{ 'rule-node-config.ai.response-json' | translate }}</tb-toggle-option>
<tb-toggle-option [value]="responseFormat.JSON_SCHEMA">{{ 'rule-node-config.ai.response-json-schema' | translate }}</tb-toggle-option> <tb-toggle-option [value]="responseFormat.JSON_SCHEMA">{{ 'rule-node-config.ai.response-json-schema' | translate }}</tb-toggle-option>
@ -107,7 +107,7 @@
</mat-expansion-panel-header> </mat-expansion-panel-header>
<div class="tb-form-panel no-border no-padding-top" style="margin-top: 0"> <div class="tb-form-panel no-border no-padding-top" style="margin-top: 0">
<div class="tb-form-row space-between flex-1 columns-xs"> <div class="tb-form-row space-between flex-1 columns-xs">
<div translate tb-hint-tooltip-icon="{{'rule-node-config.ai.timeout-hint' | translate}}">{{ 'rule-node-config.ai.timeout' | translate }}</div> <div tb-hint-tooltip-icon="{{'rule-node-config.ai.timeout-hint' | translate}}">{{ 'rule-node-config.ai.timeout' | translate }}</div>
<div class="flex flex-row items-center justify-start gap-2"> <div class="flex flex-row items-center justify-start gap-2">
<tb-time-unit-input <tb-time-unit-input
required required

19
ui-ngx/src/app/modules/home/components/rule-node/external/ai-config.component.ts

@ -22,6 +22,7 @@ import { MatDialog } from '@angular/material/dialog';
import { AIModelDialogComponent, AIModelDialogData } from '@home/components/ai-model/ai-model-dialog.component'; import { AIModelDialogComponent, AIModelDialogData } from '@home/components/ai-model/ai-model-dialog.component';
import { AiModel, AiRuleNodeResponseFormatTypeOnlyText, ResponseFormat } from '@shared/models/ai-model.models'; import { AiModel, AiRuleNodeResponseFormatTypeOnlyText, ResponseFormat } from '@shared/models/ai-model.models';
import { deepTrim } from '@core/utils'; import { deepTrim } from '@core/utils';
import { TranslateService } from '@ngx-translate/core';
@Component({ @Component({
selector: 'tb-external-node-ai-config', selector: 'tb-external-node-ai-config',
@ -36,7 +37,10 @@ export class AiConfigComponent extends RuleNodeConfigurationComponent {
responseFormat = ResponseFormat; responseFormat = ResponseFormat;
disabledResponseFormatType: boolean;
constructor(private fb: UntypedFormBuilder, constructor(private fb: UntypedFormBuilder,
private translate: TranslateService,
private dialog: MatDialog) { private dialog: MatDialog) {
super(); super();
} }
@ -72,20 +76,29 @@ export class AiConfigComponent extends RuleNodeConfigurationComponent {
} }
protected prepareOutputConfig(configuration: RuleNodeConfiguration): RuleNodeConfiguration { protected prepareOutputConfig(configuration: RuleNodeConfiguration): RuleNodeConfiguration {
if (!this.aiConfigForm.get('systemPrompt').value) {
delete configuration.systemPrompt;
}
return deepTrim(configuration); return deepTrim(configuration);
} }
onEntityChange($event: AiModel) { onEntityChange($event: AiModel) {
if ($event) { if ($event) {
if (AiRuleNodeResponseFormatTypeOnlyText.includes($event.configuration.provider)) { if (AiRuleNodeResponseFormatTypeOnlyText.includes($event.configuration.provider)) {
this.aiConfigForm.get('responseFormat.type').patchValue(ResponseFormat.TEXT, {emitEvent: false}); if (this.aiConfigForm.get('responseFormat.type').value !== ResponseFormat.TEXT) {
this.aiConfigForm.get('responseFormat.type').disable({emitEvent: false}); this.aiConfigForm.get('responseFormat.type').patchValue(ResponseFormat.TEXT, {emitEvent: true});
}
this.disabledResponseFormatType = true;
} }
} else { } else {
this.aiConfigForm.get('responseFormat.type').enable({emitEvent: false}); this.disabledResponseFormatType = false;
} }
} }
get getResponseFormatHint() {
return this.translate.instant(`rule-node-config.ai.response-format-hint-${this.aiConfigForm.get('responseFormat.type').value}`);
}
createModelAi(formControl: string) { createModelAi(formControl: string) {
this.dialog.open<AIModelDialogComponent, AIModelDialogData, AiModel>(AIModelDialogComponent, { this.dialog.open<AIModelDialogComponent, AIModelDialogData, AiModel>(AIModelDialogComponent, {
disableClose: true, disableClose: true,

15
ui-ngx/src/app/modules/home/pages/ai-model/ai-model-table-config.resolve.ts

@ -62,10 +62,10 @@ export class AiModelsTableConfigResolver {
this.config.columns.push( this.config.columns.push(
new DateEntityTableColumn<AiModel>('createdTime', 'common.created-time', this.datePipe, '170px'), new DateEntityTableColumn<AiModel>('createdTime', 'common.created-time', this.datePipe, '170px'),
new EntityTableColumn<AiModel>('name', 'ai-models.name', '33%'), new EntityTableColumn<AiModel>('name', 'ai-models.name', '33%'),
new EntityTableColumn<AiModel>('provider', 'ai-models.ai-provider', '33%', new EntityTableColumn<AiModel>('provider', 'ai-models.provider', '33%',
entity => this.translate.instant(AiProviderTranslations.get(entity.configuration.provider)) entity => this.translate.instant(AiProviderTranslations.get(entity.configuration.provider))
), ),
new EntityTableColumn<AiModel>('aiModel', 'ai-models.ai-model', '33%', new EntityTableColumn<AiModel>('aiModel', 'ai-models.model', '33%',
entity => entity.configuration.modelId, () => ({}), false entity => entity.configuration.modelId, () => ({}), false
) )
) )
@ -104,7 +104,7 @@ export class AiModelsTableConfigResolver {
private editModel($event, AIModel: AiModel): void { private editModel($event, AIModel: AiModel): void {
$event?.stopPropagation(); $event?.stopPropagation();
this.addModel(AIModel, false).subscribe(); this.addModel(AIModel, false).subscribe(res => res ? this.config.updateData() : null);
} }
private addModel(AIModel: AiModel, isAdd = false): Observable<AiModel> { private addModel(AIModel: AiModel, isAdd = false): Observable<AiModel> {
@ -115,13 +115,6 @@ export class AiModelsTableConfigResolver {
isAdd, isAdd,
AIModel AIModel
} }
}).afterClosed().pipe(map(res => { }).afterClosed();
if (res) {
this.config.updateData();
return res;
} else {
return null;
}
}));
} }
} }

2
ui-ngx/src/app/shared/components/string-autocomplete.component.html

@ -29,7 +29,7 @@
(click)="clear()"> (click)="clear()">
<mat-icon class="material-icons">close</mat-icon> <mat-icon class="material-icons">close</mat-icon>
</button> </button>
<mat-icon *ngIf="selectionFormControl.hasError('required') && !showInlineError" <mat-icon *ngIf="selectionFormControl.hasError('required') && selectionFormControl.touched && !showInlineError"
matIconSuffix matIconSuffix
[matTooltip]="errorText" [matTooltip]="errorText"
matTooltipPosition="above" matTooltipPosition="above"

12
ui-ngx/src/app/shared/models/ai-model.models.ts

@ -30,7 +30,10 @@ export interface AiModel extends Omit<BaseData<AiModelId>, 'label'>, HasTenantId
projectId?: string; projectId?: string;
location?: string; location?: string;
serviceAccountKey?: string; serviceAccountKey?: string;
fileName?: string fileName?: string;
region?: string;
accessKeyId?: string;
secretAccessKey?: string;
}; };
modelId: string; modelId: string;
temperature?: number; temperature?: number;
@ -78,7 +81,10 @@ export const ProviderFieldsAllList = [
'serviceAccountKey', 'serviceAccountKey',
'fileName', 'fileName',
'endpoint', 'endpoint',
'serviceVersion' 'serviceVersion',
'region',
'accessKeyId',
'secretAccessKey'
]; ];
export const ModelFieldsAllList = ['temperature', 'topP', 'topK', 'frequencyPenalty', 'presencePenalty', 'maxOutputTokens']; export const ModelFieldsAllList = ['temperature', 'topP', 'topK', 'frequencyPenalty', 'presencePenalty', 'maxOutputTokens'];
@ -173,7 +179,7 @@ export const AiModelMap = new Map<AiProvider, { modelList: string[], providerFie
AiProvider.AMAZON_BEDROCK, AiProvider.AMAZON_BEDROCK,
{ {
modelList: [], modelList: [],
providerFieldsList: ['apiKey'], providerFieldsList: ['region', 'accessKeyId', 'secretAccessKey'],
modelFieldsList: ['temperature', 'topP', 'maxOutputTokens'], modelFieldsList: ['temperature', 'topP', 'maxOutputTokens'],
}, },
], ],

28
ui-ngx/src/assets/locale/locale.constant-en_US.json

@ -1092,6 +1092,7 @@
"ai-models": { "ai-models": {
"ai-models": "AI models", "ai-models": "AI models",
"ai-model": "AI model", "ai-model": "AI model",
"model": "Model",
"name": "Name", "name": "Name",
"ai-provider": "AI provider", "ai-provider": "AI provider",
"no-found": "No AI models found", "no-found": "No AI models found",
@ -1113,7 +1114,7 @@
"github-models": "GitHub Models" "github-models": "GitHub Models"
}, },
"name-required": "Name is required.", "name-required": "Name is required.",
"name-max-length": "Name should be less than 256 characters.", "name-max-length": "Name must be 255 characters or less.",
"provider": "Provider", "provider": "Provider",
"api-key": "API key", "api-key": "API key",
"api-key-required": "API key is required.", "api-key-required": "API key is required.",
@ -1133,22 +1134,28 @@
"deployment-name": "Deployment name", "deployment-name": "Deployment name",
"deployment-name-required": "Deployment name is required", "deployment-name-required": "Deployment name is required",
"set": "Set", "set": "Set",
"region": "Region",
"region-required": "Region is required.",
"access-key-id": "Access key ID",
"access-key-id-required": "Access key ID is required.",
"secret-access-key": "Secret access key",
"secret-access-key-required": "Secret access key is required.",
"temperature": "Temperature", "temperature": "Temperature",
"temperature-hint": "Adjusts the level of randomness in the model's output. Higher values increase randomness, while lower values decrease it.", "temperature-hint": "Adjusts the level of randomness in the model's output. Higher values increase randomness, while lower values decrease it.",
"temperature-min": "Min value is 0.", "temperature-min": "Must be 0 or greater.",
"top-p": "Top P", "top-p": "Top P",
"top-p-hint": "Creates a pool of the most probable tokens for the model to choose from. Higher values create a larger and more diverse pool, while lower values create a smaller one.", "top-p-hint": "Creates a pool of the most probable tokens for the model to choose from. Higher values create a larger and more diverse pool, while lower values create a smaller one.",
"top-p-min-max": "Min value is more than 0, max value is 1.", "top-p-min-max": "Must be greater than 0 and up to 1.",
"top-k": "Top K", "top-k": "Top K",
"top-k-hint": "Restricts the model's choices to a fixed set of the \"K\" most likely tokens.", "top-k-hint": "Restricts the model's choices to a fixed set of the \"K\" most likely tokens.",
"top-k-min": "Min value is 0.", "top-k-min": "Must be 0 or greater.",
"presence-penalty": "Presence penalty", "presence-penalty": "Presence penalty",
"presence-penalty-hint": "Applies a fixed penalty to the likelihood of a token if it has already appeared in the text.", "presence-penalty-hint": "Applies a fixed penalty to the likelihood of a token if it has already appeared in the text.",
"frequency-penalty": "Frequency penalty", "frequency-penalty": "Frequency penalty",
"frequency-penalty-hint": "Applies a penalty to a token's likelihood that increases based on its frequency in the text.", "frequency-penalty-hint": "Applies a penalty to a token's likelihood that increases based on its frequency in the text.",
"max-output-token": "Maximum output token", "max-output-tokens": "Maximum output tokens",
"max-output-token-min": "Min value is more than 0.", "max-output-tokens-min": "Must be greater than 0.",
"max-output-token-hint": "Sets the maximum number of tokens that the \nmodel can generate in a single response.", "max-output-tokens-hint": "Sets the maximum number of tokens that the \nmodel can generate in a single response.",
"endpoint": "Endpoint", "endpoint": "Endpoint",
"endpoint-required": "Endpoint id required.", "endpoint-required": "Endpoint id required.",
"service-version": "Service version", "service-version": "Service version",
@ -5432,6 +5439,7 @@
}, },
"ai": { "ai": {
"ai-model": "AI model", "ai-model": "AI model",
"model": "Model",
"ai-model-hint": "Select the pre-configured AI model to process requests sent by this rule node, or use \"Create new\" to configure a new one.", "ai-model-hint": "Select the pre-configured AI model to process requests sent by this rule node, or use \"Create new\" to configure a new one.",
"prompt-settings": "Prompt settings", "prompt-settings": "Prompt settings",
"prompt-settings-hint": "Configure the instructions for the AI. The optional system prompt sets the AI's general role and constraints, while the user prompt defines the specific task to perform. Both fields also support rule node templates to include dynamic data (e.g., use $[*] to access the entire message body or ${*} to access all metadata).", "prompt-settings-hint": "Configure the instructions for the AI. The optional system prompt sets the AI's general role and constraints, while the user prompt defines the specific task to perform. Both fields also support rule node templates to include dynamic data (e.g., use $[*] to access the entire message body or ${*} to access all metadata).",
@ -5443,14 +5451,16 @@
"user-prompt-max-length": "User prompt must be 10000 characters or less.", "user-prompt-max-length": "User prompt must be 10000 characters or less.",
"user-prompt-blank": "User prompt must not be blank.", "user-prompt-blank": "User prompt must not be blank.",
"response-format": "Response format", "response-format": "Response format",
"response-format-hint": "The model is required to generate a JSON that matches the specific structure and data types defined in the provided schema. If the output is not a valid JSON object, it will be automatically wrapped within a JSON object under the \"response\" key.",
"response-text": "Text", "response-text": "Text",
"response-json": "JSON", "response-json": "JSON",
"response-json-schema": "JSON Schema", "response-json-schema": "JSON Schema",
"response-format-hint-TEXT": "Allows the model to generate arbitrary text, which may or may not be a valid JSON object. If the output is not a valid JSON object, it will be automatically wrapped within a JSON object under the \"response\" key.",
"response-format-hint-JSON": "The model is required to generate a response that is a valid JSON. If the output is not a valid JSON object, it will be automatically wrapped within a JSON object under the \"response\" key.",
"response-format-hint-JSON_SCHEMA": "The model is required to generate a JSON that matches the specific structure and data types defined in the provided schema. If the output is not a valid JSON object, it will be automatically wrapped within a JSON object under the \"response\" key.",
"response-json-schema-hint": "While any valid JSON Schema can be entered, this rule node only supports a limited subset of its features. See node documentation for details.", "response-json-schema-hint": "While any valid JSON Schema can be entered, this rule node only supports a limited subset of its features. See node documentation for details.",
"response-json-schema-required": "JSON Schema is required", "response-json-schema-required": "JSON Schema is required",
"advanced-settings": "Advanced settings", "advanced-settings": "Advanced settings",
"timeout": "Timeout", "timeout": "Timeout *",
"timeout-hint": "Maximum time to wait for a response \nfrom the AI model before the request is terminated.", "timeout-hint": "Maximum time to wait for a response \nfrom the AI model before the request is terminated.",
"timeout-required": "Timeout is required", "timeout-required": "Timeout is required",
"timeout-validation": "Must be from 1 second to 10 minutes.", "timeout-validation": "Must be from 1 second to 10 minutes.",

Loading…
Cancel
Save