Skip to content

Commit 06cc26f

Browse files
authored
Merge pull request #43 from meta-d/develop
Develop v2.5.2
2 parents 42d4ff6 + bbdbee0 commit 06cc26f

File tree

196 files changed

+3197
-1048
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

196 files changed

+3197
-1048
lines changed

.deploy/api/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ocap-server",
33
"author": "Metad",
4-
"version": "2.5.1",
4+
"version": "2.5.2",
55
"scripts": {
66
"start": "nx serve",
77
"build": "nx build",

apps/cloud/src/app/@core/auth/agent.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ import { signal } from '@angular/core'
88

99
export abstract class AbstractAgent {
1010

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

13-
// private _auth: Record<string, [string, Subject<any>]> = {}
1413
get auth() {
1514
return this.#auth
1615
}
@@ -57,7 +56,7 @@ export abstract class AbstractAgent {
5756
}
5857
}
5958

60-
return firstValueFrom(this.#auth()[dataSource.id][1])
59+
return this.#auth()[dataSource.id] ? firstValueFrom(this.#auth()[dataSource.id][1]) : null
6160
} else {
6261
return this.signIn(dataSource, event)
6362
}

apps/cloud/src/app/@core/auth/bottom-sheet-basic/bottom-sheet-basic.component.html

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ <h3 class="mb-4 text-lg">
55
<form [formGroup]="form" (ngSubmit)="onSubmit()" class="flex flex-col justify-start items-stretch">
66

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

1011
<ngm-input [label]="'PAC.KEY_WORDS.Password' | translate: {Default: 'Password'}"
1112
type="password"
12-
formControlName="password" ></ngm-input>
13+
formControlName="password"
14+
/>
1315

1416
<!-- 目前没有意义,因为 Auth 必须保存到 Server 才能被使用
1517
<mat-checkbox formControlName="remeberMe">
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { API_PREFIX } from '@metad/cloud/state'
22
export const API_VISITS = API_PREFIX + '/visits'
33
export const API_FEEDS = API_PREFIX + '/feeds'
4-
export const API_COPILOT_EXAMPLE = API_PREFIX + '/copilot-example'
5-
export const API_COPILOT_ROLE = API_PREFIX + '/copilot-role'
4+
export const API_COPILOT_KNOWLEDGE = API_PREFIX + '/copilot-knowledge'
5+
export const API_COPILOT_ROLE = API_PREFIX + '/copilot-role'
6+
export const API_COPILOT_USER = API_PREFIX + '/copilot-user'
7+
export const API_COPILOT_ORGANIZATION = API_PREFIX + '/copilot-organization'
8+
export const API_COPILOT_CHECKPOINT = API_PREFIX + '/copilot-checkpoint'

apps/cloud/src/app/@core/copilot/checkpoint-saver.ts

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,85 @@
1-
import { Injectable, Provider } from '@angular/core'
1+
import { HttpClient } from '@angular/common/http'
2+
import { inject, Injectable, Provider } from '@angular/core'
23
import { RunnableConfig } from '@langchain/core/runnables'
34
import { Checkpoint, CheckpointMetadata, CheckpointTuple } from '@langchain/langgraph/dist/checkpoint/base'
4-
import { BaseCheckpointSaver, MemorySaver } from '@langchain/langgraph/web'
5+
import { BaseCheckpointSaver } from '@langchain/langgraph/web'
6+
import { ICopilotCheckpoint } from '@metad/contracts'
7+
import { firstValueFrom, map } from 'rxjs'
8+
import { API_COPILOT_CHECKPOINT } from '../constants/app.constants'
59

610
@Injectable({
711
providedIn: 'root'
812
})
9-
export class CopilotCheckpointSaver extends MemorySaver { // extends BaseCheckpointSaver {
13+
export class CopilotCheckpointSaver extends BaseCheckpointSaver {
14+
readonly #httpClient = inject(HttpClient)
15+
1016
constructor() {
1117
super()
1218
}
1319

14-
// async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {
15-
// console.log(`get tuple:`, config.configurable)
16-
// return null
17-
// }
20+
async getTuple(config: RunnableConfig): Promise<CheckpointTuple | undefined> {
21+
const { thread_id, checkpoint_id } = config.configurable || {}
22+
const row = await firstValueFrom(
23+
this.#httpClient
24+
.get<{ items: ICopilotCheckpoint[] }>(API_COPILOT_CHECKPOINT, {
25+
params: {
26+
$filter: JSON.stringify({
27+
thread_id,
28+
checkpoint_id
29+
}),
30+
$order: JSON.stringify({
31+
checkpoint_id: 'DESC'
32+
})
33+
}
34+
})
35+
.pipe(map((res) => res.items[0]))
36+
)
37+
38+
if (row) {
39+
return {
40+
config: {
41+
configurable: {
42+
thread_id: row.thread_id,
43+
checkpoint_id: row.checkpoint_id
44+
}
45+
},
46+
checkpoint: (await this.serde.parse(row.checkpoint)) as Checkpoint,
47+
metadata: (await this.serde.parse(row.metadata)) as CheckpointMetadata,
48+
parentConfig: row.parent_id
49+
? {
50+
configurable: {
51+
thread_id: row.thread_id,
52+
checkpoint_id: row.parent_id
53+
}
54+
}
55+
: undefined
56+
}
57+
}
58+
return undefined
59+
}
60+
61+
async *list(config: RunnableConfig, limit?: number, before?: RunnableConfig): AsyncGenerator<CheckpointTuple> {
62+
console.log(`list checkpoints:`, config, limit, before)
63+
}
1864

19-
// async *list(config: RunnableConfig, limit?: number, before?: RunnableConfig): AsyncGenerator<CheckpointTuple> {
20-
// console.log(`list checkpoints:`, config, limit, before)
21-
// }
65+
async put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig> {
66+
await firstValueFrom(
67+
this.#httpClient.post(API_COPILOT_CHECKPOINT, {
68+
thread_id: config.configurable?.thread_id,
69+
checkpoint_id: checkpoint.id,
70+
parent_id: config.configurable?.checkpoint_id,
71+
checkpoint: this.serde.stringify(checkpoint),
72+
metadata: this.serde.stringify(metadata)
73+
})
74+
)
2275

23-
// async put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata): Promise<RunnableConfig> {
24-
// console.log(`put checkpoint:`, config, checkpoint, metadata)
25-
// return null
26-
// }
76+
return {
77+
configurable: {
78+
thread_id: config.configurable?.thread_id,
79+
checkpoint_id: checkpoint.id
80+
}
81+
}
82+
}
2783
}
2884

2985
export function provideCheckpointSaver(): Provider[] {

apps/cloud/src/app/@core/copilot/example-vector-retriever.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,15 @@ export class ExampleVectorStoreRetriever<V extends VectorStoreInterface = Vector
4444

4545
filter?: V['FilterType']
4646

47-
command: string
47+
command: string | string[]
4848
role: Signal<string>
4949
score?: number
5050
_vectorstoreType(): string {
5151
return this.vectorStore._vectorstoreType()
5252
}
5353

5454
constructor(
55-
fields: VectorStoreRetrieverInput<V> & { command: string; role: Signal<string>; score?: number },
55+
fields: VectorStoreRetrieverInput<V> & { command: string | string[]; role: Signal<string>; score?: number },
5656
private readonly service: CopilotExampleService
5757
) {
5858
super(fields)

apps/cloud/src/app/@core/copilot/references.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { ExampleVectorStoreRetrieverInput, NgmCopilotService } from '@metad/copi
33
import { CopilotExampleService } from '../services/copilot-example.service'
44
import { ExampleVectorStoreRetriever } from './example-vector-retriever'
55

6-
export function injectExampleRetriever(command: string, fields?: ExampleVectorStoreRetrieverInput) {
6+
export function injectExampleRetriever(command: string | string[], fields?: ExampleVectorStoreRetrieverInput) {
77
const copilotService = inject(NgmCopilotService)
88
const copilotExampleService = inject(CopilotExampleService)
99

apps/cloud/src/app/@core/services/chatbi-conversation.service.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import { HttpClient } from '@angular/common/http'
22
import { inject, Injectable } from '@angular/core'
3-
import { API_PREFIX, SystemPrivacyFields } from '@metad/cloud/state'
3+
import { API_PREFIX, OrganizationBaseService, SystemPrivacyFields } from '@metad/cloud/state'
44
import { CopilotChatMessage } from '@metad/copilot'
55
import { Indicator } from '@metad/ocap-core'
66
import { omit } from 'lodash-es'
77
import { NGXLogger } from 'ngx-logger'
8-
import { BehaviorSubject, map } from 'rxjs'
9-
import { IChatBIConversation } from '../types'
8+
import { BehaviorSubject, map, switchMap } from 'rxjs'
9+
import { IChatBIConversation, OrderTypeEnum } from '../types'
1010

1111
const API_CHATBI_CONVERSATION = API_PREFIX + '/chatbi-conversation'
1212

13-
export interface ChatbiConverstion {
13+
export interface ChatbiConverstion<T = any> {
1414
id?: string
1515
key: string
1616
name: string
@@ -20,19 +20,31 @@ export interface ChatbiConverstion {
2020
command: string
2121
messages: CopilotChatMessage[]
2222
indicators: Indicator[]
23+
answer: T
2324
}
2425

2526
@Injectable({ providedIn: 'root' })
26-
export class ChatBIConversationService {
27+
export class ChatBIConversationService extends OrganizationBaseService {
2728
readonly #logger = inject(NGXLogger)
2829
readonly httpClient = inject(HttpClient)
2930

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

3233
getMy() {
33-
return this.httpClient
34-
.get<{ items: IChatBIConversation[] }>(API_CHATBI_CONVERSATION + '/my')
35-
.pipe(map(({ items }) => items.map(convertChatBIConversationResult)))
34+
return this.selectOrganizationId().pipe(
35+
switchMap(() =>
36+
this.httpClient.get<{ items: IChatBIConversation[] }>(API_CHATBI_CONVERSATION + '/my', {
37+
params: {
38+
data: JSON.stringify({
39+
order: {
40+
createdAt: OrderTypeEnum.DESC
41+
}
42+
})
43+
}
44+
})
45+
),
46+
map(({ items }) => items.map(convertChatBIConversationResult))
47+
)
3648
}
3749

3850
getById(id: string) {
@@ -62,10 +74,11 @@ export class ChatBIConversationService {
6274

6375
export function convertChatBIConversation(input: Partial<ChatbiConverstion>) {
6476
return {
65-
...omit(input, 'messages', 'indicators'),
77+
...omit(input, 'messages', 'indicators', 'answer'),
6678
options: {
6779
messages: input.messages,
6880
indicators: input.indicators,
81+
answer: input.answer
6982
}
7083
} as IChatBIConversation
7184
}
@@ -74,6 +87,7 @@ export function convertChatBIConversationResult(result: IChatBIConversation) {
7487
return {
7588
...omit(result, 'options', ...SystemPrivacyFields),
7689
messages: result.options?.messages || [],
77-
indicators: result.options?.indicators
90+
indicators: result.options?.indicators,
91+
answer: result.options?.answer
7892
} as ChatbiConverstion
7993
}

apps/cloud/src/app/@core/services/copilot-example.service.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { DocumentInterface } from '@langchain/core/documents'
44
import { MaxMarginalRelevanceSearchOptions, VectorStoreInterface } from '@langchain/core/vectorstores'
55
import { NGXLogger } from 'ngx-logger'
66
import { map, tap } from 'rxjs'
7-
import { API_COPILOT_EXAMPLE } from '../constants/app.constants'
8-
import { ICopilotExample, ICopilotRole } from '../types'
7+
import { API_COPILOT_KNOWLEDGE } from '../constants/app.constants'
8+
import { ICopilotKnowledge, ICopilotRole } from '../types'
99
import { CopilotRoleService } from './copilot-role.service'
1010

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

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

2424
maxMarginalRelevanceSearch(
2525
query: string,
2626
options: MaxMarginalRelevanceSearchOptions<VectorStoreInterface['FilterType']> & {
27-
command: string
27+
command: string | string[]
2828
role: string
2929
}
3030
) {
31-
return this.httpClient.post<DocumentInterface[]>(`${API_COPILOT_EXAMPLE}/mmr-search`, { query, options })
31+
return this.httpClient.post<DocumentInterface[]>(`${API_COPILOT_KNOWLEDGE}/mmr-search`, { query, options })
3232
}
3333

3434
getAll(options?: { relations: string[]; filter?: Record<string, any> }) {
3535
const { relations, filter } = options || {}
3636
return this.httpClient
37-
.get<{ items: ICopilotExample[] }>(`${API_COPILOT_EXAMPLE}`, {
37+
.get<{ items: ICopilotKnowledge[] }>(`${API_COPILOT_KNOWLEDGE}`, {
3838
params: {
39-
$fitler: JSON.stringify(filter),
39+
$filter: JSON.stringify(filter),
4040
$relations: JSON.stringify(relations)
4141
}
4242
})
4343
.pipe(map(({ items }) => items))
4444
}
4545

4646
getById(id: string) {
47-
return this.httpClient.get<ICopilotExample>(`${API_COPILOT_EXAMPLE}/${id}`)
47+
return this.httpClient.get<ICopilotKnowledge>(`${API_COPILOT_KNOWLEDGE}/${id}`)
4848
}
4949

50-
create(entity: Partial<ICopilotExample>) {
51-
return this.httpClient.post<ICopilotExample>(`${API_COPILOT_EXAMPLE}`, entity)
50+
create(entity: Partial<ICopilotKnowledge>) {
51+
return this.httpClient.post<ICopilotKnowledge>(`${API_COPILOT_KNOWLEDGE}`, entity)
5252
}
5353

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

5858
delete(id: string) {
59-
return this.httpClient.delete(`${API_COPILOT_EXAMPLE}/${id}`)
59+
return this.httpClient.delete(`${API_COPILOT_KNOWLEDGE}/${id}`)
6060
}
6161

6262
getCommands(filter: { role: string }) {
6363
return this.httpClient
64-
.get<ICopilotExample[]>(`${API_COPILOT_EXAMPLE}/commands`, {
64+
.get<ICopilotKnowledge[]>(`${API_COPILOT_KNOWLEDGE}/commands`, {
6565
params: {
66-
$fitler: JSON.stringify(filter)
66+
$filter: JSON.stringify(filter)
6767
}
6868
})
6969
.pipe(map((items) => items.map(({ command }) => command)))
7070
}
7171

72-
createBulk(entities: ICopilotExample[], roles: ICopilotRole[], options: { clearRole: boolean }) {
72+
createBulk(entities: ICopilotKnowledge[], roles: ICopilotRole[], options: { clearRole: boolean }) {
7373
return this.httpClient
74-
.post<ICopilotExample[]>(`${API_COPILOT_EXAMPLE}/bulk`, {
74+
.post<ICopilotKnowledge[]>(`${API_COPILOT_KNOWLEDGE}/bulk`, {
7575
examples: entities,
7676
roles,
7777
options
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { HttpClient } from '@angular/common/http'
2+
import { inject, Injectable } from '@angular/core'
3+
import { ICopilotOrganization, ICopilotUser } from '@metad/contracts'
4+
import { NGXLogger } from 'ngx-logger'
5+
import { map } from 'rxjs'
6+
import { API_COPILOT_ORGANIZATION, API_COPILOT_USER } from '../constants/app.constants'
7+
8+
@Injectable({ providedIn: 'root' })
9+
export class CopilotUsageService {
10+
readonly #logger = inject(NGXLogger)
11+
readonly httpClient = inject(HttpClient)
12+
13+
getOrgUsages() {
14+
return this.httpClient
15+
.get<{ items: ICopilotOrganization[] }>(API_COPILOT_ORGANIZATION, {
16+
params: {
17+
$relations: JSON.stringify(['org'])
18+
}
19+
})
20+
.pipe(map(({ items }) => items))
21+
}
22+
23+
getUserUsages() {
24+
return this.httpClient
25+
.get<{ items: ICopilotUser[] }>(API_COPILOT_USER, {
26+
params: {
27+
$relations: JSON.stringify(['user', 'org'])
28+
}
29+
})
30+
.pipe(map(({ items }) => items))
31+
}
32+
33+
renewOrgLimit(id: string, tokenLimit: number) {
34+
return this.httpClient.post<ICopilotOrganization>(API_COPILOT_ORGANIZATION + `/${id}/renew`, { tokenLimit })
35+
}
36+
37+
renewUserLimit(id: string, tokenLimit: number) {
38+
return this.httpClient.post<ICopilotUser>(API_COPILOT_USER + `/${id}/renew`, { tokenLimit })
39+
}
40+
}

0 commit comments

Comments
 (0)