zames_pro 2.81.13 → 2.81.15
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/CHANGELOG.md +12 -0
- package/dist/glm-net-capture.js +10 -1
- package/dist/web.js +36 -22
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.81.15] - 2026-10-21
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **web:** a search result without a snippet no longer borrows the next one
|
|
15
|
+
|
|
16
|
+
## [2.81.14] - 2026-10-21
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **glm:** an answer that mentions the captcha is not the captcha
|
|
21
|
+
|
|
10
22
|
## [2.81.13] - 2026-10-21
|
|
11
23
|
|
|
12
24
|
### Fixed
|
package/dist/glm-net-capture.js
CHANGED
|
@@ -320,7 +320,16 @@ export function isCaptchaText(body) {
|
|
|
320
320
|
const b = String(body || '');
|
|
321
321
|
if (!b)
|
|
322
322
|
return false;
|
|
323
|
-
|
|
323
|
+
const hit = /security verification|drag the slider|CertifyId/i.test(b);
|
|
324
|
+
if (!hit)
|
|
325
|
+
return false;
|
|
326
|
+
// The SAME body may be the answer SSE stream (this classifier runs on every
|
|
327
|
+
// response). An answer that merely MENTIONS the captcha must not be taken
|
|
328
|
+
// for the challenge page: an error payload or a body WITHOUT answer text
|
|
329
|
+
// only (same rule as the rate-limit / guest classifiers).
|
|
330
|
+
if (!ERROR_PAYLOAD_RE.test(b) && hasAnswerContent(b))
|
|
331
|
+
return false;
|
|
332
|
+
return true;
|
|
324
333
|
}
|
|
325
334
|
/**
|
|
326
335
|
* Read the chat id off the RAW body (the chat list / history JSON carries it as
|
package/dist/web.js
CHANGED
|
@@ -645,33 +645,47 @@ export function createWebTools() {
|
|
|
645
645
|
// wraps links in a /l/?uddg=... redirect which must be unwrapped.
|
|
646
646
|
export function parseDuckDuckGoResults(body, limit) {
|
|
647
647
|
const results = [];
|
|
648
|
-
|
|
648
|
+
// Parse the page ROW BY ROW: each `result__a` title opens a result, and a
|
|
649
|
+
// `result__snippet` belongs to the result opened most recently. The old
|
|
650
|
+
// single regex made the snippet group OPTIONAL with an unbounded gap, so a
|
|
651
|
+
// result without a snippet picked up the FOLLOWING result's snippet (wrong
|
|
652
|
+
// text under a URL). A row scan ties every snippet to its own result.
|
|
653
|
+
const anchorRe = /<a[^>]*class="[^"]*result__(a|snippet)[^"]*"[^>]*>([\s\S]*?)<\/a>/gi;
|
|
654
|
+
const hrefOf = (tag) => {
|
|
655
|
+
const m = tag.match(/href="([^"]*)"/i);
|
|
656
|
+
return m ? m[1] : '';
|
|
657
|
+
};
|
|
658
|
+
let cur = null;
|
|
649
659
|
let m;
|
|
650
|
-
while ((m =
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
try {
|
|
658
|
-
href = decodeURIComponent(uddgMatch[1]);
|
|
660
|
+
while ((m = anchorRe.exec(body))) {
|
|
661
|
+
const kind = m[1].toLowerCase();
|
|
662
|
+
if (kind === 'a') {
|
|
663
|
+
if (cur && cur.title && /^https?:\/\//i.test(cur.url)) {
|
|
664
|
+
results.push(cur);
|
|
665
|
+
if (results.length >= limit)
|
|
666
|
+
return results;
|
|
659
667
|
}
|
|
660
|
-
|
|
661
|
-
|
|
668
|
+
cur = { title: htmlToText(m[2] || '').trim(), url: '', snippet: '' };
|
|
669
|
+
// The href lives in the OPENING tag, which m[0] starts with.
|
|
670
|
+
let href = hrefOf(m[0].slice(0, m[0].indexOf('>') + 1));
|
|
671
|
+
const uddg = href.match(/[?&]uddg=([^&]+)/);
|
|
672
|
+
if (uddg) {
|
|
673
|
+
try {
|
|
674
|
+
href = decodeURIComponent(uddg[1]);
|
|
675
|
+
}
|
|
676
|
+
catch {
|
|
677
|
+
href = uddg[1];
|
|
678
|
+
}
|
|
662
679
|
}
|
|
663
|
-
|
|
664
|
-
const title = htmlToText(m[2] || '').trim();
|
|
665
|
-
const snippet = htmlToText(m[3] || '').trim();
|
|
666
|
-
// Only an absolute http(s) link is a real result. The page can carry a
|
|
667
|
-
// `javascript:`/`data:` href (malicious or broken markup) or a
|
|
668
|
-
// site-relative one; handing either to the model as a result URL is wrong
|
|
669
|
-
// (a `javascript:` URL looks fetchable, a relative one is not).
|
|
670
|
-
if (!title || !/^https?:\/\//i.test(href))
|
|
680
|
+
cur.url = href;
|
|
671
681
|
continue;
|
|
672
|
-
|
|
682
|
+
}
|
|
683
|
+
if (cur && !cur.snippet)
|
|
684
|
+
cur.snippet = htmlToText(m[2] || '').trim();
|
|
673
685
|
}
|
|
674
|
-
|
|
686
|
+
if (cur && cur.title && /^https?:\/\//i.test(cur.url))
|
|
687
|
+
results.push(cur);
|
|
688
|
+
return results.slice(0, limit);
|
|
675
689
|
}
|
|
676
690
|
function formatResult(status, url, text, limit) {
|
|
677
691
|
let out = text;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zames_pro",
|
|
3
|
-
"version": "2.81.
|
|
3
|
+
"version": "2.81.15",
|
|
4
4
|
"description": "Terminal coding agent that drives a real browser to chat with DeepSeek, Qwen and other web LLMs — no API key required. Reads and edits files, runs commands, commits to git, like Claude Code / Codex CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|