diff --git a/frontend/src/app/profile/profile.component.ts b/frontend/src/app/profile/profile.component.ts index 988bfdda..2a948972 100644 --- a/frontend/src/app/profile/profile.component.ts +++ b/frontend/src/app/profile/profile.component.ts @@ -3,6 +3,7 @@ import { FormGroup, FormControl } from '@angular/forms'; import { HttpClient } from '@angular/common/http'; import { environment } from '@env/environment'; import { MatSnackBar } from '@angular/material/snack-bar'; +import { LlmService } from '../shared/services/llm.service'; @Component({ selector: 'app-profile', @@ -11,7 +12,7 @@ import { MatSnackBar } from '@angular/material/snack-bar'; }) export class ProfileComponent implements OnInit { profileForm: FormGroup; - constructor(private http: HttpClient, private snackBar: MatSnackBar) { + constructor(private http: HttpClient, private snackBar: MatSnackBar, private llmService: LlmService) { this.profileForm = this.createProfileForm(); } @@ -66,6 +67,8 @@ export class ProfileComponent implements OnInit { this.http.post(updateUrl, { user: formValue }).subscribe({ next: () => { this.snackBar.open('Profile updated', 'Close', { duration: 3000 }); + this.llmService.clearCache(); + this.loadLlmList(); }, error: (error) => { this.snackBar.open('Failed to save profile.', 'Close', { duration: 3000 }); @@ -74,9 +77,8 @@ export class ProfileComponent implements OnInit { }); } - // ... (rest of the component methods) private loadUserProfile(): void { - console.log('Loading profile profile...'); + console.log('Loading user profile...'); const profileUrl = `${environment.serverUrl}/profile/view`; this.http.get(profileUrl).subscribe( (response: any) => { @@ -89,4 +91,16 @@ export class ProfileComponent implements OnInit { } ); } + + private loadLlmList(): void { + this.llmService.getLlms().subscribe({ + next: (llms) => { + console.log('LLM list loaded:', llms); + }, + error: (error) => { + console.error('Failed to load LLM list:', error); + this.snackBar.open('Failed to load LLM list', 'Close', { duration: 3000 }); + }, + }); + } } diff --git a/frontend/src/app/shared/services/llm.service.spec.ts b/frontend/src/app/shared/services/llm.service.spec.ts index db87d803..012aa59a 100644 --- a/frontend/src/app/shared/services/llm.service.spec.ts +++ b/frontend/src/app/shared/services/llm.service.spec.ts @@ -36,33 +36,31 @@ describe('LlmService', () => { expect(llms).toEqual(mockLlms); }); - const req = httpMock.expectOne(LLM_LIST_API_URL); + const req = httpMock.expectOne(`${LLM_LIST_API_URL}`); expect(req.request.method).toBe('GET'); req.flush({ data: mockLlms }); }); - it('should cache LLMs after the first request', () => { - const mockLlms: LLM[] = [{ id: 'llm1', name: 'LLM 1', isConfigured: true }]; + it('should cache LLMs per user', () => { + const mockLlms1: LLM[] = [{ id: 'llm1', name: 'LLM 1', isConfigured: true }]; service.getLlms().subscribe(); - httpMock.expectOne(LLM_LIST_API_URL).flush({ data: mockLlms }); + httpMock.expectOne(`${LLM_LIST_API_URL}`).flush({ data: mockLlms1 }); service.getLlms().subscribe((llms) => { - expect(llms).toEqual(mockLlms); + expect(llms).toEqual(mockLlms1); }); - - httpMock.expectNone(LLM_LIST_API_URL); }); - it('should handle errors when fetching LLMs', () => { - service.getLlms().subscribe({ - next: () => fail('should have failed with the 404 error'), - error: (error) => { - expect(error.message).toContain('Error Code: 404'); - }, - }); + it('should clear the cache', () => { + const mockLlms: LLM[] = [{ id: 'llm1', name: 'LLM 1', isConfigured: true }]; - const req = httpMock.expectOne(LLM_LIST_API_URL); - req.flush('Not Found', { status: 404, statusText: 'Not Found' }); + service.getLlms().subscribe(); + httpMock.expectOne(`${LLM_LIST_API_URL}`).flush({ data: mockLlms }); + + service.clearCache(); + + service.getLlms().subscribe(); + httpMock.expectOne(`${LLM_LIST_API_URL}`); }); }); diff --git a/frontend/src/app/shared/services/llm.service.ts b/frontend/src/app/shared/services/llm.service.ts index b7f036b2..fdd08e14 100644 --- a/frontend/src/app/shared/services/llm.service.ts +++ b/frontend/src/app/shared/services/llm.service.ts @@ -3,6 +3,7 @@ import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { Observable, BehaviorSubject, throwError } from 'rxjs'; import { tap, shareReplay, map, catchError, retry } from 'rxjs/operators'; import { environment } from '@env/environment'; +import { CredentialsService } from '@app/auth'; export interface LLM { id: string; @@ -40,6 +41,12 @@ export class LlmService { ); } + clearCache() { + this.llmsLoaded = false; + this.llmsSubject.next([]); + this.getLlms(); + } + private handleError(error: HttpErrorResponse) { let errorMessage = 'An error occurred'; if (error.error instanceof ErrorEvent) { diff --git a/src/routes/llms/llm-routes.ts b/src/routes/llms/llm-routes.ts index 59e56b6a..6cd7e036 100644 --- a/src/routes/llms/llm-routes.ts +++ b/src/routes/llms/llm-routes.ts @@ -5,6 +5,7 @@ import { AppFastifyInstance } from '../../app'; const basePath = '/api/llms'; export async function llmRoutes(fastify: AppFastifyInstance) { + // Returns the LLMs which are configured for the current user fastify.get(`${basePath}/list`, async (req, reply) => { const configuredLLMs = LLM_TYPES.map((llm) => getLLM(llm.id)) .filter((llm) => llm.isConfigured()) diff --git a/src/swe/lang/nodejs/typescriptTools.ts b/src/swe/lang/nodejs/typescriptTools.ts index 6858fc34..130a9079 100644 --- a/src/swe/lang/nodejs/typescriptTools.ts +++ b/src/swe/lang/nodejs/typescriptTools.ts @@ -98,7 +98,7 @@ export class TypescriptTools implements LanguageTools { if (packageJson.devDependencies) { info += '\n'; for (const [pkg, version] of Object.entries(packageJson.devDependencies)) { - info += `${pkg}: ${version}\n`; + if (!pkg.startsWith('@types/')) info += `${pkg}: ${version}\n`; } info += '\n'; }