-
Notifications
You must be signed in to change notification settings - Fork 197
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: CEC in M365 Copilot: implement citation in rag ts&js template (#…
…12378) * implement citation in rag ts&js template * fix eslint issue * remove unuse code * use module.exports * add error handling * update error log
- Loading branch information
1 parent
ea03ef7
commit ec3398e
Showing
24 changed files
with
715 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
templates/js/custom-copilot-rag-azure-ai-search/src/app/customSayCommand.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
const botbuilder = require("botbuilder"); | ||
const Utilities = require("@microsoft/teams-ai"); | ||
|
||
function sayCommand(feedbackLoopEnabled = false) { | ||
return async (context, _state, data) => { | ||
if (!data.response?.content) { | ||
return ""; | ||
} | ||
const isTeamsChannel = context.activity.channelId === botbuilder.Channels.Msteams; | ||
let content = ""; | ||
let result = undefined; | ||
try { | ||
result = JSON.parse(data.response.content); | ||
} catch (error) { | ||
console.error(`Response is not valid json, send the raw text. error: ${error}`); | ||
await context.sendActivity({ | ||
type: botbuilder.ActivityTypes.Message, | ||
text: data.response.content, | ||
...(isTeamsChannel ? { channelData: { feedbackLoopEnabled } } : {}), | ||
entities: [ | ||
{ | ||
type: "https://schema.org/Message", | ||
"@type": "Message", | ||
"@context": "https://schema.org", | ||
"@id": "", | ||
additionalType: ["AIGeneratedContent"], | ||
}, | ||
], | ||
}); | ||
return ""; | ||
} | ||
// If the response from AI includes citations, those citations will be parsed and added to the SAY command. | ||
let citations = []; | ||
let position = 1; | ||
if (result.results && result.results.length > 0) { | ||
result.results.forEach((contentItem) => { | ||
if (contentItem.citationTitle && contentItem.citationTitle.length > 0) { | ||
const clientCitation = { | ||
"@type": "Claim", | ||
position: `${position}`, | ||
appearance: { | ||
"@type": "DigitalDocument", | ||
name: contentItem.citationTitle || `Document #${position}`, | ||
url: contentItem.citationUrl, | ||
abstract: Utilities.Utilities.snippet(contentItem.citationContent, 500), | ||
}, | ||
}; | ||
content += `${contentItem.answer}[${position}]<br>`; | ||
position++; | ||
citations.push(clientCitation); | ||
} else { | ||
content += `${contentItem.answer}<br>`; | ||
} | ||
}); | ||
} else { | ||
content = data.response.content; | ||
} | ||
|
||
if (isTeamsChannel) { | ||
content = content.split("\n").join("<br>"); | ||
} | ||
// If there are citations, modify the content so that the sources are numbers instead of [doc1], [doc2], etc. | ||
const contentText = | ||
citations.length < 1 ? content : Utilities.Utilities.formatCitationsResponse(content); | ||
// If there are citations, filter out the citations unused in content. | ||
const referencedCitations = | ||
citations.length > 0 | ||
? Utilities.Utilities.getUsedCitations(contentText, citations) | ||
: undefined; | ||
await context.sendActivity({ | ||
type: botbuilder.ActivityTypes.Message, | ||
text: contentText, | ||
...(isTeamsChannel ? { channelData: { feedbackLoopEnabled } } : {}), | ||
entities: [ | ||
{ | ||
type: "https://schema.org/Message", | ||
"@type": "Message", | ||
"@context": "https://schema.org", | ||
"@id": "", | ||
additionalType: ["AIGeneratedContent"], | ||
...(referencedCitations ? { citation: referencedCitations } : {}), | ||
}, | ||
], | ||
}); | ||
return ""; | ||
}; | ||
} | ||
module.exports = { | ||
sayCommand, | ||
}; |
22 changes: 20 additions & 2 deletions
22
templates/js/custom-copilot-rag-azure-ai-search/src/prompts/chat/skprompt.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,21 @@ | ||
The following is a conversation with an AI assistant, who is an expert on answering questions over the given context. | ||
Responses should be in a short journalistic style with no more than 80 words. | ||
Use the context provided in the `<context></context>` tags as the source for your answers. | ||
Responses should be in a short journalistic style with no more than 80 words, and provide citations. | ||
Use the context provided in the `<context></context>` tags as the source for your answers. | ||
Response should be a json array, list all the answers and citations. | ||
If the answer no citation, set the citationTitle and citationContent as empty. | ||
Data format: | ||
{ | ||
"results":[ | ||
{ | ||
"answer":"{$answer1}", | ||
"citationTitle":"{$citationTitle1}", | ||
"citationContent":"{$citationContent1}" | ||
}, | ||
{ | ||
"answer":"{$answer2}", | ||
"citationTitle":"{$citationTitle2}", | ||
"citationContent":"{$citationContent2}" | ||
}, | ||
... | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
templates/js/custom-copilot-rag-customize/src/app/customSayCommand.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
const botbuilder = require("botbuilder"); | ||
const Utilities = require("@microsoft/teams-ai"); | ||
|
||
function sayCommand(feedbackLoopEnabled = false) { | ||
return async (context, _state, data) => { | ||
if (!data.response?.content) { | ||
return ""; | ||
} | ||
const isTeamsChannel = context.activity.channelId === botbuilder.Channels.Msteams; | ||
let content = ""; | ||
let result = undefined; | ||
try { | ||
result = JSON.parse(data.response.content); | ||
} catch (error) { | ||
console.error(`Response is not valid json, send the raw text. error: ${error}`); | ||
await context.sendActivity({ | ||
type: botbuilder.ActivityTypes.Message, | ||
text: data.response.content, | ||
...(isTeamsChannel ? { channelData: { feedbackLoopEnabled } } : {}), | ||
entities: [ | ||
{ | ||
type: "https://schema.org/Message", | ||
"@type": "Message", | ||
"@context": "https://schema.org", | ||
"@id": "", | ||
additionalType: ["AIGeneratedContent"], | ||
}, | ||
], | ||
}); | ||
return ""; | ||
} | ||
// If the response from AI includes citations, those citations will be parsed and added to the SAY command. | ||
let citations = []; | ||
let position = 1; | ||
if (result.results && result.results.length > 0) { | ||
result.results.forEach((contentItem) => { | ||
if (contentItem.citationTitle && contentItem.citationTitle.length > 0) { | ||
const clientCitation = { | ||
"@type": "Claim", | ||
position: `${position}`, | ||
appearance: { | ||
"@type": "DigitalDocument", | ||
name: contentItem.citationTitle || `Document #${position}`, | ||
url: contentItem.citationUrl, | ||
abstract: Utilities.Utilities.snippet(contentItem.citationContent, 500), | ||
}, | ||
}; | ||
content += `${contentItem.answer}[${position}]<br>`; | ||
position++; | ||
citations.push(clientCitation); | ||
} else { | ||
content += `${contentItem.answer}<br>`; | ||
} | ||
}); | ||
} else { | ||
content = data.response.content; | ||
} | ||
|
||
if (isTeamsChannel) { | ||
content = content.split("\n").join("<br>"); | ||
} | ||
// If there are citations, modify the content so that the sources are numbers instead of [doc1], [doc2], etc. | ||
const contentText = | ||
citations.length < 1 ? content : Utilities.Utilities.formatCitationsResponse(content); | ||
// If there are citations, filter out the citations unused in content. | ||
const referencedCitations = | ||
citations.length > 0 | ||
? Utilities.Utilities.getUsedCitations(contentText, citations) | ||
: undefined; | ||
await context.sendActivity({ | ||
type: botbuilder.ActivityTypes.Message, | ||
text: contentText, | ||
...(isTeamsChannel ? { channelData: { feedbackLoopEnabled } } : {}), | ||
entities: [ | ||
{ | ||
type: "https://schema.org/Message", | ||
"@type": "Message", | ||
"@context": "https://schema.org", | ||
"@id": "", | ||
additionalType: ["AIGeneratedContent"], | ||
...(referencedCitations ? { citation: referencedCitations } : {}), | ||
}, | ||
], | ||
}); | ||
return ""; | ||
}; | ||
} | ||
module.exports = { | ||
sayCommand, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 20 additions & 2 deletions
22
templates/js/custom-copilot-rag-customize/src/prompts/chat/skprompt.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,21 @@ | ||
The following is a conversation with an AI assistant, who is an expert on answering questions over the given context. | ||
Responses should be in a short journalistic style with no more than 80 words. | ||
Use the context provided in the `<context></context>` tags as the source for your answers. | ||
Responses should be in a short journalistic style with no more than 80 words, and provide citations. | ||
Use the context provided in the `<context></context>` tags as the source for your answers. | ||
Response should be a json array, list all the answers and citations. | ||
If the answer no citation, set the citationTitle and citationContent as empty. | ||
Data format: | ||
{ | ||
"results":[ | ||
{ | ||
"answer":"{$answer1}", | ||
"citationTitle":"{$citationTitle1}", | ||
"citationContent":"{$citationContent1}" | ||
}, | ||
{ | ||
"answer":"{$answer2}", | ||
"citationTitle":"{$citationTitle2}", | ||
"citationContent":"{$citationContent2}" | ||
}, | ||
... | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.