Skip to content

Commit

Permalink
New workflow works end-end - pass questions back to LL for enrichment…
Browse files Browse the repository at this point in the history
…, also ask it to generate follow up questions.
  • Loading branch information
Jon committed May 20, 2024
1 parent a61324c commit 0c284c2
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 16 deletions.
75 changes: 60 additions & 15 deletions public/assets/js/aibot.pack.js
Original file line number Diff line number Diff line change
Expand Up @@ -331722,7 +331722,6 @@ const ConversationControllerRow = (props) => {
const [audience, setAudience] = (0, react_1.useState)(new Map());
const [fluidConnection, setFluidConnection] = (0, react_1.useState)(undefined);
const [joining, setJoining] = (0, react_1.useState)(false);
const [sessionKey, setSessionKey] = (0, react_1.useState)(props.sessionKey);
const [conversationKey, setConversationKey] = (0, react_1.useState)(props.conversationKey);
const [isBusy, setIsBusy] = (0, react_1.useState)(false);
const [suggested, setSuggested] = (0, react_1.useState)(undefined);
Expand Down Expand Up @@ -331754,7 +331753,7 @@ const ConversationControllerRow = (props) => {
if (!hasRecentHepfulStart(fluidMessagesConnection_)) {
if (!suggested) {
let embeddingRespository = (0, IEmbeddingRepositoryFactory_1.getEmbeddingRepository)(props.sessionKey);
let suggestion = embeddingRespository.lookForSuggestedContent(undefined, UIStrings_1.EUIStrings.kNewUserNeedInspiration);
let suggestion = embeddingRespository.lookForRelatedContent(undefined, UIStrings_1.EUIStrings.kNewUserNeedInspiration);
suggestion.then((message) => {
if (message)
setSuggested(message);
Expand Down Expand Up @@ -331808,16 +331807,16 @@ const ConversationControllerRow = (props) => {
setJoining(true);
let fluidMessagesConnection = new MessageBotFluidConnection_1.MessageBotFluidConnection({}, props.localPersona);
if (!(props.conversationKey.looksValidConversationKey())) {
fluidMessagesConnection.createNew(sessionKey).then(conversationKey_ => {
fluidMessagesConnection.createNew(props.sessionKey).then(conversationKey_ => {
initialiseConnectionState(fluidMessagesConnection, conversationKey_);
setJoining(false);
}).catch((e) => {
props.onFluidError(e ? e.toString() : "Error creating new conversation, " + sessionKey.toString() + ".");
props.onFluidError("Error creating new conversation, session: " + props.sessionKey.toString() + ".");
setJoining(false);
});
}
else {
fluidMessagesConnection.attachToExisting(sessionKey, conversationKey).then(conversationKey_ => {
fluidMessagesConnection.attachToExisting(props.sessionKey, conversationKey).then(conversationKey_ => {
initialiseConnectionState(fluidMessagesConnection, conversationKey_);
setJoining(false);
}).catch((e) => {
Expand Down Expand Up @@ -331857,18 +331856,36 @@ const ConversationControllerRow = (props) => {
let record = new UrlActivityRecord_1.UrlActivityRecord(keyGenerator.generateKey(), props.conversationKey.toString(), email, new Date(), url_);
repository.save(record);
let embeddingRespository = (0, IEmbeddingRepositoryFactory_1.getEmbeddingRepository)(props.sessionKey);
let suggestion = embeddingRespository.lookForSuggestedContent(url_, UIStrings_1.EUIStrings.kNeedInspirationHereIsAnother);
suggestion.then((message) => {
if (message)
setSuggested(message);
// Get the summary of the URL the user clocked on
let summary = embeddingRespository.lookupUrlSummary(url_);
summary.then((summaryText) => {
let connectionPromise = AIConnection_1.AIConnector.connect(props.sessionKey);
// Connext to the LLM
connectionPromise.then((connection) => {
// Ask the LLM for a question based on the summary
connection.makeFollowUpCall(summaryText).then((result_) => {
if (result_) {
result_.authorId = props.localPersona.id;
setSuggested(result_);
}
});
});
});
}
function onAddSuggestedContent() {
(0, Asserts_1.throwIfUndefined)(fluidConnection);
let fluidMessagesConnection = fluidConnection;
(0, Asserts_1.throwIfUndefined)(suggested);
suggested.sentAt = new Date(); // Need to reset date so it goes at the end.
addMessage(fluidMessagesConnection, suggested);
if (suggested.chunks && suggested.chunks.length > 0) {
// If we have attached chucks, its a full message that we just replay
addMessage(fluidMessagesConnection, suggested);
}
else {
// Else its is text, so we play it as a message that makes a request to the LLM
let fullMessage = ConfigStrings_1.EConfigStrings.kLLMRequestSignature + " " + suggested.text;
onSend(fullMessage);
}
setSuggested(undefined);
}
function onSend(messageText_) {
Expand Down Expand Up @@ -331936,7 +331953,7 @@ const ConversationControllerRow = (props) => {
return (react_1.default.createElement("div", null));
}
else
return (react_1.default.createElement(ConversationRow_1.ConversationRow, { isConnected: sessionKey.looksValidSessionKey() && conversationKey.looksValidConversationKey(), isBusy: isBusy, sessionKey: sessionKey, conversationKey: conversationKey, conversation: conversation, audience: audience, hasSuggestedContent: suggested ? true : false, onSend: onSend, onAddSuggestedContent: onAddSuggestedContent, onTrimConversation: onTrimConversation, onExitConversation: onExitConversation, onClickUrl: onClickUrl }));
return (react_1.default.createElement(ConversationRow_1.ConversationRow, { isConnected: props.sessionKey.looksValidSessionKey() && conversationKey.looksValidConversationKey(), isBusy: isBusy, sessionKey: props.sessionKey, conversationKey: conversationKey, conversation: conversation, audience: audience, hasSuggestedContent: suggested ? true : false, suggestedContent: suggested ? suggested.text : "", onSend: onSend, onAddSuggestedContent: onAddSuggestedContent, onTrimConversation: onTrimConversation, onExitConversation: onExitConversation, onClickUrl: onClickUrl }));
};
exports.ConversationControllerRow = ConversationControllerRow;

Expand Down Expand Up @@ -332113,7 +332130,7 @@ const ConversationRow = (props) => {
"\u00A0",
react_1.default.createElement("div", { className: footerSectionClasses.root },
props.isBusy ? react_1.default.createElement(DefaultSpinner, null) : react_1.default.createElement("div", null),
react_1.default.createElement(exports.InputView, { onSend: onSend, onAddSuggestedContent: props.onAddSuggestedContent, isBusy: props.isBusy, hasSuggestedContent: props.hasSuggestedContent })))));
react_1.default.createElement(exports.InputView, { onSend: onSend, onAddSuggestedContent: props.onAddSuggestedContent, isBusy: props.isBusy, hasSuggestedContent: props.hasSuggestedContent, suggestedContent: props.suggestedContent })))));
}
};
exports.ConversationRow = ConversationRow;
Expand Down Expand Up @@ -332216,7 +332233,7 @@ const KowledgeSegmentsView = (props) => {
event.stopPropagation();
event.preventDefault();
props.onClickUrl(segment.url);
window.open(segment.url, '_blank').focus();
window.open(segment.url, '_blank');
};
relevanceClasses = segment.relevance ? segment.relevance >= 0.8 ? greenClasses : amberClasses : amberClasses;
linkClasses = linkStyles();
Expand Down Expand Up @@ -332352,7 +332369,7 @@ const InputView = (props) => {
react_1.default.createElement(react_components_1.Tooltip, { content: UIStrings_1.EUIStrings.kSendButtonPrompt, relationship: "label", positioning: 'above' },
react_1.default.createElement(react_components_1.Button, { className: buttonClasses.root, disabled: (!canSend) || (props.isBusy), icon: react_1.default.createElement(react_icons_1.Send24Regular, null), onClick: onMessageSend })),
"\u00A0",
react_1.default.createElement(AnimatedIconButton_1.AnimatedIconButton, { animate: props.hasSuggestedContent, icon: AnimatedIconButton_1.EAnimatedIconButtonTypes.kLightBulb, promptAnimated: UIStrings_1.EUIStrings.kAiHasSuggestedDocuments, promptUnamimated: UIStrings_1.EUIStrings.kAiHasNoSuggestedDocuments, onClick: props.onAddSuggestedContent }))))));
react_1.default.createElement(AnimatedIconButton_1.AnimatedIconButton, { animate: props.hasSuggestedContent, icon: AnimatedIconButton_1.EAnimatedIconButtonTypes.kLightBulb, promptAnimated: props.suggestedContent, promptUnamimated: UIStrings_1.EUIStrings.kAiHasNoSuggestedDocuments, onClick: props.onAddSuggestedContent }))))));
};
exports.InputView = InputView;

Expand Down Expand Up @@ -332876,6 +332893,13 @@ class AIConnection {
let keyGenerator = (0, IKeyGeneratorFactory_1.getDefaultKeyGenerator)();
return new Message_1.Message(keyGenerator.generateKey(), ConfigStrings_1.EConfigStrings.kLLMGuid, messageId, directResponse, new Date(), enriched.chunks);
}
// Asks the LLM for a question that relates to the context
async makeFollowUpCall(context) {
let followUpQuery = this.buildFollowUpQuery(context);
const [enrichedResponse] = await Promise.all([this.makeSingleCall(followUpQuery)]);
let keyGenerator = (0, IKeyGeneratorFactory_1.getDefaultKeyGenerator)();
return new Message_1.Message(keyGenerator.generateKey(), ConfigStrings_1.EConfigStrings.kLLMGuid, undefined, enrichedResponse, new Date());
}
// Makes an Axios call to call web endpoint
async createEmbedding(input) {
let self = this;
Expand Down Expand Up @@ -332942,6 +332966,16 @@ class AIConnection {
builtQuery.push(entry);
return builtQuery;
}
buildFollowUpQuery(context) {
let builtQuery = new Array();
let engineeredPrompt = ConfigStrings_1.EConfigStrings.kFollowUpPrompt;
let prompt = { role: 'system', content: engineeredPrompt };
builtQuery.push(prompt);
let engineeredQuestion = ConfigStrings_1.EConfigStrings.kFollowUpPrefix + context;
let entry = { role: 'user', content: engineeredQuestion };
builtQuery.push(entry);
return builtQuery;
}
// Makes an Axios call to call web endpoint
async makeSingleCall(input) {
let self = this;
Expand Down Expand Up @@ -333634,7 +333668,9 @@ var EConfigStrings;
EConfigStrings["kLLMNearRequestSignatureLowerCase"] = "braid";
EConfigStrings["kOpenAiPersonaPrompt"] = "You are an AI assistant helping a team of developers understand AI. You explaining complex concepts in simple language, using Python examples if it helps. You limit replies to 100 words or less. If you don't know the answer to a question, just say 'I don't know'.";
EConfigStrings["kEnrichmentPrompt"] = "You will be provided with a question about building applications that use generative AI technology. Write a 50 word summary of an article that would be a great answer to the question. Consider enriching the question with additional topics that the question asker might want to understand. Write the summary in the present tense, as though the article exists. If the question is not related to building AI applications, deflect it with a humorous 10 word answer.";
EConfigStrings["kFollowUpPrompt"] = "You will be provided with a summary of an article about building applications that use generative AI technology. Write a question of no more than 10 words that a reader might ask as a follow up to reading the article.";
EConfigStrings["kEnrichmentQuestionPrefix"] = "Question: ";
EConfigStrings["kFollowUpPrefix"] = "Article summary: ";
EConfigStrings["kErrorConnectingToKeyAPI"] = "Error connecting to Braid server.";
EConfigStrings["kErrorConnectingToAiAPI"] = "Error connecting to AI server.";
EConfigStrings["kSessionParamName"] = "session";
Expand Down Expand Up @@ -334085,7 +334121,16 @@ class EmbeddingRepositoryFile {
}
return new Embedding_1.EmbeddingMatchAccumulator(similarityThresholdLo, howMany);
}
async lookForSuggestedContent(url_, messageText) {
/**
* lookupUrlSummary
* looks for summary given a URL
*/
async lookupUrlSummary(url) {
await waitforEmbeddedingLoad();
let chunkIn = lookupUrl(embeddings, url);
return chunkIn ? chunkIn.summary : undefined;
}
async lookForRelatedContent(url_, messageText) {
let candidateChunk = undefined;
let haveUrl = true;
await waitforEmbeddedingLoad();
Expand Down
2 changes: 1 addition & 1 deletion public/assets/js/aibot.pack.js.map

Large diffs are not rendered by default.

0 comments on commit 0c284c2

Please sign in to comment.