Spaces:
Building
Building
<mat-dialog-content class="version-management-container"> | |
<h2 mat-dialog-title> | |
Manage Versions - {{ project.name }} | |
<mat-chip-listbox class="title-chips"> | |
<mat-chip-option [disabled]="true"> | |
<mat-icon>layers</mat-icon> | |
{{ versions.length }} versions | |
</mat-chip-option> | |
</mat-chip-listbox> | |
</h2> | |
<div class="dialog-content"> | |
<!-- Version Selector --> | |
<div class="version-selector"> | |
<mat-form-field appearance="outline" class="version-select"> | |
<mat-label>Select Version</mat-label> | |
<mat-select [(value)]="selectedVersion" (selectionChange)="loadVersion($event.value)"> | |
<mat-option *ngFor="let version of versions" [value]="version"> | |
Version {{ version.no }} - {{ version.caption || 'No description' }} | |
<span class="version-status" *ngIf="version.published">[Published]</span> | |
</mat-option> | |
</mat-select> | |
</mat-form-field> | |
<div class="version-actions"> | |
<button mat-raised-button color="primary" (click)="createVersion()" [disabled]="creating"> | |
<mat-icon>add</mat-icon> | |
New Version | |
</button> | |
<button mat-button (click)="compareVersions()" [disabled]="versions.length < 2"> | |
<mat-icon>compare_arrows</mat-icon> | |
Compare | |
</button> | |
</div> | |
</div> | |
<mat-progress-bar *ngIf="loading" mode="indeterminate"></mat-progress-bar> | |
<!-- Warning for published version --> | |
<div class="alert alert-warning" *ngIf="selectedVersion?.published"> | |
<mat-icon>info</mat-icon> | |
This version is published and cannot be edited. Create a new version or unpublish to make changes. | |
</div> | |
<!-- Version Editor --> | |
<div class="version-editor" *ngIf="selectedVersion && !loading"> | |
<form [formGroup]="versionForm"> | |
<mat-tab-group [(selectedIndex)]="selectedTabIndex" dynamicHeight> | |
<!-- General Tab --> | |
<mat-tab label="General"> | |
<div class="tab-content"> | |
<div class="metadata-info"> | |
<mat-chip-listbox> | |
<mat-chip-option>Version {{ selectedVersion.no }}</mat-chip-option> | |
<mat-chip-option *ngIf="selectedVersion.published" selected>Published</mat-chip-option> | |
<mat-chip-option *ngIf="!selectedVersion.published">Draft</mat-chip-option> | |
<mat-chip-option *ngIf="selectedVersion.last_update_date"> | |
Last updated: {{ selectedVersion.last_update_date | date:'short' }} | |
</mat-chip-option> | |
</mat-chip-listbox> | |
</div> | |
<mat-form-field appearance="outline" class="full-width"> | |
<mat-label>Caption</mat-label> | |
<input matInput formControlName="caption" placeholder="Version description" [readonly]="!canEdit"> | |
</mat-form-field> | |
<mat-form-field appearance="outline" class="full-width"> | |
<mat-label>General System Prompt</mat-label> | |
<textarea matInput | |
class="code-textarea" | |
formControlName="general_prompt" | |
rows="10" | |
placeholder="Define the assistant's behavior and capabilities..." | |
[readonly]="!canEdit"></textarea> | |
<mat-hint>This prompt defines the overall behavior of your assistant</mat-hint> | |
</mat-form-field> | |
<mat-form-field appearance="outline" class="full-width"> | |
<mat-label>Welcome Prompt</mat-label> | |
<textarea matInput formControlName="welcome_prompt" rows="4" [readonly]="!canEdit"></textarea> | |
<mat-hint>Initial greeting message (use {{ '{{user_name}}' }} for personalization)</mat-hint> | |
</mat-form-field> | |
<div class="action-buttons"> | |
<button mat-raised-button color="warn" | |
(click)="deleteVersion()" | |
[disabled]="selectedVersion.published" | |
*ngIf="!selectedVersion.published"> | |
<mat-icon>delete</mat-icon> | |
Delete Version | |
</button> | |
</div> | |
</div> | |
</mat-tab> | |
<!-- LLM Configuration Tab --> | |
<mat-tab label="LLM"> | |
<div class="tab-content" formGroupName="llm"> | |
<mat-form-field appearance="outline" class="full-width"> | |
<mat-label>Model Repository ID</mat-label> | |
<input matInput formControlName="repo_id" | |
placeholder="e.g., ytu-ce-cosmos/Turkish-Llama-8b-Instruct-v0.1" | |
[readonly]="!canEdit"> | |
<mat-hint>HuggingFace model repository ID</mat-hint> | |
</mat-form-field> | |
<h4>Generation Configuration</h4> | |
<div formGroupName="generation_config" class="generation-config"> | |
<mat-form-field appearance="outline"> | |
<mat-label>Max New Tokens</mat-label> | |
<input matInput type="number" formControlName="max_new_tokens" [readonly]="!canEdit"> | |
<mat-hint>Maximum tokens to generate (1-2048)</mat-hint> | |
</mat-form-field> | |
<mat-form-field appearance="outline"> | |
<mat-label>Temperature</mat-label> | |
<input matInput type="number" step="0.1" formControlName="temperature" [readonly]="!canEdit"> | |
<mat-hint>Controls randomness (0-2)</mat-hint> | |
</mat-form-field> | |
<mat-form-field appearance="outline"> | |
<mat-label>Top P</mat-label> | |
<input matInput type="number" step="0.1" formControlName="top_p" [readonly]="!canEdit"> | |
<mat-hint>Nucleus sampling (0-1)</mat-hint> | |
</mat-form-field> | |
<mat-form-field appearance="outline"> | |
<mat-label>Repetition Penalty</mat-label> | |
<input matInput type="number" step="0.1" formControlName="repetition_penalty" [readonly]="!canEdit"> | |
<mat-hint>Penalty for repetition (1-2)</mat-hint> | |
</mat-form-field> | |
</div> | |
<mat-divider></mat-divider> | |
<div class="fine-tune-section"> | |
<mat-checkbox formControlName="use_fine_tune" [disabled]="!canEdit"> | |
Use Fine-Tuned Model | |
</mat-checkbox> | |
<mat-form-field appearance="outline" class="full-width" | |
*ngIf="versionForm.get('llm.use_fine_tune')?.value"> | |
<mat-label>Fine-Tune ZIP URL</mat-label> | |
<input matInput formControlName="fine_tune_zip" | |
placeholder="https://example.com/lora-adapter.zip" | |
[readonly]="!canEdit"> | |
<mat-hint>URL to LoRA adapter ZIP file</mat-hint> | |
</mat-form-field> | |
</div> | |
</div> | |
</mat-tab> | |
<!-- Intents Tab --> | |
<mat-tab label="Intents" [matBadge]="intents.length" matBadgeColor="primary"> | |
<div class="tab-content"> | |
<div class="intents-header"> | |
<h3>Intent Definitions</h3> | |
<button mat-raised-button color="primary" (click)="addIntent()" [disabled]="!canEdit"> | |
<mat-icon>add</mat-icon> | |
Add Intent | |
</button> | |
</div> | |
<!-- Example Language Selector --> | |
<mat-form-field appearance="outline" class="locale-selector"> | |
<mat-label>Example Language</mat-label> | |
<mat-select [(value)]="selectedExampleLocale"> | |
<mat-option *ngFor="let locale of getAvailableLocales()" [value]="locale.code"> | |
{{ locale.name }} | |
</mat-option> | |
</mat-select> | |
</mat-form-field> | |
<div formArrayName="intents" class="intents-list"> | |
<mat-expansion-panel *ngFor="let intent of intents.controls; let i = index" | |
[formGroupName]="i"> | |
<mat-expansion-panel-header> | |
<mat-panel-title> | |
{{ intent.get('name')?.value || 'New Intent' }} | |
</mat-panel-title> | |
<mat-panel-description> | |
{{ intent.get('caption')?.value || 'No description' }} | |
<mat-chip-listbox class="intent-chips"> | |
<mat-chip-option>{{ getIntentParameters(i).length }} params</mat-chip-option> | |
<mat-chip-option>{{ intent.get('action')?.value || 'No API' }}</mat-chip-option> | |
</mat-chip-listbox> | |
</mat-panel-description> | |
</mat-expansion-panel-header> | |
<div class="intent-content"> | |
<div class="intent-actions"> | |
<button mat-button color="primary" (click)="editIntent(i)" [disabled]="!canEdit"> | |
<mat-icon>edit</mat-icon> | |
Edit Details | |
</button> | |
<button mat-button color="warn" (click)="removeIntent(i)" [disabled]="!canEdit"> | |
<mat-icon>delete</mat-icon> | |
Delete | |
</button> | |
</div> | |
<!-- Quick view of intent details --> | |
<div class="intent-summary"> | |
<div class="summary-item"> | |
<strong>Detection Prompt:</strong> | |
<p>{{ intent.get('detection_prompt')?.value || 'Not set' }}</p> | |
</div> | |
<div class="summary-item" *ngIf="getLocalizedExamples(intent.get('examples')?.value, selectedExampleLocale).length > 0"> | |
<strong>Examples ({{ getLocaleName(selectedExampleLocale) }}):</strong> | |
<div class="examples-display"> | |
<mat-chip-row *ngFor="let ex of getLocalizedExamples(intent.get('examples')?.value, selectedExampleLocale)"> | |
{{ ex.example }} | |
</mat-chip-row> | |
</div> | |
</div> | |
<div class="summary-item" *ngIf="getIntentParameters(i).length > 0"> | |
<strong>Parameters:</strong> | |
<mat-list> | |
<mat-list-item *ngFor="let param of getIntentParameters(i).controls"> | |
<mat-icon matListItemIcon> | |
{{ param.get('required')?.value ? 'check_box' : 'check_box_outline_blank' }} | |
</mat-icon> | |
<div matListItemTitle>{{ param.get('name')?.value }}</div> | |
<div matListItemLine> | |
{{ getParameterCaptionDisplay(param.get('caption')?.value) }} | |
({{ param.get('type')?.value }}) | |
</div> | |
</mat-list-item> | |
</mat-list> | |
</div> | |
</div> | |
</div> | |
</mat-expansion-panel> | |
</div> | |
<div class="empty-state" *ngIf="intents.length === 0"> | |
<mat-icon>psychology</mat-icon> | |
<p>No intents defined yet.</p> | |
<button mat-raised-button color="primary" (click)="addIntent()" [disabled]="!canEdit"> | |
Add First Intent | |
</button> | |
</div> | |
</div> | |
</mat-tab> | |
<!-- Test Tab --> | |
<mat-tab label="Test"> | |
<div class="tab-content"> | |
<h3>Test Intent Detection</h3> | |
<p>Enter a user message to test which intent would be detected.</p> | |
<mat-form-field appearance="outline" class="full-width"> | |
<mat-label>User Message</mat-label> | |
<textarea matInput | |
[(ngModel)]="testUserMessage" | |
[ngModelOptions]="{standalone: true}" | |
rows="3" | |
placeholder="e.g., I want to book a flight from Istanbul to Ankara"></textarea> | |
</mat-form-field> | |
<button mat-raised-button color="accent" | |
(click)="testIntentDetection()" | |
[disabled]="testing || !testUserMessage"> | |
<mat-icon>play_arrow</mat-icon> | |
{{ testing ? 'Testing...' : 'Test Intent Detection' }} | |
</button> | |
<div class="test-result" *ngIf="testResult"> | |
<h4>Test Result:</h4> | |
<div class="result-card" [class.success]="testResult.intent" [class.no-match]="!testResult.intent"> | |
<div class="result-header"> | |
<mat-icon>{{ testResult.intent ? 'check_circle' : 'info' }}</mat-icon> | |
<span *ngIf="testResult.intent">Intent Detected: <strong>{{ testResult.intent }}</strong></span> | |
<span *ngIf="!testResult.intent">No intent matched</span> | |
</div> | |
<div class="result-details" *ngIf="testResult.intent"> | |
<div class="confidence"> | |
Confidence: {{ (testResult.confidence * 100).toFixed(0) }}% | |
<mat-progress-bar [value]="testResult.confidence * 100"></mat-progress-bar> | |
</div> | |
<div class="parameters" *ngIf="testResult.parameters.length > 0"> | |
<h5>Parameters that would be extracted:</h5> | |
<mat-list> | |
<mat-list-item *ngFor="let param of testResult.parameters"> | |
<mat-icon matListItemIcon [color]="param.extracted ? 'primary' : ''"> | |
{{ param.extracted ? 'check_circle' : 'radio_button_unchecked' }} | |
</mat-icon> | |
<div matListItemTitle>{{ param.name }}</div> | |
<div matListItemLine> | |
{{ param.extracted ? 'Value: ' + param.value : 'Missing - would ask user' }} | |
</div> | |
</mat-list-item> | |
</mat-list> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</mat-tab> | |
</mat-tab-group> | |
</form> | |
</div> | |
<!-- No Version Selected --> | |
<div class="empty-state" *ngIf="!selectedVersion && !loading"> | |
<mat-icon>layers</mat-icon> | |
<p>No version selected. Create a new version to get started.</p> | |
<button mat-raised-button color="primary" (click)="createVersion()"> | |
Create First Version | |
</button> | |
</div> | |
</div> | |
</mat-dialog-content> | |
<mat-dialog-actions align="end"> | |
<button mat-button (click)="close()">Close</button> | |
<button mat-raised-button | |
color="primary" | |
(click)="saveVersion()" | |
[disabled]="!selectedVersion || !canEdit || versionForm.invalid || saving"> | |
{{ saving ? 'Saving...' : 'Save Changes' }} | |
</button> | |
<button mat-raised-button | |
color="accent" | |
(click)="publishVersion()" | |
[disabled]="!selectedVersion || selectedVersion.published || publishing || isDirty || versionForm.invalid"> | |
{{ publishing ? 'Publishing...' : 'Publish Version' }} | |
</button> | |
</mat-dialog-actions> |