Format markdown output
This commit is contained in:
Родитель
18a4801660
Коммит
1147bbedb0
|
@ -12,6 +12,8 @@
|
|||
"@mozilla/readability": "0.5.0",
|
||||
"@rollup/plugin-commonjs": "26.0.1",
|
||||
"@rollup/plugin-node-resolve": "15.2.3",
|
||||
"dompurify": "^3.1.6",
|
||||
"marked": "^14.1.2",
|
||||
"rollup": "4.18.1",
|
||||
"rollup-plugin-copy": "^3.5.0"
|
||||
}
|
||||
|
@ -562,6 +564,12 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/dompurify": {
|
||||
"version": "3.1.6",
|
||||
"resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.6.tgz",
|
||||
"integrity": "sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/eastasianwidth": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||
|
@ -952,6 +960,18 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/marked": {
|
||||
"version": "14.1.2",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-14.1.2.tgz",
|
||||
"integrity": "sha512-f3r0yqpz31VXiDB/wj9GaOB0a2PRLQl6vJmXiFrniNwjkKdvakqJRULhjFKJpxOchlCRiG5fcacoUZY5Xa6PEQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"marked": "bin/marked.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18"
|
||||
}
|
||||
},
|
||||
"node_modules/merge2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
"@mozilla/readability": "0.5.0",
|
||||
"@rollup/plugin-commonjs": "26.0.1",
|
||||
"@rollup/plugin-node-resolve": "15.2.3",
|
||||
"dompurify": "3.1.6",
|
||||
"marked": "14.1.2",
|
||||
"rollup": "4.18.1",
|
||||
"rollup-plugin-copy": "^3.5.0"
|
||||
}
|
||||
|
|
|
@ -2,22 +2,35 @@ import { nodeResolve } from '@rollup/plugin-node-resolve';
|
|||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import copy from 'rollup-plugin-copy';
|
||||
|
||||
export default {
|
||||
input: 'scripts/extract-content.js',
|
||||
output: {
|
||||
dir: 'dist/scripts',
|
||||
format: 'cjs'
|
||||
export default [
|
||||
{
|
||||
input: 'sidepanel/index.js',
|
||||
output: {
|
||||
dir: 'dist/sidepanel',
|
||||
format: 'es',
|
||||
},
|
||||
plugins: [
|
||||
commonjs(),
|
||||
nodeResolve(),
|
||||
copy({
|
||||
targets: [
|
||||
{
|
||||
src: ['manifest.json', 'background.js', 'sidepanel', 'images'],
|
||||
dest: 'dist'
|
||||
}
|
||||
]
|
||||
})
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
commonjs(),
|
||||
nodeResolve(),
|
||||
copy({
|
||||
targets: [
|
||||
{
|
||||
src: ['manifest.json', 'background.js', 'sidepanel', 'images'],
|
||||
dest: 'dist'
|
||||
}
|
||||
]
|
||||
})
|
||||
]
|
||||
};
|
||||
{
|
||||
input: 'scripts/extract-content.js',
|
||||
output: {
|
||||
dir: 'dist/scripts',
|
||||
format: 'es'
|
||||
},
|
||||
plugins: [
|
||||
commonjs(),
|
||||
nodeResolve(),
|
||||
]
|
||||
}
|
||||
];
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import DOMPurify from '../node_modules/dompurify/dist/purify.es.mjs';
|
||||
import { marked } from '../node_modules/marked/marked.min';
|
||||
|
||||
// The underlying model has a context of 1,024 tokens, out of which 26 are used by the internal prompt,
|
||||
// leaving about 998 tokens for the input text. Each token corresponds, roughly, to about 4 characters, so 4,000
|
||||
// is used as a limit to warn the user the content might be too long to summarize.
|
||||
|
@ -42,7 +45,7 @@ async function onContentChange(newContent) {
|
|||
|
||||
async function generateSummary(text) {
|
||||
try {
|
||||
let session = await createSummarizationSession((message, progress) => {
|
||||
let session = await createSummarizer((message, progress) => {
|
||||
console.log(`${message} (${progress.loaded}/${progress.total})`);
|
||||
});
|
||||
let summary = await session.summarize(text);
|
||||
|
@ -55,39 +58,32 @@ async function generateSummary(text) {
|
|||
}
|
||||
}
|
||||
|
||||
async function createSummarizationSession(downloadProgressCallback) {
|
||||
async function createSummarizer() {
|
||||
if (!window.ai || !window.ai.summarizer) {
|
||||
throw new Error('AI Summarization is not supported in this browser');
|
||||
}
|
||||
const canSummarize = await window.ai.summarizer.capabilities();
|
||||
if (canSummarize.available === 'no') {
|
||||
throw new Error('AI Summarization is not availabe');
|
||||
}
|
||||
|
||||
const summarizationSession = await window.ai.summarizer.create();
|
||||
if (canSummarize.available === 'after-download') {
|
||||
if (downloadProgressCallback) {
|
||||
summarizationSession.addEventListener(
|
||||
'downloadprogress',
|
||||
downloadProgressCallback
|
||||
);
|
||||
let summarizer;
|
||||
if (canSummarize && canSummarize.available !== 'no') {
|
||||
if (canSummarize.available === 'readily') {
|
||||
// The summarizer can immediately be used.
|
||||
summarizer = await window.ai.summarizer.create();
|
||||
} else {
|
||||
// The summarizer can be used after the model download.
|
||||
summarizer = await window.ai.summarizer.create();
|
||||
summarizer.addEventListener('downloadprogress', (e) => {
|
||||
console.log('Downloading model', e.loaded, e.total);
|
||||
});
|
||||
await summarizer.ready;
|
||||
}
|
||||
await summarizationSession.ready;
|
||||
} else {
|
||||
throw new Error(`AI Summarizer not available (${canSummarize.available})`);
|
||||
}
|
||||
|
||||
return summarizationSession;
|
||||
return summarizer;
|
||||
}
|
||||
|
||||
async function showSummary(text) {
|
||||
// Make sure to preserve line breaks in the response
|
||||
summaryElement.textContent = '';
|
||||
const paragraphs = text.split(/\r?\n/);
|
||||
for (const paragraph of paragraphs) {
|
||||
if (paragraph) {
|
||||
summaryElement.appendChild(document.createTextNode(paragraph));
|
||||
}
|
||||
summaryElement.appendChild(document.createElement('BR'));
|
||||
}
|
||||
summaryElement.innerHTML = DOMPurify.sanitize(marked.parse(text));
|
||||
}
|
||||
|
||||
async function updateWarning(warning) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче