Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/assets/wise5/components/aiChat/AiChatMessage.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
export class AiChatMessage {
content: string;
hidden: boolean;
role: 'assistant' | 'system' | 'user';

constructor(role: 'assistant' | 'system' | 'user', content: string) {
constructor(role: 'assistant' | 'system' | 'user', content: string, hidden: boolean = false) {
this.content = content;
this.role = role;
this.hidden = hidden;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AiChatBotMessageComponent } from './ai-chat-bot-message.component';
import { MatIconModule } from '@angular/material/icon';
import { ComputerAvatarService } from '../../../services/computerAvatarService';
import { AiChatMessage } from '../AiChatMessage';

describe('AiChatBotMessageComponent', () => {
let component: AiChatBotMessageComponent;
Expand All @@ -15,7 +16,7 @@ describe('AiChatBotMessageComponent', () => {
});
fixture = TestBed.createComponent(AiChatBotMessageComponent);
component = fixture.componentInstance;
component.message = { content: 'Hello', role: 'assistant' };
component.message = new AiChatMessage('assistant', 'Hello');
component.computerAvatar = {
id: 'robot1',
name: 'Robot',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<ng-container *ngFor="let message of messages">
<ai-chat-student-message
*ngIf="message.role === 'user'"
*ngIf="message.role === 'user' && !message.hidden"
class="ai-chat-message"
[message]="message"
[workgroupId]="workgroupId"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,24 @@ import { AiChatStudentMessageComponent } from './ai-chat-student-message.compone
import { ConfigService } from '../../../services/configService';
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import { AiChatMessage } from '../AiChatMessage';

describe('AiChatStudentMessageComponent', () => {
let component: AiChatStudentMessageComponent;
let fixture: ComponentFixture<AiChatStudentMessageComponent>;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [AiChatStudentMessageComponent],
imports: [],
providers: [ConfigService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()]
});
declarations: [AiChatStudentMessageComponent],
providers: [
ConfigService,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting()
]
});
fixture = TestBed.createComponent(AiChatStudentMessageComponent);
component = fixture.componentInstance;
component.message = { content: 'Hello', role: 'user' };
component.message = new AiChatMessage('user', 'Hello');
fixture.detectChanges();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,19 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { ChatInputComponent } from '../../../common/chat-input/chat-input.component';
import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { MatButtonHarness } from '@angular/material/button/testing';
import { By } from '@angular/platform-browser';

describe('AiChatStudentComponent', () => {
let component: AiChatStudentComponent;
let fixture: ComponentFixture<AiChatStudentComponent>;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [AiChatStudentComponent],
imports: [AiChatModule,
declarations: [AiChatStudentComponent],
imports: [
AiChatModule,
BrowserAnimationsModule,
ChatInputComponent,
ComponentHeaderComponent,
Expand All @@ -34,18 +38,29 @@ describe('AiChatStudentComponent', () => {
MatFormFieldModule,
MatInputModule,
MatSnackBarModule,
StudentTeacherCommonServicesModule],
providers: [AiChatService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()]
});
StudentTeacherCommonServicesModule
],
providers: [
AiChatService,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting()
]
});
fixture = TestBed.createComponent(AiChatStudentComponent);
component = fixture.componentInstance;
component.component = new AiChatComponent({ id: 'component1', type: 'aiChat' }, 'node1');
component.componentState = { studentData: { messages: [{ role: 'user' }] } };
spyOn(component, 'isNotebookEnabled').and.returnValue(false);
spyOn(TestBed.inject(ProjectService), 'getThemeSettings').and.returnValue({});
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
it('should not show response from a connected component', async () => {
const studentMessages = fixture.debugElement.queryAll(By.css('ai-chat-student-message'));
expect(studentMessages.length).toBe(1);
component.processConnectedComponentState({ studentData: { response: 'test response' } });
const loader = TestbedHarnessEnvironment.loader(fixture);
await (await loader.getHarness(MatButtonHarness)).click();
expect(studentMessages.length).toBe(1); // no new message should be added
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,16 @@ import { ComputerAvatarService } from '../../../services/computerAvatarService';
import { StudentStatusService } from '../../../services/studentStatusService';

@Component({
selector: 'ai-chat-student',
templateUrl: './ai-chat-student.component.html',
styleUrls: ['./ai-chat-student.component.scss'],
standalone: false
selector: 'ai-chat-student',
templateUrl: './ai-chat-student.component.html',
styleUrls: ['./ai-chat-student.component.scss'],
standalone: false
})
export class AiChatStudentComponent extends ComponentStudent {
component: AiChatComponent;
protected computerAvatar: ComputerAvatar;
protected computerAvatarSelectorVisible: boolean = false;
private connectedComponentResponse: string;
protected messages: AiChatMessage[] = [];
protected studentResponse: string = '';
protected submitEnabled: boolean = false;
Expand Down Expand Up @@ -82,6 +83,10 @@ export class AiChatStudentComponent extends ComponentStudent {

protected async submitStudentResponse(response: string): Promise<void> {
this.waitingForComputerResponse = true;
if (this.connectedComponentResponse != null) {
this.messages.push(new AiChatMessage('user', this.connectedComponentResponse, true));
this.connectedComponentResponse = null;
}
this.messages.push(new AiChatMessage('user', response));
try {
const response = await this.aiChatService.sendChatMessage(
Expand Down Expand Up @@ -119,6 +124,10 @@ export class AiChatStudentComponent extends ComponentStudent {
return promise;
}

processConnectedComponentState(componentState: any): void {
this.connectedComponentResponse = componentState.studentData.response;
}

initializeComputerAvatar: () => void;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,12 @@
<mat-option *ngFor="let model of models" [value]="model">{{ model }}</mat-option>
</mat-select>
</mat-form-field>
<edit-connected-components
[nodeId]="component.nodeId"
[componentId]="component.id"
[allowedConnectedComponentTypes]="allowedConnectedComponentTypes"
[componentContent]="component.content"
[connectedComponents]="component.content.connectedComponents"
(connectedComponentsChanged)="connectedComponentsChanged($event)"
/>
<edit-component-json [component]="component"></edit-component-json>
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,20 @@ describe('EditAiChatAdvancedComponent', () => {

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [EditAiChatAdvancedComponent],
imports: [BrowserAnimationsModule,
declarations: [EditAiChatAdvancedComponent],
imports: [
BrowserAnimationsModule,
ComponentAuthoringModule,
MatDialogModule,
StudentTeacherCommonServicesModule],
providers: [TeacherNodeService, TeacherProjectService, provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting()]
});
StudentTeacherCommonServicesModule
],
providers: [
TeacherNodeService,
TeacherProjectService,
provideHttpClient(withInterceptorsFromDi()),
provideHttpClientTesting()
]
});
fixture = TestBed.createComponent(EditAiChatAdvancedComponent);
component = fixture.componentInstance;
component.nodeId = 'node1';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ import { EditAdvancedComponentComponent } from '../../../../../app/authoring-too
import { AiChatContent } from '../AiChatContent';

@Component({
selector: 'edit-ai-chat-advanced',
templateUrl: './edit-ai-chat-advanced.component.html',
standalone: false
selector: 'edit-ai-chat-advanced',
templateUrl: './edit-ai-chat-advanced.component.html',
standalone: false
})
export class EditAiChatAdvancedComponent extends EditAdvancedComponentComponent {
protected allowedConnectedComponentTypes = ['OpenResponse'];
componentContent: AiChatContent;
protected models: string[] = ['gpt-3.5-turbo', 'gpt-4'];
}
2 changes: 1 addition & 1 deletion src/messages.xlf
Original file line number Diff line number Diff line change
Expand Up @@ -15830,7 +15830,7 @@ Are you sure you want to proceed?</source>
<source>An error occurred.</source>
<context-group purpose="location">
<context context-type="sourcefile">src/assets/wise5/components/aiChat/ai-chat-student/ai-chat-student.component.ts</context>
<context context-type="linenumber">96</context>
<context context-type="linenumber">101</context>
</context-group>
</trans-unit>
<trans-unit id="1141886420788473147" datatype="html">
Expand Down
Loading