Skip to content

Commit e415624

Browse files
authored
Merge pull request #41 from meta-d/develop
Version 2.5 ChatBI
2 parents 9978a5d + 47d6737 commit e415624

File tree

313 files changed

+13949
-12375
lines changed

Some content is hidden

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

313 files changed

+13949
-12375
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.4.7",
4+
"version": "2.5.0",
55
"scripts": {
66
"start": "nx serve",
77
"build": "nx build",

.deploy/webapp/package.json

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ocap",
3-
"version": "2.4.7",
3+
"version": "2.5",
44
"description": "",
55
"license": "AGPL-3.0",
66
"homepage": "https://mtda.cloud",
@@ -45,10 +45,11 @@
4545
"@casl/angular": "^6.0.0",
4646
"@datorama/akita": "^6.2.3",
4747
"@duckdb/duckdb-wasm": "1.25.0",
48-
"@langchain/community": "0.2.11",
49-
"@langchain/core": "0.2.7",
50-
"@langchain/langgraph": "0.0.26",
51-
"@langchain/openai": "0.1.3",
48+
"@langchain/community": "0.2.20",
49+
"@langchain/core": "0.2.18",
50+
"@langchain/langgraph": "0.0.31",
51+
"@langchain/ollama": "^0.0.2",
52+
"@langchain/openai": "0.2.4",
5253
"@microsoft/fetch-event-source": "^2.0.1",
5354
"@ng-matero/extensions": "^13.1.0",
5455
"@ng-web-apis/common": "^2.0.1",
@@ -71,7 +72,6 @@
7172
"@sentry/tracing": "^7.38.0",
7273
"@swc/helpers": "0.5.3",
7374
"@tinymce/tinymce-angular": "^6.0.1",
74-
"ai": "^2.2.30",
7575
"angular-gridster2": "^14.0.1",
7676
"apache-arrow": "^9.0.0",
7777
"axios": "1.6.8",
@@ -91,7 +91,7 @@
9191
"immer": "^10.0.1",
9292
"js-yaml": "^4.1.0",
9393
"json5": "^2.2.3",
94-
"langchain": "0.2.5",
94+
"langchain": "0.2.10",
9595
"lato-font": "^3.0.0",
9696
"lodash": "^4.17.21",
9797
"lodash-es": "^4.17.21",
@@ -108,6 +108,7 @@
108108
"ngx-quill": "^16.1.2",
109109
"ngxtension": "^3.1.2",
110110
"noto-serif-sc": "^8.0.0",
111+
"ollama": "^0.5.6",
111112
"openai": "^4.6.0",
112113
"prismjs": "^1.29.0",
113114
"quill": "^1.3.7",

apps/cloud/src/app/@core/copilot/agent-route.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
import { BaseMessage, HumanMessage } from '@langchain/core/messages'
1+
import { BaseChatModel } from '@langchain/core/language_models/chat_models'
2+
import { HumanMessage } from '@langchain/core/messages'
23
import { ChatPromptTemplate, MessagesPlaceholder, TemplateFormat } from '@langchain/core/prompts'
4+
import { Runnable, RunnableConfig } from '@langchain/core/runnables'
35
import { StructuredToolInterface } from '@langchain/core/tools'
46
import { PartialValues } from '@langchain/core/utils/types'
5-
import { Runnable, RunnableConfig } from '@langchain/core/runnables'
6-
import { ChatOpenAI } from '@langchain/openai'
7+
import { createCopilotAgentState } from '@metad/copilot'
78
import { AgentState } from '@metad/copilot-angular'
89
import { AgentExecutor, createOpenAIToolsAgent } from 'langchain/agents'
910
import { z } from 'zod'
10-
import { createCopilotAgentState } from '@metad/copilot'
1111

1212
type ZodAny = z.ZodObject<any, any, any, any>
1313

@@ -48,7 +48,7 @@ export function createState() {
4848
* @returns
4949
*/
5050
export async function createWorkerAgent<NewPartialVariableName extends string>(
51-
llm: ChatOpenAI,
51+
llm: BaseChatModel,
5252
tools: StructuredToolInterface<ZodAny>[],
5353
systemPrompt: string,
5454
partialValues?: PartialValues<NewPartialVariableName>,

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

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import {
88
VectorStoreRetrieverInterface,
99
VectorStoreRetrieverMMRSearchKwargs
1010
} from '@langchain/core/vectorstores'
11-
import { CopilotExampleService } from '../services/'
1211
import { catchError, firstValueFrom, of, timeout } from 'rxjs'
1312
import { SERVER_REQUEST_TIMEOUT } from '../config'
13+
import { CopilotExampleService } from '../services/'
1414

1515
/**
1616
* Type for options when adding a document to the VectorStore.
@@ -22,7 +22,7 @@ type AddDocumentOptions = Record<string, any>
2222
* Class for performing document retrieval from a VectorStore. Can perform
2323
* similarity search or maximal marginal relevance search.
2424
*/
25-
export class VectorStoreRetriever<V extends VectorStoreInterface = VectorStoreInterface>
25+
export class ExampleVectorStoreRetriever<V extends VectorStoreInterface = VectorStoreInterface>
2626
extends BaseRetriever
2727
implements VectorStoreRetrieverInterface
2828
{
@@ -78,32 +78,40 @@ export class VectorStoreRetriever<V extends VectorStoreInterface = VectorStoreIn
7878
`The vector store backing this retriever, ${this._vectorstoreType()} does not support max marginal relevance search.`
7979
)
8080
}
81-
return await firstValueFrom(this.service.maxMarginalRelevanceSearch(query, {
82-
k: this.k,
83-
filter: this.filter,
84-
command: this.command,
85-
role: this.role(),
86-
...this.searchKwargs
87-
}).pipe(
88-
timeout(SERVER_REQUEST_TIMEOUT),
89-
catchError((error) => {
90-
return of([])
91-
})
92-
))
81+
return await firstValueFrom(
82+
this.service
83+
.maxMarginalRelevanceSearch(query, {
84+
k: this.k,
85+
filter: this.filter,
86+
command: this.command,
87+
role: this.role(),
88+
...this.searchKwargs
89+
})
90+
.pipe(
91+
timeout(SERVER_REQUEST_TIMEOUT),
92+
catchError((error) => {
93+
return of([])
94+
})
95+
)
96+
)
9397
}
9498

95-
return await firstValueFrom(this.service.similaritySearch(query, {
96-
command: this.command,
97-
k: this.k,
98-
filter: this.filter,
99-
role: this.role(),
100-
score: this.score
101-
}).pipe(
102-
timeout(SERVER_REQUEST_TIMEOUT),
103-
catchError((error) => {
104-
return of([])
105-
})
106-
))
99+
return await firstValueFrom(
100+
this.service
101+
.similaritySearch(query, {
102+
command: this.command,
103+
k: this.k,
104+
filter: this.filter,
105+
role: this.role(),
106+
score: this.score
107+
})
108+
.pipe(
109+
timeout(SERVER_REQUEST_TIMEOUT),
110+
catchError((error) => {
111+
return of([])
112+
})
113+
)
114+
)
107115
}
108116

109117
async addDocuments(documents: DocumentInterface[], options?: AddDocumentOptions): Promise<string[] | void> {

apps/cloud/src/app/@core/copilot/few-shot.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import { inject, Provider } from '@angular/core'
22
import { SemanticSimilarityExampleSelector } from '@langchain/core/example_selectors'
33
import { FewShotPromptTemplate, PromptTemplate } from '@langchain/core/prompts'
4-
import { ExampleVectorStoreRetrieverInput, NgmCommandFewShotPromptToken, NgmCopilotService } from '@metad/copilot-angular'
4+
import {
5+
ExampleVectorStoreRetrieverInput,
6+
NgmCommandFewShotPromptToken,
7+
NgmCopilotService
8+
} from '@metad/copilot-angular'
59
import { CopilotExampleService } from '../services/copilot-example.service'
6-
import { VectorStoreRetriever } from './example-vector-retriever'
10+
import { ExampleVectorStoreRetriever } from './example-vector-retriever'
711

812
export function injectAgentFewShotTemplate(command: string, fields?: ExampleVectorStoreRetrieverInput) {
913
const copilotService = inject(NgmCopilotService)
@@ -19,15 +23,15 @@ function createExampleFewShotPrompt(
1923
fields?: ExampleVectorStoreRetrieverInput
2024
) {
2125
const examplePrompt = PromptTemplate.fromTemplate(
22-
`Question: {{input}}
23-
Answer: {{output}}`,
26+
`Question: {{input}}
27+
Answer: {{output}}`,
2428
{
2529
templateFormat: 'mustache'
2630
}
2731
)
2832
return new FewShotPromptTemplate({
2933
exampleSelector: new SemanticSimilarityExampleSelector({
30-
vectorStoreRetriever: new VectorStoreRetriever(
34+
vectorStoreRetriever: new ExampleVectorStoreRetriever(
3135
{
3236
...(fields ?? { vectorStore: null }),
3337
vectorStore: null,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ export * from './dimension-member-retriever'
22
export * from './example-vector-retriever'
33
export * from './few-shot'
44
export * from './checkpoint-saver'
5+
export * from './references'
56
export * as Route from './agent-route'
67
export * as Plan from './agent-plan'
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { inject } from '@angular/core'
2+
import { ExampleVectorStoreRetrieverInput, NgmCopilotService } from '@metad/copilot-angular'
3+
import { CopilotExampleService } from '../services/copilot-example.service'
4+
import { ExampleVectorStoreRetriever } from './example-vector-retriever'
5+
6+
export function injectExampleRetriever(command: string, fields?: ExampleVectorStoreRetrieverInput) {
7+
const copilotService = inject(NgmCopilotService)
8+
const copilotExampleService = inject(CopilotExampleService)
9+
10+
return new ExampleVectorStoreRetriever(
11+
{
12+
...(fields ?? { vectorStore: null }),
13+
vectorStore: null,
14+
command,
15+
role: copilotService.role
16+
},
17+
copilotExampleService
18+
)
19+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { HttpClient } from '@angular/common/http'
2+
import { inject, Injectable } from '@angular/core'
3+
import { API_PREFIX, SystemPrivacyFields } from '@metad/cloud/state'
4+
import { CopilotChatMessage } from '@metad/copilot'
5+
import { Indicator } from '@metad/ocap-core'
6+
import { omit } from 'lodash-es'
7+
import { NGXLogger } from 'ngx-logger'
8+
import { BehaviorSubject, map } from 'rxjs'
9+
import { IChatBIConversation } from '../types'
10+
11+
const API_CHATBI_CONVERSATION = API_PREFIX + '/chatbi-conversation'
12+
13+
export interface ChatbiConverstion {
14+
id?: string
15+
key: string
16+
name: string
17+
modelId: string
18+
dataSource: string
19+
entity: string
20+
command: string
21+
messages: CopilotChatMessage[]
22+
indicators: Indicator[]
23+
}
24+
25+
@Injectable({ providedIn: 'root' })
26+
export class ChatBIConversationService {
27+
readonly #logger = inject(NGXLogger)
28+
readonly httpClient = inject(HttpClient)
29+
30+
readonly #refresh = new BehaviorSubject<void>(null)
31+
32+
getMy() {
33+
return this.httpClient
34+
.get<{ items: IChatBIConversation[] }>(API_CHATBI_CONVERSATION + '/my')
35+
.pipe(map(({ items }) => items.map(convertChatBIConversationResult)))
36+
}
37+
38+
getById(id: string) {
39+
return this.httpClient
40+
.get<IChatBIConversation>(API_CHATBI_CONVERSATION + '/' + id)
41+
.pipe(map(convertChatBIConversationResult))
42+
}
43+
44+
upsert(entity: Partial<ChatbiConverstion>) {
45+
return entity.id
46+
? this.httpClient
47+
.put<ChatbiConverstion>(`${API_CHATBI_CONVERSATION}/${entity.id}`, convertChatBIConversation(entity))
48+
.pipe(map(() => entity as ChatbiConverstion))
49+
: this.httpClient
50+
.post<ChatbiConverstion>(API_CHATBI_CONVERSATION, convertChatBIConversation(entity))
51+
.pipe(map((result) => convertChatBIConversationResult(result)))
52+
}
53+
54+
delete(id: string) {
55+
return this.httpClient.delete(`${API_CHATBI_CONVERSATION}/${id}`)
56+
}
57+
58+
refresh() {
59+
this.#refresh.next()
60+
}
61+
}
62+
63+
export function convertChatBIConversation(input: Partial<ChatbiConverstion>) {
64+
return {
65+
...omit(input, 'messages', 'indicators'),
66+
options: {
67+
messages: input.messages,
68+
indicators: input.indicators,
69+
}
70+
} as IChatBIConversation
71+
}
72+
73+
export function convertChatBIConversationResult(result: IChatBIConversation) {
74+
return {
75+
...omit(result, 'options', ...SystemPrivacyFields),
76+
messages: result.options?.messages || [],
77+
indicators: result.options?.indicators
78+
} as ChatbiConverstion
79+
}

0 commit comments

Comments
 (0)