@steipete/summarize-core 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/esm/content/cache/types.js +2 -0
- package/dist/esm/content/cache/types.js.map +1 -0
- package/dist/esm/content/index.js +1 -0
- package/dist/esm/content/index.js.map +1 -1
- package/dist/esm/content/link-preview/client.js +3 -0
- package/dist/esm/content/link-preview/client.js.map +1 -1
- package/dist/esm/content/link-preview/content/fetcher.js +1 -1
- package/dist/esm/content/link-preview/content/fetcher.js.map +1 -1
- package/dist/esm/content/link-preview/content/html.js +1 -1
- package/dist/esm/content/link-preview/content/html.js.map +1 -1
- package/dist/esm/content/link-preview/content/index.js +22 -3
- package/dist/esm/content/link-preview/content/index.js.map +1 -1
- package/dist/esm/content/link-preview/deps.js.map +1 -1
- package/dist/esm/content/transcript/index.js +1 -0
- package/dist/esm/content/transcript/index.js.map +1 -1
- package/dist/esm/content/transcript/providers/generic.js +84 -4
- package/dist/esm/content/transcript/providers/generic.js.map +1 -1
- package/dist/esm/content/transcript/providers/podcast.js +1 -0
- package/dist/esm/content/transcript/providers/podcast.js.map +1 -1
- package/dist/esm/content/transcript/providers/youtube/captions.js +35 -14
- package/dist/esm/content/transcript/providers/youtube/captions.js.map +1 -1
- package/dist/esm/content/transcript/providers/youtube/yt-dlp.js +84 -12
- package/dist/esm/content/transcript/providers/youtube/yt-dlp.js.map +1 -1
- package/dist/esm/content/transcript/providers/youtube.js +38 -2
- package/dist/esm/content/transcript/providers/youtube.js.map +1 -1
- package/dist/esm/content/transcript/utils.js +25 -69
- package/dist/esm/content/transcript/utils.js.map +1 -1
- package/dist/esm/content/url.js +76 -0
- package/dist/esm/content/url.js.map +1 -0
- package/dist/esm/prompts/cli.js +25 -5
- package/dist/esm/prompts/cli.js.map +1 -1
- package/dist/esm/prompts/file.js +51 -12
- package/dist/esm/prompts/file.js.map +1 -1
- package/dist/esm/prompts/format.js +26 -0
- package/dist/esm/prompts/format.js.map +1 -0
- package/dist/esm/prompts/link-summary.js +51 -22
- package/dist/esm/prompts/link-summary.js.map +1 -1
- package/dist/types/content/cache/types.d.ts +25 -0
- package/dist/types/content/index.d.ts +3 -1
- package/dist/types/content/link-preview/client.d.ts +6 -1
- package/dist/types/content/link-preview/content/types.d.ts +1 -1
- package/dist/types/content/link-preview/deps.d.ts +11 -20
- package/dist/types/content/transcript/cache.d.ts +1 -1
- package/dist/types/content/transcript/providers/generic.d.ts +1 -1
- package/dist/types/content/transcript/providers/youtube/captions.d.ts +3 -1
- package/dist/types/content/transcript/providers/youtube/yt-dlp.d.ts +3 -1
- package/dist/types/content/transcript/types.d.ts +2 -1
- package/dist/types/content/transcript/utils.d.ts +1 -3
- package/dist/types/content/url.d.ts +8 -0
- package/dist/types/prompts/cli.d.ts +4 -1
- package/dist/types/prompts/file.d.ts +9 -2
- package/dist/types/prompts/format.d.ts +14 -0
- package/dist/types/prompts/link-summary.d.ts +4 -1
- package/package.json +11 -8
package/dist/esm/prompts/cli.js
CHANGED
|
@@ -1,20 +1,40 @@
|
|
|
1
1
|
import { formatOutputLanguageInstruction } from '../language.js';
|
|
2
|
+
import { buildInstructions, buildTaggedPrompt } from './format.js';
|
|
2
3
|
function formatTargetLength(summaryLength) {
|
|
3
4
|
if (typeof summaryLength === 'string')
|
|
4
5
|
return '';
|
|
5
6
|
const max = summaryLength.maxCharacters;
|
|
6
7
|
return `Target length: around ${max.toLocaleString()} characters total (including Markdown and whitespace). This is a soft guideline; prioritize clarity.`;
|
|
7
8
|
}
|
|
8
|
-
export function buildPathSummaryPrompt({ kindLabel, filePath, filename, mediaType, outputLanguage, summaryLength, }) {
|
|
9
|
+
export function buildPathSummaryPrompt({ kindLabel, filePath, filename, mediaType, outputLanguage, summaryLength, promptOverride, lengthInstruction, languageInstruction, }) {
|
|
9
10
|
const headerLines = [
|
|
10
11
|
`Path: ${filePath}`,
|
|
11
12
|
filename ? `Filename: ${filename}` : null,
|
|
12
13
|
mediaType ? `Media type: ${mediaType}` : null,
|
|
13
14
|
].filter(Boolean);
|
|
14
15
|
const maxCharactersLine = formatTargetLength(summaryLength);
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const baseInstructions = [
|
|
17
|
+
`You summarize ${kindLabel === 'image' ? 'images' : 'files'} for curious users.`,
|
|
18
|
+
`Summarize the ${kindLabel} at the path below.`,
|
|
19
|
+
'Be factual and do not invent details.',
|
|
20
|
+
'Format the answer in Markdown.',
|
|
21
|
+
'Use short paragraphs; use bullet lists only when they improve scanability; avoid rigid templates.',
|
|
22
|
+
'Do not use emojis.',
|
|
23
|
+
maxCharactersLine,
|
|
24
|
+
formatOutputLanguageInstruction(outputLanguage ?? { kind: 'auto' }),
|
|
25
|
+
'Return only the summary.',
|
|
26
|
+
]
|
|
27
|
+
.filter((line) => typeof line === 'string' && line.trim().length > 0)
|
|
28
|
+
.join('\n');
|
|
29
|
+
const instructions = buildInstructions({
|
|
30
|
+
base: baseInstructions,
|
|
31
|
+
overrides: { promptOverride, lengthInstruction, languageInstruction },
|
|
32
|
+
});
|
|
33
|
+
const context = headerLines.join('\n');
|
|
34
|
+
return buildTaggedPrompt({
|
|
35
|
+
instructions,
|
|
36
|
+
context,
|
|
37
|
+
content: '',
|
|
38
|
+
});
|
|
19
39
|
}
|
|
20
40
|
//# sourceMappingURL=cli.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/prompts/cli.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/prompts/cli.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAwB,MAAM,aAAa,CAAA;AAGxF,SAAS,kBAAkB,CAAC,aAAkC;IAC5D,IAAI,OAAO,aAAa,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAA;IAChD,MAAM,GAAG,GAAG,aAAa,CAAC,aAAa,CAAA;IACvC,OAAO,yBAAyB,GAAG,CAAC,cAAc,EAAE,sGAAsG,CAAA;AAC5J,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,EACrC,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,SAAS,EACT,cAAc,EACd,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,mBAAmB,GAWpB;IACC,MAAM,WAAW,GAAG;QAClB,SAAS,QAAQ,EAAE;QACnB,QAAQ,CAAC,CAAC,CAAC,aAAa,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI;QACzC,SAAS,CAAC,CAAC,CAAC,eAAe,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI;KAC9C,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;IAEjB,MAAM,iBAAiB,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAA;IAC3D,MAAM,gBAAgB,GAAG;QACvB,iBAAiB,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,qBAAqB;QAChF,iBAAiB,SAAS,qBAAqB;QAC/C,uCAAuC;QACvC,gCAAgC;QAChC,mGAAmG;QACnG,oBAAoB;QACpB,iBAAiB;QACjB,+BAA+B,CAAC,cAAc,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACnE,0BAA0B;KAC3B;SACE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;SACpE,IAAI,CAAC,IAAI,CAAC,CAAA;IAEb,MAAM,YAAY,GAAG,iBAAiB,CAAC;QACrC,IAAI,EAAE,gBAAgB;QACtB,SAAS,EAAE,EAAE,cAAc,EAAE,iBAAiB,EAAE,mBAAmB,EAA4B;KAChG,CAAC,CAAA;IACF,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAEtC,OAAO,iBAAiB,CAAC;QACvB,YAAY;QACZ,OAAO;QACP,OAAO,EAAE,EAAE;KACZ,CAAC,CAAA;AACJ,CAAC"}
|
package/dist/esm/prompts/file.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { formatOutputLanguageInstruction } from '../language.js';
|
|
2
|
-
|
|
2
|
+
import { buildInstructions, buildTaggedPrompt } from './format.js';
|
|
3
|
+
export function buildFileSummaryPrompt({ filename, mediaType, outputLanguage, summaryLength, contentLength, promptOverride, lengthInstruction, languageInstruction, }) {
|
|
3
4
|
const contentCharacters = typeof contentLength === 'number' ? contentLength : null;
|
|
4
5
|
const effectiveSummaryLength = typeof summaryLength === 'string'
|
|
5
6
|
? summaryLength
|
|
@@ -18,14 +19,32 @@ export function buildFileSummaryPrompt({ filename, mediaType, outputLanguage, su
|
|
|
18
19
|
filename ? `Filename: ${filename}` : null,
|
|
19
20
|
mediaType ? `Media type: ${mediaType}` : null,
|
|
20
21
|
].filter(Boolean);
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
const baseInstructions = [
|
|
23
|
+
'You summarize files for curious users.',
|
|
24
|
+
'Summarize the attached file.',
|
|
25
|
+
'Be factual and do not invent details.',
|
|
26
|
+
'Format the answer in Markdown.',
|
|
27
|
+
'Use short paragraphs; use bullet lists only when they improve scanability; avoid rigid templates.',
|
|
28
|
+
'Do not use emojis.',
|
|
29
|
+
maxCharactersLine,
|
|
30
|
+
contentLengthLine,
|
|
31
|
+
formatOutputLanguageInstruction(outputLanguage ?? { kind: 'auto' }),
|
|
32
|
+
'Return only the summary.',
|
|
33
|
+
]
|
|
34
|
+
.filter((line) => typeof line === 'string' && line.trim().length > 0)
|
|
35
|
+
.join('\n');
|
|
36
|
+
const instructions = buildInstructions({
|
|
37
|
+
base: baseInstructions,
|
|
38
|
+
overrides: { promptOverride, lengthInstruction, languageInstruction },
|
|
39
|
+
});
|
|
40
|
+
const context = headerLines.join('\n');
|
|
41
|
+
return buildTaggedPrompt({
|
|
42
|
+
instructions,
|
|
43
|
+
context,
|
|
44
|
+
content: '',
|
|
45
|
+
});
|
|
27
46
|
}
|
|
28
|
-
export function buildFileTextSummaryPrompt({ filename, originalMediaType, contentMediaType, outputLanguage, summaryLength, contentLength, }) {
|
|
47
|
+
export function buildFileTextSummaryPrompt({ filename, originalMediaType, contentMediaType, outputLanguage, summaryLength, contentLength, content, promptOverride, lengthInstruction, languageInstruction, }) {
|
|
29
48
|
const effectiveSummaryLength = typeof summaryLength === 'string'
|
|
30
49
|
? summaryLength
|
|
31
50
|
: summaryLength.maxCharacters > contentLength
|
|
@@ -40,9 +59,29 @@ export function buildFileTextSummaryPrompt({ filename, originalMediaType, conten
|
|
|
40
59
|
`Provided as: ${contentMediaType}`,
|
|
41
60
|
`Extracted content length: ${contentLength.toLocaleString()} characters. Hard limit: never exceed this length. If the requested length is larger, do not pad—finish early rather than adding filler.`,
|
|
42
61
|
].filter(Boolean);
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
62
|
+
const baseInstructions = [
|
|
63
|
+
'You summarize files for curious users.',
|
|
64
|
+
'Summarize the file content below.',
|
|
65
|
+
'Be factual and do not invent details.',
|
|
66
|
+
'Format the answer in Markdown.',
|
|
67
|
+
'Use short paragraphs; use bullet lists only when they improve scanability; avoid rigid templates.',
|
|
68
|
+
'Do not use emojis.',
|
|
69
|
+
maxCharactersLine,
|
|
70
|
+
formatOutputLanguageInstruction(outputLanguage ?? { kind: 'auto' }),
|
|
71
|
+
'Return only the summary.',
|
|
72
|
+
]
|
|
73
|
+
.filter((line) => typeof line === 'string' && line.trim().length > 0)
|
|
74
|
+
.join('\n');
|
|
75
|
+
const instructions = buildInstructions({
|
|
76
|
+
base: baseInstructions,
|
|
77
|
+
overrides: { promptOverride, lengthInstruction, languageInstruction },
|
|
78
|
+
});
|
|
79
|
+
const context = headerLines.join('\n');
|
|
80
|
+
const contentText = typeof content === 'string' ? content : '';
|
|
81
|
+
return buildTaggedPrompt({
|
|
82
|
+
instructions,
|
|
83
|
+
context,
|
|
84
|
+
content: contentText,
|
|
85
|
+
});
|
|
47
86
|
}
|
|
48
87
|
//# sourceMappingURL=file.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../../src/prompts/file.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../../src/prompts/file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function buildInstructions({ base, overrides, }) {
|
|
2
|
+
const lines = [];
|
|
3
|
+
const override = overrides?.promptOverride?.trim();
|
|
4
|
+
if (override) {
|
|
5
|
+
lines.push(override);
|
|
6
|
+
}
|
|
7
|
+
else {
|
|
8
|
+
const trimmedBase = base.trim();
|
|
9
|
+
if (trimmedBase)
|
|
10
|
+
lines.push(trimmedBase);
|
|
11
|
+
}
|
|
12
|
+
const lengthInstruction = overrides?.lengthInstruction?.trim();
|
|
13
|
+
if (lengthInstruction)
|
|
14
|
+
lines.push(lengthInstruction);
|
|
15
|
+
const languageInstruction = overrides?.languageInstruction?.trim();
|
|
16
|
+
if (languageInstruction)
|
|
17
|
+
lines.push(languageInstruction);
|
|
18
|
+
return lines.join('\n');
|
|
19
|
+
}
|
|
20
|
+
export function buildTaggedPrompt({ instructions, context, content, }) {
|
|
21
|
+
const safeInstructions = instructions.trim();
|
|
22
|
+
const safeContext = context.trim();
|
|
23
|
+
const safeContent = typeof content === 'string' ? content : '';
|
|
24
|
+
return `<instructions>\n${safeInstructions}\n</instructions>\n\n<context>\n${safeContext}\n</context>\n\n<content>\n${safeContent}\n</content>\n`;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/prompts/format.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,iBAAiB,CAAC,EAChC,IAAI,EACJ,SAAS,GAIV;IACC,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,MAAM,QAAQ,GAAG,SAAS,EAAE,cAAc,EAAE,IAAI,EAAE,CAAA;IAClD,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IACtB,CAAC;SAAM,CAAC;QACN,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC/B,IAAI,WAAW;YAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAC1C,CAAC;IAED,MAAM,iBAAiB,GAAG,SAAS,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAA;IAC9D,IAAI,iBAAiB;QAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAA;IAEpD,MAAM,mBAAmB,GAAG,SAAS,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAA;IAClE,IAAI,mBAAmB;QAAE,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;IAExD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,EAChC,YAAY,EACZ,OAAO,EACP,OAAO,GAKR;IACC,MAAM,gBAAgB,GAAG,YAAY,CAAC,IAAI,EAAE,CAAA;IAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,EAAE,CAAA;IAClC,MAAM,WAAW,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAA;IAC9D,OAAO,mBAAmB,gBAAgB,mCAAmC,WAAW,8BAA8B,WAAW,gBAAgB,CAAA;AACnJ,CAAC"}
|
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
import { formatOutputLanguageInstruction } from '../language.js';
|
|
2
|
+
import { buildInstructions, buildTaggedPrompt } from './format.js';
|
|
2
3
|
const SUMMARY_LENGTH_DIRECTIVES = {
|
|
3
4
|
short: {
|
|
4
|
-
guidance: 'Write a tight
|
|
5
|
-
formatting: '
|
|
5
|
+
guidance: 'Write a tight summary in 2–3 sentences that delivers the primary claim plus one high-signal supporting detail.',
|
|
6
|
+
formatting: 'Return a single short paragraph.',
|
|
6
7
|
},
|
|
7
8
|
medium: {
|
|
8
|
-
guidance: 'Write two short paragraphs covering the core claim in the first paragraph and the most important supporting evidence
|
|
9
|
-
formatting: 'Each paragraph should contain 2–3 sentences. Separate paragraphs with a blank line.
|
|
9
|
+
guidance: 'Write two short paragraphs covering the core claim in the first paragraph and the most important supporting evidence or data points in the second.',
|
|
10
|
+
formatting: 'Each paragraph should contain 2–3 sentences. Separate paragraphs with a blank line.',
|
|
10
11
|
},
|
|
11
12
|
long: {
|
|
12
|
-
guidance: 'Write three paragraphs: (1)
|
|
13
|
-
formatting: '
|
|
13
|
+
guidance: 'Write three short paragraphs that summarize the text in order of importance: (1) core claim and scope, (2) key supporting facts or events, (3) other notable details or conclusions stated in the source.',
|
|
14
|
+
formatting: 'Each paragraph should contain 2–4 sentences. Separate paragraphs with a blank line.',
|
|
14
15
|
},
|
|
15
16
|
xl: {
|
|
16
|
-
guidance: '
|
|
17
|
-
formatting: 'Use
|
|
17
|
+
guidance: 'Write a detailed summary in 4–6 short paragraphs. Focus on what the text says (facts, events, arguments) and include concrete numbers or quotes when present.',
|
|
18
|
+
formatting: 'Use Markdown paragraphs separated by single blank lines.',
|
|
18
19
|
},
|
|
19
20
|
xxl: {
|
|
20
|
-
guidance: '
|
|
21
|
-
formatting: 'Use Markdown
|
|
21
|
+
guidance: 'Write a comprehensive summary in 6–10 short paragraphs. Cover background, main points, evidence, and stated outcomes in the source text; avoid adding implications or recommendations unless explicitly stated.',
|
|
22
|
+
formatting: 'Use Markdown paragraphs separated by single blank lines.',
|
|
22
23
|
},
|
|
23
24
|
};
|
|
25
|
+
const HEADING_LENGTH_CHAR_THRESHOLD = 6000;
|
|
24
26
|
export const SUMMARY_LENGTH_TO_TOKENS = {
|
|
25
27
|
short: 768,
|
|
26
28
|
medium: 1536,
|
|
@@ -48,7 +50,7 @@ const resolveSummaryDirective = (length) =>
|
|
|
48
50
|
// eslint-disable-next-line security/detect-object-injection
|
|
49
51
|
SUMMARY_LENGTH_DIRECTIVES[length];
|
|
50
52
|
const formatCount = (value) => value.toLocaleString();
|
|
51
|
-
export function buildLinkSummaryPrompt({ url, title, siteName, description, content, truncated, hasTranscript, outputLanguage, summaryLength, shares, }) {
|
|
53
|
+
export function buildLinkSummaryPrompt({ url, title, siteName, description, content, truncated, hasTranscript, outputLanguage, summaryLength, shares, promptOverride, lengthInstruction, languageInstruction, }) {
|
|
52
54
|
const contentCharacters = content.length;
|
|
53
55
|
const contextLines = [`Source URL: ${url}`];
|
|
54
56
|
if (title) {
|
|
@@ -76,6 +78,13 @@ export function buildLinkSummaryPrompt({ url, title, siteName, description, cont
|
|
|
76
78
|
? effectiveSummaryLength
|
|
77
79
|
: pickSummaryLengthForCharacters(effectiveSummaryLength.maxCharacters);
|
|
78
80
|
const directive = resolveSummaryDirective(preset);
|
|
81
|
+
const needsHeadings = preset === 'xl' ||
|
|
82
|
+
preset === 'xxl' ||
|
|
83
|
+
(typeof effectiveSummaryLength !== 'string' &&
|
|
84
|
+
effectiveSummaryLength.maxCharacters >= HEADING_LENGTH_CHAR_THRESHOLD);
|
|
85
|
+
const headingInstruction = needsHeadings
|
|
86
|
+
? 'Use Markdown headings with the "### " prefix to break sections. Include at least 3 headings and start with a heading. Do not use bold for headings.'
|
|
87
|
+
: '';
|
|
79
88
|
const maxCharactersLine = typeof effectiveSummaryLength === 'string'
|
|
80
89
|
? ''
|
|
81
90
|
: `Target length: up to ${formatCount(effectiveSummaryLength.maxCharacters)} characters total (including Markdown and whitespace). Hard limit: do not exceed it.`;
|
|
@@ -101,16 +110,36 @@ export function buildLinkSummaryPrompt({ url, title, siteName, description, cont
|
|
|
101
110
|
const shareGuidance = shares.length > 0
|
|
102
111
|
? 'You are also given quotes from people who recently shared this link. When these quotes contain substantive commentary, append a brief subsection titled "What sharers are saying" with one or two bullet points summarizing the key reactions. If they are generic reshares with no commentary, omit that subsection.'
|
|
103
112
|
: 'You are not given any quotes from people who shared this link. Do not fabricate reactions or add a "What sharers are saying" subsection.';
|
|
104
|
-
const
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
113
|
+
const shareBlock = shares.length > 0 ? `Tweets from sharers:\n${shareLines.join('\n')}` : '';
|
|
114
|
+
const baseInstructions = [
|
|
115
|
+
audienceLine,
|
|
116
|
+
directive.guidance,
|
|
117
|
+
directive.formatting,
|
|
118
|
+
headingInstruction,
|
|
119
|
+
maxCharactersLine,
|
|
120
|
+
contentLengthLine,
|
|
121
|
+
formatOutputLanguageInstruction(outputLanguage ?? { kind: 'auto' }),
|
|
122
|
+
'Keep the response compact by avoiding blank lines between sentences or list items; use only the single newlines required by the formatting instructions.',
|
|
123
|
+
'Do not use emojis, disclaimers, or speculation.',
|
|
124
|
+
'Write in direct, factual language.',
|
|
125
|
+
'Format the answer in Markdown and obey the length-specific formatting above.',
|
|
126
|
+
'Use short paragraphs; use bullet lists only when they improve scanability; avoid rigid templates.',
|
|
127
|
+
'Base everything strictly on the provided content and never invent details.',
|
|
128
|
+
shareGuidance,
|
|
129
|
+
]
|
|
130
|
+
.filter((line) => typeof line === 'string' && line.trim().length > 0)
|
|
131
|
+
.join('\n');
|
|
132
|
+
const instructions = buildInstructions({
|
|
133
|
+
base: baseInstructions,
|
|
134
|
+
overrides: { promptOverride, lengthInstruction, languageInstruction },
|
|
135
|
+
});
|
|
136
|
+
const context = [contextHeader, shareBlock]
|
|
137
|
+
.filter((line) => typeof line === 'string' && line.trim().length > 0)
|
|
138
|
+
.join('\n');
|
|
139
|
+
return buildTaggedPrompt({
|
|
140
|
+
instructions,
|
|
141
|
+
context,
|
|
142
|
+
content,
|
|
143
|
+
});
|
|
115
144
|
}
|
|
116
145
|
//# sourceMappingURL=link-summary.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link-summary.js","sourceRoot":"","sources":["../../../src/prompts/link-summary.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"link-summary.js","sourceRoot":"","sources":["../../../src/prompts/link-summary.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { TranscriptSource } from '../link-preview/types.js';
|
|
2
|
+
/** Public shape returned by transcript cache implementations. */
|
|
3
|
+
export interface TranscriptCacheGetResult {
|
|
4
|
+
content: string | null;
|
|
5
|
+
source: TranscriptSource | null;
|
|
6
|
+
expired: boolean;
|
|
7
|
+
metadata?: Record<string, unknown> | null;
|
|
8
|
+
}
|
|
9
|
+
/** Public write arguments for transcript cache implementations. */
|
|
10
|
+
export interface TranscriptCacheSetArgs {
|
|
11
|
+
url: string;
|
|
12
|
+
service: string;
|
|
13
|
+
resourceKey: string | null;
|
|
14
|
+
content: string | null;
|
|
15
|
+
source: TranscriptSource | null;
|
|
16
|
+
ttlMs: number;
|
|
17
|
+
metadata?: Record<string, unknown> | null;
|
|
18
|
+
}
|
|
19
|
+
/** Public interface for pluggable transcript caches (CLI, daemon, apps). */
|
|
20
|
+
export interface TranscriptCache {
|
|
21
|
+
get(args: {
|
|
22
|
+
url: string;
|
|
23
|
+
}): Promise<TranscriptCacheGetResult | null>;
|
|
24
|
+
set(args: TranscriptCacheSetArgs): Promise<void>;
|
|
25
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
export type { TranscriptCache, TranscriptCacheGetResult, TranscriptCacheSetArgs, } from './cache/types.js';
|
|
1
2
|
export { createLinkPreviewClient, type LinkPreviewClient, type LinkPreviewClientOptions, } from './link-preview/client.js';
|
|
2
3
|
export { DEFAULT_CACHE_MODE, DEFAULT_MAX_CONTENT_CHARACTERS, DEFAULT_TIMEOUT_MS, type ExtractedLinkContent, type FetchLinkContentOptions, } from './link-preview/content/types.js';
|
|
3
|
-
export type { ConvertHtmlToMarkdown, FirecrawlScrapeResult, LinkPreviewDeps, LinkPreviewProgressEvent, ReadTweetWithBird, ScrapeWithFirecrawl,
|
|
4
|
+
export type { ConvertHtmlToMarkdown, FirecrawlScrapeResult, LinkPreviewDeps, LinkPreviewProgressEvent, ReadTweetWithBird, ScrapeWithFirecrawl, } from './link-preview/deps.js';
|
|
4
5
|
export { ProgressKind } from './link-preview/deps.js';
|
|
5
6
|
export { CACHE_MODES, type CacheMode, type CacheStatus, type TranscriptSource, } from './link-preview/types.js';
|
|
7
|
+
export { extractYouTubeVideoId, isDirectMediaUrl, isPodcastHost, isTwitterStatusUrl, isYouTubeUrl, isYouTubeVideoUrl, shouldPreferUrlMode, } from './url.js';
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import type { TranscriptCache } from '../cache/types.js';
|
|
1
2
|
import type { ExtractedLinkContent, FetchLinkContentOptions } from './content/types.js';
|
|
2
|
-
import type { ConvertHtmlToMarkdown, LinkPreviewDeps, LinkPreviewProgressEvent,
|
|
3
|
+
import type { ConvertHtmlToMarkdown, LinkPreviewDeps, LinkPreviewProgressEvent, ResolveTwitterCookies, ScrapeWithFirecrawl } from './deps.js';
|
|
4
|
+
/** Public client used by external consumers to fetch link content. */
|
|
3
5
|
export interface LinkPreviewClient {
|
|
4
6
|
fetchLinkContent(url: string, options?: FetchLinkContentOptions): Promise<ExtractedLinkContent>;
|
|
5
7
|
}
|
|
8
|
+
/** Public options for wiring dependencies into the link preview client. */
|
|
6
9
|
export interface LinkPreviewClientOptions {
|
|
7
10
|
fetch?: typeof fetch;
|
|
8
11
|
scrapeWithFirecrawl?: ScrapeWithFirecrawl | null;
|
|
@@ -13,6 +16,8 @@ export interface LinkPreviewClientOptions {
|
|
|
13
16
|
convertHtmlToMarkdown?: ConvertHtmlToMarkdown | null;
|
|
14
17
|
transcriptCache?: TranscriptCache | null;
|
|
15
18
|
readTweetWithBird?: LinkPreviewDeps['readTweetWithBird'];
|
|
19
|
+
resolveTwitterCookies?: ResolveTwitterCookies | null;
|
|
16
20
|
onProgress?: ((event: LinkPreviewProgressEvent) => void) | null;
|
|
17
21
|
}
|
|
22
|
+
/** Public factory for a link preview client with injectable dependencies. */
|
|
18
23
|
export declare function createLinkPreviewClient(options?: LinkPreviewClientOptions): LinkPreviewClient;
|
|
@@ -2,7 +2,7 @@ import type { CacheMode, ContentFetchDiagnostics, TranscriptDiagnostics, Transcr
|
|
|
2
2
|
export declare const DEFAULT_TIMEOUT_MS = 120000;
|
|
3
3
|
export declare const DEFAULT_MAX_CONTENT_CHARACTERS = 8000;
|
|
4
4
|
export declare const DEFAULT_CACHE_MODE: CacheMode;
|
|
5
|
-
export type YoutubeTranscriptMode = 'auto' | 'web' | 'apify' | 'yt-dlp';
|
|
5
|
+
export type YoutubeTranscriptMode = 'auto' | 'web' | 'apify' | 'yt-dlp' | 'no-auto';
|
|
6
6
|
export type FirecrawlMode = 'off' | 'auto' | 'always';
|
|
7
7
|
export type ContentFormat = 'text' | 'markdown';
|
|
8
8
|
export type MarkdownMode = 'off' | 'auto' | 'llm' | 'readability';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { TranscriptCache } from '../cache/types.js';
|
|
1
2
|
import type { CacheMode, TranscriptSource } from './types.js';
|
|
2
3
|
export declare const ProgressKind: {
|
|
3
4
|
readonly FetchHtmlStart: "fetch-html-start";
|
|
@@ -17,6 +18,7 @@ export declare const ProgressKind: {
|
|
|
17
18
|
readonly BirdStart: "bird-start";
|
|
18
19
|
readonly BirdDone: "bird-done";
|
|
19
20
|
};
|
|
21
|
+
/** Public progress events emitted by link preview fetchers. */
|
|
20
22
|
export type LinkPreviewProgressEvent = {
|
|
21
23
|
kind: 'fetch-html-start';
|
|
22
24
|
url: string;
|
|
@@ -132,27 +134,15 @@ export type ReadTweetWithBird = (args: {
|
|
|
132
134
|
url: string;
|
|
133
135
|
timeoutMs: number;
|
|
134
136
|
}) => Promise<BirdTweetPayload | null>;
|
|
135
|
-
export
|
|
136
|
-
|
|
137
|
-
source
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
export interface TranscriptCacheSetArgs {
|
|
137
|
+
export type TwitterCookieSource = {
|
|
138
|
+
cookiesFromBrowser: string | null;
|
|
139
|
+
source?: string | null;
|
|
140
|
+
warnings?: string[];
|
|
141
|
+
};
|
|
142
|
+
export type ResolveTwitterCookies = (args: {
|
|
142
143
|
url: string;
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
content: string | null;
|
|
146
|
-
source: TranscriptSource | null;
|
|
147
|
-
ttlMs: number;
|
|
148
|
-
metadata?: Record<string, unknown> | null;
|
|
149
|
-
}
|
|
150
|
-
export interface TranscriptCache {
|
|
151
|
-
get(args: {
|
|
152
|
-
url: string;
|
|
153
|
-
}): Promise<TranscriptCacheGetResult | null>;
|
|
154
|
-
set(args: TranscriptCacheSetArgs): Promise<void>;
|
|
155
|
-
}
|
|
144
|
+
}) => Promise<TwitterCookieSource>;
|
|
145
|
+
/** Internal dependency bag; prefer createLinkPreviewClient unless you need custom wiring. */
|
|
156
146
|
export interface LinkPreviewDeps {
|
|
157
147
|
fetch: typeof fetch;
|
|
158
148
|
scrapeWithFirecrawl: ScrapeWithFirecrawl | null;
|
|
@@ -163,5 +153,6 @@ export interface LinkPreviewDeps {
|
|
|
163
153
|
convertHtmlToMarkdown: ConvertHtmlToMarkdown | null;
|
|
164
154
|
transcriptCache: TranscriptCache | null;
|
|
165
155
|
readTweetWithBird?: ReadTweetWithBird | null;
|
|
156
|
+
resolveTwitterCookies?: ResolveTwitterCookies | null;
|
|
166
157
|
onProgress?: ((event: LinkPreviewProgressEvent) => void) | null;
|
|
167
158
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TranscriptCache } from '../
|
|
1
|
+
import type { TranscriptCache } from '../cache/types.js';
|
|
2
2
|
import type { CacheMode, TranscriptDiagnostics, TranscriptResolution, TranscriptSource } from '../link-preview/types.js';
|
|
3
3
|
export declare const DEFAULT_TTL_MS: number;
|
|
4
4
|
export declare const NEGATIVE_TTL_MS: number;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { ProviderContext, ProviderFetchOptions, ProviderResult } from '../types.js';
|
|
2
2
|
export declare const canHandle: () => boolean;
|
|
3
|
-
export declare const fetchTranscript: (
|
|
3
|
+
export declare const fetchTranscript: (context: ProviderContext, options: ProviderFetchOptions) => Promise<ProviderResult>;
|
|
@@ -3,5 +3,7 @@ interface YoutubeTranscriptContext {
|
|
|
3
3
|
originalUrl: string;
|
|
4
4
|
videoId: string;
|
|
5
5
|
}
|
|
6
|
-
export declare const fetchTranscriptFromCaptionTracks: (fetchImpl: typeof fetch, { html, originalUrl, videoId }: YoutubeTranscriptContext
|
|
6
|
+
export declare const fetchTranscriptFromCaptionTracks: (fetchImpl: typeof fetch, { html, originalUrl, videoId, skipAutoGenerated, }: YoutubeTranscriptContext & {
|
|
7
|
+
skipAutoGenerated?: boolean;
|
|
8
|
+
}) => Promise<string | null>;
|
|
7
9
|
export {};
|
|
@@ -12,6 +12,8 @@ type YtDlpRequest = {
|
|
|
12
12
|
falApiKey: string | null;
|
|
13
13
|
url: string;
|
|
14
14
|
onProgress?: ((event: LinkPreviewProgressEvent) => void) | null;
|
|
15
|
+
service?: 'youtube' | 'podcast' | 'generic';
|
|
16
|
+
extraArgs?: string[];
|
|
15
17
|
};
|
|
16
|
-
export declare const fetchTranscriptWithYtDlp: ({ ytDlpPath, openaiApiKey, falApiKey, url, onProgress, }: YtDlpRequest) => Promise<YtDlpTranscriptResult>;
|
|
18
|
+
export declare const fetchTranscriptWithYtDlp: ({ ytDlpPath, openaiApiKey, falApiKey, url, onProgress, service, extraArgs, }: YtDlpRequest) => Promise<YtDlpTranscriptResult>;
|
|
17
19
|
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { YoutubeTranscriptMode } from '../link-preview/content/types.js';
|
|
2
|
-
import type { LinkPreviewProgressEvent, ScrapeWithFirecrawl } from '../link-preview/deps.js';
|
|
2
|
+
import type { LinkPreviewProgressEvent, ResolveTwitterCookies, ScrapeWithFirecrawl } from '../link-preview/deps.js';
|
|
3
3
|
import type { TranscriptResolution, TranscriptSource } from '../link-preview/types.js';
|
|
4
4
|
export type TranscriptService = 'youtube' | 'podcast' | 'generic';
|
|
5
5
|
export interface ProviderContext {
|
|
@@ -15,6 +15,7 @@ export interface ProviderFetchOptions {
|
|
|
15
15
|
ytDlpPath: string | null;
|
|
16
16
|
falApiKey: string | null;
|
|
17
17
|
openaiApiKey: string | null;
|
|
18
|
+
resolveTwitterCookies?: ResolveTwitterCookies | null;
|
|
18
19
|
onProgress?: ((event: LinkPreviewProgressEvent) => void) | null;
|
|
19
20
|
}
|
|
20
21
|
export interface ProviderResult extends TranscriptResolution {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
+
export { extractYouTubeVideoId, isYouTubeUrl, isYouTubeVideoUrl } from '../url.js';
|
|
1
2
|
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
2
|
-
export declare const isYouTubeUrl: (rawUrl: string) => boolean;
|
|
3
|
-
export declare function isYouTubeVideoUrl(rawUrl: string): boolean;
|
|
4
|
-
export declare function extractYouTubeVideoId(rawUrl: string): string | null;
|
|
5
3
|
export declare function extractEmbeddedYouTubeUrlFromHtml(html: string, maxTextChars?: number, maxReadabilityChars?: number): Promise<string | null>;
|
|
6
4
|
export declare function sanitizeYoutubeJsonResponse(input: string): string;
|
|
7
5
|
export declare function decodeHtmlEntities(input: string): string;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { isPodcastHost } from './link-preview/content/podcast-utils.js';
|
|
2
|
+
import { isTwitterStatusUrl } from './link-preview/content/twitter-utils.js';
|
|
3
|
+
export declare const isYouTubeUrl: (rawUrl: string) => boolean;
|
|
4
|
+
export declare function isYouTubeVideoUrl(rawUrl: string): boolean;
|
|
5
|
+
export declare function extractYouTubeVideoId(rawUrl: string): string | null;
|
|
6
|
+
export declare function isDirectMediaUrl(url: string): boolean;
|
|
7
|
+
export declare function shouldPreferUrlMode(url: string): boolean;
|
|
8
|
+
export { isTwitterStatusUrl, isPodcastHost };
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import type { OutputLanguage } from '../language.js';
|
|
2
2
|
import type { SummaryLengthTarget } from './link-summary.js';
|
|
3
|
-
export declare function buildPathSummaryPrompt({ kindLabel, filePath, filename, mediaType, outputLanguage, summaryLength, }: {
|
|
3
|
+
export declare function buildPathSummaryPrompt({ kindLabel, filePath, filename, mediaType, outputLanguage, summaryLength, promptOverride, lengthInstruction, languageInstruction, }: {
|
|
4
4
|
kindLabel: 'file' | 'image';
|
|
5
5
|
filePath: string;
|
|
6
6
|
filename: string | null;
|
|
7
7
|
mediaType: string | null;
|
|
8
8
|
summaryLength: SummaryLengthTarget;
|
|
9
9
|
outputLanguage?: OutputLanguage | null;
|
|
10
|
+
promptOverride?: string | null;
|
|
11
|
+
lengthInstruction?: string | null;
|
|
12
|
+
languageInstruction?: string | null;
|
|
10
13
|
}): string;
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
import type { OutputLanguage } from '../language.js';
|
|
2
2
|
import type { SummaryLengthTarget } from './link-summary.js';
|
|
3
|
-
export declare function buildFileSummaryPrompt({ filename, mediaType, outputLanguage, summaryLength, contentLength, }: {
|
|
3
|
+
export declare function buildFileSummaryPrompt({ filename, mediaType, outputLanguage, summaryLength, contentLength, promptOverride, lengthInstruction, languageInstruction, }: {
|
|
4
4
|
filename: string | null;
|
|
5
5
|
mediaType: string | null;
|
|
6
6
|
summaryLength: SummaryLengthTarget;
|
|
7
7
|
contentLength?: number | null;
|
|
8
8
|
outputLanguage?: OutputLanguage | null;
|
|
9
|
+
promptOverride?: string | null;
|
|
10
|
+
lengthInstruction?: string | null;
|
|
11
|
+
languageInstruction?: string | null;
|
|
9
12
|
}): string;
|
|
10
|
-
export declare function buildFileTextSummaryPrompt({ filename, originalMediaType, contentMediaType, outputLanguage, summaryLength, contentLength, }: {
|
|
13
|
+
export declare function buildFileTextSummaryPrompt({ filename, originalMediaType, contentMediaType, outputLanguage, summaryLength, contentLength, content, promptOverride, lengthInstruction, languageInstruction, }: {
|
|
11
14
|
filename: string | null;
|
|
12
15
|
originalMediaType: string | null;
|
|
13
16
|
contentMediaType: string;
|
|
14
17
|
summaryLength: SummaryLengthTarget;
|
|
15
18
|
contentLength: number;
|
|
16
19
|
outputLanguage?: OutputLanguage | null;
|
|
20
|
+
content?: string | null;
|
|
21
|
+
promptOverride?: string | null;
|
|
22
|
+
lengthInstruction?: string | null;
|
|
23
|
+
languageInstruction?: string | null;
|
|
17
24
|
}): string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type PromptOverrides = {
|
|
2
|
+
promptOverride?: string | null;
|
|
3
|
+
lengthInstruction?: string | null;
|
|
4
|
+
languageInstruction?: string | null;
|
|
5
|
+
};
|
|
6
|
+
export declare function buildInstructions({ base, overrides, }: {
|
|
7
|
+
base: string;
|
|
8
|
+
overrides?: PromptOverrides | null;
|
|
9
|
+
}): string;
|
|
10
|
+
export declare function buildTaggedPrompt({ instructions, context, content, }: {
|
|
11
|
+
instructions: string;
|
|
12
|
+
context: string;
|
|
13
|
+
content: string;
|
|
14
|
+
}): string;
|
|
@@ -15,7 +15,7 @@ export type ShareContextEntry = {
|
|
|
15
15
|
replyCount?: number | null;
|
|
16
16
|
timestamp?: string | null;
|
|
17
17
|
};
|
|
18
|
-
export declare function buildLinkSummaryPrompt({ url, title, siteName, description, content, truncated, hasTranscript, outputLanguage, summaryLength, shares, }: {
|
|
18
|
+
export declare function buildLinkSummaryPrompt({ url, title, siteName, description, content, truncated, hasTranscript, outputLanguage, summaryLength, shares, promptOverride, lengthInstruction, languageInstruction, }: {
|
|
19
19
|
url: string;
|
|
20
20
|
title: string | null;
|
|
21
21
|
siteName: string | null;
|
|
@@ -26,4 +26,7 @@ export declare function buildLinkSummaryPrompt({ url, title, siteName, descripti
|
|
|
26
26
|
summaryLength: SummaryLengthTarget;
|
|
27
27
|
outputLanguage?: OutputLanguage | null;
|
|
28
28
|
shares: ShareContextEntry[];
|
|
29
|
+
promptOverride?: string | null;
|
|
30
|
+
lengthInstruction?: string | null;
|
|
31
|
+
languageInstruction?: string | null;
|
|
29
32
|
}): string;
|