@bitkyc08/opencodex 2.6.11 → 2.6.12
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/README.ko.md +135 -35
- package/README.md +6 -0
- package/README.zh-CN.md +147 -26
- package/gui/dist/assets/{index-DaRQZAM0.js → index-CTjsL04v.js} +1 -1
- package/gui/dist/index.html +1 -1
- package/package.json +1 -1
- package/src/web-search/parse.ts +52 -15
package/gui/dist/index.html
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
} catch (e) {}
|
|
17
17
|
})();
|
|
18
18
|
</script>
|
|
19
|
-
<script type="module" crossorigin src="/assets/index-
|
|
19
|
+
<script type="module" crossorigin src="/assets/index-CTjsL04v.js"></script>
|
|
20
20
|
<link rel="stylesheet" crossorigin href="/assets/index-DIBiVVC0.css">
|
|
21
21
|
</head>
|
|
22
22
|
<body>
|
package/package.json
CHANGED
package/src/web-search/parse.ts
CHANGED
|
@@ -41,38 +41,75 @@ function collectAnnotation(ann: AnnotationLike | undefined, sources: WebSearchSo
|
|
|
41
41
|
* answer text with that section stripped so the tool_result renderer doesn't double-print sources.
|
|
42
42
|
*
|
|
43
43
|
* Handles the per-line forms seen from the backend: `- title: url`, `- title (url)`,
|
|
44
|
-
* `- [title](url)`, `- <url>`, `- url`,
|
|
44
|
+
* `- [title](url)`, `- <url>`, `- url`, numbered `1. ...` variants, a markdown-prefixed header
|
|
45
|
+
* (`### Sources:`, `**Sources**`), a title line whose URL sits on the FOLLOWING line, and trailing
|
|
46
|
+
* URL punctuation (`;`, `,`, `)`, `]`, `.`). Prose that follows the source list is preserved.
|
|
45
47
|
*/
|
|
46
|
-
const URL_RE = /https?:\/\/[^\s<>()\]]+/;
|
|
48
|
+
const URL_RE = /https?:\/\/[^\s<>()\[\]]+/;
|
|
49
|
+
// A "Sources:" / "Source:" header, allowing markdown prefixes (#, *, -, >) and bold/italic wrappers.
|
|
50
|
+
const SOURCES_HEADER_RE = /^\s*(?:#{1,6}\s*)?[-*>\s]*\**\s*sources?\s*\**\s*:?\s*\**\s*$/i;
|
|
51
|
+
|
|
52
|
+
/** Trim wrapping/trailing noise from a captured URL: angle brackets, then trailing punctuation. */
|
|
53
|
+
function cleanUrl(url: string): string {
|
|
54
|
+
return url.replace(/^<+/, "").replace(/[)>\].,;:]+$/, "");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Derive a human title from the list-item text preceding the URL (strip markers, md link, seps). */
|
|
58
|
+
function cleanTitle(prefix: string): string {
|
|
59
|
+
let title = prefix.replace(/^[-*>\d.)\s]+/, "").trim();
|
|
60
|
+
// `[title](` from a markdown link, or a leading `[`.
|
|
61
|
+
title = title.replace(/^\[/, "").replace(/\]\(?$/, "").replace(/[:\-—(<]\s*$/, "").trim();
|
|
62
|
+
return title;
|
|
63
|
+
}
|
|
64
|
+
|
|
47
65
|
function extractTrailingSources(text: string): { text: string; sources: WebSearchSource[] } {
|
|
48
66
|
const lines = text.split("\n");
|
|
49
|
-
// Find the LAST line that is
|
|
67
|
+
// Find the LAST line that is a "Sources:" header (markdown prefixes allowed).
|
|
50
68
|
let headerIdx = -1;
|
|
51
69
|
for (let i = lines.length - 1; i >= 0; i--) {
|
|
52
|
-
if (
|
|
70
|
+
if (SOURCES_HEADER_RE.test(lines[i])) { headerIdx = i; break; }
|
|
53
71
|
}
|
|
54
72
|
if (headerIdx === -1) return { text, sources: [] };
|
|
55
73
|
const sources: WebSearchSource[] = [];
|
|
56
74
|
const seen = new Set<string>();
|
|
75
|
+
// Track the last line index actually consumed as part of the source list so trailing prose after
|
|
76
|
+
// the list survives (we strip the header through the last consumed source line, not to EOF).
|
|
77
|
+
let lastConsumed = headerIdx;
|
|
78
|
+
// A title line whose URL is expected on a following line (multiline entry).
|
|
79
|
+
let pendingTitle: string | null = null;
|
|
57
80
|
for (let i = headerIdx + 1; i < lines.length; i++) {
|
|
58
81
|
const raw = lines[i].trim();
|
|
59
|
-
if (raw === "")
|
|
60
|
-
|
|
61
|
-
|
|
82
|
+
if (raw === "") {
|
|
83
|
+
// Blank line between header and first entry is fine; a blank AFTER entries ends the list.
|
|
84
|
+
if (sources.length > 0 || pendingTitle !== null) break;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
62
87
|
const m = raw.match(URL_RE);
|
|
63
|
-
if (!m)
|
|
64
|
-
|
|
88
|
+
if (!m) {
|
|
89
|
+
// A list-ish line with no URL may be a title whose URL is on the next line. Only treat it as a
|
|
90
|
+
// pending title when it looks like a list item; otherwise it's prose → stop.
|
|
91
|
+
if (/^[-*>\d.)]/.test(raw) || pendingTitle === null) {
|
|
92
|
+
if (/^[-*>\d.)]/.test(raw)) { pendingTitle = raw; lastConsumed = i; continue; }
|
|
93
|
+
}
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
const url = cleanUrl(m[0]);
|
|
97
|
+
if (!url) { break; }
|
|
98
|
+
lastConsumed = i;
|
|
99
|
+
// Title: text before the URL on this line, else a buffered title from a preceding line.
|
|
100
|
+
const inlinePrefix = raw.slice(0, m.index);
|
|
101
|
+
const title = cleanTitle(inlinePrefix) || (pendingTitle ? cleanTitle(pendingTitle) : "");
|
|
102
|
+
pendingTitle = null;
|
|
65
103
|
if (seen.has(url)) continue;
|
|
66
104
|
seen.add(url);
|
|
67
|
-
// Derive a title from the text before the URL: strip list markers, [md](), and separators.
|
|
68
|
-
let title = raw.slice(0, m.index).replace(/^[-*\d.)\s]+/, "").trim();
|
|
69
|
-
title = title.replace(/^\[/, "").replace(/\]\(?$/, "").replace(/[:\-—(]\s*$/, "").trim();
|
|
70
105
|
sources.push(title ? { url, title } : { url });
|
|
71
106
|
}
|
|
72
107
|
if (sources.length === 0) return { text, sources: [] };
|
|
73
|
-
//
|
|
74
|
-
const
|
|
75
|
-
|
|
108
|
+
// Keep text before the header AND any prose after the consumed source lines.
|
|
109
|
+
const before = lines.slice(0, headerIdx).join("\n").replace(/\s+$/, "");
|
|
110
|
+
const after = lines.slice(lastConsumed + 1).join("\n").replace(/^\s+/, "");
|
|
111
|
+
const body = after ? (before ? `${before}\n\n${after}` : after) : before;
|
|
112
|
+
return { text: body, sources };
|
|
76
113
|
}
|
|
77
114
|
|
|
78
115
|
/** Pull final text + url_citation sources from a completed Responses `output[]` array. */
|