Spaces:
Paused
Paused
| <mat-card> | |
| <mat-card-header> | |
| <mat-card-title> | |
| <mat-icon>settings</mat-icon> | |
| Environment Configuration | |
| </mat-card-title> | |
| </mat-card-header> | |
| <mat-card-content> | |
| @if (loading) { | |
| <div class="loading-container"> | |
| <mat-spinner></mat-spinner> | |
| <p>Loading configuration...</p> | |
| </div> | |
| } @else { | |
| <form [formGroup]="form"> | |
| <!-- LLM Provider Section --> | |
| <div class="provider-section"> | |
| <h3> | |
| <mat-icon>smart_toy</mat-icon> | |
| LLM Provider | |
| </h3> | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Provider</mat-label> | |
| <mat-icon matPrefix>{{ getLLMProviderIcon(currentLLMProviderSafe) }}</mat-icon> | |
| <mat-select formControlName="llm_provider_name" | |
| (selectionChange)="onLLMProviderChange($event.value)"> | |
| @for (provider of llmProviders; track provider.name) { | |
| <mat-option [value]="provider.name"> | |
| <mat-icon>{{ getLLMProviderIcon(provider) }}</mat-icon> | |
| {{ provider.display_name }} | |
| </mat-option> | |
| } | |
| </mat-select> | |
| @if (currentLLMProviderSafe?.description) { | |
| <mat-hint>{{ currentLLMProviderSafe?.description }}</mat-hint> | |
| } | |
| </mat-form-field> | |
| @if (currentLLMProviderSafe?.requires_api_key) { | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>{{ getApiKeyLabel('llm') }}</mat-label> | |
| <mat-icon matPrefix>key</mat-icon> | |
| <input matInput | |
| type="password" | |
| formControlName="llm_provider_api_key" | |
| [placeholder]="getApiKeyPlaceholder('llm')"> | |
| <mat-error *ngIf="form.get('llm_provider_api_key')?.hasError('required')"> | |
| API key is required for {{ currentLLMProviderSafe?.display_name || 'this provider' }} | |
| </mat-error> | |
| </mat-form-field> | |
| } | |
| @if (currentLLMProviderSafe?.requires_endpoint) { | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Endpoint URL</mat-label> | |
| <mat-icon matPrefix>link</mat-icon> | |
| <input matInput | |
| formControlName="llm_provider_endpoint" | |
| [placeholder]="getEndpointPlaceholder('llm')"> | |
| <button mat-icon-button matSuffix | |
| (click)="testConnection()" | |
| type="button" | |
| matTooltip="Test connection"> | |
| <mat-icon>wifi_tethering</mat-icon> | |
| </button> | |
| <mat-error *ngIf="form.get('llm_provider_endpoint')?.hasError('required')"> | |
| Endpoint is required for {{ currentLLMProviderSafe?.display_name || 'this provider' }} | |
| </mat-error> | |
| </mat-form-field> | |
| } | |
| <!-- LLM Settings (Internal Prompt & Parameter Collection) --> | |
| @if (currentLLMProviderSafe) { | |
| <mat-expansion-panel class="settings-panel"> | |
| <mat-expansion-panel-header> | |
| <mat-panel-title> | |
| <mat-icon>psychology</mat-icon> | |
| Internal System Prompt | |
| </mat-panel-title> | |
| <mat-panel-description> | |
| Configure the internal prompt for intent detection | |
| </mat-panel-description> | |
| </mat-expansion-panel-header> | |
| <div class="panel-content"> | |
| <p class="hint-text"> | |
| This prompt is prepended to all intent detection requests. | |
| </p> | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Internal Prompt</mat-label> | |
| <textarea matInput | |
| [(ngModel)]="internalPrompt" | |
| [ngModelOptions]="{standalone: true}" | |
| rows="10" | |
| placeholder="Enter the system prompt that guides intent detection..."></textarea> | |
| <mat-hint>Use clear instructions to guide the LLM's behavior</mat-hint> | |
| </mat-form-field> | |
| </div> | |
| </mat-expansion-panel> | |
| <mat-expansion-panel class="settings-panel"> | |
| <mat-expansion-panel-header> | |
| <mat-panel-title> | |
| <mat-icon>tune</mat-icon> | |
| Parameter Collection Configuration | |
| </mat-panel-title> | |
| <mat-panel-description> | |
| Fine-tune how parameters are collected from users | |
| </mat-panel-description> | |
| </mat-expansion-panel-header> | |
| <div class="panel-content"> | |
| <mat-slide-toggle [(ngModel)]="parameterCollectionConfig.enabled" | |
| [ngModelOptions]="{standalone: true}"> | |
| Enable Smart Parameter Collection | |
| </mat-slide-toggle> | |
| <div class="config-item"> | |
| <label>Max Parameters per Question</label> | |
| <mat-slider min="1" max="5" step="1" discrete> | |
| <input matSliderThumb [(ngModel)]="parameterCollectionConfig.max_params_per_question" | |
| [ngModelOptions]="{standalone: true}"> | |
| </mat-slider> | |
| <span class="slider-value">{{ parameterCollectionConfig.max_params_per_question }}</span> | |
| </div> | |
| <mat-slide-toggle [(ngModel)]="parameterCollectionConfig.show_all_required" | |
| [ngModelOptions]="{standalone: true}"> | |
| Show All Required Parameters | |
| </mat-slide-toggle> | |
| <mat-slide-toggle [(ngModel)]="parameterCollectionConfig.ask_optional_params" | |
| [ngModelOptions]="{standalone: true}"> | |
| Ask for Optional Parameters | |
| </mat-slide-toggle> | |
| <mat-slide-toggle [(ngModel)]="parameterCollectionConfig.group_related_params" | |
| [ngModelOptions]="{standalone: true}"> | |
| Group Related Parameters | |
| </mat-slide-toggle> | |
| <div class="config-item"> | |
| <label>Minimum Confidence Score</label> | |
| <mat-slider min="0" max="1" step="0.1" discrete> | |
| <input matSliderThumb [(ngModel)]="parameterCollectionConfig.min_confidence_score" | |
| [ngModelOptions]="{standalone: true}"> | |
| </mat-slider> | |
| <span class="slider-value">{{ parameterCollectionConfig.min_confidence_score }}</span> | |
| </div> | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Collection Prompt Template</mat-label> | |
| <textarea matInput | |
| [(ngModel)]="parameterCollectionConfig.collection_prompt" | |
| [ngModelOptions]="{standalone: true}" | |
| rows="8"></textarea> | |
| <button mat-icon-button matSuffix | |
| (click)="resetCollectionPrompt()" | |
| type="button" | |
| matTooltip="Reset to default"> | |
| <mat-icon>refresh</mat-icon> | |
| </button> | |
| </mat-form-field> | |
| </div> | |
| </mat-expansion-panel> | |
| } | |
| </div> | |
| <mat-divider></mat-divider> | |
| <!-- TTS Provider Section --> | |
| <div class="provider-section"> | |
| <h3> | |
| <mat-icon>record_voice_over</mat-icon> | |
| TTS Provider | |
| </h3> | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Provider</mat-label> | |
| <mat-icon matPrefix>{{ getTTSProviderIcon(currentTTSProviderSafe) }}</mat-icon> | |
| <mat-select formControlName="tts_provider_name" | |
| (selectionChange)="onTTSProviderChange($event.value)"> | |
| @for (provider of ttsProviders; track provider.name) { | |
| <mat-option [value]="provider.name"> | |
| <mat-icon>{{ getTTSProviderIcon(provider) }}</mat-icon> | |
| {{ provider.display_name }} | |
| </mat-option> | |
| } | |
| </mat-select> | |
| @if (currentTTSProviderSafe?.description) { | |
| <mat-hint>{{ currentTTSProviderSafe?.description }}</mat-hint> | |
| } | |
| </mat-form-field> | |
| @if (currentTTSProviderSafe?.requires_api_key) { | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>API Key</mat-label> | |
| <mat-icon matPrefix>key</mat-icon> | |
| <input matInput | |
| type="password" | |
| formControlName="tts_provider_api_key" | |
| [placeholder]="getApiKeyPlaceholder('tts')"> | |
| <mat-error *ngIf="form.get('tts_provider_api_key')?.hasError('required')"> | |
| API key is required for {{ currentTTSProviderSafe?.display_name || 'this provider' }} | |
| </mat-error> | |
| </mat-form-field> | |
| } | |
| @if (currentTTSProviderSafe?.requires_endpoint) { | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Endpoint URL</mat-label> | |
| <mat-icon matPrefix>link</mat-icon> | |
| <input matInput | |
| formControlName="tts_provider_endpoint" | |
| [placeholder]="getEndpointPlaceholder('tts')"> | |
| </mat-form-field> | |
| } | |
| </div> | |
| <mat-divider></mat-divider> | |
| <!-- STT Provider Section --> | |
| <div class="provider-section"> | |
| <h3> | |
| <mat-icon>mic</mat-icon> | |
| STT Provider | |
| </h3> | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Provider</mat-label> | |
| <mat-icon matPrefix>{{ getSTTProviderIcon(currentSTTProviderSafe) }}</mat-icon> | |
| <mat-select formControlName="stt_provider_name" | |
| (selectionChange)="onSTTProviderChange($event.value)"> | |
| @for (provider of sttProviders; track provider.name) { | |
| <mat-option [value]="provider.name"> | |
| <mat-icon>{{ getSTTProviderIcon(provider) }}</mat-icon> | |
| {{ provider.display_name }} | |
| </mat-option> | |
| } | |
| </mat-select> | |
| @if (currentSTTProviderSafe?.description) { | |
| <mat-hint>{{ currentSTTProviderSafe?.description }}</mat-hint> | |
| } | |
| </mat-form-field> | |
| @if (currentSTTProviderSafe?.requires_api_key) { | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>{{ getApiKeyLabel('stt') }}</mat-label> | |
| <mat-icon matPrefix>key</mat-icon> | |
| <input matInput | |
| [type]="currentSTTProviderSafe?.name === 'google' ? 'text' : 'password'" | |
| formControlName="stt_provider_api_key" | |
| [placeholder]="getApiKeyPlaceholder('stt')"> | |
| <mat-error *ngIf="form.get('stt_provider_api_key')?.hasError('required')"> | |
| {{ currentSTTProviderSafe?.name === 'google' ? 'Credentials path' : 'API key' }} is required for {{ currentSTTProviderSafe?.display_name || 'this provider' }} | |
| </mat-error> | |
| </mat-form-field> | |
| } | |
| @if (currentSTTProviderSafe?.requires_endpoint) { | |
| <mat-form-field appearance="outline" class="full-width"> | |
| <mat-label>Endpoint URL</mat-label> | |
| <mat-icon matPrefix>link</mat-icon> | |
| <input matInput | |
| formControlName="stt_provider_endpoint" | |
| [placeholder]="getEndpointPlaceholder('stt')"> | |
| </mat-form-field> | |
| } | |
| </div> | |
| <mat-card-actions align="end"> | |
| <button mat-raised-button | |
| color="primary" | |
| (click)="saveEnvironment()" | |
| [disabled]="form.invalid || saving"> | |
| <mat-icon>save</mat-icon> | |
| {{ saving ? 'Saving...' : 'Save Configuration' }} | |
| </button> | |
| </mat-card-actions> | |
| </form> | |
| } | |
| </mat-card-content> | |
| </mat-card> |