2025-07-08 12:53:27 +03:00
|
|
|
<!--
|
|
|
|
|
|
|
|
|
|
Copyright © 2016-2025 The Thingsboard Authors
|
|
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
|
limitations under the License.
|
|
|
|
|
|
|
|
|
|
-->
|
|
|
|
|
<section [formGroup]="aiConfigForm" class="flex flex-col gap-4">
|
|
|
|
|
<section class="tb-form-panel stroked no-padding-bottom">
|
|
|
|
|
<div class="tb-form-panel-title" tb-hint-tooltip-icon="{{ 'rule-node-config.ai.ai-model-hint' | translate }}">
|
|
|
|
|
{{ 'rule-node-config.ai.ai-model' | translate }}
|
|
|
|
|
</div>
|
|
|
|
|
<section class="flex flex-col">
|
|
|
|
|
<tb-entity-autocomplete
|
|
|
|
|
allowCreateNew
|
|
|
|
|
useFullEntityId
|
|
|
|
|
required
|
|
|
|
|
appearance="outline"
|
|
|
|
|
labelText="ai-models.ai-model"
|
|
|
|
|
(entityChanged)="onEntityChange($event)"
|
2025-07-09 18:07:02 +03:00
|
|
|
[entityType]="entityType.AI_MODEL"
|
2025-07-10 13:32:39 +03:00
|
|
|
(createNew)="createModelAi('modelId')"
|
|
|
|
|
formControlName="modelId">
|
2025-07-08 12:53:27 +03:00
|
|
|
</tb-entity-autocomplete>
|
|
|
|
|
</section>
|
|
|
|
|
</section>
|
|
|
|
|
|
|
|
|
|
<div class="tb-form-panel stroked no-padding no-gap">
|
|
|
|
|
<mat-expansion-panel class="tb-settings" expanded>
|
|
|
|
|
<mat-expansion-panel-header style="padding: 16px">
|
2025-07-10 15:58:45 +03:00
|
|
|
<mat-panel-title>
|
2025-07-08 12:53:27 +03:00
|
|
|
{{'rule-node-config.ai.prompt-settings' | translate}}
|
|
|
|
|
</mat-panel-title>
|
|
|
|
|
</mat-expansion-panel-header>
|
2025-07-10 15:58:45 +03:00
|
|
|
<div class="tb-form-panel no-border no-padding-top" style="margin-top: 0">
|
|
|
|
|
<tb-example-hint
|
|
|
|
|
[hintText]="'rule-node-config.ai.prompt-settings-hint'"
|
|
|
|
|
[popupHelpLink]="'rulenode/ai_node_prompt_settings'">
|
|
|
|
|
</tb-example-hint>
|
|
|
|
|
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
|
|
|
|
<mat-label translate>rule-node-config.ai.system-prompt</mat-label>
|
|
|
|
|
<textarea matInput rows="4" formControlName="systemPrompt"></textarea>
|
|
|
|
|
<mat-error *ngIf="aiConfigForm.get('systemPrompt').hasError('maxlength')">
|
|
|
|
|
{{ 'rule-node-config.ai.system-prompt-max-length' | translate }}
|
|
|
|
|
</mat-error>
|
|
|
|
|
<mat-error *ngIf="aiConfigForm.get('systemPrompt').hasError('pattern')">
|
|
|
|
|
{{ 'rule-node-config.ai.system-prompt-blank' | translate }}
|
|
|
|
|
</mat-error>
|
|
|
|
|
</mat-form-field>
|
|
|
|
|
<mat-form-field class="flex" appearance="outline" subscriptSizing="dynamic">
|
|
|
|
|
<mat-label translate>rule-node-config.ai.user-prompt</mat-label>
|
|
|
|
|
<textarea required matInput rows="4" formControlName="userPrompt"></textarea>
|
|
|
|
|
<mat-error *ngIf="aiConfigForm.get('userPrompt').hasError('required')">
|
|
|
|
|
{{ 'rule-node-config.ai.user-prompt-required' | translate }}
|
|
|
|
|
</mat-error>
|
|
|
|
|
<mat-error *ngIf="aiConfigForm.get('userPrompt').hasError('maxlength')">
|
|
|
|
|
{{ 'rule-node-config.ai.user-prompt-max-length' | translate }}
|
|
|
|
|
</mat-error>
|
|
|
|
|
<mat-error *ngIf="aiConfigForm.get('userPrompt').hasError('pattern')">
|
|
|
|
|
{{ 'rule-node-config.ai.user-prompt-blank' | translate }}
|
|
|
|
|
</mat-error>
|
|
|
|
|
</mat-form-field>
|
|
|
|
|
</div>
|
2025-07-08 12:53:27 +03:00
|
|
|
</mat-expansion-panel>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<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="tb-form-panel-title" tb-hint-tooltip-icon="{{ 'rule-node-config.ai.response-format-hint' | translate }}">
|
|
|
|
|
{{ 'rule-node-config.ai.response-format' | translate }}
|
|
|
|
|
</div>
|
|
|
|
|
<tb-toggle-select formControlName="type">
|
|
|
|
|
<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_SCHEMA">{{ 'rule-node-config.ai.response-json-schema' | translate }}</tb-toggle-option>
|
|
|
|
|
</tb-toggle-select>
|
|
|
|
|
</div>
|
|
|
|
|
@if (aiConfigForm.get('responseFormat.type').value === responseFormat.JSON_SCHEMA) {
|
|
|
|
|
<tb-json-object-edit
|
|
|
|
|
jsonRequired
|
2025-07-10 13:32:39 +03:00
|
|
|
iconHint="{{ 'rule-node-config.ai.response-json-schema-hint' | translate }}"
|
2025-07-08 12:53:27 +03:00
|
|
|
label="{{ 'rule-node-config.ai.response-json-schema' | translate }}"
|
|
|
|
|
formControlName="schema">
|
|
|
|
|
</tb-json-object-edit>
|
|
|
|
|
}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="tb-form-panel stroked no-padding no-gap">
|
|
|
|
|
<mat-expansion-panel class="tb-settings">
|
|
|
|
|
<mat-expansion-panel-header style="padding: 16px">
|
|
|
|
|
<mat-panel-title translate>rule-node-config.ai.advanced-settings</mat-panel-title>
|
|
|
|
|
</mat-expansion-panel-header>
|
2025-07-10 15:58:45 +03:00
|
|
|
<div class="tb-form-panel no-border no-padding-top" style="margin-top: 0">
|
2025-07-09 20:05:06 +03:00
|
|
|
<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 class="flex flex-row items-center justify-start gap-2">
|
|
|
|
|
<tb-time-unit-input
|
|
|
|
|
required
|
|
|
|
|
inlineField
|
|
|
|
|
requiredText="{{ 'rule-node-config.ai.timeout-required' | translate }}"
|
|
|
|
|
minErrorText="{{ 'rule-node-config.ai.timeout-validation' | translate }}"
|
|
|
|
|
maxErrorText="{{ 'rule-node-config.ai.timeout-validation' | translate }}"
|
|
|
|
|
[maxTime]="600"
|
|
|
|
|
[minTime]="1"
|
|
|
|
|
formControlName="timeoutSeconds">
|
|
|
|
|
</tb-time-unit-input>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2025-07-10 15:58:45 +03:00
|
|
|
<div tb-hint-tooltip-icon="{{ 'rule-node-config.ai.force-acknowledgement-hint' | translate }}"
|
|
|
|
|
class="tb-form-row same-padding">
|
|
|
|
|
<mat-slide-toggle class="mat-slide margin" formControlName="forceAck">
|
|
|
|
|
{{ 'rule-node-config.ai.force-acknowledgement' | translate }}
|
|
|
|
|
</mat-slide-toggle>
|
|
|
|
|
</div>
|
2025-07-08 12:53:27 +03:00
|
|
|
</div>
|
|
|
|
|
</mat-expansion-panel>
|
|
|
|
|
</div>
|
|
|
|
|
</section>
|