diff --git a/src/app/authoring-tool/edit-advanced-component/edit-advanced-component.component.ts b/src/app/authoring-tool/edit-advanced-component/edit-advanced-component.component.ts index 58824235d2a..ed94b95e9df 100644 --- a/src/app/authoring-tool/edit-advanced-component/edit-advanced-component.component.ts +++ b/src/app/authoring-tool/edit-advanced-component/edit-advanced-component.component.ts @@ -1,13 +1,15 @@ -import { Directive, Input } from '@angular/core'; +import { Directive, inject, Input } from '@angular/core'; import { ComponentContent } from '../../../assets/wise5/common/ComponentContent'; import { Component } from '../../../assets/wise5/common/Component'; import { NotebookService } from '../../../assets/wise5/services/notebookService'; import { TeacherProjectService } from '../../../assets/wise5/services/teacherProjectService'; import { TeacherNodeService } from '../../../assets/wise5/services/teacherNodeService'; import { moveObjectDown, moveObjectUp } from '../../../assets/wise5/common/array/array'; +import { ComponentServiceLookupService } from '../../../assets/wise5/services/componentServiceLookupService'; @Directive() export abstract class EditAdvancedComponentComponent { + protected aiEnabled: boolean; component: Component; componentContent: ComponentContent; protected selectedTabIndex: number = 0; @@ -16,6 +18,8 @@ export abstract class EditAdvancedComponentComponent { @Input() nodeId: string; @Input() tab: string = 'general'; + private componentServiceLookupService = inject(ComponentServiceLookupService); + constructor( protected nodeService: TeacherNodeService, protected notebookService: NotebookService, @@ -25,6 +29,19 @@ export abstract class EditAdvancedComponentComponent { ngOnInit(): void { this.componentContent = this.teacherProjectService.getComponent(this.nodeId, this.componentId); this.component = new Component(this.componentContent, this.nodeId); + this.aiEnabled = this.teacherProjectService.getProject().ai?.enabled; + if (this.aiEnabled && ['Discussion', 'OpenResponse'].includes(this.component.content.type)) { + if (this.component.content.ai == null) { + const componentService = this.componentServiceLookupService.getService( + this.component.content.type + ); + this.component.content.ai = { + teacherSummarySystemPrompt: componentService.getDefaultTeacherSummarySystemPrompt( + this.component.content.prompt + ) + }; + } + } this.teacherProjectService.uiChanged(); switch (this.tab) { diff --git a/src/app/authoring-tool/edit-component-advanced/edit-component-advanced-shared.module.ts b/src/app/authoring-tool/edit-component-advanced/edit-component-advanced-shared.module.ts index d0e6ffee11e..7782418c9f2 100644 --- a/src/app/authoring-tool/edit-component-advanced/edit-component-advanced-shared.module.ts +++ b/src/app/authoring-tool/edit-component-advanced/edit-component-advanced-shared.module.ts @@ -16,6 +16,7 @@ import { MatCheckboxModule } from '@angular/material/checkbox'; import { FormsModule } from '@angular/forms'; import { EditComponentAddToNotebookButtonComponent } from '../edit-component-add-to-notebook-button/edit-component-add-to-notebook-button.component'; import { EditConnectedComponentsComponent } from '../edit-connected-components/edit-connected-components.component'; +import { EditComponentSummarizerSystemPromptComponent } from '../edit-component-summarizer-system-prompt/edit-component-summarizer-system-prompt.component'; @NgModule({ imports: [ @@ -29,6 +30,7 @@ import { EditConnectedComponentsComponent } from '../edit-connected-components/e EditComponentExcludeFromTotalScoreComponent, EditComponentWidthComponent, EditComponentRubricComponent, + EditComponentSummarizerSystemPromptComponent, EditComponentTagsComponent, EditComponentConstraintsComponent, EditComponentJsonComponent, @@ -48,6 +50,7 @@ import { EditConnectedComponentsComponent } from '../edit-connected-components/e EditComponentExcludeFromTotalScoreComponent, EditComponentWidthComponent, EditComponentRubricComponent, + EditComponentSummarizerSystemPromptComponent, EditComponentTagsComponent, EditComponentConstraintsComponent, EditComponentJsonComponent, diff --git a/src/app/authoring-tool/edit-component-advanced/edit-component-advanced.component.spec.ts b/src/app/authoring-tool/edit-component-advanced/edit-component-advanced.component.spec.ts index a364f114868..2166cae3fe7 100644 --- a/src/app/authoring-tool/edit-component-advanced/edit-component-advanced.component.spec.ts +++ b/src/app/authoring-tool/edit-component-advanced/edit-component-advanced.component.spec.ts @@ -8,6 +8,7 @@ import { NotificationService } from '../../../assets/wise5/services/notification import { TeacherNodeService } from '../../../assets/wise5/services/teacherNodeService'; import { TeacherProjectService } from '../../../assets/wise5/services/teacherProjectService'; import { EditComponentAdvancedComponent } from './edit-component-advanced.component'; +import { ComponentServiceLookupService } from '../../../assets/wise5/services/componentServiceLookupService'; let component: EditComponentAdvancedComponent; let fixture: ComponentFixture; @@ -34,6 +35,7 @@ describe('EditComponentAdvancedComponent', () => { } }, MockProviders( + ComponentServiceLookupService, TeacherNodeService, NotebookService, NotificationService, @@ -47,6 +49,8 @@ describe('EditComponentAdvancedComponent', () => { spyOn(TestBed.inject(TeacherProjectService), 'getComponent').and.returnValue({ type: 'ShowMyWork' } as ComponentContent); + spyOn(TestBed.inject(TeacherProjectService), 'getProject').and.returnValue({}); + fixture.detectChanges(); }); diff --git a/src/app/authoring-tool/edit-component-summarizer-system-prompt/edit-component-summarizer-system-prompt.component.html b/src/app/authoring-tool/edit-component-summarizer-system-prompt/edit-component-summarizer-system-prompt.component.html new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/app/authoring-tool/edit-component-summarizer-system-prompt/edit-component-summarizer-system-prompt.component.ts b/src/app/authoring-tool/edit-component-summarizer-system-prompt/edit-component-summarizer-system-prompt.component.ts new file mode 100644 index 00000000000..43c02268678 --- /dev/null +++ b/src/app/authoring-tool/edit-component-summarizer-system-prompt/edit-component-summarizer-system-prompt.component.ts @@ -0,0 +1,21 @@ +import { Component } from '@angular/core'; +import { EditComponentFieldComponent } from '../edit-component-field.component'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { FormsModule } from '@angular/forms'; +import { MatInputModule } from '@angular/material/input'; +import { CdkTextareaAutosize } from '@angular/cdk/text-field'; + +@Component({ + imports: [CdkTextareaAutosize, FormsModule, MatFormFieldModule, MatInputModule], + selector: 'edit-component-summarizer-system-prompt', + template: ` + Teacher Summary System Prompt + + ` +}) +export class EditComponentSummarizerSystemPromptComponent extends EditComponentFieldComponent {} diff --git a/src/assets/wise5/common/ComponentContent.ts b/src/assets/wise5/common/ComponentContent.ts index 6273bb3663e..ea9795e1a05 100644 --- a/src/assets/wise5/common/ComponentContent.ts +++ b/src/assets/wise5/common/ComponentContent.ts @@ -4,6 +4,9 @@ import { DynamicPrompt } from '../directives/dynamic-prompt/DynamicPrompt'; export interface ComponentContent { id: string; + ai?: { + teacherSummarySystemPrompt?: string; + }; anonymizeResponses?: boolean; connectedComponents?: any[]; constraints?: any[]; diff --git a/src/assets/wise5/components/aiChat/edit-ai-chat-advanced/edit-ai-chat-advanced.component.spec.ts b/src/assets/wise5/components/aiChat/edit-ai-chat-advanced/edit-ai-chat-advanced.component.spec.ts index aa84662ac04..3fb55dd1c6c 100644 --- a/src/assets/wise5/components/aiChat/edit-ai-chat-advanced/edit-ai-chat-advanced.component.spec.ts +++ b/src/assets/wise5/components/aiChat/edit-ai-chat-advanced/edit-ai-chat-advanced.component.spec.ts @@ -7,6 +7,7 @@ import { NotebookService } from '../../../services/notebookService'; import { EditConnectedComponentsComponent } from '../../../../../app/authoring-tool/edit-connected-components/edit-connected-components.component'; import { EditComponentJsonComponent } from '../../../../../app/authoring-tool/edit-component-json/edit-component-json.component'; import { EditComponentWidthComponent } from '../../../../../app/authoring-tool/edit-component-width/edit-component-width.component'; +import { ComponentServiceLookupService } from '../../../services/componentServiceLookupService'; describe('EditAiChatAdvancedComponent', () => { let component: EditAiChatAdvancedComponent; @@ -22,7 +23,14 @@ describe('EditAiChatAdvancedComponent', () => { EditConnectedComponentsComponent ) ], - providers: [MockProviders(NotebookService, TeacherNodeService, TeacherProjectService)] + providers: [ + MockProviders( + ComponentServiceLookupService, + NotebookService, + TeacherNodeService, + TeacherProjectService + ) + ] }); fixture = TestBed.createComponent(EditAiChatAdvancedComponent); component = fixture.componentInstance; @@ -31,6 +39,7 @@ describe('EditAiChatAdvancedComponent', () => { id: 'component1', type: 'aiChat' }); + spyOn(TestBed.inject(TeacherProjectService), 'getProject').and.returnValue({}); fixture.detectChanges(); }); diff --git a/src/assets/wise5/components/conceptMap/edit-concept-map-advanced/edit-concept-map-advanced.component.spec.ts b/src/assets/wise5/components/conceptMap/edit-concept-map-advanced/edit-concept-map-advanced.component.spec.ts index 9b0a0c940c4..adc1646b8cd 100644 --- a/src/assets/wise5/components/conceptMap/edit-concept-map-advanced/edit-concept-map-advanced.component.spec.ts +++ b/src/assets/wise5/components/conceptMap/edit-concept-map-advanced/edit-concept-map-advanced.component.spec.ts @@ -26,6 +26,7 @@ describe('EditConceptMapAdvancedComponent', () => { spyOn(TestBed.inject(TeacherProjectService), 'getComponent').and.returnValue({ rules: [] } as ConceptMapContent); + spyOn(TestBed.inject(TeacherProjectService), 'getProject').and.returnValue({}); spyOn(TestBed.inject(NotebookService), 'isNotebookEnabled').and.returnValue(true); fixture = TestBed.createComponent(EditConceptMapAdvancedComponent); component = fixture.componentInstance; diff --git a/src/assets/wise5/components/discussion/discussionService.ts b/src/assets/wise5/components/discussion/discussionService.ts index a4691ac14d0..2a7ed4abfae 100644 --- a/src/assets/wise5/components/discussion/discussionService.ts +++ b/src/assets/wise5/components/discussion/discussionService.ts @@ -27,6 +27,9 @@ export class DiscussionService extends ComponentService { component.isStudentAttachmentEnabled = true; component.gateClassmateResponses = true; component.anonymizeResponses = false; + component.ai = { + teacherSummarySystemPrompt: this.getDefaultTeacherSummarySystemPrompt() + }; return component; } @@ -335,4 +338,10 @@ export class DiscussionService extends ComponentService { col2: evenResponses.reverse() }; } + + getDefaultTeacherSummarySystemPrompt(): string { + return `You are a teacher who is summarizing students' discussion threads, which include posts and replies to the following question: "$QUESTION$". + Each thread is in the format: $RESPONSE_FORMAT$. + In the same language as the question, provide a summary of the threads in 100 words or less.`; + } } diff --git a/src/assets/wise5/components/discussion/edit-discussion-advanced/edit-discussion-advanced.component.html b/src/assets/wise5/components/discussion/edit-discussion-advanced/edit-discussion-advanced.component.html index 596f1aec514..2999a2aadbd 100644 --- a/src/assets/wise5/components/discussion/edit-discussion-advanced/edit-discussion-advanced.component.html +++ b/src/assets/wise5/components/discussion/edit-discussion-advanced/edit-discussion-advanced.component.html @@ -9,6 +9,14 @@ + @if (aiEnabled) { + + + auto_awesome AI + + + + } visibility Visibility diff --git a/src/assets/wise5/components/graph/edit-graph-advanced/edit-graph-advanced.component.spec.ts b/src/assets/wise5/components/graph/edit-graph-advanced/edit-graph-advanced.component.spec.ts index 194ad8826b9..824fe1d9320 100644 --- a/src/assets/wise5/components/graph/edit-graph-advanced/edit-graph-advanced.component.spec.ts +++ b/src/assets/wise5/components/graph/edit-graph-advanced/edit-graph-advanced.component.spec.ts @@ -30,6 +30,7 @@ describe('EditGraphAdvancedComponent', () => { xAxis: {}, yAxis: {} } as GraphContent); + spyOn(TestBed.inject(TeacherProjectService), 'getProject').and.returnValue({}); spyOn(projectService, 'getLocale').and.returnValue(new ProjectLocale({ default: 'en-US' })); spyOn(projectService, 'isDefaultLocale').and.returnValue(true); spyOn(TestBed.inject(NotebookService), 'isNotebookEnabled').and.returnValue(true); diff --git a/src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html b/src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html index 5bbddbff026..9f821e5c9a6 100644 --- a/src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html +++ b/src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html @@ -74,6 +74,10 @@ auto_awesome AI + @if (aiEnabled) { + + + }
{ beforeEach(() => { const projectService = TestBed.inject(TeacherProjectService); spyOn(projectService, 'getComponent').and.returnValue({} as ComponentContent); + spyOn(TestBed.inject(TeacherProjectService), 'getProject').and.returnValue({}); spyOn(TestBed.inject(NotebookService), 'isNotebookEnabled').and.returnValue(true); spyOn(projectService, 'getFlattenedProjectAsNodeIds').and.returnValue([ 'node1', diff --git a/src/assets/wise5/components/openResponse/openResponseService.ts b/src/assets/wise5/components/openResponse/openResponseService.ts index f44f0a37ca9..7c576e391c6 100644 --- a/src/assets/wise5/components/openResponse/openResponseService.ts +++ b/src/assets/wise5/components/openResponse/openResponseService.ts @@ -19,6 +19,9 @@ export class OpenResponseService extends ComponentService { component.type = 'OpenResponse'; component.starterSentence = null; component.isStudentAttachmentEnabled = false; + component.ai = { + teacherSummarySystemPrompt: this.getDefaultTeacherSummarySystemPrompt() + }; return component; } @@ -127,4 +130,10 @@ export class OpenResponseService extends ComponentService { } return false; } + + getDefaultTeacherSummarySystemPrompt(): string { + return `You are a teacher who is summarizing student responses to the following question: "$QUESTION$". + Each student response is in the format: $RESPONSE_FORMAT$. + In the same language as the question, provide a summary of the responses in 100 words or less.`; + } } diff --git a/src/assets/wise5/components/peerChat/edit-peer-chat-advanced-component/edit-peer-chat-advanced-component.component.spec.ts b/src/assets/wise5/components/peerChat/edit-peer-chat-advanced-component/edit-peer-chat-advanced-component.component.spec.ts index bf3016c1d53..5094c9969ac 100644 --- a/src/assets/wise5/components/peerChat/edit-peer-chat-advanced-component/edit-peer-chat-advanced-component.component.spec.ts +++ b/src/assets/wise5/components/peerChat/edit-peer-chat-advanced-component/edit-peer-chat-advanced-component.component.spec.ts @@ -7,6 +7,7 @@ import { TeacherProjectService } from '../../../services/teacherProjectService'; import { PeerChatContent } from '../PeerChatContent'; import { EditPeerChatAdvancedComponentComponent } from './edit-peer-chat-advanced-component.component'; import { EditComponentJsonComponent } from '../../../../../app/authoring-tool/edit-component-json/edit-component-json.component'; +import { ComponentServiceLookupService } from '../../../services/componentServiceLookupService'; describe('EditPeerChatAdvancedComponentComponent', () => { let component: EditPeerChatAdvancedComponentComponent; @@ -16,7 +17,12 @@ describe('EditPeerChatAdvancedComponentComponent', () => { await TestBed.configureTestingModule({ imports: [EditPeerChatAdvancedComponentComponent, MockComponent(EditComponentJsonComponent)], providers: [ - MockProviders(TeacherNodeService, TeacherProjectService, NotebookService), + MockProviders( + ComponentServiceLookupService, + TeacherNodeService, + TeacherProjectService, + NotebookService + ), provideHttpClient(withInterceptorsFromDi()) ] }).compileComponents(); @@ -26,6 +32,7 @@ describe('EditPeerChatAdvancedComponentComponent', () => { spyOn(TestBed.inject(TeacherProjectService), 'getComponent').and.returnValue( {} as PeerChatContent ); + spyOn(TestBed.inject(TeacherProjectService), 'getProject').and.returnValue({}); fixture = TestBed.createComponent(EditPeerChatAdvancedComponentComponent); component = fixture.componentInstance; fixture.detectChanges(); diff --git a/src/assets/wise5/components/table/edit-table-advanced/edit-table-advanced.component.spec.ts b/src/assets/wise5/components/table/edit-table-advanced/edit-table-advanced.component.spec.ts index 4f653192c81..a45e0627cc0 100644 --- a/src/assets/wise5/components/table/edit-table-advanced/edit-table-advanced.component.spec.ts +++ b/src/assets/wise5/components/table/edit-table-advanced/edit-table-advanced.component.spec.ts @@ -30,6 +30,7 @@ describe('EditTableAdvancedComponent', () => { beforeEach(() => { spyOn(TestBed.inject(TeacherProjectService), 'getComponent').and.returnValue(createComponent()); + spyOn(TestBed.inject(TeacherProjectService), 'getProject').and.returnValue({}); spyOn(TestBed.inject(NotebookService), 'isNotebookEnabled').and.returnValue(true); spyOn(TestBed.inject(TeacherProjectService), 'getFlattenedProjectAsNodeIds').and.returnValue([ 'node1', diff --git a/src/assets/wise5/directives/teacher-summary-display/ai-summary/ai-summary.component.ts b/src/assets/wise5/directives/teacher-summary-display/ai-summary/ai-summary.component.ts index 12916ebcf82..666cd099779 100644 --- a/src/assets/wise5/directives/teacher-summary-display/ai-summary/ai-summary.component.ts +++ b/src/assets/wise5/directives/teacher-summary-display/ai-summary/ai-summary.component.ts @@ -10,6 +10,7 @@ import { DatePipe } from '@angular/common'; import { TeacherProjectService } from '../../../services/teacherProjectService'; import { ChatService } from '../../../../../app/services/chat/chat.service'; import { OpenAiChatService } from '../../../../../app/services/chat/openAiChat.service'; +import { ComponentContent } from '../../../common/ComponentContent'; /** * Abstract base class for components that use an LLM to summarize student responses. @@ -25,6 +26,7 @@ export abstract class AiSummaryComponent { @Input() periodId: number; private chatService: ChatService = inject(OpenAiChatService); + private component: ComponentContent; protected dataService: TeacherDataService = inject(TeacherDataService); protected datePipe: DatePipe = inject(DatePipe); private localStorageService: LocalStorageService = inject(LocalStorageService); @@ -38,6 +40,7 @@ export abstract class AiSummaryComponent { protected summaryDate: Date; ngOnInit(): void { + this.component = this.projectService.getComponent(this.nodeId, this.componentId); this.latestComponentStates = this.getLatestComponentStates(); this.hasStudentResponses = this.latestComponentStates.length > 0; if (this.hasStudentResponses) { @@ -64,9 +67,8 @@ export abstract class AiSummaryComponent { protected async generateSummary(): Promise { this.generatingSummary = true; - const prompt = this.projectService.getComponent(this.nodeId, this.componentId).prompt; this.summary = await this.chatService.sendMessage([ - new ChatMessage('system', this.getSystemPrompt(prompt), this.nodeId), + new ChatMessage('system', this.getSystemPrompt(this.component.prompt), this.nodeId), new ChatMessage('user', this.getStudentResponses(), this.nodeId) ]); this.localStorageService.setItem(this.getSummaryKey(), this.summary); @@ -79,7 +81,17 @@ export abstract class AiSummaryComponent { protected abstract getStudentResponses(): string; - protected abstract getSystemPrompt(prompt: string): string; + protected getSystemPrompt(prompt: string): string { + const systemPrompt = + this.component.ai?.teacherSummarySystemPrompt ?? this.getDefaultSystemPrompt(); + return systemPrompt + .replace('$QUESTION$', prompt) + .replace('$RESPONSE_FORMAT$', this.getResponseFormat()); + } + + protected abstract getResponseFormat(): string; + + protected abstract getDefaultSystemPrompt(): string; private getSummaryKey(): string { return `component-summary-${this.periodId}-${this.nodeId}-${this.componentId}`; diff --git a/src/assets/wise5/directives/teacher-summary-display/discussion-ai-summary/discussion-ai-summary.component.ts b/src/assets/wise5/directives/teacher-summary-display/discussion-ai-summary/discussion-ai-summary.component.ts index c3727aef2f2..14ce5adb2f7 100644 --- a/src/assets/wise5/directives/teacher-summary-display/discussion-ai-summary/discussion-ai-summary.component.ts +++ b/src/assets/wise5/directives/teacher-summary-display/discussion-ai-summary/discussion-ai-summary.component.ts @@ -1,11 +1,12 @@ import { DatePipe } from '@angular/common'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { MatButton } from '@angular/material/button'; import { MatIcon } from '@angular/material/icon'; import { MatProgressSpinner } from '@angular/material/progress-spinner'; import { MatTooltipModule } from '@angular/material/tooltip'; import { MarkdownComponent } from 'ngx-markdown'; import { AiSummaryComponent } from '../ai-summary/ai-summary.component'; +import { DiscussionService } from '../../../components/discussion/discussionService'; interface Thread { id: number; @@ -23,10 +24,14 @@ interface Thread { templateUrl: '../ai-summary/ai-summary.component.html' }) export class DiscussionAiSummaryComponent extends AiSummaryComponent { - protected getSystemPrompt(prompt: string): string { - return `You are a teacher who is summarizing students' discussion threads, which include posts and replies to the following question: "${prompt}". - Each thread is in the format: PostReply 1Reply 2. - In the same language as the question, provide a summary of the threads in 100 words or less.`; + private discussionService = inject(DiscussionService); + + protected getDefaultSystemPrompt(): string { + return this.discussionService.getDefaultTeacherSummarySystemPrompt(); + } + + protected getResponseFormat(): string { + return 'PostReply 1Reply 2'; } protected getStudentResponses(): string { diff --git a/src/assets/wise5/directives/teacher-summary-display/open-response-ai-summary/open-response-ai-summary.component.spec.ts b/src/assets/wise5/directives/teacher-summary-display/open-response-ai-summary/open-response-ai-summary.component.spec.ts index 7bbffdebf0d..d905d404af8 100644 --- a/src/assets/wise5/directives/teacher-summary-display/open-response-ai-summary/open-response-ai-summary.component.spec.ts +++ b/src/assets/wise5/directives/teacher-summary-display/open-response-ai-summary/open-response-ai-summary.component.spec.ts @@ -15,6 +15,7 @@ import { MarkdownComponent, MarkdownService } from 'ngx-markdown'; import { TeacherProjectService } from '../../../services/teacherProjectService'; import { ChatService } from '../../../../../app/services/chat/chat.service'; import { OpenAiChatService } from '../../../../../app/services/chat/openAiChat.service'; +import { OpenResponseService } from '../../../components/openResponse/openResponseService'; describe('OpenResponseAiSummaryComponent', () => { let component: OpenResponseAiSummaryComponent; @@ -38,6 +39,7 @@ describe('OpenResponseAiSummaryComponent', () => { LocalStorageService, MarkdownService, OpenAiChatService, + OpenResponseService, TeacherProjectService, SummaryService, TeacherDataService @@ -53,7 +55,10 @@ describe('OpenResponseAiSummaryComponent', () => { spyOn(projectService, 'getComponent').and.returnValue({ id: 'component1', type: 'OpenResponse', - prompt: 'What is your opinion on climate change?' + prompt: 'What is your opinion on climate change?', + ai: { + teacherSummarySystemPrompt: 'You are a teacher summarizing student responses.' + } } as any); fixture = TestBed.createComponent(OpenResponseAiSummaryComponent); @@ -172,7 +177,7 @@ describe('OpenResponseAiSummaryComponent', () => { await component['generateSummary'](); const messages = sendMessageSpy.calls.mostRecent().args[0]; expect(messages[0].role).toBe('system'); - expect(messages[0].content).toContain('What is your opinion on climate change?'); + expect(messages[0].content).toContain('You are a teacher summarizing student responses.'); }); it('should call chatService with student responses', async () => { diff --git a/src/assets/wise5/directives/teacher-summary-display/open-response-ai-summary/open-response-ai-summary.component.ts b/src/assets/wise5/directives/teacher-summary-display/open-response-ai-summary/open-response-ai-summary.component.ts index 6953cf4b80e..4758e457c57 100644 --- a/src/assets/wise5/directives/teacher-summary-display/open-response-ai-summary/open-response-ai-summary.component.ts +++ b/src/assets/wise5/directives/teacher-summary-display/open-response-ai-summary/open-response-ai-summary.component.ts @@ -1,11 +1,12 @@ import { DatePipe } from '@angular/common'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; import { MatButton } from '@angular/material/button'; import { MatIcon } from '@angular/material/icon'; import { MatProgressSpinner } from '@angular/material/progress-spinner'; import { MatTooltipModule } from '@angular/material/tooltip'; import { MarkdownComponent } from 'ngx-markdown'; import { AiSummaryComponent } from '../ai-summary/ai-summary.component'; +import { OpenResponseService } from '../../../components/openResponse/openResponseService'; /** * Uses an LLM to summarize students' responses to open response questions. @@ -17,10 +18,14 @@ import { AiSummaryComponent } from '../ai-summary/ai-summary.component'; templateUrl: '../ai-summary/ai-summary.component.html' }) export class OpenResponseAiSummaryComponent extends AiSummaryComponent { - protected getSystemPrompt(prompt: string): string { - return `You are a teacher who is summarizing student responses to the following question: "${prompt}". - Each student response is in the format: Response. - In the same language as the question, provide a summary of the responses in 100 words or less.`; + private openResponseService = inject(OpenResponseService); + + protected getDefaultSystemPrompt(): string { + return this.openResponseService.getDefaultTeacherSummarySystemPrompt(); + } + + protected getResponseFormat(): string { + return 'Response'; } protected getStudentResponses(): string { diff --git a/src/messages.xlf b/src/messages.xlf index 978d7ae9f02..1de44e5fab6 100644 --- a/src/messages.xlf +++ b/src/messages.xlf @@ -973,6 +973,13 @@ 15,18 + + Teacher Summary System Prompt + + src/app/authoring-tool/edit-component-summarizer-system-prompt/edit-component-summarizer-system-prompt.component.ts + 12,16 + + Tags @@ -1001,7 +1008,7 @@ src/assets/wise5/components/discussion/edit-discussion-advanced/edit-discussion-advanced.component.html - 41,42 + 49,50 src/assets/wise5/components/draw/edit-draw-advanced/edit-draw-advanced.component.html @@ -1706,11 +1713,11 @@ src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 97,98 + 101,102 src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 556,557 + 560,561 src/assets/wise5/vle/node/node.component.html @@ -1772,7 +1779,7 @@ src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 537,538 + 541,542 src/assets/wise5/components/summary/summary-authoring/summary-authoring.component.html @@ -1787,7 +1794,7 @@ src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 547,550 + 551,554 src/assets/wise5/components/showGroupWork/show-group-work-authoring/show-group-work-authoring.component.html @@ -1826,7 +1833,7 @@ src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 525,526 + 529,530 src/assets/wise5/components/summary/summary-authoring/summary-authoring.component.html @@ -1860,11 +1867,11 @@ src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 98,99 + 102,103 src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 557,559 + 561,563 src/assets/wise5/vle/node/node.component.html @@ -2747,7 +2754,7 @@ src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 164,167 + 168,171 @@ -10673,7 +10680,7 @@ src/assets/wise5/components/discussion/edit-discussion-advanced/edit-discussion-advanced.component.html - 33,36 + 41,44 src/assets/wise5/components/draw/edit-draw-advanced/edit-draw-advanced.component.html @@ -10783,7 +10790,7 @@ src/assets/wise5/components/discussion/edit-discussion-advanced/edit-discussion-advanced.component.html - 45,47 + 53,55 src/assets/wise5/components/draw/edit-draw-advanced/edit-draw-advanced.component.html @@ -10815,7 +10822,7 @@ src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 611,613 + 615,617 src/assets/wise5/components/outsideURL/edit-outside-url-advanced/edit-outside-url-advanced.component.ts @@ -16634,7 +16641,7 @@ Are you sure you want to proceed? src/assets/wise5/components/discussion/edit-discussion-advanced/edit-discussion-advanced.component.html - 14,16 + 22,24 src/assets/wise5/components/draw/edit-draw-advanced/edit-draw-advanced.component.html @@ -16717,7 +16724,7 @@ Are you sure you want to proceed? src/assets/wise5/components/discussion/edit-discussion-advanced/edit-discussion-advanced.component.html - 20,23 + 28,31 src/assets/wise5/components/draw/edit-draw-advanced/edit-draw-advanced.component.html @@ -18275,7 +18282,7 @@ Are you ready to receive feedback on this answer? src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 350,351 + 354,355 @@ -19386,6 +19393,17 @@ Category Name: 232 + + AI + + src/assets/wise5/components/discussion/edit-discussion-advanced/edit-discussion-advanced.component.html + 15,17 + + + src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html + 75,78 + + Students draw on a canvas using a variety of tools. @@ -21254,7 +21272,7 @@ Warning: This will delete all existing choices and buckets in this activity. src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 121,124 + 125,128 @@ -21411,212 +21429,205 @@ Warning: This will delete all existing choices in this activity. 21,26 - - AI - - src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 75,79 - - Enable AI Model src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 85,88 + 89,92 Score On src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 92,94 + 96,98 Change src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 99,102 + 103,106 Show Score src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 111,115 + 115,119 Enable Feedback Rules src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 131,133 + 135,137 Scoring Rule src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 143,146 + 147,150 Add Scoring Rule src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 148,151 + 152,155 Feedback Text src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 176,178 + 180,182 Move Scoring Rule Up src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 187,189 + 191,193 Move Scoring Rule Down src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 198,200 + 202,204 Delete Scoring Rule src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 208,210 + 212,214 Enable Multiple Attempt Feedback src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 228,231 + 232,235 Multiple Attempt Scoring Rules src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 233,236 + 237,240 Add Multiple Attempt Scoring Rule src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 238,241 + 242,245 Previous Score src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 254,257 + 258,261 src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 363,366 + 367,370 Current Score src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 263,266 + 267,270 src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 373,376 + 377,380 Feedback to Student src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 274,276 + 278,280 src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 461,463 + 465,467 Move Multiple Attempt Scoring Rule Up src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 290,292 + 294,296 Move Multiple Attempt Scoring Rule Down src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 306,308 + 310,312 Delet Multiple Attempt Scoring src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 316,318 + 320,322 Enable Notifications src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 336,339 + 340,343 Notifications src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 341,344 + 345,348 Move Notification Up src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 394,396 + 398,400 Move Notification Down src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 410,412 + 414,416 Delete Notification src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 420,422 + 424,426 Enable Ambient Display Dismiss Mode src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 435,437 + 439,441 Dismiss Code src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 439,442 + 443,446 src/assets/wise5/vle/dismiss-ambient-notification-dialog/dismiss-ambient-notification-dialog.component.html @@ -21627,63 +21638,63 @@ Warning: This will delete all existing choices in this activity. Notify Student src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 455,457 + 459,461 Notify Teacher src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 475,477 + 479,481 Feedback to Teacher src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 481,483 + 485,487 Use Custom Completion Criteria src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 500,502 + 504,506 Custom Completion Criteria src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 504,507 + 508,511 Add Completion Criteria src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 509,512 + 513,516 Move Completion Criteria Up src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 569,571 + 573,575 Move Completion Criteria Down src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 582,584 + 586,588 Delete Completion Criteria src/assets/wise5/components/openResponse/edit-open-response-advanced/edit-open-response-advanced.component.html - 592,594 + 596,598 @@ -23085,14 +23096,14 @@ If this problem continues, let your teacher know and move on to the next activit Summary generated from responses src/assets/wise5/directives/teacher-summary-display/ai-summary/ai-summary.component.ts - 93 + 105 Summary generated from posts and comments src/assets/wise5/directives/teacher-summary-display/discussion-ai-summary/discussion-ai-summary.component.ts - 55 + 60