Skip to content

Commit

Permalink
Merge pull request #43 from meta-d/develop
Browse files Browse the repository at this point in the history
Develop v2.5.2
  • Loading branch information
meta-d authored Aug 12, 2024
2 parents 42d4ff6 + bbdbee0 commit 06cc26f
Show file tree
Hide file tree
Showing 196 changed files with 3,197 additions and 1,048 deletions.
2 changes: 1 addition & 1 deletion .deploy/api/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "ocap-server",
"author": "Metad",
"version": "2.5.1",
"version": "2.5.2",
"scripts": {
"start": "nx serve",
"build": "nx build",
Expand Down
5 changes: 2 additions & 3 deletions apps/cloud/src/app/@core/auth/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ import { signal } from '@angular/core'

export abstract class AbstractAgent {

#auth = signal<Record<string, [string, Subject<any>]>>({})
readonly #auth = signal<Record<string, [string, Subject<any>]>>({})

// private _auth: Record<string, [string, Subject<any>]> = {}
get auth() {
return this.#auth
}
Expand Down Expand Up @@ -57,7 +56,7 @@ export abstract class AbstractAgent {
}
}

return firstValueFrom(this.#auth()[dataSource.id][1])
return this.#auth()[dataSource.id] ? firstValueFrom(this.#auth()[dataSource.id][1]) : null
} else {
return this.signIn(dataSource, event)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ <h3 class="mb-4 text-lg">
<form [formGroup]="form" (ngSubmit)="onSubmit()" class="flex flex-col justify-start items-stretch">

<ngm-input [label]="'PAC.KEY_WORDS.Username' | translate: {Default: 'Username'}"
formControlName="username" ></ngm-input>
formControlName="username"
/>

<ngm-input [label]="'PAC.KEY_WORDS.Password' | translate: {Default: 'Password'}"
type="password"
formControlName="password" ></ngm-input>
formControlName="password"
/>

<!-- 目前没有意义,因为 Auth 必须保存到 Server 才能被使用
<mat-checkbox formControlName="remeberMe">
Expand Down
7 changes: 5 additions & 2 deletions apps/cloud/src/app/@core/constants/app.constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { API_PREFIX } from '@metad/cloud/state'
export const API_VISITS = API_PREFIX + '/visits'
export const API_FEEDS = API_PREFIX + '/feeds'
export const API_COPILOT_EXAMPLE = API_PREFIX + '/copilot-example'
export const API_COPILOT_ROLE = API_PREFIX + '/copilot-role'
export const API_COPILOT_KNOWLEDGE = API_PREFIX + '/copilot-knowledge'
export const API_COPILOT_ROLE = API_PREFIX + '/copilot-role'
export const API_COPILOT_USER = API_PREFIX + '/copilot-user'
export const API_COPILOT_ORGANIZATION = API_PREFIX + '/copilot-organization'
export const API_COPILOT_CHECKPOINT = API_PREFIX + '/copilot-checkpoint'
84 changes: 70 additions & 14 deletions apps/cloud/src/app/@core/copilot/checkpoint-saver.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,85 @@
import { Injectable, Provider } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import { inject, Injectable, Provider } from '@angular/core'
import { RunnableConfig } from '@langchain/core/runnables'
import { Checkpoint, CheckpointMetadata, CheckpointTuple } from '@langchain/langgraph/dist/checkpoint/base'
import { BaseCheckpointSaver, MemorySaver } from '@langchain/langgraph/web'
import { BaseCheckpointSaver } from '@langchain/langgraph/web'
import { ICopilotCheckpoint } from '@metad/contracts'
import { firstValueFrom, map } from 'rxjs'
import { API_COPILOT_CHECKPOINT } from '../constants/app.constants'

@Injectable({
providedIn: 'root'
})
export class CopilotCheckpointSaver extends MemorySaver { // extends BaseCheckpointSaver {
export class CopilotCheckpointSaver extends BaseCheckpointSaver {
readonly #httpClient = inject(HttpClient)

constructor() {
super()
}

// async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {
// console.log(`get tuple:`, config.configurable)
// return null
// }
async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {
const { thread_id, checkpoint_id } = config.configurable || {}
const row = await firstValueFrom(
this.#httpClient
.get<{ items: ICopilotCheckpoint[] }>(API_COPILOT_CHECKPOINT, {
params: {
$filter: JSON.stringify({
thread_id,
checkpoint_id
}),
$order: JSON.stringify({
checkpoint_id: 'DESC'
})
}
})
.pipe(map((res) => res.items[0]))
)

if (row) {
return {
config: {
configurable: {
thread_id: row.thread_id,
checkpoint_id: row.checkpoint_id
}
},
checkpoint: (await this.serde.parse(row.checkpoint)) as Checkpoint,
metadata: (await this.serde.parse(row.metadata)) as CheckpointMetadata,
parentConfig: row.parent_id
? {
configurable: {
thread_id: row.thread_id,
checkpoint_id: row.parent_id
}
}
: undefined
}
}
return undefined
}

async *list(config: RunnableConfig, limit?: number, before?: RunnableConfig): AsyncGenerator<CheckpointTuple> {
console.log(`list checkpoints:`, config, limit, before)
}

// async *list(config: RunnableConfig, limit?: number, before?: RunnableConfig): AsyncGenerator<CheckpointTuple> {
// console.log(`list checkpoints:`, config, limit, before)
// }
async put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig> {
await firstValueFrom(
this.#httpClient.post(API_COPILOT_CHECKPOINT, {
thread_id: config.configurable?.thread_id,
checkpoint_id: checkpoint.id,
parent_id: config.configurable?.checkpoint_id,
checkpoint: this.serde.stringify(checkpoint),
metadata: this.serde.stringify(metadata)
})
)

// async put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig> {
// console.log(`put checkpoint:`, config, checkpoint, metadata)
// return null
// }
return {
configurable: {
thread_id: config.configurable?.thread_id,
checkpoint_id: checkpoint.id
}
}
}
}

export function provideCheckpointSaver(): Provider[] {
Expand Down
4 changes: 2 additions & 2 deletions apps/cloud/src/app/@core/copilot/example-vector-retriever.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,15 @@ export class ExampleVectorStoreRetriever<V extends VectorStoreInterface = Vector

filter?: V['FilterType']

command: string
command: string | string[]
role: Signal<string>
score?: number
_vectorstoreType(): string {
return this.vectorStore._vectorstoreType()
}

constructor(
fields: VectorStoreRetrieverInput<V> & { command: string; role: Signal<string>; score?: number },
fields: VectorStoreRetrieverInput<V> & { command: string | string[]; role: Signal<string>; score?: number },
private readonly service: CopilotExampleService
) {
super(fields)
Expand Down
2 changes: 1 addition & 1 deletion apps/cloud/src/app/@core/copilot/references.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ExampleVectorStoreRetrieverInput, NgmCopilotService } from '@metad/copi
import { CopilotExampleService } from '../services/copilot-example.service'
import { ExampleVectorStoreRetriever } from './example-vector-retriever'

export function injectExampleRetriever(command: string, fields?: ExampleVectorStoreRetrieverInput) {
export function injectExampleRetriever(command: string | string[], fields?: ExampleVectorStoreRetrieverInput) {
const copilotService = inject(NgmCopilotService)
const copilotExampleService = inject(CopilotExampleService)

Expand Down
34 changes: 24 additions & 10 deletions apps/cloud/src/app/@core/services/chatbi-conversation.service.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { HttpClient } from '@angular/common/http'
import { inject, Injectable } from '@angular/core'
import { API_PREFIX, SystemPrivacyFields } from '@metad/cloud/state'
import { API_PREFIX, OrganizationBaseService, SystemPrivacyFields } from '@metad/cloud/state'
import { CopilotChatMessage } from '@metad/copilot'
import { Indicator } from '@metad/ocap-core'
import { omit } from 'lodash-es'
import { NGXLogger } from 'ngx-logger'
import { BehaviorSubject, map } from 'rxjs'
import { IChatBIConversation } from '../types'
import { BehaviorSubject, map, switchMap } from 'rxjs'
import { IChatBIConversation, OrderTypeEnum } from '../types'

const API_CHATBI_CONVERSATION = API_PREFIX + '/chatbi-conversation'

export interface ChatbiConverstion {
export interface ChatbiConverstion<T = any> {
id?: string
key: string
name: string
Expand All @@ -20,19 +20,31 @@ export interface ChatbiConverstion {
command: string
messages: CopilotChatMessage[]
indicators: Indicator[]
answer: T
}

@Injectable({ providedIn: 'root' })
export class ChatBIConversationService {
export class ChatBIConversationService extends OrganizationBaseService {
readonly #logger = inject(NGXLogger)
readonly httpClient = inject(HttpClient)

readonly #refresh = new BehaviorSubject<void>(null)

getMy() {
return this.httpClient
.get<{ items: IChatBIConversation[] }>(API_CHATBI_CONVERSATION + '/my')
.pipe(map(({ items }) => items.map(convertChatBIConversationResult)))
return this.selectOrganizationId().pipe(
switchMap(() =>
this.httpClient.get<{ items: IChatBIConversation[] }>(API_CHATBI_CONVERSATION + '/my', {
params: {
data: JSON.stringify({
order: {
createdAt: OrderTypeEnum.DESC
}
})
}
})
),
map(({ items }) => items.map(convertChatBIConversationResult))
)
}

getById(id: string) {
Expand Down Expand Up @@ -62,10 +74,11 @@ export class ChatBIConversationService {

export function convertChatBIConversation(input: Partial<ChatbiConverstion>) {
return {
...omit(input, 'messages', 'indicators'),
...omit(input, 'messages', 'indicators', 'answer'),
options: {
messages: input.messages,
indicators: input.indicators,
answer: input.answer
}
} as IChatBIConversation
}
Expand All @@ -74,6 +87,7 @@ export function convertChatBIConversationResult(result: IChatBIConversation) {
return {
...omit(result, 'options', ...SystemPrivacyFields),
messages: result.options?.messages || [],
indicators: result.options?.indicators
indicators: result.options?.indicators,
answer: result.options?.answer
} as ChatbiConverstion
}
36 changes: 18 additions & 18 deletions apps/cloud/src/app/@core/services/copilot-example.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { DocumentInterface } from '@langchain/core/documents'
import { MaxMarginalRelevanceSearchOptions, VectorStoreInterface } from '@langchain/core/vectorstores'
import { NGXLogger } from 'ngx-logger'
import { map, tap } from 'rxjs'
import { API_COPILOT_EXAMPLE } from '../constants/app.constants'
import { ICopilotExample, ICopilotRole } from '../types'
import { API_COPILOT_KNOWLEDGE } from '../constants/app.constants'
import { ICopilotKnowledge, ICopilotRole } from '../types'
import { CopilotRoleService } from './copilot-role.service'

@Injectable({ providedIn: 'root' })
Expand All @@ -16,62 +16,62 @@ export class CopilotExampleService {

similaritySearch(
query: string,
options: { k?: number; filter?: VectorStoreInterface['FilterType']; command: string; role: string; score: number }
options: { k?: number; filter?: VectorStoreInterface['FilterType']; command: string | string[]; role: string; score: number }
) {
return this.httpClient.post<DocumentInterface[]>(`${API_COPILOT_EXAMPLE}/similarity-search`, { query, options })
return this.httpClient.post<DocumentInterface[]>(`${API_COPILOT_KNOWLEDGE}/similarity-search`, { query, options })
}

maxMarginalRelevanceSearch(
query: string,
options: MaxMarginalRelevanceSearchOptions<VectorStoreInterface['FilterType']> & {
command: string
command: string | string[]
role: string
}
) {
return this.httpClient.post<DocumentInterface[]>(`${API_COPILOT_EXAMPLE}/mmr-search`, { query, options })
return this.httpClient.post<DocumentInterface[]>(`${API_COPILOT_KNOWLEDGE}/mmr-search`, { query, options })
}

getAll(options?: { relations: string[]; filter?: Record<string, any> }) {
const { relations, filter } = options || {}
return this.httpClient
.get<{ items: ICopilotExample[] }>(`${API_COPILOT_EXAMPLE}`, {
.get<{ items: ICopilotKnowledge[] }>(`${API_COPILOT_KNOWLEDGE}`, {
params: {
$fitler: JSON.stringify(filter),
$filter: JSON.stringify(filter),
$relations: JSON.stringify(relations)
}
})
.pipe(map(({ items }) => items))
}

getById(id: string) {
return this.httpClient.get<ICopilotExample>(`${API_COPILOT_EXAMPLE}/${id}`)
return this.httpClient.get<ICopilotKnowledge>(`${API_COPILOT_KNOWLEDGE}/${id}`)
}

create(entity: Partial<ICopilotExample>) {
return this.httpClient.post<ICopilotExample>(`${API_COPILOT_EXAMPLE}`, entity)
create(entity: Partial<ICopilotKnowledge>) {
return this.httpClient.post<ICopilotKnowledge>(`${API_COPILOT_KNOWLEDGE}`, entity)
}

update(id: string, entity: Partial<ICopilotExample>) {
return this.httpClient.put<ICopilotExample>(`${API_COPILOT_EXAMPLE}/${id}`, entity)
update(id: string, entity: Partial<ICopilotKnowledge>) {
return this.httpClient.put<ICopilotKnowledge>(`${API_COPILOT_KNOWLEDGE}/${id}`, entity)
}

delete(id: string) {
return this.httpClient.delete(`${API_COPILOT_EXAMPLE}/${id}`)
return this.httpClient.delete(`${API_COPILOT_KNOWLEDGE}/${id}`)
}

getCommands(filter: { role: string }) {
return this.httpClient
.get<ICopilotExample[]>(`${API_COPILOT_EXAMPLE}/commands`, {
.get<ICopilotKnowledge[]>(`${API_COPILOT_KNOWLEDGE}/commands`, {
params: {
$fitler: JSON.stringify(filter)
$filter: JSON.stringify(filter)
}
})
.pipe(map((items) => items.map(({ command }) => command)))
}

createBulk(entities: ICopilotExample[], roles: ICopilotRole[], options: { clearRole: boolean }) {
createBulk(entities: ICopilotKnowledge[], roles: ICopilotRole[], options: { clearRole: boolean }) {
return this.httpClient
.post<ICopilotExample[]>(`${API_COPILOT_EXAMPLE}/bulk`, {
.post<ICopilotKnowledge[]>(`${API_COPILOT_KNOWLEDGE}/bulk`, {
examples: entities,
roles,
options
Expand Down
40 changes: 40 additions & 0 deletions apps/cloud/src/app/@core/services/copilot-usage.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { HttpClient } from '@angular/common/http'
import { inject, Injectable } from '@angular/core'
import { ICopilotOrganization, ICopilotUser } from '@metad/contracts'
import { NGXLogger } from 'ngx-logger'
import { map } from 'rxjs'
import { API_COPILOT_ORGANIZATION, API_COPILOT_USER } from '../constants/app.constants'

@Injectable({ providedIn: 'root' })
export class CopilotUsageService {
readonly #logger = inject(NGXLogger)
readonly httpClient = inject(HttpClient)

getOrgUsages() {
return this.httpClient
.get<{ items: ICopilotOrganization[] }>(API_COPILOT_ORGANIZATION, {
params: {
$relations: JSON.stringify(['org'])
}
})
.pipe(map(({ items }) => items))
}

getUserUsages() {
return this.httpClient
.get<{ items: ICopilotUser[] }>(API_COPILOT_USER, {
params: {
$relations: JSON.stringify(['user', 'org'])
}
})
.pipe(map(({ items }) => items))
}

renewOrgLimit(id: string, tokenLimit: number) {
return this.httpClient.post<ICopilotOrganization>(API_COPILOT_ORGANIZATION + `/${id}/renew`, { tokenLimit })
}

renewUserLimit(id: string, tokenLimit: number) {
return this.httpClient.post<ICopilotUser>(API_COPILOT_USER + `/${id}/renew`, { tokenLimit })
}
}
Loading

0 comments on commit 06cc26f

Please sign in to comment.