Skip to content

Commit

Permalink
feat: implemented SendMessageToConversation backend primary side
Browse files Browse the repository at this point in the history
  • Loading branch information
alebg committed Sep 19, 2024
1 parent fc04e31 commit 45c40fa
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 216 deletions.
14 changes: 1 addition & 13 deletions src/lib/core/entity/kernel-models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,11 @@ export const ConversationSchema = z.object({
export type TConversation = z.infer<typeof ConversationSchema>;


export const BaseMessageSchema = z.object({
export const MessageSchema = z.object({
id: z.number(),
content: z.string(),
timestamp: z.string(),
sender: z.string(),
});

export const UserMessageSchema = z.object({
senderType: z.literal("user"),
});

export const AgentMessageSchema = z.object({
senderType: z.literal("agent"),
});

export const MessageSchema = z.discriminatedUnion("senderType", [
UserMessageSchema,
AgentMessageSchema
]);
export type TMessage = z.infer<typeof MessageSchema>;
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { type TSendMessageToConversationErrorResponse, type TSendMessageToConversationProgressResponse, type TSendMessageToConversationRequest, type TSendMessageToConversationSuccessResponse } from "../../usecase-models/send-message-to-conversation-usecase-models";
/* eslint-disable @typescript-eslint/no-explicit-any */
import { type Signal } from "../../entity/signals";
import {
type TSendMessageToConversationErrorResponse,
type TSendMessageToConversationProgressResponse,
type TSendMessageToConversationRequest,
type TSendMessageToConversationSuccessResponse,
} from "../../usecase-models/send-message-to-conversation-usecase-models";
import { type TSendMessageToConversationViewModel } from "../../view-models/send-message-to-conversation-view-model";

export interface SendMessageToConversationInputPort {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
presenter: SendMessageToConversationOutputPort<any>;
execute(request: TSendMessageToConversationRequest): Promise<void>;
execute(request: TSendMessageToConversationRequest): Promise<void>;
}

export interface SendMessageToConversationOutputPort<TResponse> {
response: TResponse;
presentProgress(progress: TSendMessageToConversationProgressResponse): void;
presentSuccess(success: TSendMessageToConversationSuccessResponse): void;
presentError(error: TSendMessageToConversationErrorResponse): void;
}
export interface SendMessageToConversationOutputPort {
response: Signal<TSendMessageToConversationViewModel>;
presentProgress(usecaseProgressResponse: TSendMessageToConversationProgressResponse): Promise<void>;
presentSuccess(usecaseSuccessResponse: TSendMessageToConversationSuccessResponse): Promise<void>;
presentError(usecaseErrorResponse: TSendMessageToConversationErrorResponse): Promise<void>;
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,38 @@
import { z } from 'zod'
import { MessageSchema } from '../entity/kernel-models'
import { z } from "zod";
import { MessageSchema } from "../entity/kernel-models";

export const SendMessageToConversationRequestSchema = z.object({
researchContextID: z.string(),
conversationID: z.string(),
message: MessageSchema,
})
status: z.literal("request"),
researchContextID: z.string(),
conversationID: z.string(),
messageToSendContent: z.string(),
messageToSendTimestamp: z.string(),
});

export type TSendMessageToConversationRequest = z.infer<typeof SendMessageToConversationRequestSchema>
export type TSendMessageToConversationRequest = z.infer<typeof SendMessageToConversationRequestSchema>;

export const SendMessageToConversationSuccessResponseSchema = z.object({
message: MessageSchema,
response: MessageSchema,
})
export type TSendMessageToConversationSuccessResponse = z.infer<typeof SendMessageToConversationSuccessResponseSchema>
status: z.literal("success"),
message: MessageSchema,
response: MessageSchema,
});
export type TSendMessageToConversationSuccessResponse = z.infer<typeof SendMessageToConversationSuccessResponseSchema>;

export const SendMessageToConversationErrorResponseSchema = z.object({
operation: z.string(),
message: z.string(),
context: z.any(),
})
export type TSendMessageToConversationErrorResponse = z.infer<typeof SendMessageToConversationErrorResponseSchema>
status: z.literal("error"),
operation: z.string(),
message: z.string(),
context: z.any().optional(),
});
export type TSendMessageToConversationErrorResponse = z.infer<typeof SendMessageToConversationErrorResponseSchema>;

export const SendMessageToConversationProgressResponseSchema = z.object({
message: MessageSchema,
progress: z.string(),
context: z.any(),
})
export type TSendMessageToConversationProgressResponse = z.infer<typeof SendMessageToConversationProgressResponseSchema>
status: z.literal("progress"),
message: MessageSchema,
progress: z.string(),
context: z.any().optional(),
});
export type TSendMessageToConversationProgressResponse = z.infer<typeof SendMessageToConversationProgressResponseSchema>;

export const SendMessageToConversationResponseSchema = z.discriminatedUnion("status", [SendMessageToConversationSuccessResponseSchema, SendMessageToConversationErrorResponseSchema, SendMessageToConversationProgressResponseSchema]);
export type TSendMessageToConversationResponse = z.infer<typeof SendMessageToConversationResponseSchema>;
164 changes: 92 additions & 72 deletions src/lib/core/usecase/send-message-to-conversation-usecase.ts
Original file line number Diff line number Diff line change
@@ -1,88 +1,108 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
import { type TMessage } from "../entity/kernel-models";
import { type SendMessageToConversationInputPort, type SendMessageToConversationOutputPort } from "../ports/primary/send-message-to-conversation-primary-ports";
import type AgentGatewayOutputPort from "../ports/secondary/agent-gateway-output-port";
import type ConversationGatewayOutputPort from "../ports/secondary/conversation-gateway-output-port";
import { type TSendMessageToConversationRequest } from "../usecase-models/send-message-to-conversation-usecase-models";

export default class BrowserSendMessageToConversationUseCase implements SendMessageToConversationInputPort {
presenter: SendMessageToConversationOutputPort<any>;
agentGateway: AgentGatewayOutputPort<any>;
conversationGateway: ConversationGatewayOutputPort;
constructor(presenter: SendMessageToConversationOutputPort<any>, agentGateway: AgentGatewayOutputPort<any>, conversationGateway: ConversationGatewayOutputPort) {
this.presenter = presenter;
this.agentGateway = agentGateway
this.conversationGateway = conversationGateway;
presenter: SendMessageToConversationOutputPort;
agentGateway: AgentGatewayOutputPort<any>;
conversationGateway: ConversationGatewayOutputPort;
constructor(presenter: SendMessageToConversationOutputPort, agentGateway: AgentGatewayOutputPort<any>, conversationGateway: ConversationGatewayOutputPort) {
this.presenter = presenter;
this.agentGateway = agentGateway;
this.conversationGateway = conversationGateway;
}

async execute(request: TSendMessageToConversationRequest): Promise<void> {

const messageToSend: TMessage = {
id: -1, // this should be assigned by KP at some point
content: request.messageToSendContent,
sender: "User", // this should be obtained from the auth gateway at some point
timestamp: request.messageToSendTimestamp,
}

async execute(request: TSendMessageToConversationRequest): Promise<void> {
// TODO: check if conversation exists
// send incoming message to the conversation
const registerIncomingMessageDTO = await this.conversationGateway.sendMessageToConversation(request.conversationID, request.message)
const dummyResponse: TMessage = {
id: -1,
content: "Dummy response",
sender: "Dummy",
timestamp: new Date().toDateString(),
};

if (!registerIncomingMessageDTO.success) {
this.presenter.presentError(
{
operation: "usecase#send-message-to-conversation",
message: "",
context: {}
}
)
return;
}
await this.presenter.presentSuccess({
status: "success",
message: messageToSend,
response: dummyResponse,
});

const prepareMessageDTO = await this.agentGateway.prepareMessageContext(request.researchContextID, request.conversationID, request.message)
if (!prepareMessageDTO.success) {
this.presenter.presentError(
{
operation: "usecase#send-message-to-conversation",
message: "",
context: {}
}
)
return;
}
// TODO: finish secondary side, then come back here
//// TODO: check if conversation exists
//// send incoming message to the conversation
//const registerIncomingMessageDTO = await this.conversationGateway.sendMessageToConversation(request.conversationID, request.message);

this.presenter.presentProgress({
message: request.message,
progress: "Sending message to agent",
context: prepareMessageDTO
})
//if (!registerIncomingMessageDTO.success) {
//this.presenter.presentError({
//status: "error",
//operation: "usecase#send-message-to-conversation",
//message: "",
//context: {},
//});
//return;
//}

const sendMessageToAgentDTO = await this.agentGateway.sendMessage(prepareMessageDTO.data, request.message)
if (!sendMessageToAgentDTO.success) {
this.presenter.presentError(
{
operation: "usecase#send-message-to-conversation",
message: "",
context: {}
}
)
return;
}
//const prepareMessageDTO = await this.agentGateway.prepareMessageContext(request.researchContextID, request.conversationID, request.message);
//if (!prepareMessageDTO.success) {
//this.presenter.presentError({
//status: "error",
//operation: "usecase#send-message-to-conversation",
//message: "",
//context: {},
//});
//return;
//}

this.presenter.presentProgress({
message: request.message,
progress: "Agent replied to the message",
context: sendMessageToAgentDTO
})
//this.presenter.presentProgress({
//status: "progress",
//message: request.message,
//progress: "Sending message to agent",
//context: prepareMessageDTO,
//});

const registerOutgoingMessageDTO = await this.conversationGateway.sendMessageToConversation(request.conversationID, sendMessageToAgentDTO.data)
if (!registerOutgoingMessageDTO.success) {
this.presenter.presentError(
{
operation: "usecase#send-message-to-conversation",
message: "",
context: {}
}
)
return;
}
//const sendMessageToAgentDTO = await this.agentGateway.sendMessage(prepareMessageDTO.data, request.message);
//if (!sendMessageToAgentDTO.success) {
//this.presenter.presentError({
//status: "error",
//operation: "usecase#send-message-to-conversation",
//message: "",
//context: {},
//});
//return;
//}

this.presenter.presentSuccess({
message: request.message,
response: sendMessageToAgentDTO.data
})
}
}
//this.presenter.presentProgress({
//status: "progress",
//message: request.message,
//progress: "Agent replied to the message",
//context: sendMessageToAgentDTO,
//});

//const registerOutgoingMessageDTO = await this.conversationGateway.sendMessageToConversation(request.conversationID, sendMessageToAgentDTO.data);
//if (!registerOutgoingMessageDTO.success) {
//this.presenter.presentError({
//status: "error",
//operation: "usecase#send-message-to-conversation",
//message: "",
//context: {},
//});
//return;
//}

//this.presenter.presentSuccess({
//status: "success",
//message: request.message,
//response: sendMessageToAgentDTO.data,
//});
}
}
63 changes: 30 additions & 33 deletions src/lib/core/view-models/send-message-to-conversation-view-model.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,39 @@
import { z } from 'zod'
import { MessageSchema } from '../entity/kernel-models'
import { z } from "zod";
import { MessageSchema } from "../entity/kernel-models";

export const SendMessageToConversationRequestViewModelSchema = z.object({
status: z.enum(['request']),
conversationId: z.string(),
message: z.string(),
})
status: z.enum(["request"]),
conversationID: z.string(),
message: z.string(),
});

export type TSendMessageToConversationRequestViewModel = z.infer<typeof SendMessageToConversationRequestViewModelSchema>
export type TSendMessageToConversationRequestViewModel = z.infer<typeof SendMessageToConversationRequestViewModelSchema>;

export const SendMessageToConversationSuccessViewModelSchema = z.object({
status: z.enum(['success']),
message: MessageSchema,
response: MessageSchema,
})
export type TSendMessageToConversationSuccessViewModel = z.infer<typeof SendMessageToConversationSuccessViewModelSchema>
status: z.enum(["success"]),
message: MessageSchema,
response: MessageSchema,
});
export type TSendMessageToConversationSuccessViewModel = z.infer<typeof SendMessageToConversationSuccessViewModelSchema>;

export const SendMessageToConversationErrorViewModelSchema = z.object({
status: z.enum(['error']),
message: z.string(),
context: z.any(),
})
export type TSendMessageToConversationErrorViewModel = z.infer<typeof SendMessageToConversationErrorViewModelSchema>
status: z.enum(["error"]),
message: z.string(),
context: z.any(),
});
export type TSendMessageToConversationErrorViewModel = z.infer<typeof SendMessageToConversationErrorViewModelSchema>;

export const SendMessageToConversationProgressViewModelSchema = z.object({
status: z.enum(['progress']),
message: MessageSchema,
progressReport: z.string(),
})
export type TSendMessageToConversationProgressViewModel = z.infer<typeof SendMessageToConversationProgressViewModelSchema>

export const SendMessageToConversationViewModelSchema = z.discriminatedUnion('status', [
SendMessageToConversationRequestViewModelSchema,
SendMessageToConversationSuccessViewModelSchema,
SendMessageToConversationErrorViewModelSchema,
SendMessageToConversationProgressViewModelSchema,
])
export type TSendMessageToConversationViewModel = z.infer<typeof SendMessageToConversationViewModelSchema>



status: z.enum(["progress"]),
message: MessageSchema,
progressReport: z.string(),
});
export type TSendMessageToConversationProgressViewModel = z.infer<typeof SendMessageToConversationProgressViewModelSchema>;

export const SendMessageToConversationViewModelSchema = z.discriminatedUnion("status", [
SendMessageToConversationRequestViewModelSchema,
SendMessageToConversationSuccessViewModelSchema,
SendMessageToConversationErrorViewModelSchema,
SendMessageToConversationProgressViewModelSchema,
]);
export type TSendMessageToConversationViewModel = z.infer<typeof SendMessageToConversationViewModelSchema>;
Loading

0 comments on commit 45c40fa

Please sign in to comment.