Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Version 3.0.10 #19

Merged
merged 12 commits into from
Jan 4, 2025
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
102 changes: 48 additions & 54 deletions apps/cloud/src/app/@core/services/feature/feature.service.ts
Original file line number Diff line number Diff line change
@@ -1,59 +1,53 @@
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { HttpClient } from '@angular/common/http'
import { Injectable } from '@angular/core'
import { API_PREFIX } from '@metad/cloud/state'
import {
IFeature,
IFeatureOrganization,
IFeatureOrganizationUpdateInput,
IFeatureOrganizationFindInput,
IPagination
} from '@metad/contracts';
import { toParams } from '@metad/core';
import { Observable } from 'rxjs';
import { API_PREFIX } from '@metad/cloud/state';

IFeature,
IFeatureOrganization,
IFeatureOrganizationFindInput,
IFeatureOrganizationUpdateInput,
IPagination
} from '@metad/contracts'
import { toParams } from '@metad/core'
import { Observable } from 'rxjs'

@Injectable()
export class FeatureService {
API_URL = `${API_PREFIX}/feature/toggle`;

constructor(private http: HttpClient) {}

getFeatureToggleDefinition() {
return this.http.get<IFeature[]>(`${this.API_URL}/definition`)
}

getParentFeatures(
relations?: string[]
): Observable<{ items: IFeature[]; total: number }> {
const data = { relations };
return this.http.get<{ items: IFeature[]; total: number }>(
`${this.API_URL}/parent`,
{
params: toParams({ data })
}
);
}

getAllFeatures(): Observable<{ items: IFeature[]; total: number }> {
return this.http.get<{ items: IFeature[]; total: number }>(
`${this.API_URL}`
);
}

getFeatureOrganizations(
findInput?: IFeatureOrganizationFindInput,
relations?: string[]
): Observable<IPagination<IFeatureOrganization>> {
const data = { relations, findInput };
return this.http.get<IPagination<IFeatureOrganization>>(
`${this.API_URL}/organizations`,
{
params: toParams({ data })
}
);
}

featureToggle(payload: IFeatureOrganizationUpdateInput) {
return this.http.post(`${this.API_URL}`, payload);
}
API_URL = `${API_PREFIX}/feature/toggle`
API_FEATURE = `${API_PREFIX}/feature`

constructor(private http: HttpClient) {}

getFeatureToggleDefinition() {
return this.http.get<IFeature[]>(`${this.API_URL}/definition`)
}

getParentFeatures(relations?: string[]): Observable<{ items: IFeature[]; total: number }> {
const data = { relations }
return this.http.get<{ items: IFeature[]; total: number }>(`${this.API_URL}/parent`, {
params: toParams({ data })
})
}

getAllFeatures(): Observable<{ items: IFeature[]; total: number }> {
return this.http.get<{ items: IFeature[]; total: number }>(`${this.API_URL}`)
}

getFeatureOrganizations(
findInput?: IFeatureOrganizationFindInput,
relations?: string[]
): Observable<IPagination<IFeatureOrganization>> {
const data = { relations, findInput }
return this.http.get<IPagination<IFeatureOrganization>>(`${this.API_URL}/organizations`, {
params: toParams({ data })
})
}

featureToggle(payload: IFeatureOrganizationUpdateInput) {
return this.http.post(`${this.API_URL}`, payload)
}

upgrade() {
return this.http.post(`${this.API_FEATURE}/upgrade`, {})
}
}
6 changes: 5 additions & 1 deletion apps/cloud/src/app/@core/services/fetch-event-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import { EventSourceMessage, EventStreamContentType, fetchEventSource } from '@m
import { firstValueFrom, Observable } from 'rxjs'
import { AuthStrategy } from '../auth'
import { Store } from './store.service'
import { injectLanguage } from '../providers'

export function injectFetchEventSource<T extends BodyInit | null>() {
const store = inject(Store)
const auth = inject(AuthStrategy)
const lang = injectLanguage()


return (url: string, data: T) => {
return new Observable<EventSourceMessage>((subscriber) => {
Expand All @@ -21,7 +24,8 @@ export function injectFetchEventSource<T extends BodyInit | null>() {
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`,
'Organization-Id': `${organization.id}`
'Organization-Id': `${organization.id}`,
Language: lang()
},
body: data,
signal: ctrl.signal,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
>
<div class="grow h-0">
<div class="py-1">
<img alt="provider-icon" [src]="provider.icon_large | i18n" class="w-auto h-7">
@if (provider.icon_large) {
<img alt="provider-icon" [src]="provider.icon_large | i18n" class="w-auto h-7">
} @else {
{{ provider.label | i18n }}
}
</div>
<div class="mt-1 leading-4 text-sm text-zinc-600 line-clamp-4" [title]="provider.description | i18n">{{provider.description | i18n}}</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@
</button>
}
@if (selectedCopilotWithModels(); as copilot) {
<img [src]="copilot.providerWithModels.icon_small | i18n" class="w-4 h-4 mx-1.5">
@if (copilot.providerWithModels.icon_small) {
<img [src]="copilot.providerWithModels.icon_small | i18n" class="w-4 h-4 mx-1.5">
}

<div class="flex items-center truncate text-[13px] font-medium mr-1.5">
<div class="truncate" [title]="_copilotModel()?.model">{{_copilotModel()?.model}}</div>
@if (selectedAiModel()?.model_type === eModelType.LLM) {
Expand Down Expand Up @@ -134,7 +137,9 @@
<div class="text-base px-4 my-4 font-semibold flex justify-start items-center">
<span class="uppercase">{{ ('PAC.Copilot.Role_' + copilot.role) | translate: {Default: copilot.role} }}</span>
<span class="mx-1">•</span>
<img [src]="(copilot.providerWithModels.icon_small | i18n)" class="w-4 h-4 inline-block mx-1">
@if (copilot.providerWithModels.icon_small) {
<img [src]="(copilot.providerWithModels.icon_small | i18n)" class="w-4 h-4 inline-block mx-1">
}
{{copilot.providerWithModels?.label | i18n }}
</div>
@for (item of copilot.providerWithModels?.models; track item.model) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,64 +1,73 @@
<div cdkDrag cdkDragRootElement=".cdk-overlay-pane" cdkDragHandle class="flex justify-between items-center mb-2 cursor-move">
<div class="text-xl font-semibold text-gray-900">{{'PAC.ACTIONS.Add' | translate: {Default: 'Add'} }} {{label() | i18n}}</div>
<div cdkDrag cdkDragRootElement=".cdk-overlay-pane" cdkDragHandle class="flex justify-between items-center mb-2 px-8 py-4 cursor-move sticky top-0 z-10 bg-components-card-bg">
<div class="text-xl font-semibold text-gray-900">{{'PAC.ACTIONS.Add' | translate: {Default: 'Add'} }} {{label() | i18n}}</div>
@if (icon()) {
<img
alt="provider-icon"
[src]="icon() | i18n"
class="w-auto h-8"
/>
} @else {
<div>
{{ label() | i18n }}
</div>
}
</div>

<div>
<div class="py-2 leading-5 text-base font-medium">
{{ 'PAC.Copilot.ModelType' | translate: { Default: 'Model type' } }}
<span class="ml-1 text-red-500">*</span>
<div class="px-8 flex flex-col w-full">
<div>
<div class="py-2 leading-5 text-base font-medium">
{{ 'PAC.Copilot.ModelType' | translate: { Default: 'Model type' } }}
<span class="ml-1 text-red-500">*</span>
</div>
<ul class="ngm-radio-select grid grid-cols-3 gap-3" cdkListbox [(ngModel)]="modelTypes">
@for (type of supported_model_types(); track type) {
<li [cdkOption]="type">
<div class="radio-indicator"></div>
<div class="text-sm font-normal">{{type | kebabToCamelCase}}</div>
</li>
}
</ul>
</div>
<ul class="ngm-radio-select grid grid-cols-3 gap-3" cdkListbox [(ngModel)]="modelTypes">
@for (type of supported_model_types(); track type) {
<li [cdkOption]="type">
<div class="radio-indicator"></div>
<div class="text-sm font-normal">{{type | kebabToCamelCase}}</div>
</li>
}
</ul>
</div>

<div class="py-3">
<div class="flex items-center py-2 text-base text-gray-900">
{{ modelSchema().label | i18n }}
<span class="ml-1 text-red-500">*</span>
<div class="py-3">
<div class="flex items-center py-2 text-base text-gray-900">
{{ modelSchema().label | i18n }}
<span class="ml-1 text-red-500">*</span>
</div>
<div class="relative">
<input class="block px-3 w-full h-9 bg-gray-100 text-sm rounded-lg border border-transparent
appearance-none outline-none caret-primary-600
hover:border-[rgba(0,0,0,0.08)] hover:bg-gray-50
focus:bg-white focus:border-gray-300 focus:shadow-xs
placeholder:text-sm placeholder:text-gray-400"
[placeholder]="modelSchema().placeholder | i18n"
[(ngModel)]="modelName"
type="text"
>
</div>
</div>

<div class="relative">
<input class="block px-3 w-full h-9 bg-gray-100 text-sm rounded-lg border border-transparent
appearance-none outline-none caret-primary-600
hover:border-[rgba(0,0,0,0.08)] hover:bg-gray-50
focus:bg-white focus:border-gray-300 focus:shadow-xs
placeholder:text-sm placeholder:text-gray-400"
[placeholder]="modelSchema().placeholder | i18n"
[(ngModel)]="modelName"
type="text"
>
<copilot-credential-form #credentialForm [credentialFormSchemas]="credential_form_schemas()" [(ngModel)]="credentials"/>
@if (loading()) {
<ngm-spin class="absolute top-0 left-0 w-full h-full" />
}
</div>
</div>

<div class="relative">
<copilot-credential-form #credentialForm [credentialFormSchemas]="credential_form_schemas()" [(ngModel)]="credentials"/>
@if (loading()) {
<ngm-spin class="absolute top-0 left-0 w-full h-full" />
}
<div class="mt-1 mb-4 border-t-[0.5px] border-t-gray-100"></div>
</div>


<div class="mt-1 mb-4 border-t-[0.5px] border-t-gray-100"></div>

<div class="sticky bottom-0 flex justify-between items-center mt-2 -mx-2 pt-4 px-2 pb-2 flex-wrap gap-y-2 bg-white">
@if (help()) {
<a [href]="help().url | i18n" target="_blank" rel="noopener noreferrer" class="inline-flex items-center text-sm text-primary-600">
{{help().title | i18n}}
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" class="ml-1 w-3 h-3" >
<g id="link-external-02"><path id="Icon" d="M10.5 4.5L10.5 1.5M10.5 1.5H7.49999M10.5 1.5L6 6M5 1.5H3.9C3.05992 1.5 2.63988 1.5 2.31901 1.66349C2.03677 1.8073 1.8073 2.03677 1.66349 2.31901C1.5 2.63988 1.5 3.05992 1.5 3.9V8.1C1.5 8.94008 1.5 9.36012 1.66349 9.68099C1.8073 9.96323 2.03677 10.1927 2.31901 10.3365C2.63988 10.5 3.05992 10.5 3.9 10.5H8.1C8.94008 10.5 9.36012 10.5 9.68099 10.3365C9.96323 10.1927 10.1927 9.96323 10.3365 9.68099C10.5 9.36012 10.5 8.94008 10.5 8.1V7" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></g>
</svg>
</a>
}
<div class="sticky bottom-0 flex justify-between items-center mt-2 px-8 py-4 flex-wrap gap-y-2 bg-white">
<div class="flex-1">
@if (help()) {
<a [href]="help().url | i18n" target="_blank" rel="noopener noreferrer" class="inline-flex items-center text-sm text-primary-600">
{{help().title | i18n}}
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" class="ml-1 w-3 h-3" >
<g id="link-external-02"><path id="Icon" d="M10.5 4.5L10.5 1.5M10.5 1.5H7.49999M10.5 1.5L6 6M5 1.5H3.9C3.05992 1.5 2.63988 1.5 2.31901 1.66349C2.03677 1.8073 1.8073 2.03677 1.66349 2.31901C1.5 2.63988 1.5 3.05992 1.5 3.9V8.1C1.5 8.94008 1.5 9.36012 1.66349 9.68099C1.8073 9.96323 2.03677 10.1927 2.31901 10.3365C2.63988 10.5 3.05992 10.5 3.9 10.5H8.1C8.94008 10.5 9.36012 10.5 9.68099 10.3365C9.96323 10.1927 10.1927 9.96323 10.3365 9.68099C10.5 9.36012 10.5 8.94008 10.5 8.1V7" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"></path></g>
</svg>
</a>
}
</div>

<div class="flex items-center gap-1">
@if (modelId()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
:host {
@apply flex flex-col w-[600px] p-8 rounded-2xl bg-components-card-bg overflow-y-auto;
@apply flex flex-col w-[600px] max-h-screen rounded-2xl bg-components-card-bg overflow-y-auto;
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
<div class="group flex pl-3 py-2 pr-2 rounded-t-xl">
<div class="grow px-1 pt-1 pb-0.5">
<div class="flex items-center">
<img
alt="provider-icon"
[src]="icon() | i18n"
class="w-auto h-8 mb-2"
/>
</div>
@if (icon()) {
<div class="flex items-center">
<img
alt="provider-icon"
[src]="icon() | i18n"
class="w-auto h-8 mb-2"
/>
</div>
} @else {
<div class="flex items-center">
{{ label() | i18n }}
</div>
}

<div class="flex gap-0.5">
@for (modelType of supported_model_types(); track modelType) {
Expand Down Expand Up @@ -114,11 +120,11 @@

@for (model of customModels(); track model.id) {
<div class="group flex items-center pl-2 pr-2.5 h-8 rounded-lg hover:bg-gray-50">
<img
alt="model-icon"
[src]="smallIcon() | i18n"
class="w-4 h-4 shrink-0 mr-2"
/>
@if (smallIcon()) {
<img alt="model-icon" class="w-4 h-4 shrink-0 mr-2"
[src]="smallIcon() | i18n"
/>
}

<div class="flex items-center truncate text-[13px] grow text-sm font-normal text-gray-900">
<div class="truncate" [title]="model.modelName">{{model.modelName}}</div>
Expand All @@ -128,9 +134,7 @@
</div>

@if (model.modelProperties?.context_size) {
<div
class="flex items-center px-1 h-[18px] rounded-[5px] border border-black/8 bg-white/[0.48] text-[10px] font-medium text-gray-500 cursor-default ml-1"
>
<div class="flex items-center px-1 h-[18px] rounded-[5px] border border-black/8 bg-white/[0.48] text-[10px] font-medium text-gray-500 cursor-default ml-1">
{{(model.modelProperties.context_size / 1000) | number: '0.0-0'}}K
</div>
}
Expand Down
Loading
Loading