Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions dotnet/SK-dotnet.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
<Project Path="samples/Demos/OnnxSimpleRAG/OnnxSimpleRAG.csproj" />
<Project Path="samples/Demos/OnnxSimpleChatWithCuda/OnnxSimpleChatWithCuda.csproj" />
<Project Path="samples/Demos/OpenAIRealtime/OpenAIRealtime.csproj" />
<Project Path="samples/Demos/ProcessWithDapr/ProcessWithDapr.csproj" />
<Project Path="samples/Demos/ProcessWithLocalRuntime/ProcessWithLocalRuntime.csproj" />
<Project Path="samples/Demos/QualityCheck/QualityCheckWithFilters/QualityCheckWithFilters.csproj" />
<Project Path="samples/Demos/StepwisePlannerMigration/StepwisePlannerMigration.csproj" />
<Project Path="samples/Demos/StructuredDataPlugin/StructuredDataPlugin.csproj" />
Expand Down Expand Up @@ -81,7 +81,7 @@
</Folder>
<Folder Name="/samples/Demos/ProcessWithCloudEvents/">
<File Path="samples/Demos/ProcessWithCloudEvents/README.md" />
<Project Path="samples/Demos/ProcessWithCloudEvents/ProcessWithCloudEvents.Grpc/ProcessWithCloudEvents.Grpc.csproj" />
<Project Path="samples/Demos/ProcessWithCloudEvents/ProcessWithCloudEvents.Grpc.LocalRuntime/ProcessWithCloudEvents.Grpc.LocalRuntime.csproj" />
<Project Path="samples/Demos/ProcessWithCloudEvents/ProcessWithCloudEvents.Processes/ProcessWithCloudEvents.Processes.csproj" />
</Folder>
<Folder Name="/src/">
Expand Down Expand Up @@ -160,14 +160,10 @@
<Folder Name="/src/experimental/process/">
<Project Path="src/Experimental/Process.Abstractions/Process.Abstractions.csproj" />
<Project Path="src/Experimental/Process.Core/Process.Core.csproj" />
<Project Path="src/Experimental/Process.IntegrationTestHost.Dapr/Process.IntegrationTestHost.Dapr.csproj" />
<Project Path="src/Experimental/Process.IntegrationTestRunner.Dapr/Process.IntegrationTestRunner.Dapr.csproj" />
<Project Path="src/Experimental/Process.IntegrationTestRunner.Local/Process.IntegrationTestRunner.Local.csproj" />
<Project Path="src/Experimental/Process.IntegrationTests.Resources/Process.IntegrationTests.Resources.csproj" />
<Project Path="src/Experimental/Process.IntegrationTests.Shared/Process.IntegrationTests.Shared.csproj" />
<Project Path="src/Experimental/Process.LocalRuntime/Process.LocalRuntime.csproj" />
<Project Path="src/Experimental/Process.Runtime.Dapr.UnitTests/Process.Runtime.Dapr.UnitTests.csproj" />
<Project Path="src/Experimental/Process.Runtime.Dapr/Process.Runtime.Dapr.csproj" />
<Project Path="src/Experimental/Process.UnitTests/Process.UnitTests.csproj" />
<Project Path="src/Experimental/Process.Utilities.UnitTests/Process.Utilities.UnitTests.csproj" />
</Folder>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@

processBuilder
.OnInputEvent(ProcessEvents.TranslateDocument)
.SendEventTo(new(translateDocumentStep, TranslateStep.ProcessFunctions.Translate, parameterName: "textToTranslate"));
.SendEventTo(new(translateDocumentStep, TranslateStep.ProcessFunctions.Translate));

translateDocumentStep
.OnEvent(ProcessEvents.DocumentTranslated)
.SendEventTo(new ProcessFunctionTargetBuilder(summarizeDocumentStep, SummarizeStep.ProcessFunctions.Summarize, parameterName: "textToSummarize"));
.SendEventTo(new ProcessFunctionTargetBuilder(summarizeDocumentStep, SummarizeStep.ProcessFunctions.Summarize));

summarizeDocumentStep
.OnEvent(ProcessEvents.DocumentSummarized)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,24 @@
"type": "npm",
"script": "protoc --ts_out .\\src\\services\\grpc\\gen --ts_opt generate_dependencies --proto_path .\\src\\services\\grpc\\proto .\\src\\services\\grpc\\proto\\documentGeneration.proto",
"problemMatcher": [],
"label": "protobuf: generate document generation proto files",
"label": "protobuf: generate 'document generation' proto files",
"detail": "Generate necessary proto files for document generation"
},
{
"type": "npm",
"script": "protoc --ts_out .\\src\\services\\grpc\\gen --ts_opt generate_dependencies --proto_path .\\src\\services\\grpc\\proto .\\src\\services\\grpc\\proto\\teacherStudentInteraction.proto",
"problemMatcher": [],
"label": "protobuf: generate 'teacher student interaction' proto files",
"detail": "Generate necessary proto files for teacher student interaction"
},
{
"label": "protobuf: generate all proto files",
"type": "shell",
"dependsOn": [
"protobuf: generate 'document generation' proto files",
"protobuf: generate 'teacher student interaction' proto files"
],
"problemMatcher": []
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ import GenerateDocsChat, {
NewDocument,
} from "./components/GenerateDocumentsChat";
import { ExitIcon } from "./components/Icons";
import TeacherStudentInteractionChat, {
StudentTeacherEntry,
TeacherStudentInteractionUser,
} from "./components/TeacherStudentInteractionChat";
import { grpcTeacherStudentService } from "./services/grpc/grpcClients";
import { User } from "./services/grpc/gen/teacherStudentInteraction";

interface AppProps {
grpcDocClient?: GrpcDocumentationGenerationClient;
Expand Down Expand Up @@ -77,12 +83,16 @@ const App: React.FC<AppProps> = ({ grpcDocClient }) => {
const [selectedAppPage, setSelectedAppPage] = useState<AppPages>(
AppPages.DocumentGeneration
);
// generated documents related
const [generatedDocuments, setGeneratedDocuments] = useState<NewDocument[]>(
[]
);
const [publishedDocuments, setPublishedDocuments] = useState<NewDocument[]>(
[]
);
// teacher student interaction related
const [studentAgentInteractionMessages, setStudentAgentInteractionMessages] =
useState<StudentTeacherEntry[]>([]);

const [hasGrpcError, setHasGrpcError] = useState(false);

Expand Down Expand Up @@ -196,7 +206,9 @@ const App: React.FC<AppProps> = ({ grpcDocClient }) => {
}
};

const subscribeToSpecificProcessId = async (processId: string) => {
const subscribeToSpecificProcessIdForDocumentGeneration = async (
processId: string
) => {
subscribeReceiveDocumentForReview(processId);
subscribeToReceivePublishedDocument(processId);
return Promise.all([
Expand All @@ -207,6 +219,109 @@ const App: React.FC<AppProps> = ({ grpcDocClient }) => {
});
};

// teacher student interaction related

const onUserStartedTeacherInteractionProcess = (
processId: string
): Promise<boolean> => {
if (selectedCloudTech == CloudTechnology.GRPC) {
if (grpcTeacherStudentService) {
return grpcTeacherStudentService
.startProcess({
processId: processId,
})
.then(() => {
console.log(
"[GRPC] User student interaction process started"
);
setHasGrpcError(false);
return true;
})
.catch((error) => {
console.error(
"[GRPC] Error starting student interaction process",
error
);
setHasGrpcError(true);
return false;
});
}
}
return new Promise((resolve) => resolve(false));
};

const onSendTeacherQuestion = (
teacherInteraction: StudentTeacherEntry
): Promise<boolean> => {
if (selectedCloudTech == CloudTechnology.GRPC) {
if (grpcTeacherStudentService) {
return grpcTeacherStudentService
.requestStudentAgentResponse({
processId: teacherInteraction.processId,
content: teacherInteraction.content!,
user: User.TEACHER,
})
.then(() => {
console.log(
"[GRPC] User teacher question sent to student agent"
);
setHasGrpcError(false);
return true;
})
.catch((error) => {
console.error(
"[GRPC] Error sending teacher question to student agent",
error
);
setHasGrpcError(true);
return false;
});
}
}
return new Promise((resolve) => resolve(false));
};

const subscribeToStudentAgentResponses = async (processId: string) => {
if (selectedCloudTech == CloudTechnology.GRPC) {
if (grpcTeacherStudentService) {
// grpc stream for receiving published document
const studentResponseStream =
grpcTeacherStudentService.receiveStudentAgentResponse({
processId: processId,
});
for await (const message of studentResponseStream.responses) {
setStudentAgentInteractionMessages((prevMessages) => [
...prevMessages,
{
processId: message.processId,
content: message.content,
user: TeacherStudentInteractionUser.STUDENT,
},
]);
console.log(
"[GRPC] Student interaction received: ",
message
);
}
}
}
};

const subscribeToSpecificProcessIdForTeacherStudentInteraction = async (
processId: string
) => {
subscribeReceiveDocumentForReview(processId);
subscribeToReceivePublishedDocument(processId);
return Promise.all([subscribeToStudentAgentResponses(processId)]).then(
() => {
return;
}
);
};

const getCloudTechnologyName = () =>
CloudTechnologiesDetails.get(selectedCloudTech)!.name;

return (
<div className={styles.root}>
<div className={styles.innerContainer}>
Expand Down Expand Up @@ -285,19 +400,31 @@ const App: React.FC<AppProps> = ({ grpcDocClient }) => {
)}
{selectedAppPage == AppPages.DocumentGeneration && (
<GenerateDocsChat
cloudTechnologyName={
CloudTechnologiesDetails.get(selectedCloudTech)!
.name
}
cloudTechnologyName={getCloudTechnologyName()}
onCreateNewDocument={onCreateDocumentRequest}
onUserReviewedDocument={onUserReviewedDocument}
subscribeToSpecificProcessId={
subscribeToSpecificProcessId
subscribeToSpecificProcessIdForDocumentGeneration
}
generatedDocuments={generatedDocuments}
publishedDocuments={publishedDocuments}
/>
)}
{selectedAppPage == AppPages.TeacherStudentInteraction && (
<TeacherStudentInteractionChat
cloudTechnologyName={getCloudTechnologyName()}
newStudentAgentResponses={
studentAgentInteractionMessages
}
onStartNewProcess={
onUserStartedTeacherInteractionProcess
}
onSendTeacherQuestion={onSendTeacherQuestion}
subscribeToSpecificProcessId={
subscribeToSpecificProcessIdForTeacherStudentInteraction
}
/>
)}
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
// Additionally update the AppPagesDetails map to include the new process sample and its details.
export enum AppPages {
DocumentGeneration = "DocumentGeneration",
TeacherStudentInteraction = "TeacherStudentInteraction",
}

interface EnumDetails {
Expand All @@ -23,6 +24,14 @@ export const AppPagesDetails = new Map<AppPages, EnumDetails>([
"Demo used to show case document generation using different cloud technologies with SK Processes",
},
],
[
AppPages.TeacherStudentInteraction,
{
name: "Teacher Student Interaction",
description:
"Demo used to show case teacher student interaction using different cloud technologies and declarative agents with SK Processes",
}
]
]);

// When more cloud technologies are added, add them to this enum and the CloudTechnologiesDetails map below.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2025 Microsoft
* All rights reserved.
*/

import React from "react";
import { Title2, Label, makeStyles } from "@fluentui/react-components"; // Adjust imports based on your UI library

interface ChatHeaderProps {
header: string;
processId?: string;
}

const useStyles = makeStyles({
processIdContainer: {
display: "flex",
flexDirection: "column",
rowGap: "8px",
alignItems: "flex-end",
},
headerContainer: {
display: "flex",
justifyContent: "space-between",
},
});

const ChatHeader: React.FC<ChatHeaderProps> = ({
header,
processId,
}) => {
const styles = useStyles();

return (
<div className={styles.headerContainer}>
<Title2>
{header}
</Title2>
<div className={styles.processIdContainer}>
<Label>ProcessId : </Label>
<Label>{processId ?? "-"}</Label>
</div>
</div>
);
};

export default ChatHeader;
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Markdown from "react-markdown";
import { ChatMessageContent, ChatUser } from "../common/ChatConstants";
import SimpleChat from "./SimpleChat";
import { CheckIcon, RejectIcon } from "./Icons";
import ChatHeader from "./ChatHeader";

export interface NewDocument {
title?: string;
Expand Down Expand Up @@ -51,12 +52,6 @@ const useStyles = makeStyles({
rowGap: "8px",
width: "90%",
},
processIdContainer: {
display: "flex",
flexDirection: "column",
rowGap: "8px",
alignItems: "flex-end",
},
buttonsFamily: {
display: "flex",
columnGap: "40px",
Expand All @@ -69,10 +64,6 @@ const useStyles = makeStyles({
newDocHeaderHeader: {
marginTop: "0",
},
headerContainer: {
display: "flex",
justifyContent: "space-between",
},
});

const GenerateDocsChat: React.FC<GenerateDocsChatProps> = ({
Expand Down Expand Up @@ -264,13 +255,7 @@ const GenerateDocsChat: React.FC<GenerateDocsChatProps> = ({

return (
<div className={styles.root}>
<div className={styles.headerContainer}>
<Title2>Document Generation with {cloudTechnologyName}</Title2>
<div className={styles.processIdContainer}>
<Label>ProcessId : </Label>
<Label>{processId ?? "-"}</Label>
</div>
</div>
<ChatHeader header={`Document Generation with ${cloudTechnologyName}`} processId={processId} />
<SimpleChat messages={messages} />
<div className={styles.buttonsFamily}>
<Popover withArrow>
Expand Down
Loading
Loading