mirror of
https://github.com/ONLYOFFICE/onlyoffice.github.io.git
synced 2026-02-10 18:05:06 +08:00
Unification of assistants
This commit is contained in:
@ -166,36 +166,36 @@ function CustomAnnotationPopup()
|
||||
|
||||
if (data.type === 0) { // Hint
|
||||
this.content = `<div>
|
||||
<div class="ballon-color text-color border-color" style="font-size:12px; color:${textColor}; line-height:1.5; padding:10px;">${data.reason}</div>
|
||||
<div class="ballon-color text-color border-color" style="font-size:12px; color:${textColor}; line-height:1.5; padding:10px;">${data.explanation}</div>
|
||||
</div>`;
|
||||
}
|
||||
} else { // Replace + Hint or Replace
|
||||
if (data.suggested) {
|
||||
this.content = `<div class="back-color text-color" style="background:${backColor}; overflow:hidden; max-width:320px; min-width:280px;color:${textColor}; user-select:none;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;">
|
||||
<div style="padding:16px 16px 0px 16px;">
|
||||
|
||||
if (data.suggested) {
|
||||
this.content = `<div class="back-color text-color" style="background:${backColor}; overflow:hidden; max-width:320px; min-width:280px;color:${textColor}; user-select:none;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;">
|
||||
<div style="padding:16px 16px 0px 16px;">
|
||||
|
||||
<div style="margin-bottom:12px;">
|
||||
<div class="text-color" style="font-size:11px; font-weight:700; color:${textColor}; margin-bottom:6px;">
|
||||
${window.Asc.plugin.tr("Suggested correction")}
|
||||
</div>
|
||||
|
||||
<div class="ballon-color text-color border-color" style="font-size:12px; color:${textColor}; line-height:1.5; background:${ballonColor}; border:1px solid ${borderColor}; border-radius:3px; padding:10px;">
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<span class="text-color" style="color:${textColor}; font-weight:normal;">${data.original}</span>
|
||||
<span class="text-color" style="color:${textColor}; font-weight:bold;">→</span>
|
||||
<span class="text-color" style="color:${textColor}; font-weight:normal;">${data.suggested}</span>
|
||||
<div style="margin-bottom:12px;">
|
||||
<div class="text-color" style="font-size:11px; font-weight:700; color:${textColor}; margin-bottom:6px;">
|
||||
${window.Asc.plugin.tr("Suggested correction")}
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
if (data.explanation) {
|
||||
this.content += `<div style="margin-bottom:16px;">
|
||||
<div class="text-color" class="text-color" style="font-size:11px; font-weight:700; color:${textColor}; margin-bottom:6px;">
|
||||
${window.Asc.plugin.tr("Explanation")}
|
||||
</div>
|
||||
|
||||
<div class="ballon-color text-color border-color" style="font-size:12px; color:${textColor}; line-height:1.5; background:${ballonColor}; border:1px solid ${borderColor}; border-radius:3px; padding:10px;">${data.explanation}</div>
|
||||
</div>`;
|
||||
<div class="ballon-color text-color border-color" style="font-size:12px; color:${textColor}; line-height:1.5; background:${ballonColor}; border:1px solid ${borderColor}; border-radius:3px; padding:10px;">
|
||||
<div style="display:flex; align-items:center; gap:8px;">
|
||||
<span class="text-color" style="color:${textColor}; font-weight:normal;">${data.original}</span>
|
||||
<span class="text-color" style="color:${textColor}; font-weight:bold;">→</span>
|
||||
<span class="text-color" style="color:${textColor}; font-weight:normal;">${data.suggested}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
if (data.explanation) {
|
||||
this.content += `<div style="margin-bottom:16px;">
|
||||
<div class="text-color" class="text-color" style="font-size:11px; font-weight:700; color:${textColor}; margin-bottom:6px;">
|
||||
${window.Asc.plugin.tr("Explanation")}
|
||||
</div>
|
||||
|
||||
<div class="ballon-color text-color border-color" style="font-size:12px; color:${textColor}; line-height:1.5; background:${ballonColor}; border:1px solid ${borderColor}; border-radius:3px; padding:10px;">${data.explanation}</div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
this.content += "</div></div>";
|
||||
|
||||
@ -40,16 +40,13 @@ function AssistantHint(assistantData)
|
||||
this.type = assistantData.type; // 0
|
||||
this.assistantData = assistantData;
|
||||
}
|
||||
|
||||
AssistantHint.prototype = Object.create(CustomAnnotator.prototype);
|
||||
AssistantHint.prototype.constructor = AssistantHint;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} paraId
|
||||
* @param {string} recalcId
|
||||
* @param {string} text
|
||||
* @returns
|
||||
* @param {string} text
|
||||
*/
|
||||
AssistantHint.prototype.annotateParagraph = async function(paraId, recalcId, text)
|
||||
{
|
||||
@ -71,11 +68,9 @@ AssistantHint.prototype.annotateParagraph = async function(paraId, recalcId, tex
|
||||
let response = "";
|
||||
await requestEngine.chatRequest(argPrompt, false, async function (/** @type {string} */data)
|
||||
{
|
||||
if (!data) {
|
||||
if (!data)
|
||||
return;
|
||||
}
|
||||
await checkEndAction();
|
||||
|
||||
response += data;
|
||||
});
|
||||
await checkEndAction();
|
||||
@ -103,7 +98,7 @@ AssistantHint.prototype.annotateParagraph = async function(paraId, recalcId, tex
|
||||
{
|
||||
const index = text.indexOf(origin, searchStart);
|
||||
if (index === -1) break;
|
||||
|
||||
|
||||
count++;
|
||||
if (count === occurrence)
|
||||
{
|
||||
@ -114,7 +109,7 @@ AssistantHint.prototype.annotateParagraph = async function(paraId, recalcId, tex
|
||||
});
|
||||
_t.paragraphs[paraId][rangeId] = {
|
||||
"original" : origin,
|
||||
"reason" : reason,
|
||||
"reason" : reason
|
||||
};
|
||||
++rangeId;
|
||||
break;
|
||||
@ -140,8 +135,13 @@ AssistantHint.prototype.annotateParagraph = async function(paraId, recalcId, tex
|
||||
{ }
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @returns {string}
|
||||
*/
|
||||
AssistantHint.prototype._createPrompt = function(text) {
|
||||
return `You are a text analysis specialist. Your task is to find text fragments that match the user's criteria.
|
||||
let prompt = `You are a multi-disciplinary text analysis assistant.
|
||||
Your task is to find text fragments that match the user's criteria.
|
||||
|
||||
MANDATORY RULES:
|
||||
1. Analyze ONLY the provided text.
|
||||
@ -173,7 +173,7 @@ AssistantHint.prototype._createPrompt = function(text) {
|
||||
- "confidence": Value between 0 and 1 indicating certainty (1.0 = completely certain, 0.5 = uncertain)
|
||||
|
||||
CRITICAL
|
||||
- Ouput should be in the exact this format
|
||||
- Output should be in the exact this format
|
||||
- No any comments are allowed
|
||||
|
||||
CRITICAL - Output Format:
|
||||
@ -182,15 +182,14 @@ AssistantHint.prototype._createPrompt = function(text) {
|
||||
- DO NOT include any explanatory text before or after the JSON
|
||||
- DO NOT use escaped newlines (\\n) - return the JSON on a single line if possible
|
||||
- The response should start with [ and end with ]
|
||||
|
||||
USER REQUEST: ${this.assistantData.query}
|
||||
`;
|
||||
prompt += "\n\nUSER REQUEST:\n```" + this.assistantData.query + "\n```\n\n";
|
||||
|
||||
TEXT TO ANALYZE:
|
||||
"""
|
||||
${text}
|
||||
"""
|
||||
prompt += "TEXT TO ANALYZE:\n```\n" + text + "\n```\n\n";
|
||||
|
||||
Please analyze this text and find all fragments that match the user's request. Be thorough but precise.`;
|
||||
prompt += `Please analyze this text and find all fragments that match the user's request. Be thorough but precise.`;
|
||||
|
||||
return prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,7 +202,7 @@ AssistantHint.prototype.getInfoForPopup = function(paraId, rangeId)
|
||||
let _s = this.getAnnotation(paraId, rangeId);
|
||||
return {
|
||||
original : _s["original"],
|
||||
reason : _s["reason"],
|
||||
explanation : _s["reason"],
|
||||
type : this.type
|
||||
};
|
||||
};
|
||||
@ -215,7 +214,7 @@ AssistantHint.prototype.getInfoForPopup = function(paraId, rangeId)
|
||||
AssistantHint.prototype.onAccept = async function(paraId, rangeId)
|
||||
{
|
||||
await Asc.Editor.callMethod("StartAction", ["GroupActions"]);
|
||||
|
||||
|
||||
let range = this.getAnnotationRangeObj(paraId, rangeId);
|
||||
await Asc.Editor.callMethod("SelectAnnotationRange", [range]);
|
||||
|
||||
@ -253,7 +252,7 @@ AssistantHint.prototype._handleNewRangePositions = async function(range, paraId,
|
||||
|
||||
let start = range["start"];
|
||||
let len = range["length"];
|
||||
|
||||
|
||||
if (annot["original"] !== text.substring(start, start + len))
|
||||
{
|
||||
let annotRange = this.getAnnotationRangeObj(paraId, rangeId);
|
||||
|
||||
@ -40,16 +40,20 @@ function AssistantReplaceHint(assistantData)
|
||||
this.type = assistantData.type; // 1
|
||||
this.assistantData = assistantData;
|
||||
}
|
||||
|
||||
AssistantReplaceHint.prototype = Object.create(CustomAnnotator.prototype);
|
||||
AssistantReplaceHint.prototype.constructor = AssistantReplaceHint;
|
||||
|
||||
/**
|
||||
* @param {string} paraId
|
||||
* @param {string} recalcId
|
||||
* @param {string} text
|
||||
*/
|
||||
AssistantReplaceHint.prototype.annotateParagraph = async function(paraId, recalcId, text)
|
||||
{
|
||||
this.paragraphs[paraId] = {};
|
||||
|
||||
let requestEngine = AI.Request.create(AI.ActionType.Chat);
|
||||
if (!requestEngine)
|
||||
if (!requestEngine || text.length === 0)
|
||||
return false;
|
||||
|
||||
let isSendedEndLongAction = false;
|
||||
@ -59,15 +63,14 @@ AssistantReplaceHint.prototype.annotateParagraph = async function(paraId, recalc
|
||||
isSendedEndLongAction = true;
|
||||
}
|
||||
|
||||
let argPrompt = this._createPrompt(text);
|
||||
const argPrompt = this._createPrompt(text);
|
||||
|
||||
let response = "";
|
||||
await requestEngine.chatRequest(argPrompt, false, async function (data)
|
||||
await requestEngine.chatRequest(argPrompt, false, async function (/** @type {string} */data)
|
||||
{
|
||||
if (!data)
|
||||
return;
|
||||
await checkEndAction();
|
||||
|
||||
response += data;
|
||||
});
|
||||
await checkEndAction();
|
||||
@ -76,14 +79,14 @@ AssistantReplaceHint.prototype.annotateParagraph = async function(paraId, recalc
|
||||
let ranges = [];
|
||||
|
||||
let _t = this;
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} text
|
||||
* @param {ReplaceHintAiResponse[]} corrections
|
||||
*/
|
||||
function convertToRanges(text, corrections)
|
||||
{
|
||||
for (const { origin, suggestion, difference, description, occurrence, confidence } of corrections)
|
||||
for (const { origin, suggestion, difference, reason, paragraph, occurrence, confidence } of corrections)
|
||||
{
|
||||
if (origin === suggestion || confidence <= 0.7)
|
||||
continue;
|
||||
@ -95,7 +98,7 @@ AssistantReplaceHint.prototype.annotateParagraph = async function(paraId, recalc
|
||||
{
|
||||
const index = text.indexOf(origin, searchStart);
|
||||
if (index === -1) break;
|
||||
|
||||
|
||||
count++;
|
||||
if (count === occurrence)
|
||||
{
|
||||
@ -108,7 +111,7 @@ AssistantReplaceHint.prototype.annotateParagraph = async function(paraId, recalc
|
||||
"original" : origin,
|
||||
"suggestion" : suggestion,
|
||||
"difference" : difference,
|
||||
"description" : description
|
||||
"reason" : reason
|
||||
};
|
||||
++rangeId;
|
||||
break;
|
||||
@ -139,12 +142,12 @@ AssistantReplaceHint.prototype.annotateParagraph = async function(paraId, recalc
|
||||
* @returns {string}
|
||||
*/
|
||||
AssistantReplaceHint.prototype._createPrompt = function(text) {
|
||||
return `You are an intelligent text analysis and transformation assistant.
|
||||
Your task is to analyze text and identify elements that match user-defined criteria for replacement.
|
||||
let prompt = `You are a multi-disciplinary text analysis and transformation assistant.
|
||||
Your task is to analyze text based on user's specific criteria and provide intelligent corrections.
|
||||
|
||||
MANDATORY RULES:
|
||||
1. UNDERSTAND the user's intent from their criteria.
|
||||
2. FIND all text elements matching the criteria.
|
||||
2. Find words, phrases, or sentences that match the user's criteria.
|
||||
3. For EACH match you find:
|
||||
- Provide the exact quote.
|
||||
- SUGGEST appropriate replacements.
|
||||
@ -152,27 +155,14 @@ AssistantReplaceHint.prototype._createPrompt = function(text) {
|
||||
- Provide position information (paragraph number).
|
||||
4. If no matches are found, return an empty array: [].
|
||||
5. Format your response STRICTLY in JSON format.
|
||||
|
||||
ANALYSIS FRAMEWORK:
|
||||
For each text element, consider:
|
||||
- SEMANTIC: Does it match the meaning criteria?
|
||||
- STYLISTIC: Does it match the style criteria?
|
||||
- CONTEXTUAL: Is it appropriate for the context?
|
||||
- FUNCTIONAL: Does it serve the intended purpose?
|
||||
|
||||
REPLACEMENT STRATEGIES:
|
||||
1. Direct synonym replacement
|
||||
2. Paraphrasing for better fit
|
||||
3. Complete restructuring if needed
|
||||
4. Adding/removing elements as required
|
||||
5. Adjusting tone or register
|
||||
6. Support multiple languages (English, Russian, etc.)
|
||||
|
||||
Response format - return ONLY this JSON array with no additional text:
|
||||
[
|
||||
{
|
||||
"origin": "exact text fragment that matches the query",
|
||||
"suggestion": "suggested replacement",
|
||||
"description": "detailed explanation why it matches the criteria",
|
||||
"reason": "detailed explanation why it matches the criteria",
|
||||
"difference":"difference between origin and suggestion"
|
||||
"paragraph": paragraph_number,
|
||||
"occurrence": 1,
|
||||
@ -185,16 +175,15 @@ AssistantReplaceHint.prototype._createPrompt = function(text) {
|
||||
- "suggestion": Your suggested replacement for the fragment.
|
||||
* Ensure it aligns with the user's criteria.
|
||||
* Maintain coherence with surrounding text.
|
||||
- "description": Clear explanation of why this fragment matches the criteria.
|
||||
- "reason": Clear explanation of why this fragment matches the criteria.
|
||||
- "difference": The difference between origin and suggestion in html format: the differences wrapped with <strong> tag
|
||||
- "paragraph": Paragraph number where the fragment is found (0-based index)
|
||||
- "occurrence": Which occurrence of this sentence if it appears multiple times (1 for first, 2 for second, etc.)
|
||||
- "confidence": Value between 0 and 1 indicating certainty (1.0 = completely certain, 0.5 = uncertain)
|
||||
|
||||
CRITICAL - Word Boundaries (MOST IMPORTANT):
|
||||
- ONLY match complete, standalone words separated by spaces, punctuation, or at the start/end of text
|
||||
- DO NOT match letters or substrings that are PART of other words
|
||||
- A word is bounded by: spaces, punctuation (.,!?;:), quotes, or start/end of text
|
||||
CRITICAL:
|
||||
- Output should be in the exact this format
|
||||
- No any comments are allowed
|
||||
|
||||
CRITICAL - Output Format:
|
||||
- Return ONLY the raw JSON array, nothing else
|
||||
@ -202,14 +191,14 @@ AssistantReplaceHint.prototype._createPrompt = function(text) {
|
||||
- DO NOT include any explanatory text before or after the JSON
|
||||
- DO NOT use escaped newlines (\\n) - return the JSON on a single line if possible
|
||||
- The response should start with [ and end with ]
|
||||
|
||||
USER REQUEST: ${this.assistantData.query}
|
||||
`;
|
||||
prompt += "\n\nUSER REQUEST:\n```" + this.assistantData.query + "\n```\n\n";
|
||||
|
||||
TEXT TO ANALYZE:
|
||||
"""
|
||||
${text}
|
||||
"""
|
||||
`;
|
||||
prompt += "TEXT TO ANALYZE:\n```\n" + text + "\n```\n\n";
|
||||
|
||||
prompt += `Please analyze this text and find all fragments that match the user's request. Be thorough but precise.`;
|
||||
|
||||
return prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -221,18 +210,23 @@ AssistantReplaceHint.prototype.getInfoForPopup = function(paraId, rangeId)
|
||||
{
|
||||
let _s = this.getAnnotation(paraId, rangeId);
|
||||
return {
|
||||
suggested : _s["difference"],
|
||||
original : _s["original"],
|
||||
explanation : _s["description"],
|
||||
suggested : _s["difference"],
|
||||
explanation : _s["reason"],
|
||||
type : this.type
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} paraId
|
||||
* @param {string} rangeId
|
||||
*/
|
||||
AssistantReplaceHint.prototype.onAccept = async function(paraId, rangeId)
|
||||
{
|
||||
let text = this.getAnnotation(paraId, rangeId)["suggestion"];
|
||||
|
||||
await Asc.Editor.callMethod("StartAction", ["GroupActions"]);
|
||||
|
||||
|
||||
let range = this.getAnnotationRangeObj(paraId, rangeId);
|
||||
await Asc.Editor.callMethod("SelectAnnotationRange", [range]);
|
||||
|
||||
@ -246,6 +240,11 @@ AssistantReplaceHint.prototype.onAccept = async function(paraId, rangeId)
|
||||
await Asc.Editor.callMethod("EndAction", ["GroupActions"]);
|
||||
await Asc.Editor.callMethod("FocusEditor");
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} paraId
|
||||
* @param {string} rangeId
|
||||
*/
|
||||
AssistantReplaceHint.prototype.getAnnotationRangeObj = function(paraId, rangeId)
|
||||
{
|
||||
return {
|
||||
@ -267,7 +266,7 @@ AssistantReplaceHint.prototype._handleNewRangePositions = async function(range,
|
||||
|
||||
let start = range["start"];
|
||||
let len = range["length"];
|
||||
|
||||
|
||||
if (annot["original"] !== text.substring(start, start + len))
|
||||
{
|
||||
let annotRange = this.getAnnotationRangeObj(paraId, rangeId);
|
||||
|
||||
@ -43,12 +43,17 @@ function AssistantReplace(assistantData)
|
||||
AssistantReplace.prototype = Object.create(CustomAnnotator.prototype);
|
||||
AssistantReplace.prototype.constructor = AssistantReplace;
|
||||
|
||||
/**
|
||||
* @param {string} paraId
|
||||
* @param {string} recalcId
|
||||
* @param {string} text
|
||||
*/
|
||||
AssistantReplace.prototype.annotateParagraph = async function(paraId, recalcId, text)
|
||||
{
|
||||
this.paragraphs[paraId] = {};
|
||||
|
||||
let requestEngine = AI.Request.create(AI.ActionType.Chat);
|
||||
if (!requestEngine)
|
||||
if (!requestEngine || text.length === 0)
|
||||
return false;
|
||||
|
||||
let isSendedEndLongAction = false;
|
||||
@ -59,8 +64,9 @@ AssistantReplace.prototype.annotateParagraph = async function(paraId, recalcId,
|
||||
}
|
||||
|
||||
const argPrompt = this._createPrompt(text);
|
||||
|
||||
let response = "";
|
||||
await requestEngine.chatRequest(argPrompt, false, async function (data)
|
||||
await requestEngine.chatRequest(argPrompt, false, async function (/** @type {string} */data)
|
||||
{
|
||||
if (!data)
|
||||
return;
|
||||
@ -80,9 +86,9 @@ AssistantReplace.prototype.annotateParagraph = async function(paraId, recalcId,
|
||||
*/
|
||||
function convertToRanges(text, corrections)
|
||||
{
|
||||
for (const { wrong, correct, reason, paragraph, occurrence, confidence } of corrections)
|
||||
for (const { origin, suggestion, paragraph, occurrence, confidence } of corrections)
|
||||
{
|
||||
if (wrong === correct)
|
||||
if (origin === suggestion || confidence <= 0.7)
|
||||
continue;
|
||||
|
||||
let count = 0;
|
||||
@ -90,35 +96,29 @@ AssistantReplace.prototype.annotateParagraph = async function(paraId, recalcId,
|
||||
|
||||
while (searchStart < text.length)
|
||||
{
|
||||
const index = text.indexOf(wrong, searchStart);
|
||||
const index = text.indexOf(origin, searchStart);
|
||||
if (index === -1) break;
|
||||
|
||||
const isStartBoundary = index === 0 || _t._isWordBoundary(text[index - 1]);
|
||||
const isEndBoundary = index + wrong.length === text.length || _t._isWordBoundary(text[index + wrong.length]);
|
||||
|
||||
if (isStartBoundary && isEndBoundary)
|
||||
count++;
|
||||
if (count === occurrence)
|
||||
{
|
||||
count++;
|
||||
if (count === occurrence)
|
||||
{
|
||||
ranges.push({
|
||||
"start": index,
|
||||
"length": wrong.length,
|
||||
"id": rangeId
|
||||
});
|
||||
_t.paragraphs[paraId][rangeId] = {
|
||||
"suggested" : correct,
|
||||
"original" : wrong
|
||||
};
|
||||
++rangeId;
|
||||
break;
|
||||
}
|
||||
ranges.push({
|
||||
"start": index,
|
||||
"length": origin.length,
|
||||
"id": rangeId
|
||||
});
|
||||
_t.paragraphs[paraId][rangeId] = {
|
||||
"original" : origin,
|
||||
"suggestion" : suggestion,
|
||||
};
|
||||
++rangeId;
|
||||
break;
|
||||
}
|
||||
searchStart = index + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
convertToRanges(text, JSON.parse(response));
|
||||
@ -140,8 +140,8 @@ AssistantReplace.prototype.annotateParagraph = async function(paraId, recalcId,
|
||||
* @returns {string}
|
||||
*/
|
||||
AssistantReplace.prototype._createPrompt = function(text) {
|
||||
return `You are an intelligent text analysis and transformation assistant.
|
||||
Your task is to analyze text and identify words that match user-defined criteria for replacement.
|
||||
let prompt = `You are a multi-disciplinary text analysis and transformation assistant.
|
||||
Your task is to analyze text based on user's specific criteria and provide intelligent corrections.
|
||||
|
||||
MANDATORY RULES:
|
||||
1. UNDERSTAND the user's intent from their criteria.
|
||||
@ -153,26 +153,13 @@ AssistantReplace.prototype._createPrompt = function(text) {
|
||||
- Provide position information (paragraph number).
|
||||
4. If no matches are found, return an empty array: [].
|
||||
5. Format your response STRICTLY in JSON format.
|
||||
|
||||
ANALYSIS FRAMEWORK:
|
||||
For each text element, consider:
|
||||
- SEMANTIC: Does it match the meaning criteria?
|
||||
- STYLISTIC: Does it match the style criteria?
|
||||
- CONTEXTUAL: Is it appropriate for the context?
|
||||
- FUNCTIONAL: Does it serve the intended purpose?
|
||||
|
||||
REPLACEMENT STRATEGIES:
|
||||
1. Direct synonym replacement
|
||||
2. Paraphrasing for better fit
|
||||
3. Complete restructuring if needed
|
||||
4. Adding/removing elements as required
|
||||
5. Adjusting tone or register
|
||||
6. Support multiple languages (English, Russian, etc.)
|
||||
|
||||
Response format - return ONLY this JSON array with no additional text:
|
||||
[
|
||||
{
|
||||
"wrong": "exact text fragment that matches the query",
|
||||
"correct": "suggested replacement",
|
||||
"origin": "exact text fragment that matches the query",
|
||||
"suggestion": "suggested replacement",
|
||||
"paragraph": paragraph_number,
|
||||
"occurrence": 1,
|
||||
"confidence": 0.95
|
||||
@ -180,18 +167,17 @@ AssistantReplace.prototype._createPrompt = function(text) {
|
||||
]
|
||||
|
||||
Guidelines for each field:
|
||||
- "wrong": EXACT UNCHANGED original text fragment. Do not fix anything in this field.
|
||||
- "correct": Your suggested replacement for the fragment.
|
||||
- "origin": EXACT UNCHANGED original text fragment. Do not fix anything in this field.
|
||||
- "suggestion": Your suggested replacement for the fragment.
|
||||
* Ensure it aligns with the user's criteria.
|
||||
* Maintain coherence with surrounding text.
|
||||
- "paragraph": Paragraph number where the fragment is found (0-based index)
|
||||
- "occurrence": Which occurrence of this sentence if it appears multiple times (1 for first, 2 for second, etc.)
|
||||
- "confidence": Value between 0 and 1 indicating certainty (1.0 = completely certain, 0.5 = uncertain)
|
||||
|
||||
CRITICAL - Word Boundaries (MOST IMPORTANT):
|
||||
- ONLY match complete, standalone words separated by spaces, punctuation, or at the start/end of text
|
||||
- DO NOT match letters or substrings that are PART of other words
|
||||
- A word is bounded by: spaces, punctuation (.,!?;:), quotes, or start/end of text
|
||||
CRITICAL:
|
||||
- Output should be in the exact this format
|
||||
- No any comments are allowed
|
||||
|
||||
CRITICAL - Output Format:
|
||||
- Return ONLY the raw JSON array, nothing else
|
||||
@ -199,15 +185,14 @@ AssistantReplace.prototype._createPrompt = function(text) {
|
||||
- DO NOT include any explanatory text before or after the JSON
|
||||
- DO NOT use escaped newlines (\\n) - return the JSON on a single line if possible
|
||||
- The response should start with [ and end with ]
|
||||
|
||||
USER REQUEST: ${this.assistantData.query}
|
||||
`;
|
||||
prompt += "\n\nUSER REQUEST:\n```" + this.assistantData.query + "\n```\n\n";
|
||||
|
||||
TEXT TO ANALYZE:
|
||||
"""
|
||||
${text}
|
||||
"""
|
||||
prompt += "TEXT TO ANALYZE:\n```\n" + text + "\n```\n\n";
|
||||
|
||||
Please analyze this text and find all words that match the user's request. Be thorough but precise.`;
|
||||
prompt += `Please analyze this text and find all fragments that match the user's request. Be thorough but precise.`;
|
||||
|
||||
return prompt;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -217,33 +202,42 @@ AssistantReplace.prototype._createPrompt = function(text) {
|
||||
*/
|
||||
AssistantReplace.prototype.getInfoForPopup = function(paraId, rangeId)
|
||||
{
|
||||
let anot = this.getAnnotation(paraId, rangeId);
|
||||
let _s = this.getAnnotation(paraId, rangeId);
|
||||
return {
|
||||
suggested : anot["suggested"],
|
||||
original : anot["original"],
|
||||
original : _s["original"],
|
||||
suggested : _s["suggestion"],
|
||||
type : this.type
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} paraId
|
||||
* @param {string} rangeId
|
||||
*/
|
||||
AssistantReplace.prototype.onAccept = async function(paraId, rangeId)
|
||||
{
|
||||
let anot = this.getAnnotation(paraId, rangeId);
|
||||
if (!anot)
|
||||
return;
|
||||
let text = this.getAnnotation(paraId, rangeId)["suggestion"];
|
||||
|
||||
let range = this.getAnnotationRangeObj(paraId, rangeId);
|
||||
await Asc.Editor.callMethod("StartAction", ["GroupActions"]);
|
||||
|
||||
let range = this.getAnnotationRangeObj(paraId, rangeId);
|
||||
await Asc.Editor.callMethod("SelectAnnotationRange", [range]);
|
||||
|
||||
Asc.scope.text = anot["suggested"];
|
||||
Asc.scope.text = text;
|
||||
await Asc.Editor.callCommand(function(){
|
||||
Api.ReplaceTextSmart([Asc.scope.text]);
|
||||
Api.GetDocument().RemoveSelection();
|
||||
});
|
||||
});
|
||||
|
||||
await Asc.Editor.callMethod("RemoveAnnotationRange", [range]);
|
||||
await Asc.Editor.callMethod("EndAction", ["GroupActions"]);
|
||||
await Asc.Editor.callMethod("FocusEditor");
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} paraId
|
||||
* @param {string} rangeId
|
||||
*/
|
||||
AssistantReplace.prototype.getAnnotationRangeObj = function(paraId, rangeId)
|
||||
{
|
||||
return {
|
||||
@ -265,17 +259,10 @@ AssistantReplace.prototype._handleNewRangePositions = async function(range, para
|
||||
|
||||
let start = range["start"];
|
||||
let len = range["length"];
|
||||
|
||||
const isStartBoundary = start === 0 || this._isWordBoundary(text[start - 1]);
|
||||
const isEndBoundary = start + len === text.length || this._isWordBoundary(text[start + len]);
|
||||
|
||||
if (!isStartBoundary || !isEndBoundary || annot["original"] !== text.substring(start, start + len))
|
||||
|
||||
if (annot["original"] !== text.substring(start, start + len))
|
||||
{
|
||||
let annotRange = this.getAnnotationRangeObj(paraId, rangeId);
|
||||
Asc.Editor.callMethod("RemoveAnnotationRange", [annotRange]);
|
||||
}
|
||||
};
|
||||
AssistantReplace.prototype._isWordBoundary = function(char)
|
||||
{
|
||||
return /[\s.,!?;:'"()\[\]{}\-–—\/\\]/.test(char);
|
||||
};
|
||||
|
||||
@ -7,20 +7,8 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ReplaceHintAiResponse
|
||||
* @typedef {Object} HintAiResponse
|
||||
* @property {string} origin
|
||||
* @property {string} suggestion
|
||||
* @property {string} description
|
||||
* @property {string} difference
|
||||
* @property {number} paragraph
|
||||
* @property {number} occurrence
|
||||
* @property {number} confidence
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ReplaceAiResponse
|
||||
* @property {string} wrong
|
||||
* @property {string} correct
|
||||
* @property {string} reason
|
||||
* @property {number} paragraph
|
||||
* @property {number} occurrence
|
||||
@ -28,8 +16,16 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} HintAiResponse
|
||||
* @typedef {Object} HintInfoForPopup
|
||||
* @property {string} original
|
||||
* @property {string} explanation
|
||||
* @property {number} type
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} ReplaceAiResponse
|
||||
* @property {string} origin
|
||||
* @property {string} suggestion
|
||||
* @property {string} reason
|
||||
* @property {number} paragraph
|
||||
* @property {number} occurrence
|
||||
@ -44,10 +40,14 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Object} HintInfoForPopup
|
||||
* @property {string} original
|
||||
* @typedef {Object} ReplaceHintAiResponse
|
||||
* @property {string} origin
|
||||
* @property {string} suggestion
|
||||
* @property {string} reason
|
||||
* @property {number} type
|
||||
* @property {string} difference
|
||||
* @property {number} paragraph
|
||||
* @property {number} occurrence
|
||||
* @property {number} confidence
|
||||
*/
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user