|
|
@@ -6,6 +6,7 @@ import { StateGraph, START, END, Annotation } from "@langchain/langgraph";
|
|
|
import { BaseMessage, HumanMessage, AIMessage } from "@langchain/core/messages";
|
|
|
import { forwardRef, Inject } from '@nestjs/common';
|
|
|
import { FFBGateway } from '../ffb.gateway';
|
|
|
+import { ThoughtPayload } from '../ffb-production.schema';
|
|
|
// State Definition using Annotation
|
|
|
const AgentState = Annotation.Root({
|
|
|
messages: Annotation<BaseMessage[]>({
|
|
|
@@ -102,12 +103,14 @@ export class FFBLangChainService {
|
|
|
reasoning: z.string()
|
|
|
});
|
|
|
|
|
|
- this.gateway.emitThought(state.socketId, {
|
|
|
+ let payload: ThoughtPayload = {
|
|
|
node: 'router_node',
|
|
|
status: 'processing',
|
|
|
message: 'Analyzing user intent...',
|
|
|
input: lastMessage
|
|
|
- });
|
|
|
+ }
|
|
|
+
|
|
|
+ this.gateway.emitThought(state.socketId, payload);
|
|
|
|
|
|
const routerPrompt = `
|
|
|
You are an Application Router for a production database.
|
|
|
@@ -147,12 +150,14 @@ User Input: "${lastMessage}"
|
|
|
private async clarifierNode(state: typeof AgentState.State): Promise<Partial<typeof AgentState.State>> {
|
|
|
const prompt = `User mentioned ${JSON.stringify(state.entityStore)}. Ask them to clarify what they want to know (e.g., total production, specific issues, etc.).`;
|
|
|
|
|
|
- this.gateway.emitThought(state.socketId, {
|
|
|
+ let payload: ThoughtPayload = {
|
|
|
node: 'clarifier_node',
|
|
|
status: 'processing',
|
|
|
message: 'Asking for clarification',
|
|
|
context: state.entityStore
|
|
|
- });
|
|
|
+ }
|
|
|
+
|
|
|
+ this.gateway.emitThought(state.socketId, payload);
|
|
|
|
|
|
const response = await this.model.invoke(prompt);
|
|
|
return {
|
|
|
@@ -180,13 +185,14 @@ User Input: "${lastMessage}"
|
|
|
|
|
|
const results = await this.vectorService.vectorSearch(lastMessage, 5, filter);
|
|
|
|
|
|
- this.gateway.emitThought(state.socketId, {
|
|
|
+ let payload: ThoughtPayload = {
|
|
|
node: 'vector_search_node',
|
|
|
status: 'completed',
|
|
|
query: lastMessage,
|
|
|
filter: filter,
|
|
|
resultsCount: results.length
|
|
|
- });
|
|
|
+ }
|
|
|
+ this.gateway.emitThought(state.socketId, payload);
|
|
|
|
|
|
return {
|
|
|
actionPayload: { type: 'search', query: lastMessage, results }
|
|
|
@@ -239,6 +245,12 @@ User Input: "${lastMessage}"
|
|
|
|
|
|
const results = await this.vectorService.aggregate(pipeline);
|
|
|
|
|
|
+ let payload: ThoughtPayload = {
|
|
|
+ node: `aggregation_node`,
|
|
|
+ status: 'completed',
|
|
|
+ pipeline: pipeline,
|
|
|
+ results: results
|
|
|
+ }
|
|
|
this.gateway.emitThought(state.socketId, {
|
|
|
node: 'aggregation_node',
|
|
|
status: 'completed',
|
|
|
@@ -263,12 +275,13 @@ User Input: "${lastMessage}"
|
|
|
Cite the source (e.g., "Based on aggregation results...").
|
|
|
`;
|
|
|
|
|
|
- this.gateway.emitThought(state.socketId, {
|
|
|
+ let thoughtPayload: ThoughtPayload = {
|
|
|
node: 'synthesis_node',
|
|
|
status: 'processing',
|
|
|
message: 'Synthesizing final response',
|
|
|
dataContextLength: JSON.stringify(payload).length
|
|
|
- });
|
|
|
+ }
|
|
|
+ this.gateway.emitThought(state.socketId, thoughtPayload);
|
|
|
|
|
|
const response = await this.model.invoke(prompt);
|
|
|
return {
|