Skip to content

Commit

Permalink
feat: create ocap copilot component
Browse files Browse the repository at this point in the history
  • Loading branch information
meta-d committed Dec 20, 2023
1 parent fb869b0 commit 985bcd0
Show file tree
Hide file tree
Showing 57 changed files with 2,075 additions and 226 deletions.
2 changes: 1 addition & 1 deletion apps/cloud/src/app/@core/services/copilot.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export class CopilotService extends NgmCopilotService {
this.openai = new OpenAIApi(this.configuration)
})

private async getOne(orgId: string) {
async getOne(orgId?: string) {
const result = await firstValueFrom(this.httpClient.get<{ items: ICopilot[] }>(API_PREFIX + '/copilot'))
this._copilot$.next(result.items[0])
return this._copilot$.value
Expand Down
3 changes: 3 additions & 0 deletions apps/cloud/src/app/@shared/copilot/chat/chat.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ import { NgmSearchComponent } from '@metad/ocap-angular/common'
// }
// }

/**
* @deprecated use NgmCopilotChatComponent instead
*/
@Component({
standalone: true,
changeDetection: ChangeDetectionStrategy.OnPush,
Expand Down
26 changes: 16 additions & 10 deletions apps/cloud/src/app/features/features.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { PacAuthModule } from '@metad/cloud/auth'
import { NxTableModule } from '@metad/components/table'
import { ICopilot } from '@metad/copilot'
import { NgmFormlyModule } from '@metad/formly'
import { PACMaterialThemeModule } from '@metad/material-theme'
import { NgmCopilotService } from '@metad/ocap-angular/copilot'
import {
DensityDirective,
NgmAgentService,
Expand All @@ -9,13 +15,8 @@ import {
} from '@metad/ocap-angular/core'
import { NGM_WASM_AGENT_WORKER, WasmAgentService } from '@metad/ocap-angular/wasm-agent'
import { DataSource, Type } from '@metad/ocap-core'
import { LetDirective } from '@ngrx/component'
import { PacAuthModule } from '@metad/cloud/auth'
import { NxTableModule } from '@metad/components/table'
import { NgmFormlyModule } from '@metad/formly'
import { NgmCopilotService } from '@metad/core'
import { PACMaterialThemeModule } from '@metad/material-theme'
import { NX_STORY_FEED, NX_STORY_MODEL, NX_STORY_STORE } from '@metad/story/core'
import { LetDirective } from '@ngrx/component'
import { NgxPopperjsModule } from 'ngx-popperjs'
import { CopilotService, DirtyCheckGuard, LocalAgent, ServerAgent } from '../@core/index'
import { AssetsComponent } from '../@shared/assets/assets.component'
Expand Down Expand Up @@ -54,7 +55,7 @@ import { FeaturesComponent } from './features.component'
CopilotGlobalComponent,

// Formly
NgmFormlyModule.forRoot({}),
NgmFormlyModule.forRoot({})
],
providers: [
DirtyCheckGuard,
Expand Down Expand Up @@ -117,9 +118,14 @@ import { FeaturesComponent } from './features.component'
useClass: StoryFeedService
},
{
provide: NgmCopilotService,
useExisting: CopilotService
}
// Provide CopilotConfig factory to NgmCopilotService
provide: NgmCopilotService.CopilotConfigFactoryToken,
useFactory: (copilotService: CopilotService) => (): Promise<ICopilot> => {
return copilotService.getOne()
},
deps: [CopilotService]
},
NgmCopilotService,
]
})
export class FeaturesModule {}
19 changes: 15 additions & 4 deletions apps/cloud/src/app/features/home/insight/insight.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import {
DataSettings,
EntityType,
getEntityDimensions,
isEntityType
isEntityType,
getEntityHierarchy
} from '@metad/ocap-core'
import { TranslateService } from '@ngx-translate/core'
import { convertNewSemanticModelResult, ModelsService, NgmSemanticModel } from '@metad/cloud/state'
Expand Down Expand Up @@ -282,11 +283,11 @@ ${calcEntityTypePrompt(entityType)}
}
)

let answer
let answer: any
try {
answer = getFunctionCall(choices[0].message)

const { chartAnnotation, slicers, limit, chartOptions } = transformCopilotChart(answer.arguments)
const { chartAnnotation, slicers, limit, chartOptions } = transformCopilotChart(answer.arguments, entityType)
const answerMessage = {
message: JSON.stringify(answer.arguments, null, 2),
dataSettings: {
Expand Down Expand Up @@ -545,7 +546,15 @@ ${JSON.stringify([

}

export function transformCopilotChart(answer) {

/**
* Transform copilot answer to chart annotation
*
* @param answer Answer from copilot
* @param entityType Entity type of the cube
* @returns
*/
export function transformCopilotChart(answer: any, entityType: EntityType) {
const chartAnnotation = {} as ChartAnnotation
if (answer.chartType) {
chartAnnotation.chartType = {
Expand All @@ -562,6 +571,8 @@ export function transformCopilotChart(answer) {
chartAnnotation.dimensions = dimensions.map((dimension) => (
{
...dimension,
// Determine dimension attr by hierarchy
dimension: getEntityHierarchy(entityType, dimension.hierarchy).dimension,
zeroSuppression: true,
chartOptions: {
dataZoom: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {
SystemCommandFree,
SystemCommands
} from '@metad/copilot'
import { NgmCopilotService } from '@metad/core'
import { pick } from '@metad/ocap-core'
import { TranslateService } from '@ngx-translate/core'
import { NGXLogger } from 'ngx-logger'
Expand All @@ -27,6 +26,7 @@ import { getErrorMessage } from '../../../../@core'
import { ModelEntityService } from '../entity/entity.service'
import { SemanticModelService } from '../model.service'
import { ModelCopilotChatConversation, ModelCopilotCommandArea } from './types'
import { NgmCopilotService } from '@metad/ocap-angular/copilot'

export const I18N_MODEL_NAMESPACE = 'PAC.MODEL'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { NgmCopilotService } from '@metad/core'
import { EntityType } from '@metad/ocap-core'
import { CopilotChatConversation } from '@metad/copilot'
import { NgmCopilotService } from '@metad/ocap-angular/copilot'
import { EntityType } from '@metad/ocap-core'
import { NGXLogger } from 'ngx-logger'
import { SemanticModelService } from '../model.service'
import { ModelEntityService } from '../entity/entity.service'
import { SemanticModelService } from '../model.service'

export interface ModelCopilotChatConversation extends CopilotChatConversation {
dataSource: string
Expand All @@ -17,4 +17,4 @@ export interface ModelCopilotChatConversation extends CopilotChatConversation {
sharedDimensionsPrompt: string
}

export const ModelCopilotCommandArea = 'Model'
export const ModelCopilotCommandArea = 'Model'
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
[color]="copilotDrawer.opened?'accent':''"
(click)="copilotDrawer.toggle()"
>
<span>🤖</span>
<div class="flex justify-center items-center text-xl">🤖</div>
</button>
</div>

Expand Down Expand Up @@ -231,11 +231,12 @@
<mat-drawer-content class="flex">
<mat-drawer-container class="flex-1 h-full" [hasBackdrop]="false" autosize>
<mat-drawer #copilotDrawer class="mat-elevation-z" position="end" mode="side" ngmResizer [resizerWidth]="400">
<pac-copilot-chat #copilotChat class="pac-cdk-drop__list pac-cdk-drop__area w-full h-full rounded-lg shadow-lg overflow-hidden"
<ngm-copilot-chat #copilotChat class="pac-cdk-drop__list pac-cdk-drop__area w-full h-full rounded-lg shadow-lg overflow-hidden"
[copilotEngine]="copilotEngine"
[user]="user"
cdkDropList
(cdkDropListDropped)="dropCopilot($event)"
></pac-copilot-chat>
></ngm-copilot-chat>

<div ngmResizerBar resizerBarPosition="left"
cdkDrag
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { MatDialog, MatDialogConfig } from '@angular/material/dialog'
import { ActivatedRoute, Router } from '@angular/router'
import { CopilotChatMessageRoleEnum } from '@metad/copilot'
import { DBTable, PropertyAttributes, TableEntity, pick } from '@metad/ocap-core'
import { ModelsService, NgmSemanticModel } from '@metad/cloud/state'
import { ModelsService, NgmSemanticModel, Store } from '@metad/cloud/state'
import { ConfirmDeleteComponent, ConfirmUniqueComponent } from '@metad/components/confirm'
import { NX_STORY_STORE, NxStoryStore, StoryModel } from '@metad/story/core'
import { NxSettingsPanelService } from '@metad/story/designer'
Expand All @@ -36,8 +36,6 @@ import {
tap
} from 'rxjs'
import { ISemanticModel, MenuCatalog, ToastrService, getErrorMessage, routeAnimations, uuid } from '../../../@core'
import { CopilotChatComponent } from '../../../@shared'
import { TranslationBaseComponent } from '../../../@shared/language/translation-base.component'
import { AppService } from '../../../app.service'
import { exportSemanticModel } from '../types'
import { ModelUploadComponent } from '../upload/upload.component'
Expand All @@ -49,6 +47,8 @@ import { MODEL_TYPE, SemanticModelEntity, SemanticModelEntityType, TOOLBAR_ACTIO
import { stringifyTableType } from './utils'
import { IsDirty } from '@metad/core'
import { ModelCopilotEngineService } from './copilot'
import { NgmCopilotChatComponent } from '@metad/ocap-angular/copilot'
import { TranslationBaseComponent } from '../../../@shared'


@Component({
Expand All @@ -67,6 +67,7 @@ export class ModelComponent extends TranslationBaseComponent implements IsDirty
TOOLBAR_ACTION_CATEGORY = TOOLBAR_ACTION_CATEGORY

private readonly _modelCopilotEngine = inject(ModelCopilotEngineService)
#store = inject(Store)
public appService = inject(AppService)
private modelService = inject(SemanticModelService)
private modelsService = inject(ModelsService)
Expand All @@ -77,6 +78,9 @@ export class ModelComponent extends TranslationBaseComponent implements IsDirty
private _viewContainerRef = inject(ViewContainerRef);
private toastrService = inject(ToastrService);

get user() {
return this.#store.user
}
get copilotEngine() {
return this._copilotEngine ?? this._modelCopilotEngine
}
Expand All @@ -85,7 +89,7 @@ export class ModelComponent extends TranslationBaseComponent implements IsDirty
}
private _copilotEngine = null

@ViewChild('copilotChat') copilotChat!: CopilotChatComponent
@ViewChild('copilotChat') copilotChat!: NgmCopilotChatComponent

@HostBinding('class.pac-fullscreen')
public isFullscreen = false
Expand Down
45 changes: 21 additions & 24 deletions apps/cloud/src/app/features/semantic-model/model/model.module.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
import { CdkMenuModule } from '@angular/cdk/menu'
import { ScrollingModule } from '@angular/cdk/scrolling'
import { CommonModule } from '@angular/common'
import { NgModule } from '@angular/core'
import { OcapCoreModule } from '@metad/ocap-angular/core'
import { ContentLoaderModule } from '@ngneat/content-loader'
import { FormlyModule } from '@ngx-formly/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NxActionStripModule } from '@metad/components/action-strip'
import { NxEditorModule } from '@metad/components/editor'
import { NxTableModule } from '@metad/components/table'
import { NgmCommonModule, NgmTableComponent, ResizerModule, SplitterModule } from '@metad/ocap-angular/common'
import { NgmCopilotChatComponent } from '@metad/ocap-angular/copilot'
import { OcapCoreModule } from '@metad/ocap-angular/core'
import { NxComponentSettingsComponent, NxDesignerModule, STORY_DESIGNER_COMPONENT } from '@metad/story/designer'
import { ContentLoaderModule } from '@ngneat/content-loader'
import { LetDirective } from '@ngrx/component'
import { FormlyModule } from '@ngx-formly/core'
import { TranslateModule } from '@ngx-translate/core'
import { MonacoEditorModule } from 'ngx-monaco-editor'
import { NgmCommonModule, ResizerModule, SplitterModule } from '@metad/ocap-angular/common'
import { CopilotChatComponent, CreatedByPipe, MaterialModule, UserPipe } from '../../../@shared'
import { NgxPopperjsModule } from 'ngx-popperjs'
import { CreatedByPipe, MaterialModule, UserPipe } from '../../../@shared'
import { ModelUploadComponent } from '../upload/upload.component'
import { registerModelCommands } from './copilot'
import { ModelCreateEntityComponent } from './create-entity/create-entity.component'
import { ModelRoutingModule } from './model-routing.module'
import { ModelComponent } from './model.component'
import { ModelOverviewComponent } from './overview/overview.component'
import { ModelPreferencesComponent } from './preferences/preferences.component'
import {
CalculatedMemberAttributesSchema,
Expand All @@ -31,25 +40,12 @@ import {
} from './schema/index'
import { StoryModelResolver } from './story-model.resolver'
import { ModelDesignerType } from './types'
import { ModelOverviewComponent } from './overview/overview.component'
import { ModelUploadComponent } from '../upload/upload.component'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { NgxPopperjsModule } from 'ngx-popperjs'
import { TranslateModule } from '@ngx-translate/core'
import { CommonModule } from '@angular/common'
import { LetDirective } from '@ngrx/component'
import { CdkMenuModule } from '@angular/cdk/menu'
import { registerModelCommands } from './copilot'
import { NgmCopilotService } from '@metad/core'

registerModelCommands()

@NgModule({
declarations: [
ModelComponent,
ModelOverviewComponent,
ModelCreateEntityComponent,
ModelPreferencesComponent,
],
declarations: [ModelComponent, ModelOverviewComponent, ModelCreateEntityComponent, ModelPreferencesComponent],
imports: [
CommonModule,
ModelRoutingModule,
Expand All @@ -64,25 +60,26 @@ registerModelCommands()
NgxPopperjsModule,
LetDirective,
NxEditorModule,
NxTableModule,
CreatedByPipe,
UserPipe,

NxActionStripModule,
NxDesignerModule,
ModelUploadComponent,
CopilotChatComponent,

// OCAP Modules
ResizerModule,
SplitterModule,
MonacoEditorModule.forRoot(),
OcapCoreModule.forRoot(),
NgmCommonModule,
NgmCopilotChatComponent,
NgmTableComponent

// Thirdparty
],
providers: [
NgmCopilotService,
StoryModelResolver,
{
provide: STORY_DESIGNER_COMPONENT,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,10 +427,11 @@
</div>

<div *ngIf="showDetails === 'copilot'" @inOut class="w-96 h-full flex flex-col text-slate-800 overflow-hidden backdrop-blur-sm bg-white/90">
<pac-copilot-chat class="w-full h-full"
<ngm-copilot-chat class="w-full h-full"
[welcomeTitle]=" 'Story.Toolbar.WelcomeCopilot' | translate: {Default: 'Metad Copilot'} "
[copilotEngine]="copilotEngine"
[(conversations)]="conversations"
></pac-copilot-chat>
></ngm-copilot-chat>
</div>

<ng-template #fileMenu>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,15 @@ import { StorySharesComponent } from '@metad/story/story'
import { combineLatest, firstValueFrom } from 'rxjs'
import { map } from 'rxjs/operators'
import { ToastrService, tryHttp } from '../../../@core'
import { CopilotChatComponent, MaterialModule, ProjectFilesComponent } from '../../../@shared'
import { MaterialModule, ProjectFilesComponent } from '../../../@shared'
import { StoryDesignerComponent } from '../designer'
import { SaveAsTemplateComponent } from '../save-as-template/save-as-template.component'
import { StoryDetailsComponent } from '../story-details/story-details.component'
import { DeviceOrientation, DeviceZooms, EmulatedDevices, StoryScales, downloadStory } from '../types'
import { StoryToolbarService } from './toolbar.service'
import { COMPONENTS, PAGES } from './types'
import { CHARTS } from '@metad/story/widgets/analytical-card'
import { NgmCopilotChatComponent } from '@metad/ocap-angular/copilot'


@Component({
Expand All @@ -72,7 +73,7 @@ import { CHARTS } from '@metad/story/widgets/analytical-card'
AppearanceDirective,
DensityDirective,
StoryDesignerComponent,
CopilotChatComponent,
NgmCopilotChatComponent,
NgmInputComponent
],
selector: 'pac-story-toolbar',
Expand Down
3 changes: 3 additions & 0 deletions apps/cloud/src/assets/i18n/zh-Hans.json
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,9 @@
"CubeAlreadyExists": "多维数据集已存在!",
"DimensionAlreadyExists": "维度已存在!",
"MeasureAlreadyExists": "度量已存在!"
},
"Copilot": {
"InstructionExecutionComplete": "指令执行完成"
}
},
"BUSINESS_AREA": {
Expand Down
9 changes: 7 additions & 2 deletions apps/cloud/src/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,14 @@ body {
font-size: 14px;
}

$text-font: Lato, 'Noto Serif SC', monospace;

body {
--mdc-dialog-subhead-font: Lato, 'Noto Serif SC', monospace;
--mdc-dialog-supporting-text-font: Lato, 'Noto Serif SC', monospace;
--mdc-dialog-subhead-font: $text-font;
--mdc-dialog-supporting-text-font: $text-font;
--mat-table-row-item-label-text-font: $text-font;
--mat-table-header-headline-font: $text-font;

display: flex;
margin: 0;

Expand Down
Loading

0 comments on commit 985bcd0

Please sign in to comment.