diff --git a/frontend/src/app/chat/chat-controls/chat-controls.component.html b/frontend/src/app/chat/chat-controls/chat-controls.component.html new file mode 100644 index 00000000..c8429b66 --- /dev/null +++ b/frontend/src/app/chat/chat-controls/chat-controls.component.html @@ -0,0 +1,70 @@ + + + + + + + + + + send + + + + + + attach_file + + + + Attachments: + + + + insert_drive_file + {{ attachment.name }} + cancel + + + + 0" + mode="determinate" + value="getUploadPercentage(i) | async" + > + + diff --git a/frontend/src/app/chat/chat-controls/chat-controls.component.scss b/frontend/src/app/chat/chat-controls/chat-controls.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/app/chat/chat-controls/chat-controls.component.spec.ts b/frontend/src/app/chat/chat-controls/chat-controls.component.spec.ts new file mode 100644 index 00000000..b853f4ae --- /dev/null +++ b/frontend/src/app/chat/chat-controls/chat-controls.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChatControlsComponent } from './chat-controls.component'; + +describe('ChatControlsComponent', () => { + let component: ChatControlsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ChatControlsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ChatControlsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/chat/chat-controls/chat-controls.component.ts b/frontend/src/app/chat/chat-controls/chat-controls.component.ts new file mode 100644 index 00000000..cc21e338 --- /dev/null +++ b/frontend/src/app/chat/chat-controls/chat-controls.component.ts @@ -0,0 +1,85 @@ +import { Component, Input, OnInit } from '@angular/core'; + +import { FormBuilder, FormControl, FormGroup } from '@angular/forms'; +import { debounceTime, filter, throttleTime } from 'rxjs/operators'; +// import {FirebaseAttachmentService} from "@app/chat/services/firebase/firebase-attachment.service"; +import {FirebaseChatService} from "@app/chat/services/firebase/firebase-chat.service"; + +@Component({ + selector: 'app-chat-controls', + templateUrl: './chat-controls.component.html', + styleUrls: ['./chat-controls.component.scss'] +}) +export class ChatControlsComponent implements OnInit { + @Input() chatId: string = ''; + + messageControl: FormControl; + chatForm: FormGroup; + + constructor( + // private attachmentService: FirebaseAttachmentService, + private chatService: FirebaseChatService, + private fb: FormBuilder + ) { + this.messageControl = new FormControl(); + this.chatForm = this.fb.group({ message: this.messageControl }); + } + + ngOnInit() { + this.scrollBottom(); + + this.messageControl.valueChanges + .pipe( + filter(data => data !== ''), + throttleTime(1400) + ) + .subscribe(data => { + // this.chatService.sendIsTyping(this.chatId).then(); + }); + + this.messageControl.valueChanges + .pipe( + filter(data => data !== ''), + debounceTime(1500) + ) + .subscribe(data => { + // this.chatService.deleteIsTyping(this.chatId).then(); + }); + } + + submit(): void { + const msg = this.messageControl.value; + if (!msg) { + return alert('Please enter a message.'); + } + this.chatService.sendMessage(this.chatId, msg).then(); + // this.attachmentService.uploadAttachments().subscribe( + // (res: any) => console.log(res), + // (err: any) => console.log(err) + // ); + this.messageControl.reset(); + this.scrollBottom(); + } + + private scrollBottom(): void { + setTimeout(() => window.scrollTo(0, document.body.scrollHeight), 500); + } + + setSelectedFiles(event: any): void { + // this.attachmentService.setSelectedFiles(event); + } + + deleteAttachment(file: any): void { + // return this.attachmentService.deleteFile(file); + } + + getAttachments(): File[] { + // return this.attachmentService.getFiles(); + return [] + } + + hasAttachments() { + // return this.attachmentService.getFiles().length > 0; + false; + } +} diff --git a/frontend/src/app/chat/chat-header/chat-header.component.html b/frontend/src/app/chat/chat-header/chat-header.component.html new file mode 100644 index 00000000..c3aa3f79 --- /dev/null +++ b/frontend/src/app/chat/chat-header/chat-header.component.html @@ -0,0 +1,9 @@ + + Asset Chat - {{ chatId }} + + + Back + + \ No newline at end of file diff --git a/frontend/src/app/chat/chat-header/chat-header.component.scss b/frontend/src/app/chat/chat-header/chat-header.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/app/chat/chat-header/chat-header.component.spec.ts b/frontend/src/app/chat/chat-header/chat-header.component.spec.ts new file mode 100644 index 00000000..87907728 --- /dev/null +++ b/frontend/src/app/chat/chat-header/chat-header.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChatHeaderComponent } from './chat-header.component'; + +describe('ChatHeaderComponent', () => { + let component: ChatHeaderComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ChatHeaderComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ChatHeaderComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/chat/chat-header/chat-header.component.ts b/frontend/src/app/chat/chat-header/chat-header.component.ts new file mode 100644 index 00000000..81aa05b5 --- /dev/null +++ b/frontend/src/app/chat/chat-header/chat-header.component.ts @@ -0,0 +1,10 @@ +import { Component, Input } from '@angular/core'; + +@Component({ + selector: 'app-chat-header', + templateUrl: './chat-header.component.html', + styleUrls: ['./chat-header.component.scss'] +}) +export class ChatHeaderComponent { + @Input() chatId: string = ''; +} diff --git a/frontend/src/app/chat/chat-message/chat-message.component.html b/frontend/src/app/chat/chat-message/chat-message.component.html new file mode 100644 index 00000000..02e15877 --- /dev/null +++ b/frontend/src/app/chat/chat-message/chat-message.component.html @@ -0,0 +1,91 @@ + + {{ getDateDivider(msg) }} + + + + + + {{ getUserName(msg.user) }} + + + + + + + {{ getCreatedDate(msg) }} + + {{ msg.content }} + + + + REPLY + + + + + + insert_drive_file + {{ attachment.name }} + + + + + diff --git a/frontend/src/app/chat/chat-message/chat-message.component.scss b/frontend/src/app/chat/chat-message/chat-message.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/app/chat/chat-message/chat-message.component.spec.ts b/frontend/src/app/chat/chat-message/chat-message.component.spec.ts new file mode 100644 index 00000000..8165deb8 --- /dev/null +++ b/frontend/src/app/chat/chat-message/chat-message.component.spec.ts @@ -0,0 +1,24 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChatMessageComponent } from './chat-message.component'; + +describe('ChatMessageComponent', () => { + let component: ChatMessageComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ChatMessageComponent] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ChatMessageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/chat/chat-message/chat-message.component.ts b/frontend/src/app/chat/chat-message/chat-message.component.ts new file mode 100644 index 00000000..43ce50c1 --- /dev/null +++ b/frontend/src/app/chat/chat-message/chat-message.component.ts @@ -0,0 +1,73 @@ +import { Component, Input, OnInit } from '@angular/core'; +import { Message } from '../model/message'; +import { User } from '../model/user'; +import * as moment from 'moment'; + +@Component({ + selector: 'app-chat-message', + templateUrl: './chat-message.component.html', + styleUrls: ['./chat-message.component.scss'] +}) +export class ChatMessageComponent implements OnInit { + @Input() msg: Message = {} as Message; + @Input() predecessor: Message | null = null; + @Input() user: User = {} as User; + @Input() allowsReply = false; + + constructor() {} + + ngOnInit() {} + + getDateDivider(msg: Message | undefined): string { + // if (!msg.createdAt) { + // return null; + // } + // + // return msg.createdAt.format('l'); + return '' + } + + getUserName(user: User | undefined): string | null { + if (!user) { + return null; + } + return user.displayName; + } + + getCreatedDate(msg: Message): string | null { + if (!msg.createdAt) { + return null; + } + // return msg.createdAt.format('LT'); + return '' + } + + isPredecessorSameAuthor(): boolean { + if (!this.predecessor) { + return false; + } + return this.predecessor.uid === this.msg?.uid; + } + + isTemporalClose(): boolean { + if (!this.predecessor) { + return true; + } + + // const duration = moment.duration( + // this.msg?.createdAt.diff(this.predecessor.createdAt) + // ); + // return duration.asMinutes() <= 1; + return false; + } + + isPreviousMessageFromOtherDay() { + if (!this.predecessor) { + return true; + } + // const prevDate = this.predecessor.createdAt.day(); + // const date = this.msg.createdAt.day(); + // return prevDate !== date; + return false; + } +} diff --git a/src/llm/models/fireworks.ts b/src/llm/models/fireworks.ts index a20c5800..46796009 100644 --- a/src/llm/models/fireworks.ts +++ b/src/llm/models/fireworks.ts @@ -1,7 +1,6 @@ import OpenAI from 'openai'; import { addCost, agentContext } from '#agent/agentContextLocalStorage'; import { LlmCall } from '#llm/llmCallService/llmCall'; -import { CallerId } from '#llm/llmCallService/llmCallService'; import { withSpan } from '#o11y/trace'; import { currentUser } from '#user/userService/userContext'; import { sleep } from '#utils/async-utils'; @@ -130,27 +129,29 @@ export class FireworksLLM extends BaseLLM { export function fireworksLLMRegistry(): Record LLM> { return { - [`${FIREWORKS_SERVICE}:accounts/fireworks/models/llama-v3-70b-instruct`]: fireworksLlama3_70B, + [`${FIREWORKS_SERVICE}:accounts/fireworks/models/llama-v3p1-70b-instruct`]: fireworksLlama3_70B, + [`${FIREWORKS_SERVICE}:accounts/fireworks/models/llama-v3p1-405b-instruct`]: fireworksLlama3_405B, }; } + export function fireworksLlama3_70B(): LLM { return new FireworksLLM( 'LLama3 70b-i (Fireworks)', - 'accounts/fireworks/models/llama-v3-70b-instruct', - 8000, - (input: string) => (input.length * 0.9) / 1_000_000, - (output: string) => (output.length * 0.9) / 1_000_000, + 'accounts/fireworks/models/llama-v3p1-70b-instruct', + 131_072, + (input: string) => (input.length * 0.9) / 1_000_000 / 4, + (output: string) => (output.length * 0.9) / 1_000_000 / 4, ); } -export function fireworksLLmFromModel(model: string): LLM | null { - // if (model === 'meta-llama/Llama-3-8b-chat-hf') { - // return togetherLlama3_7B(); - // } - if (model === 'accounts/fireworks/models/llama-v3-70b-instruct') { - return fireworksLlama3_70B(); - } - return null; +export function fireworksLlama3_405B(): LLM { + return new FireworksLLM( + 'LLama3 405b-i (Fireworks)', + 'accounts/fireworks/models/llama-v3p1-405b-instruct', + 131_072, + (input: string) => (input.length * 3) / 1_000_000 / 4, + (output: string) => (output.length * 3) / 1_000_000 / 4, + ); } /*