@zooique/memora 3.0.1 → 5.0.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/CHANGELOG.md +161 -1033
- package/README.en.md +46 -39
- package/README.md +40 -35
- package/config.example.json +1 -8
- package/dist/agent/agent.d.ts +88 -80
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +272 -221
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/assembler.d.ts +22 -21
- package/dist/agent/assembler.d.ts.map +1 -1
- package/dist/agent/assembler.js +120 -46
- package/dist/agent/assembler.js.map +1 -1
- package/dist/agent/backgroundTasks.d.ts +194 -0
- package/dist/agent/backgroundTasks.d.ts.map +1 -0
- package/dist/agent/backgroundTasks.js +314 -0
- package/dist/agent/backgroundTasks.js.map +1 -0
- package/dist/agent/budget.d.ts +23 -5
- package/dist/agent/budget.d.ts.map +1 -1
- package/dist/agent/budget.js +8 -2
- package/dist/agent/budget.js.map +1 -1
- package/dist/agent/builtinToolHandlers.d.ts +29 -9
- package/dist/agent/builtinToolHandlers.d.ts.map +1 -1
- package/dist/agent/builtinToolHandlers.js +53 -13
- package/dist/agent/builtinToolHandlers.js.map +1 -1
- package/dist/agent/builtinTools.d.ts +15 -1
- package/dist/agent/builtinTools.d.ts.map +1 -1
- package/dist/agent/builtinTools.js +111 -30
- package/dist/agent/builtinTools.js.map +1 -1
- package/dist/agent/constants.d.ts +31 -6
- package/dist/agent/constants.d.ts.map +1 -1
- package/dist/agent/constants.js +38 -8
- package/dist/agent/constants.js.map +1 -1
- package/dist/agent/contextManager.d.ts +8 -0
- package/dist/agent/contextManager.d.ts.map +1 -1
- package/dist/agent/contextManager.js +45 -3
- package/dist/agent/contextManager.js.map +1 -1
- package/dist/agent/contextPreparer.d.ts +1 -1
- package/dist/agent/contextPreparer.d.ts.map +1 -1
- package/dist/agent/contextPreparer.js +15 -10
- package/dist/agent/contextPreparer.js.map +1 -1
- package/dist/agent/guardRail.d.ts +12 -1
- package/dist/agent/guardRail.d.ts.map +1 -1
- package/dist/agent/guardRail.js +37 -2
- package/dist/agent/guardRail.js.map +1 -1
- package/dist/agent/loop.d.ts +319 -34
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +713 -110
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/managers/archiveCoordinator.d.ts +19 -4
- package/dist/agent/managers/archiveCoordinator.d.ts.map +1 -1
- package/dist/agent/managers/archiveCoordinator.js +25 -4
- package/dist/agent/managers/archiveCoordinator.js.map +1 -1
- package/dist/agent/managers/chatLockManager.d.ts +3 -9
- package/dist/agent/managers/chatLockManager.d.ts.map +1 -1
- package/dist/agent/managers/chatLockManager.js +7 -25
- package/dist/agent/managers/chatLockManager.js.map +1 -1
- package/dist/agent/managers/llmCaller.d.ts.map +1 -1
- package/dist/agent/managers/llmCaller.js +27 -1
- package/dist/agent/managers/llmCaller.js.map +1 -1
- package/dist/agent/managers/loopMetrics.d.ts +14 -0
- package/dist/agent/managers/loopMetrics.d.ts.map +1 -1
- package/dist/agent/managers/loopMetrics.js +15 -0
- package/dist/agent/managers/loopMetrics.js.map +1 -1
- package/dist/agent/managers/memoryInspector.d.ts +13 -15
- package/dist/agent/managers/memoryInspector.d.ts.map +1 -1
- package/dist/agent/managers/memoryInspector.js +38 -49
- package/dist/agent/managers/memoryInspector.js.map +1 -1
- package/dist/agent/managers/roundSummaryGenerator.d.ts +31 -1
- package/dist/agent/managers/roundSummaryGenerator.d.ts.map +1 -1
- package/dist/agent/managers/roundSummaryGenerator.js +81 -6
- package/dist/agent/managers/roundSummaryGenerator.js.map +1 -1
- package/dist/agent/managers/sessionArchiver.d.ts +35 -3
- package/dist/agent/managers/sessionArchiver.d.ts.map +1 -1
- package/dist/agent/managers/sessionArchiver.js +34 -3
- package/dist/agent/managers/sessionArchiver.js.map +1 -1
- package/dist/agent/managers/sessionManager.d.ts +21 -88
- package/dist/agent/managers/sessionManager.d.ts.map +1 -1
- package/dist/agent/managers/sessionManager.js +94 -278
- package/dist/agent/managers/sessionManager.js.map +1 -1
- package/dist/agent/managers/toolCallHelpers.d.ts +109 -28
- package/dist/agent/managers/toolCallHelpers.d.ts.map +1 -1
- package/dist/agent/managers/toolCallHelpers.js +93 -37
- package/dist/agent/managers/toolCallHelpers.js.map +1 -1
- package/dist/agent/messageHistory.d.ts.map +1 -1
- package/dist/agent/messageHistory.js +9 -5
- package/dist/agent/messageHistory.js.map +1 -1
- package/dist/agent/seed/orchestrator.d.ts +12 -1
- package/dist/agent/seed/orchestrator.d.ts.map +1 -1
- package/dist/agent/seed/orchestrator.js +15 -4
- package/dist/agent/seed/orchestrator.js.map +1 -1
- package/dist/agent/seed/prepare.d.ts.map +1 -1
- package/dist/agent/seed/prepare.js +9 -4
- package/dist/agent/seed/prepare.js.map +1 -1
- package/dist/agent/seed/types.d.ts +11 -4
- package/dist/agent/seed/types.d.ts.map +1 -1
- package/dist/agent/seed/types.js +2 -2
- package/dist/agent/textSanitize.d.ts +36 -0
- package/dist/agent/textSanitize.d.ts.map +1 -0
- package/dist/agent/textSanitize.js +55 -0
- package/dist/agent/textSanitize.js.map +1 -0
- package/dist/agent/toolExecutor.d.ts +97 -26
- package/dist/agent/toolExecutor.d.ts.map +1 -1
- package/dist/agent/toolExecutor.js +444 -78
- package/dist/agent/toolExecutor.js.map +1 -1
- package/dist/agent/toolLedger.d.ts +93 -41
- package/dist/agent/toolLedger.d.ts.map +1 -1
- package/dist/agent/toolLedger.js +114 -42
- package/dist/agent/toolLedger.js.map +1 -1
- package/dist/agent/toolResultCache.js +1 -1
- package/dist/agent/toolResultOffload.d.ts +8 -0
- package/dist/agent/toolResultOffload.d.ts.map +1 -1
- package/dist/agent/toolResultOffload.js +10 -3
- package/dist/agent/toolResultOffload.js.map +1 -1
- package/dist/agent/toolRunner.d.ts +16 -7
- package/dist/agent/toolRunner.d.ts.map +1 -1
- package/dist/agent/toolRunner.js +74 -29
- package/dist/agent/toolRunner.js.map +1 -1
- package/dist/agent/tracer.d.ts +13 -1
- package/dist/agent/tracer.d.ts.map +1 -1
- package/dist/agent/types.d.ts +74 -30
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/code-exec/types.d.ts +9 -0
- package/dist/code-exec/types.d.ts.map +1 -1
- package/dist/index.d.ts +28 -41
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +65 -54
- package/dist/index.js.map +1 -1
- package/dist/logging/logger.d.ts +4 -1
- package/dist/logging/logger.d.ts.map +1 -1
- package/dist/logging/logger.js +5 -2
- package/dist/logging/logger.js.map +1 -1
- package/dist/memory/gcService.d.ts.map +1 -1
- package/dist/memory/gcService.js +3 -5
- package/dist/memory/gcService.js.map +1 -1
- package/dist/memory/inMemorySessionStore.d.ts +2 -2
- package/dist/memory/inMemorySessionStore.js +2 -2
- package/dist/memory/inMemoryStorage.d.ts +4 -3
- package/dist/memory/inMemoryStorage.d.ts.map +1 -1
- package/dist/memory/inMemoryStorage.js +2 -2
- package/dist/memory/inMemoryStorage.js.map +1 -1
- package/dist/memory/nodeSqliteStorage.d.ts +17 -0
- package/dist/memory/nodeSqliteStorage.d.ts.map +1 -0
- package/dist/memory/nodeSqliteStorage.js +393 -0
- package/dist/memory/nodeSqliteStorage.js.map +1 -0
- package/dist/memory/projectManager.d.ts +10 -20
- package/dist/memory/projectManager.d.ts.map +1 -1
- package/dist/memory/projectManager.js +27 -41
- package/dist/memory/projectManager.js.map +1 -1
- package/dist/memory/roundStore.d.ts +143 -82
- package/dist/memory/roundStore.d.ts.map +1 -1
- package/dist/memory/roundStore.js +4 -15
- package/dist/memory/roundStore.js.map +1 -1
- package/dist/memory/roundSummaryLookup.d.ts +26 -0
- package/dist/memory/roundSummaryLookup.d.ts.map +1 -0
- package/dist/memory/roundSummaryLookup.js +19 -0
- package/dist/memory/roundSummaryLookup.js.map +1 -0
- package/dist/memory/sessionStore.d.ts +19 -2
- package/dist/memory/sessionStore.d.ts.map +1 -1
- package/dist/memory/sessionStore.js.map +1 -1
- package/dist/memory/sourceValidation.d.ts +2 -13
- package/dist/memory/sourceValidation.d.ts.map +1 -1
- package/dist/memory/sourceValidation.js +5 -16
- package/dist/memory/sourceValidation.js.map +1 -1
- package/dist/memory/storageInterface.d.ts +26 -16
- package/dist/memory/storageInterface.d.ts.map +1 -1
- package/dist/memory/supersedeResolve.d.ts +39 -0
- package/dist/memory/supersedeResolve.d.ts.map +1 -0
- package/dist/memory/supersedeResolve.js +16 -0
- package/dist/memory/supersedeResolve.js.map +1 -0
- package/dist/memory/types.d.ts +10 -2
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/types.js +6 -1
- package/dist/memory/types.js.map +1 -1
- package/dist/role-pack/rolePackManager.d.ts +74 -33
- package/dist/role-pack/rolePackManager.d.ts.map +1 -1
- package/dist/role-pack/rolePackManager.js +112 -53
- package/dist/role-pack/rolePackManager.js.map +1 -1
- package/dist/role-pack/strategyKeys.d.ts +44 -0
- package/dist/role-pack/strategyKeys.d.ts.map +1 -1
- package/dist/role-pack/strategyKeys.js +55 -0
- package/dist/role-pack/strategyKeys.js.map +1 -1
- package/dist/role-pack/strategyResolver.d.ts +6 -1
- package/dist/role-pack/strategyResolver.d.ts.map +1 -1
- package/dist/role-pack/strategyResolver.js +20 -2
- package/dist/role-pack/strategyResolver.js.map +1 -1
- package/dist/role-pack/types.d.ts +5 -1
- package/dist/role-pack/types.d.ts.map +1 -1
- package/dist/security/confirmEntries.d.ts +44 -0
- package/dist/security/confirmEntries.d.ts.map +1 -0
- package/dist/security/confirmEntries.js +59 -0
- package/dist/security/confirmEntries.js.map +1 -0
- package/dist/security/pathGuard.d.ts +42 -6
- package/dist/security/pathGuard.d.ts.map +1 -1
- package/dist/security/pathGuard.js +126 -5
- package/dist/security/pathGuard.js.map +1 -1
- package/dist/skill/skillScriptRunner.d.ts +147 -15
- package/dist/skill/skillScriptRunner.d.ts.map +1 -1
- package/dist/skill/skillScriptRunner.js +479 -68
- package/dist/skill/skillScriptRunner.js.map +1 -1
- package/dist/utils/backgroundTask.d.ts +56 -34
- package/dist/utils/backgroundTask.d.ts.map +1 -1
- package/dist/utils/backgroundTask.js +130 -99
- package/dist/utils/backgroundTask.js.map +1 -1
- package/dist/utils/configResourceManager.d.ts +6 -2
- package/dist/utils/configResourceManager.d.ts.map +1 -1
- package/dist/utils/configResourceManager.js +8 -2
- package/dist/utils/configResourceManager.js.map +1 -1
- package/dist/utils/errors.d.ts +12 -2
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +12 -2
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/eventEmitter.d.ts +76 -23
- package/dist/utils/eventEmitter.d.ts.map +1 -1
- package/dist/utils/eventEmitter.js +23 -3
- package/dist/utils/eventEmitter.js.map +1 -1
- package/dist/utils/time.d.ts +8 -5
- package/dist/utils/time.d.ts.map +1 -1
- package/dist/utils/time.js +8 -5
- package/dist/utils/time.js.map +1 -1
- package/dist/utils/toError.d.ts +1 -1
- package/dist/utils/toError.js +1 -1
- package/dist/web-fetch/loginWall.d.ts +39 -0
- package/dist/web-fetch/loginWall.d.ts.map +1 -0
- package/dist/web-fetch/loginWall.js +78 -0
- package/dist/web-fetch/loginWall.js.map +1 -0
- package/dist/web-fetch/types.d.ts +8 -0
- package/dist/web-fetch/types.d.ts.map +1 -1
- package/dist/web-fetch/webFetchProvider.d.ts.map +1 -1
- package/dist/web-fetch/webFetchProvider.js +3 -1
- package/dist/web-fetch/webFetchProvider.js.map +1 -1
- package/dist/web-search/fetchWebSearchProvider.js +28 -23
- package/dist/web-search/fetchWebSearchProvider.js.map +1 -1
- package/docs/architecture/role-pack-authoring-guide.md +3 -1
- package/docs/architecture/role-pack-spec.md +2 -1
- package/docs/memora-api-reference.md +1349 -1175
- package/docs/memora-/345/215/207/347/272/247/346/214/207/345/215/227-4.x-/345/210/260-5.0.0.md +385 -0
- package/docs/memora-/346/216/245/345/205/245/346/214/207/345/215/227.md +91 -52
- package/docs/role-pack-/345/274/200/346/224/276/351/224/256/346/214/207/345/215/227.md +148 -148
- package/package.json +9 -4
- package/role-packs/README.md +41 -40
- package/role-packs/memora/345/212/251/346/211/213/rules.md +4 -4
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/manifest.json +1 -0
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/persona.md +1 -1
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/rules.md +1 -0
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/emotion-wave.md +1 -1
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/foreshadow.md +1 -1
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/outline-expand.md +32 -5
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/project-init/scripts/init-novel-project.mjs +10 -6
- package/role-packs//345/205/261/351/270/243/345/260/217/350/257/264/345/256/266/skills/story-bible.md +3 -1
- package/role-packs//347/231/275/350/257/235/346/226/271/346/241/210/350/256/276/350/256/241/345/270/210/manifest.json +1 -0
- package/dist/agent/managers/dedupManager.d.ts +0 -85
- package/dist/agent/managers/dedupManager.d.ts.map +0 -1
- package/dist/agent/managers/dedupManager.js +0 -248
- package/dist/agent/managers/dedupManager.js.map +0 -1
- package/dist/agent/managers/goalConsistencyChecker.d.ts +0 -42
- package/dist/agent/managers/goalConsistencyChecker.d.ts.map +0 -1
- package/dist/agent/managers/goalConsistencyChecker.js +0 -178
- package/dist/agent/managers/goalConsistencyChecker.js.map +0 -1
- package/dist/agent/managers/llmJudgeHelper.d.ts +0 -21
- package/dist/agent/managers/llmJudgeHelper.d.ts.map +0 -1
- package/dist/agent/managers/llmJudgeHelper.js +0 -32
- package/dist/agent/managers/llmJudgeHelper.js.map +0 -1
- package/dist/agent/managers/memoryAdvisor.d.ts +0 -105
- package/dist/agent/managers/memoryAdvisor.d.ts.map +0 -1
- package/dist/agent/managers/memoryAdvisor.js +0 -322
- package/dist/agent/managers/memoryAdvisor.js.map +0 -1
- package/dist/agent/managers/memoryGovernance.d.ts +0 -24
- package/dist/agent/managers/memoryGovernance.d.ts.map +0 -1
- package/dist/agent/managers/memoryGovernance.js +0 -46
- package/dist/agent/managers/memoryGovernance.js.map +0 -1
- package/dist/memory/governance.d.ts +0 -17
- package/dist/memory/governance.d.ts.map +0 -1
- package/dist/memory/governance.js +0 -17
- package/dist/memory/governance.js.map +0 -1
- package/dist/memory/projectRegistry.d.ts +0 -47
- package/dist/memory/projectRegistry.d.ts.map +0 -1
- package/dist/memory/projectRegistry.js +0 -151
- package/dist/memory/projectRegistry.js.map +0 -1
- package/dist/utils/recallDefaults.d.ts +0 -16
- package/dist/utils/recallDefaults.d.ts.map +0 -1
- package/dist/utils/recallDefaults.js +0 -16
- package/dist/utils/recallDefaults.js.map +0 -1
|
@@ -1,12 +1,26 @@
|
|
|
1
1
|
import type { AskQuestion } from '../agent/types.js';
|
|
2
|
+
import type { CompressTarget } from '../agent/loop.js';
|
|
3
|
+
import type { BackgroundTaskNaturalStatus } from '../agent/backgroundTasks.js';
|
|
2
4
|
/** Agent 事件名常量(运行时真理源,与 AgentEventMap 键集一致) */
|
|
3
5
|
export declare const AGENT_EVENTS: {
|
|
4
6
|
readonly memoryAdded: "memoryAdded";
|
|
5
7
|
readonly rolePackSwitched: "rolePackSwitched";
|
|
6
8
|
readonly memoryRecalled: "memoryRecalled";
|
|
7
9
|
readonly sessionForked: "sessionForked";
|
|
8
|
-
|
|
10
|
+
/**
|
|
11
|
+
* 会话身份切换完成(switchToSession 换会话成功后触发,载荷指向**被切走的旧会话**)。
|
|
12
|
+
* 内核自消费事件:agent 归档监听器据此对旧会话做会话级归档(summary/keyTopics 进
|
|
13
|
+
* SessionMeta 搜索索引)。宿主零消费 = 刻意设计(宿主是切换发起方,无增量信息),
|
|
14
|
+
* protocolGuard V-2 已登记 KERNEL_SELF_CONSUMED_EVENTS 豁免。
|
|
15
|
+
*/
|
|
16
|
+
readonly sessionSwitched: "sessionSwitched";
|
|
9
17
|
readonly archiveFailed: "archiveFailed";
|
|
18
|
+
/**
|
|
19
|
+
* 会话归档写入成功(updatedFields 非空才发,与 archiveFailed 对称)。
|
|
20
|
+
* 宿主据此重拉会话列表:切走时归档异步完成,列表快照若无此信号则条目摘要永不更新
|
|
21
|
+
* (悬停 tooltip 一直为空)。手动触发同样经 ArchiveCoordinator 发射。
|
|
22
|
+
*/
|
|
23
|
+
readonly sessionArchived: "sessionArchived";
|
|
10
24
|
readonly contextTruncated: "contextTruncated";
|
|
11
25
|
/** LLM 主动压缩完成(第二级压缩,与 contextTruncated 的内核自动截断区分) */
|
|
12
26
|
readonly contextCompressed: "contextCompressed";
|
|
@@ -14,7 +28,6 @@ export declare const AGENT_EVENTS: {
|
|
|
14
28
|
readonly archiveModeChanged: "archiveModeChanged";
|
|
15
29
|
readonly rolePackSwitchLocked: "rolePackSwitchLocked";
|
|
16
30
|
readonly workProjectionGenerated: "workProjectionGenerated";
|
|
17
|
-
readonly dedupCompleted: "dedupCompleted";
|
|
18
31
|
readonly sessionPauseTimedOut: "sessionPauseTimedOut";
|
|
19
32
|
readonly sessionResumeBlocked: "sessionResumeBlocked";
|
|
20
33
|
/** 订阅时宿主据此判断重要事件并 toast 提示 */
|
|
@@ -23,7 +36,6 @@ export declare const AGENT_EVENTS: {
|
|
|
23
36
|
readonly inputTooLarge: "inputTooLarge";
|
|
24
37
|
/** 回答中 LLM 调 ask_user 工具主动提问(唯一「提问后暂停」通道) */
|
|
25
38
|
readonly questionPending: "questionPending";
|
|
26
|
-
readonly goalDriftDetected: "goalDriftDetected";
|
|
27
39
|
readonly sessionPaused: "sessionPaused";
|
|
28
40
|
readonly sessionResumed: "sessionResumed";
|
|
29
41
|
readonly sessionError: "sessionError";
|
|
@@ -37,6 +49,16 @@ export declare const AGENT_EVENTS: {
|
|
|
37
49
|
* 一次 chat() 只触发一次,载荷带 roundId 溯源。
|
|
38
50
|
*/
|
|
39
51
|
readonly roundSummaryGenerated: "roundSummaryGenerated";
|
|
52
|
+
/**
|
|
53
|
+
* 后台任务**自然终态**(`run_command` background 进程自己跑完 / 到点超时强杀)。
|
|
54
|
+
* 宿主据此推 UI 快照——脱管后 turn 已结束,宿主周期性推送(step_boundary /
|
|
55
|
+
* background_report)覆盖不到「turn 结束后任务自然跑完」,缺此事件 UI 会一直显示
|
|
56
|
+
* 假活跃的「运行中」。
|
|
57
|
+
* ⚠️ **主动 kill 不发本事件**:注册表 kill 刻意不回调(防结果双份消费)——
|
|
58
|
+
* UI 终止按钮路径由宿主 kill 后自行回拉快照;LLM 调 kill_command 后靠下一个
|
|
59
|
+
* step_boundary(若 turn 当场结束则无推送点,已登记边界,见后台任务跨轮存活方案)。
|
|
60
|
+
*/
|
|
61
|
+
readonly backgroundTaskSettled: "backgroundTaskSettled";
|
|
40
62
|
};
|
|
41
63
|
/** 事件名联合类型(由 AGENT_EVENTS 推导,新增事件只需在此加一项) */
|
|
42
64
|
export type AgentEventName = keyof typeof AGENT_EVENTS;
|
|
@@ -48,6 +70,9 @@ export interface AgentEventMap extends Record<AgentEventName, unknown> {
|
|
|
48
70
|
id: string;
|
|
49
71
|
source: string;
|
|
50
72
|
name: string;
|
|
73
|
+
/** 记忆正文(5.0.0 起可选携带):宿主「已沉淀」提示按用户心智显示内容而非 name 标识。
|
|
74
|
+
* 可选 = 跨 dist 契约:4.x 内核不发此字段,宿主须容错缺失回退 name(老数据 name 可读性有限)。 */
|
|
75
|
+
content?: string;
|
|
51
76
|
};
|
|
52
77
|
rolePackSwitched: {
|
|
53
78
|
from: string | null;
|
|
@@ -56,28 +81,54 @@ export interface AgentEventMap extends Record<AgentEventName, unknown> {
|
|
|
56
81
|
memoryRecalled: {
|
|
57
82
|
count: number;
|
|
58
83
|
query: string;
|
|
84
|
+
/** 命中明细(4.1.0 新增,MEM-EVENT-1):三字段各有消费面(宿主 S3-1 可展开行渲染 + S3-3 反馈按 id 寻址)。
|
|
85
|
+
* 可选 = 跨 dist 契约:4.0.x 内核不发此字段,宿主须容错缺失降级为条数提示(类型层强制消费方容错)。
|
|
86
|
+
* 条数上限真源 = search_memories 的 parseLimit 钳制(50),载荷全量映射不截断(不另立截断常量)。 */
|
|
87
|
+
hits?: {
|
|
88
|
+
id: string;
|
|
89
|
+
name: string;
|
|
90
|
+
source: string;
|
|
91
|
+
/** 命中正文(5.0.0 起可选携带):宿主命中明细按用户心智显示内容而非 name 标识。
|
|
92
|
+
* 可选 = 跨 dist 契约:4.x 内核 hits 元素无此字段,宿主须容错缺失回退 name。 */
|
|
93
|
+
contentPreview?: string;
|
|
94
|
+
}[];
|
|
95
|
+
/** 发起本次召回的 tool_call 唯一 ID(4.1.x 新增,MEM-EVENT-2):宿主据此把命中明细挂回
|
|
96
|
+
* 对应 search_memories 工具折叠块,而非按轮次全局堆在回复体上方。
|
|
97
|
+
* 可选 = 跨 dist 契约 + 直调容错:老内核/测试直调 searchMemories 不带 ID,宿主须回退
|
|
98
|
+
* 「无配对目标 → 轮次级兜底落位」路径(类型层强制消费方容错)。
|
|
99
|
+
* 唯一来源 = toolExecutor.execute 的 toolCallId 形参(loop → toolRunner 已全程透传)。 */
|
|
100
|
+
toolCallId?: string;
|
|
59
101
|
};
|
|
60
102
|
sessionForked: {
|
|
61
103
|
from: string;
|
|
62
104
|
to: string;
|
|
63
105
|
roundCount: number;
|
|
64
106
|
};
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
107
|
+
/** date/session = 被切走的旧会话(归档对象);fromSessionId/toSessionId = 旧/新完整会话标识 */
|
|
108
|
+
sessionSwitched: {
|
|
109
|
+
date: string;
|
|
110
|
+
session: string;
|
|
111
|
+
fromSessionId: string;
|
|
112
|
+
toSessionId: string;
|
|
69
113
|
};
|
|
70
114
|
archiveFailed: {
|
|
71
115
|
stage: 'session';
|
|
72
116
|
message: string;
|
|
73
117
|
};
|
|
118
|
+
/** 会话归档写入成功载荷:sessionId = `${date}-${session}`;updatedFields = 实际落库字段(summary/keyTopics/autoName) */
|
|
119
|
+
sessionArchived: {
|
|
120
|
+
sessionId: string;
|
|
121
|
+
updatedFields: string[];
|
|
122
|
+
};
|
|
74
123
|
contextTruncated: {
|
|
75
124
|
skippedCount: number;
|
|
76
125
|
keptCount: number;
|
|
77
126
|
};
|
|
78
|
-
/** LLM 主动压缩完成载荷:压缩目标 + 被替换消息数 + 摘要长度
|
|
127
|
+
/** LLM 主动压缩完成载荷:压缩目标 + 被替换消息数 + 摘要长度
|
|
128
|
+
* ⚠️ target 类型**引用 loop 的 CompressTarget**(不另写字面量联合)——枚举增补时
|
|
129
|
+
* 本处自动跟随,禁在此复制一份(两份字面量 = 必然漂移)。 */
|
|
79
130
|
contextCompressed: {
|
|
80
|
-
target:
|
|
131
|
+
target: CompressTarget;
|
|
81
132
|
replacedCount: number;
|
|
82
133
|
summaryLength: number;
|
|
83
134
|
};
|
|
@@ -96,10 +147,6 @@ export interface AgentEventMap extends Record<AgentEventName, unknown> {
|
|
|
96
147
|
sourcePath: string;
|
|
97
148
|
summary: string;
|
|
98
149
|
};
|
|
99
|
-
dedupCompleted: {
|
|
100
|
-
deduplicatedCount: number;
|
|
101
|
-
demotedIds: string[];
|
|
102
|
-
};
|
|
103
150
|
sessionPauseTimedOut: {
|
|
104
151
|
sessionId: string;
|
|
105
152
|
pauseDuration: number;
|
|
@@ -121,16 +168,6 @@ export interface AgentEventMap extends Record<AgentEventName, unknown> {
|
|
|
121
168
|
hint: string;
|
|
122
169
|
};
|
|
123
170
|
questionPending: AskQuestion[];
|
|
124
|
-
goalDriftDetected: {
|
|
125
|
-
sessionId: string;
|
|
126
|
-
mainGoal: string;
|
|
127
|
-
newGoal: string;
|
|
128
|
-
similarity: number;
|
|
129
|
-
level: 'same' | 'confirm' | 'drift';
|
|
130
|
-
constraints: string[];
|
|
131
|
-
/** 原名 goalVersion,仅载荷不承担校验 */
|
|
132
|
-
goalChangeSeq: number;
|
|
133
|
-
};
|
|
134
171
|
sessionPaused: {
|
|
135
172
|
reason: string;
|
|
136
173
|
source: string;
|
|
@@ -156,6 +193,22 @@ export interface AgentEventMap extends Record<AgentEventName, unknown> {
|
|
|
156
193
|
roundId: string;
|
|
157
194
|
success: boolean;
|
|
158
195
|
};
|
|
196
|
+
/**
|
|
197
|
+
* 后台任务**自然终态**载荷:只读投影(与 `agent.listBackgroundTasks()` 的元素同形状)。
|
|
198
|
+
*
|
|
199
|
+
* ⚠️ **仅进程自行完成 / 超时发射**(status 类型即契约,running/killed 不可能出现):
|
|
200
|
+
* 主动 kill 不发此事件——注册表 `kill()` 刻意不回调 completion listener,防同一份输出
|
|
201
|
+
* 被 `kill_command` 返回值与完成回流双份消费;kill 后的 UI 刷新走宿主 kill 处理路径
|
|
202
|
+
* 自行回推快照。
|
|
203
|
+
*
|
|
204
|
+
* 宿主只需 taskId 即可推全量快照,**刻意不携带输出**(命令输出体量可达 KB~MB,
|
|
205
|
+
* UI 不呈现——同 `BackgroundTaskView` 刻意不含 `result` 的口径)。
|
|
206
|
+
*/
|
|
207
|
+
backgroundTaskSettled: {
|
|
208
|
+
taskId: string;
|
|
209
|
+
command: string;
|
|
210
|
+
status: BackgroundTaskNaturalStatus;
|
|
211
|
+
};
|
|
159
212
|
}
|
|
160
213
|
/** 事件处理器类型 */
|
|
161
214
|
export type AgentEventHandler<T> = (event: T) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eventEmitter.d.ts","sourceRoot":"","sources":["../../src/utils/eventEmitter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"eventEmitter.d.ts","sourceRoot":"","sources":["../../src/utils/eventEmitter.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,8 +10,20 @@ export const AGENT_EVENTS = {
|
|
|
10
10
|
rolePackSwitched: 'rolePackSwitched',
|
|
11
11
|
memoryRecalled: 'memoryRecalled',
|
|
12
12
|
sessionForked: 'sessionForked',
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* 会话身份切换完成(switchToSession 换会话成功后触发,载荷指向**被切走的旧会话**)。
|
|
15
|
+
* 内核自消费事件:agent 归档监听器据此对旧会话做会话级归档(summary/keyTopics 进
|
|
16
|
+
* SessionMeta 搜索索引)。宿主零消费 = 刻意设计(宿主是切换发起方,无增量信息),
|
|
17
|
+
* protocolGuard V-2 已登记 KERNEL_SELF_CONSUMED_EVENTS 豁免。
|
|
18
|
+
*/
|
|
19
|
+
sessionSwitched: 'sessionSwitched',
|
|
14
20
|
archiveFailed: 'archiveFailed',
|
|
21
|
+
/**
|
|
22
|
+
* 会话归档写入成功(updatedFields 非空才发,与 archiveFailed 对称)。
|
|
23
|
+
* 宿主据此重拉会话列表:切走时归档异步完成,列表快照若无此信号则条目摘要永不更新
|
|
24
|
+
* (悬停 tooltip 一直为空)。手动触发同样经 ArchiveCoordinator 发射。
|
|
25
|
+
*/
|
|
26
|
+
sessionArchived: 'sessionArchived',
|
|
15
27
|
contextTruncated: 'contextTruncated',
|
|
16
28
|
/** LLM 主动压缩完成(第二级压缩,与 contextTruncated 的内核自动截断区分) */
|
|
17
29
|
contextCompressed: 'contextCompressed',
|
|
@@ -19,7 +31,6 @@ export const AGENT_EVENTS = {
|
|
|
19
31
|
archiveModeChanged: 'archiveModeChanged',
|
|
20
32
|
rolePackSwitchLocked: 'rolePackSwitchLocked',
|
|
21
33
|
workProjectionGenerated: 'workProjectionGenerated',
|
|
22
|
-
dedupCompleted: 'dedupCompleted',
|
|
23
34
|
sessionPauseTimedOut: 'sessionPauseTimedOut',
|
|
24
35
|
sessionResumeBlocked: 'sessionResumeBlocked',
|
|
25
36
|
/** 订阅时宿主据此判断重要事件并 toast 提示 */
|
|
@@ -28,7 +39,6 @@ export const AGENT_EVENTS = {
|
|
|
28
39
|
inputTooLarge: 'inputTooLarge',
|
|
29
40
|
/** 回答中 LLM 调 ask_user 工具主动提问(唯一「提问后暂停」通道) */
|
|
30
41
|
questionPending: 'questionPending',
|
|
31
|
-
goalDriftDetected: 'goalDriftDetected',
|
|
32
42
|
sessionPaused: 'sessionPaused',
|
|
33
43
|
sessionResumed: 'sessionResumed',
|
|
34
44
|
sessionError: 'sessionError',
|
|
@@ -42,6 +52,16 @@ export const AGENT_EVENTS = {
|
|
|
42
52
|
* 一次 chat() 只触发一次,载荷带 roundId 溯源。
|
|
43
53
|
*/
|
|
44
54
|
roundSummaryGenerated: 'roundSummaryGenerated',
|
|
55
|
+
/**
|
|
56
|
+
* 后台任务**自然终态**(`run_command` background 进程自己跑完 / 到点超时强杀)。
|
|
57
|
+
* 宿主据此推 UI 快照——脱管后 turn 已结束,宿主周期性推送(step_boundary /
|
|
58
|
+
* background_report)覆盖不到「turn 结束后任务自然跑完」,缺此事件 UI 会一直显示
|
|
59
|
+
* 假活跃的「运行中」。
|
|
60
|
+
* ⚠️ **主动 kill 不发本事件**:注册表 kill 刻意不回调(防结果双份消费)——
|
|
61
|
+
* UI 终止按钮路径由宿主 kill 后自行回拉快照;LLM 调 kill_command 后靠下一个
|
|
62
|
+
* step_boundary(若 turn 当场结束则无推送点,已登记边界,见后台任务跨轮存活方案)。
|
|
63
|
+
*/
|
|
64
|
+
backgroundTaskSettled: 'backgroundTaskSettled',
|
|
45
65
|
};
|
|
46
66
|
/** 运行时校验用集合(由 AGENT_EVENTS 派生) */
|
|
47
67
|
export const AGENT_EVENT_SET = new Set(Object.values(AGENT_EVENTS));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"eventEmitter.js","sourceRoot":"","sources":["../../src/utils/eventEmitter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"eventEmitter.js","sourceRoot":"","sources":["../../src/utils/eventEmitter.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/time.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 时间工具函数
|
|
3
3
|
*
|
|
4
|
-
* 从 messageHistory.ts
|
|
5
|
-
* 消除跨模块 `new Date().toISOString()` 内联重复。
|
|
4
|
+
* 从 messageHistory.ts 提取的公共时间格式化函数,作用域 = **内核 `src/` 内部**。
|
|
6
5
|
*
|
|
7
|
-
*
|
|
6
|
+
* ⚠️ 「消除跨模块内联重复」不成立 —— `nowIso` **未**进 `src/index.ts` 公开导出面,
|
|
7
|
+
* 宿主拿不到它(实测宿主 `nowIso` 引用 = 0),宿主侧取当前时间仍是各自内联。
|
|
8
|
+
* 本文件只是内核内部的推荐入口,不是跨包单一真源。
|
|
9
|
+
*
|
|
10
|
+
* API 对齐(历史):formatDateKey(date) 曾与精灵宿主 shared/dateUtils.ts 语义一致(该宿主已移除),
|
|
8
11
|
* 用于格式化任意 Date 为 YYYY-MM-DD(本地时区)。
|
|
9
12
|
*/
|
|
10
|
-
/**
|
|
13
|
+
/** 一天对应的毫秒数(天数差换算基准;当前消费者 = 存储契约测试构造 purgeExpired 过期时间戳) */
|
|
11
14
|
export declare const ONE_DAY_MS: number;
|
|
12
15
|
/**
|
|
13
16
|
* 获取当前时间的 ISO 8601 时间戳
|
|
@@ -22,7 +25,7 @@ export declare function nowIso(): string;
|
|
|
22
25
|
* 修复场景:Asia/Shanghai 凌晨 00:00-08:00 期间 UTC 仍是前一天,导致按日期分组的
|
|
23
26
|
* 计数(chatTurns / dailyMessageCount)写入错误的日期 key。
|
|
24
27
|
*
|
|
25
|
-
*
|
|
28
|
+
* 历史对齐对象:精灵宿主 shared/dateUtils.ts:formatDateKey(该宿主已移除,现本函数为内核内唯一实现)。
|
|
26
29
|
*
|
|
27
30
|
* @param date Date 对象
|
|
28
31
|
* @returns YYYY-MM-DD 字符串(本地日期)
|
package/dist/utils/time.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/utils/time.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/utils/time.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,4DAA4D;AAC5D,eAAO,MAAM,UAAU,QAAsB,CAAC;AAE9C;;;;GAIG;AACH,wBAAgB,MAAM,IAAI,MAAM,CAE/B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAKhD;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAeD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAGpE;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAInF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE3D"}
|
package/dist/utils/time.js
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 时间工具函数
|
|
3
3
|
*
|
|
4
|
-
* 从 messageHistory.ts
|
|
5
|
-
* 消除跨模块 `new Date().toISOString()` 内联重复。
|
|
4
|
+
* 从 messageHistory.ts 提取的公共时间格式化函数,作用域 = **内核 `src/` 内部**。
|
|
6
5
|
*
|
|
7
|
-
*
|
|
6
|
+
* ⚠️ 「消除跨模块内联重复」不成立 —— `nowIso` **未**进 `src/index.ts` 公开导出面,
|
|
7
|
+
* 宿主拿不到它(实测宿主 `nowIso` 引用 = 0),宿主侧取当前时间仍是各自内联。
|
|
8
|
+
* 本文件只是内核内部的推荐入口,不是跨包单一真源。
|
|
9
|
+
*
|
|
10
|
+
* API 对齐(历史):formatDateKey(date) 曾与精灵宿主 shared/dateUtils.ts 语义一致(该宿主已移除),
|
|
8
11
|
* 用于格式化任意 Date 为 YYYY-MM-DD(本地时区)。
|
|
9
12
|
*/
|
|
10
|
-
/**
|
|
13
|
+
/** 一天对应的毫秒数(天数差换算基准;当前消费者 = 存储契约测试构造 purgeExpired 过期时间戳) */
|
|
11
14
|
export const ONE_DAY_MS = 24 * 60 * 60 * 1000;
|
|
12
15
|
/**
|
|
13
16
|
* 获取当前时间的 ISO 8601 时间戳
|
|
@@ -24,7 +27,7 @@ export function nowIso() {
|
|
|
24
27
|
* 修复场景:Asia/Shanghai 凌晨 00:00-08:00 期间 UTC 仍是前一天,导致按日期分组的
|
|
25
28
|
* 计数(chatTurns / dailyMessageCount)写入错误的日期 key。
|
|
26
29
|
*
|
|
27
|
-
*
|
|
30
|
+
* 历史对齐对象:精灵宿主 shared/dateUtils.ts:formatDateKey(该宿主已移除,现本函数为内核内唯一实现)。
|
|
28
31
|
*
|
|
29
32
|
* @param date Date 对象
|
|
30
33
|
* @returns YYYY-MM-DD 字符串(本地日期)
|
package/dist/utils/time.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/utils/time.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"time.js","sourceRoot":"","sources":["../../src/utils/time.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE9C;;;;GAIG;AACH,MAAM,UAAU,MAAM;IACpB,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,IAAU;IACtC,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAClD,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,aAAa,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,8CAA8C;AAC9C,gEAAgE;AAChE,qDAAqD;AACrD,iEAAiE;AACjE,uDAAuD;AACvD,sDAAsD;AACtD,EAAE;AACF,wBAAwB;AACxB,qDAAqD;AACrD,oEAAoE;AACpE,0CAA0C;AAC1C,4BAA4B;AAE5B;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,OAAe;IAC1D,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,OAAO,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC;AAC9B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB;IAC9C,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACjE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,OAAO,4BAA4B,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AACtD,CAAC"}
|
package/dist/utils/toError.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* 将 catch 块中的 unknown 值安全转换为 Error 对象。
|
|
5
5
|
* 从 errors.ts 中提取,确保浏览器端可直接 import 而不引入 logging/ 模块。
|
|
6
6
|
*
|
|
7
|
-
* 转换规则(5
|
|
7
|
+
* 转换规则(5 分支;历史对齐对象精灵宿主 shared/toError.ts 已随该宿主移除,现为内核内唯一实现):
|
|
8
8
|
* 1. Error 实例:原样返回
|
|
9
9
|
* 2. 字符串:包装为 Error
|
|
10
10
|
* 3. 含 message 属性的对象:提取 message 包装为 Error
|
package/dist/utils/toError.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* 将 catch 块中的 unknown 值安全转换为 Error 对象。
|
|
5
5
|
* 从 errors.ts 中提取,确保浏览器端可直接 import 而不引入 logging/ 模块。
|
|
6
6
|
*
|
|
7
|
-
* 转换规则(5
|
|
7
|
+
* 转换规则(5 分支;历史对齐对象精灵宿主 shared/toError.ts 已随该宿主移除,现为内核内唯一实现):
|
|
8
8
|
* 1. Error 实例:原样返回
|
|
9
9
|
* 2. 字符串:包装为 Error
|
|
10
10
|
* 3. 含 message 属性的对象:提取 message 包装为 Error
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 登录墙识别(SEARCH-QUALITY-1 P2-1)
|
|
3
|
+
*
|
|
4
|
+
* 问题:HTTP 200 的登录页被 `stripHtmlToText` 洗成「正文」——LLM 拿到一堆
|
|
5
|
+
* 「请登录 / 输入密码 / 注册新账号」的表单碎片,还以为是目标页面内容
|
|
6
|
+
* (「搜不准」的第二种形态:搜到了、也抓到了,但抓到的是一堵墙)。
|
|
7
|
+
*
|
|
8
|
+
* 判据(保守取向——**漏判 = 现状(可读页照常交付),误判 = 藏起可读页**,
|
|
9
|
+
* 故宁漏勿误,两条路径都要求「不像普通内容」才判墙):
|
|
10
|
+
* 1. **URL 强信号**:host/path 的**段边界**命中 login/signin/logon/passport/sso
|
|
11
|
+
* (段边界 = 段首/段尾由 `/` `.` `?` 或串首尾界定——防 `how-to-login`
|
|
12
|
+
* 教程、`mylogin` 之类词内子串误判;查询参数**值**里的 login 不算;
|
|
13
|
+
* `#fragment` 先剥除——锚点是**页内位置**不是页面身份,`article#login` 是文章)。
|
|
14
|
+
* 只认重定向后的 finalUrl(`FetchedPage.url`):带登录态参数的原始 URL
|
|
15
|
+
* 常常恰恰是要抓的页面,不能拿它判墙。
|
|
16
|
+
* 2. **弱信号组合**:标题登录词 **且** 正文密码词 **且** 正文很短
|
|
17
|
+
* (< `LOGIN_WALL_MAX_CONTENT_CHARS`)——单标题命中放行(教程/文档页
|
|
18
|
+
* 常谈「如何登录」),三条件同时满足才判墙。
|
|
19
|
+
* ⚠️ 长度判据只在**正文未被截断到阈值以下**时可信:调用方须传 `contentCap`
|
|
20
|
+
* (本次抓取的截断上限),cap < 阈值时「短正文」可能是截断假象 → 弱信号禁用
|
|
21
|
+
* (强信号不受影响——URL 身份与正文长短无关)。
|
|
22
|
+
*
|
|
23
|
+
* 纯函数:无 IO、零依赖,判据集中单点(toolExecutor web_fetch case 消费)。
|
|
24
|
+
* 命中后由调用方返回 hedged 提示(「可能」需登录——判据是启发式,不谎称确定);
|
|
25
|
+
* 「这页是否抓取失败」不归本函数(调用方以 `FetchedPage.fetchFailed` 先行排除)。
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* 判定抓取结果是否为登录墙(保守启发式,见文件头「宁漏勿误」)
|
|
29
|
+
*
|
|
30
|
+
* @param finalUrl 重定向后的实际 URL(`FetchedPage.url`;空串 = 无 URL 信息)
|
|
31
|
+
* @param title 页面标题(清洗后)
|
|
32
|
+
* @param content 页面正文(清洗后)
|
|
33
|
+
* @param contentCap 本次抓取的正文截断上限(toolExecutor 传 maxChars):
|
|
34
|
+
* 小于弱信号阈值时「短正文」可能是截断假象 → 弱信号禁用(强信号照常);
|
|
35
|
+
* 缺省 = 视为未截断(向后兼容既有调用形状)
|
|
36
|
+
* @returns true = 判为登录墙(调用方应明示不可读并引导换源)
|
|
37
|
+
*/
|
|
38
|
+
export declare function isLoginWallPage(finalUrl: string, title: string, content: string, contentCap?: number): boolean;
|
|
39
|
+
//# sourceMappingURL=loginWall.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loginWall.d.ts","sourceRoot":"","sources":["../../src/web-fetch/loginWall.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AA2BH;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAoBT"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 登录墙识别(SEARCH-QUALITY-1 P2-1)
|
|
3
|
+
*
|
|
4
|
+
* 问题:HTTP 200 的登录页被 `stripHtmlToText` 洗成「正文」——LLM 拿到一堆
|
|
5
|
+
* 「请登录 / 输入密码 / 注册新账号」的表单碎片,还以为是目标页面内容
|
|
6
|
+
* (「搜不准」的第二种形态:搜到了、也抓到了,但抓到的是一堵墙)。
|
|
7
|
+
*
|
|
8
|
+
* 判据(保守取向——**漏判 = 现状(可读页照常交付),误判 = 藏起可读页**,
|
|
9
|
+
* 故宁漏勿误,两条路径都要求「不像普通内容」才判墙):
|
|
10
|
+
* 1. **URL 强信号**:host/path 的**段边界**命中 login/signin/logon/passport/sso
|
|
11
|
+
* (段边界 = 段首/段尾由 `/` `.` `?` 或串首尾界定——防 `how-to-login`
|
|
12
|
+
* 教程、`mylogin` 之类词内子串误判;查询参数**值**里的 login 不算;
|
|
13
|
+
* `#fragment` 先剥除——锚点是**页内位置**不是页面身份,`article#login` 是文章)。
|
|
14
|
+
* 只认重定向后的 finalUrl(`FetchedPage.url`):带登录态参数的原始 URL
|
|
15
|
+
* 常常恰恰是要抓的页面,不能拿它判墙。
|
|
16
|
+
* 2. **弱信号组合**:标题登录词 **且** 正文密码词 **且** 正文很短
|
|
17
|
+
* (< `LOGIN_WALL_MAX_CONTENT_CHARS`)——单标题命中放行(教程/文档页
|
|
18
|
+
* 常谈「如何登录」),三条件同时满足才判墙。
|
|
19
|
+
* ⚠️ 长度判据只在**正文未被截断到阈值以下**时可信:调用方须传 `contentCap`
|
|
20
|
+
* (本次抓取的截断上限),cap < 阈值时「短正文」可能是截断假象 → 弱信号禁用
|
|
21
|
+
* (强信号不受影响——URL 身份与正文长短无关)。
|
|
22
|
+
*
|
|
23
|
+
* 纯函数:无 IO、零依赖,判据集中单点(toolExecutor web_fetch case 消费)。
|
|
24
|
+
* 命中后由调用方返回 hedged 提示(「可能」需登录——判据是启发式,不谎称确定);
|
|
25
|
+
* 「这页是否抓取失败」不归本函数(调用方以 `FetchedPage.fetchFailed` 先行排除)。
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* URL 登录段(段边界匹配)
|
|
29
|
+
*
|
|
30
|
+
* 段界定符:串首 `^`、`/`、`.`、`?`、串尾 `$`(`#fragment` 在判定前已剥除——
|
|
31
|
+
* 锚点是页内位置不是页面身份,`article#login` 是文章不是登录页)。
|
|
32
|
+
* `-` 刻意**不在**界定符内——`how-to-login` / `sign-in-page` 这类连字符复合词
|
|
33
|
+
* 是教程页的高频形态,放行它们(漏判代价)优于误判(藏可读页)。
|
|
34
|
+
* `sign-in` 以显式 alternation 收录(它是登录墙的常见路径形态)。
|
|
35
|
+
*/
|
|
36
|
+
const URL_LOGIN_SEGMENT_RE = /(?:^|\/|\.|\?)(?:login|logon|signin|sign-in|passport|sso)(?:\/|\.|\?|$)/i;
|
|
37
|
+
/** 标题登录词(中英;不含「密码」——谈密码的文章标题不应触发弱信号) */
|
|
38
|
+
const TITLE_LOGIN_RE = /登录|登陆|登入|sign\s*in|log\s*in|logon/i;
|
|
39
|
+
/** 正文密码词(登录表单/提示语特征) */
|
|
40
|
+
const PASSWORD_WORD_RE = /密码|password|passcode/i;
|
|
41
|
+
/**
|
|
42
|
+
* 弱信号组合的正文长度上限(字符)
|
|
43
|
+
*
|
|
44
|
+
* 登录墙表单页天然短(几个输入框 + 按钮);长正文即使带登录词也更是教程/文档。
|
|
45
|
+
*/
|
|
46
|
+
const LOGIN_WALL_MAX_CONTENT_CHARS = 600;
|
|
47
|
+
/**
|
|
48
|
+
* 判定抓取结果是否为登录墙(保守启发式,见文件头「宁漏勿误」)
|
|
49
|
+
*
|
|
50
|
+
* @param finalUrl 重定向后的实际 URL(`FetchedPage.url`;空串 = 无 URL 信息)
|
|
51
|
+
* @param title 页面标题(清洗后)
|
|
52
|
+
* @param content 页面正文(清洗后)
|
|
53
|
+
* @param contentCap 本次抓取的正文截断上限(toolExecutor 传 maxChars):
|
|
54
|
+
* 小于弱信号阈值时「短正文」可能是截断假象 → 弱信号禁用(强信号照常);
|
|
55
|
+
* 缺省 = 视为未截断(向后兼容既有调用形状)
|
|
56
|
+
* @returns true = 判为登录墙(调用方应明示不可读并引导换源)
|
|
57
|
+
*/
|
|
58
|
+
export function isLoginWallPage(finalUrl, title, content, contentCap) {
|
|
59
|
+
// 强信号:URL 段边界命中即判(不要求正文佐证——登录态 URL 抓到 200 就是墙)。
|
|
60
|
+
// 先剥 #fragment:锚点是页内位置不是页面身份(article#login 是文章);
|
|
61
|
+
// split('#') 安全——合法 URL 中首个 # 即 fragment 起点(RFC 3986,查询串内 # 同义)
|
|
62
|
+
const urlWithoutFragment = finalUrl.split('#')[0] ?? finalUrl;
|
|
63
|
+
if (urlWithoutFragment && URL_LOGIN_SEGMENT_RE.test(urlWithoutFragment))
|
|
64
|
+
return true;
|
|
65
|
+
// 弱信号组合:标题登录词 + 正文密码词 + 短正文,三条件同时满足才判。
|
|
66
|
+
// contentCap < 阈值 → 长度判据失真(截断制造伪短正文)→ 整组禁用(宁漏勿误)
|
|
67
|
+
const weakSignalsUsable = contentCap === undefined || contentCap >= LOGIN_WALL_MAX_CONTENT_CHARS;
|
|
68
|
+
if (weakSignalsUsable &&
|
|
69
|
+
title &&
|
|
70
|
+
TITLE_LOGIN_RE.test(title) &&
|
|
71
|
+
content &&
|
|
72
|
+
PASSWORD_WORD_RE.test(content) &&
|
|
73
|
+
content.length < LOGIN_WALL_MAX_CONTENT_CHARS) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=loginWall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loginWall.js","sourceRoot":"","sources":["../../src/web-fetch/loginWall.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;;;;GAQG;AACH,MAAM,oBAAoB,GACxB,0EAA0E,CAAC;AAE7E,wCAAwC;AACxC,MAAM,cAAc,GAAG,oCAAoC,CAAC;AAE5D,wBAAwB;AACxB,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,4BAA4B,GAAG,GAAG,CAAC;AAEzC;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,KAAa,EACb,OAAe,EACf,UAAmB;IAEnB,gDAAgD;IAChD,iDAAiD;IACjD,gEAAgE;IAChE,MAAM,kBAAkB,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC;IAC9D,IAAI,kBAAkB,IAAI,oBAAoB,CAAC,IAAI,CAAC,kBAAkB,CAAC;QAAE,OAAO,IAAI,CAAC;IACrF,uCAAuC;IACvC,iDAAiD;IACjD,MAAM,iBAAiB,GAAG,UAAU,KAAK,SAAS,IAAI,UAAU,IAAI,4BAA4B,CAAC;IACjG,IACE,iBAAiB;QACjB,KAAK;QACL,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;QAC1B,OAAO;QACP,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC;QAC9B,OAAO,CAAC,MAAM,GAAG,4BAA4B,EAC7C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -13,6 +13,14 @@ export interface FetchedPage {
|
|
|
13
13
|
content: string;
|
|
14
14
|
/** 内容类型(如 "text/html"、"application/pdf"),无法识别时为空串 */
|
|
15
15
|
contentType?: string;
|
|
16
|
+
/**
|
|
17
|
+
* 抓取失败降级页标记(safeFetch 专有;成功路径恒缺省,宿主自定义 provider 不打标)
|
|
18
|
+
*
|
|
19
|
+
* 值恒 `true`:只有降级页会置位,无人能置 false——「这不是一次成功抓取」是单向事实。
|
|
20
|
+
* 消费方(toolExecutor 登录墙判断)据此排除「抓取失败 + 登录段 URL 被误报为登录墙」
|
|
21
|
+
* 的谎报路径(失败语义不得改写成别的原因)。可选字段 = 契约放宽,向后兼容。
|
|
22
|
+
*/
|
|
23
|
+
fetchFailed?: true;
|
|
16
24
|
}
|
|
17
25
|
/** 抓取选项 */
|
|
18
26
|
export interface FetchOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/web-fetch/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAe;AACf,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/web-fetch/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAe;AACf,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,oBAAoB;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,IAAI,CAAC;CACpB;AAED,WAAW;AACX,MAAM,WAAW,YAAY;IAC3B,yBAAyB;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,0BAA0B;IAC1B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAClE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webFetchProvider.d.ts","sourceRoot":"","sources":["../../src/web-fetch/webFetchProvider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAKtF;;GAEG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,cAAc,EACxB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"webFetchProvider.d.ts","sourceRoot":"","sources":["../../src/web-fetch/webFetchProvider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAKtF;;GAEG;AACH,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,cAAc,EACxB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,WAAW,CAAC,CAsBtB"}
|
|
@@ -12,12 +12,14 @@ export async function safeFetch(provider, url, options) {
|
|
|
12
12
|
return await Promise.race([provider.fetch(url, options), timeoutPromise]);
|
|
13
13
|
}
|
|
14
14
|
catch (err) {
|
|
15
|
-
//
|
|
15
|
+
// 抓取失败不抛异常,返回降级提示页;fetchFailed 单向标记 = 「这不是一次成功抓取」,
|
|
16
|
+
// 供消费方(toolExecutor 登录墙判断)排除「失败被误报为登录墙」的谎报路径
|
|
16
17
|
const message = err instanceof Error ? err.message : String(err);
|
|
17
18
|
return {
|
|
18
19
|
url,
|
|
19
20
|
title: '网页抓取暂不可用',
|
|
20
21
|
content: `抓取失败:${message}。请稍后重试,或检查网络连接。`,
|
|
22
|
+
fetchFailed: true,
|
|
21
23
|
};
|
|
22
24
|
}
|
|
23
25
|
finally {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webFetchProvider.js","sourceRoot":"","sources":["../../src/web-fetch/webFetchProvider.ts"],"names":[],"mappings":"AAMA,mBAAmB;AACnB,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,QAAwB,EACxB,GAAW,EACX,OAAsB;IAEtB,IAAI,KAAgD,CAAC;IACrD,MAAM,cAAc,GAAG,IAAI,OAAO,CAAc,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAC5D,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;IAC5E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,
|
|
1
|
+
{"version":3,"file":"webFetchProvider.js","sourceRoot":"","sources":["../../src/web-fetch/webFetchProvider.ts"],"names":[],"mappings":"AAMA,mBAAmB;AACnB,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,QAAwB,EACxB,GAAW,EACX,OAAsB;IAEtB,IAAI,KAAgD,CAAC;IACrD,MAAM,cAAc,GAAG,IAAI,OAAO,CAAc,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAC5D,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAC/E,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC;IAC5E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,mDAAmD;QACnD,6CAA6C;QAC7C,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO;YACL,GAAG;YACH,KAAK,EAAE,UAAU;YACjB,OAAO,EAAE,QAAQ,OAAO,iBAAiB;YACzC,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,2BAA2B;QAC3B,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC"}
|
|
@@ -2,34 +2,39 @@ import { BROWSER_UA, fetchWithTimeout } from '../utils/http.js';
|
|
|
2
2
|
/** 单端点请求超时(ms):Bing 通常 1-2s 返回,10s 覆盖慢网络且不至于拖死主循环 */
|
|
3
3
|
const ENDPOINT_TIMEOUT_MS = 10_000;
|
|
4
4
|
/**
|
|
5
|
-
* 从 Bing 结果页 HTML
|
|
5
|
+
* 从 Bing 结果页 HTML 提取结果:结果条目 = `<li class="b_algo">` 块,块内 `<h2><a>` 取
|
|
6
|
+
* 标题+链接、块内 `<p class="b_lineclamp*">` 取摘要。
|
|
6
7
|
* 用正则而非 DOM 解析,避免引入 jsdom 依赖。
|
|
8
|
+
*
|
|
9
|
+
* **块内配对**(而非全文两个正则数组按 index 配对,SEARCH-QUALITY-1 P2-2 修订):
|
|
10
|
+
* 标题与摘要必须在同一结果块内成对——全文收集 `titles[]`/`snippets[]` 后按 index 配对时,
|
|
11
|
+
* 结果块之外的任何 `b_lineclamp`(推荐位/广告位/侧栏)都会造成错位:模块摘要被贴到
|
|
12
|
+
* 下一个结果标题上,LLM 读到「标题二 + 干扰摘要」的错位组合(搜不准的解析层根因)。
|
|
13
|
+
* 结构漂移(无 b_algo 块)→ 零结果 → 降级链切下一端点 = 诚实失败,不产错位垃圾。
|
|
14
|
+
* 块内提取范式同 parseBaiduHtml(仓内既有正确先例,嫁接而非新造)。
|
|
7
15
|
*/
|
|
8
16
|
function parseBingHtml(html, limit) {
|
|
9
17
|
const results = [];
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
18
|
+
// 结果块:<li …b_algo…>…</li>([^>]* 容忍附加 class/属性,如 b_algoBorder)。
|
|
19
|
+
// ⚠️ 正则内**禁写引号**(如 class="[^"]*b_algo…):toolFailurePrefixGuard 的字符串字面量
|
|
20
|
+
// 提取器会把正则内的引号配对成伪字面量(`[^` → 盲区标记 `^`,旧 `^>` 同源产物)——
|
|
21
|
+
// 无引号写法对 Bing 的 <li class="b_algo"> 同等正确且不新增扫描噪声。
|
|
22
|
+
const blockRegex = /<li[^>]*b_algo[^>]*>([\s\S]*?)<\/li>/gi;
|
|
13
23
|
let match;
|
|
14
|
-
while ((match =
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
results.push({
|
|
29
|
-
title: titles[i].title,
|
|
30
|
-
url: titles[i].url,
|
|
31
|
-
snippet: snippets[i] ?? '',
|
|
32
|
-
});
|
|
24
|
+
while ((match = blockRegex.exec(html)) !== null && results.length < limit) {
|
|
25
|
+
const block = match[1];
|
|
26
|
+
// 标题 + 链接:块内 <h2><a href>(块内无标题 = 非结果块,跳过不占结果位)
|
|
27
|
+
const titleMatch = /<h2[^>]*><a[^>]*href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/i.exec(block);
|
|
28
|
+
if (!titleMatch)
|
|
29
|
+
continue;
|
|
30
|
+
const url = titleMatch[1].replace(/&/g, '&').trim();
|
|
31
|
+
const title = titleMatch[2].replace(/<[^>]*>/g, '').trim();
|
|
32
|
+
if (!url || !title)
|
|
33
|
+
continue;
|
|
34
|
+
// 摘要:块内 <p class="b_lineclamp*>(块内无摘要 → 空串,不跨块借用)
|
|
35
|
+
const snipMatch = /<p[^>]*class="b_lineclamp[^"]*"[^>]*>([\s\S]*?)<\/p>/i.exec(block);
|
|
36
|
+
const snippet = snipMatch?.[1]?.replace(/<[^>]*>/g, '').trim() ?? '';
|
|
37
|
+
results.push({ title, url, snippet });
|
|
33
38
|
}
|
|
34
39
|
return results;
|
|
35
40
|
}
|