dsh-mobile-plugin 0.5.28 → 0.5.29
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/extensions/catalog.json +10 -1
- package/extensions/magpie/agentcompact.js +104 -0
- package/extensions/magpie/app.css +4902 -0
- package/extensions/magpie/app.js +24474 -0
- package/extensions/magpie/autobackup.js +185 -0
- package/extensions/magpie/autoresetown.js +151 -0
- package/extensions/magpie/balfound.js +38 -0
- package/extensions/magpie/boot.js +23 -0
- package/extensions/magpie/cfgblocked.js +39 -0
- package/extensions/magpie/checkinnow.js +111 -0
- package/extensions/magpie/claudemode.js +92 -0
- package/extensions/magpie/compat.js +41 -0
- package/extensions/magpie/context.css +433 -0
- package/extensions/magpie/context.js +1576 -0
- package/extensions/magpie/ctxtext.js +223 -0
- package/extensions/magpie/fonts.js +42 -0
- package/extensions/magpie/i18n.js +18942 -0
- package/extensions/magpie/icons/ai21.svg +1 -0
- package/extensions/magpie/icons/ai302-color.svg +1 -0
- package/extensions/magpie/icons/ai360-color.svg +1 -0
- package/extensions/magpie/icons/aihubmix-color.svg +1 -0
- package/extensions/magpie/icons/aionui.svg +1 -0
- package/extensions/magpie/icons/air.svg +4 -0
- package/extensions/magpie/icons/alibaba-color.svg +1 -0
- package/extensions/magpie/icons/alibabacloud-color.svg +1 -0
- package/extensions/magpie/icons/alma.png +0 -0
- package/extensions/magpie/icons/anthropic.svg +1 -0
- package/extensions/magpie/icons/antigravity-color.svg +1 -0
- package/extensions/magpie/icons/anyscale-color.svg +1 -0
- package/extensions/magpie/icons/app-alma.png +0 -0
- package/extensions/magpie/icons/app-cc-switch.png +0 -0
- package/extensions/magpie/icons/apple-touch-icon.png +0 -0
- package/extensions/magpie/icons/aside.svg +28 -0
- package/extensions/magpie/icons/astrbot.svg +1 -0
- package/extensions/magpie/icons/atomcode.png +0 -0
- package/extensions/magpie/icons/aws.svg +1 -0
- package/extensions/magpie/icons/azure-color.svg +1 -0
- package/extensions/magpie/icons/azureai-color.svg +1 -0
- package/extensions/magpie/icons/baichuan-color.svg +1 -0
- package/extensions/magpie/icons/baidu-color.svg +1 -0
- package/extensions/magpie/icons/baiducloud-color.svg +1 -0
- package/extensions/magpie/icons/bailian-color.svg +1 -0
- package/extensions/magpie/icons/baseten.svg +1 -0
- package/extensions/magpie/icons/bedrock-color.svg +1 -0
- package/extensions/magpie/icons/burncloud-color.svg +1 -0
- package/extensions/magpie/icons/bytedance-color.svg +1 -0
- package/extensions/magpie/icons/cerebras.svg +1 -0
- package/extensions/magpie/icons/chatglm-color.svg +1 -0
- package/extensions/magpie/icons/cherryin-color.svg +1 -0
- package/extensions/magpie/icons/chutes.svg +1 -0
- package/extensions/magpie/icons/cindy.png +0 -0
- package/extensions/magpie/icons/claude-color.svg +1 -0
- package/extensions/magpie/icons/claudecode-color.svg +1 -0
- package/extensions/magpie/icons/cline.svg +1 -0
- package/extensions/magpie/icons/cloudflare-color.svg +1 -0
- package/extensions/magpie/icons/codebuddy-color.svg +1 -0
- package/extensions/magpie/icons/codex-color.svg +1 -0
- package/extensions/magpie/icons/cohere-color.svg +1 -0
- package/extensions/magpie/icons/cometapi-color.svg +1 -0
- package/extensions/magpie/icons/commandcode.svg +1 -0
- package/extensions/magpie/icons/copilot-color.svg +1 -0
- package/extensions/magpie/icons/coze.svg +1 -0
- package/extensions/magpie/icons/crush.png +0 -0
- package/extensions/magpie/icons/curl.svg +1 -0
- package/extensions/magpie/icons/cursor.svg +1 -0
- package/extensions/magpie/icons/deepinfra-color.svg +1 -0
- package/extensions/magpie/icons/deepmind-color.svg +1 -0
- package/extensions/magpie/icons/deepseek-color.svg +1 -0
- package/extensions/magpie/icons/deveco-color.svg +12 -0
- package/extensions/magpie/icons/devin.svg +1 -0
- package/extensions/magpie/icons/doubao-color.svg +1 -0
- package/extensions/magpie/icons/empryo-color.svg +1 -0
- package/extensions/magpie/icons/factory.svg +1 -0
- package/extensions/magpie/icons/favicon.svg +1 -0
- package/extensions/magpie/icons/featherless-color.svg +1 -0
- package/extensions/magpie/icons/fireworks-color.svg +1 -0
- package/extensions/magpie/icons/friendli.svg +1 -0
- package/extensions/magpie/icons/fx.svg +1 -0
- package/extensions/magpie/icons/gemini-color.svg +1 -0
- package/extensions/magpie/icons/geminicli-color.svg +1 -0
- package/extensions/magpie/icons/gemma-color.svg +1 -0
- package/extensions/magpie/icons/giteeai.svg +1 -0
- package/extensions/magpie/icons/github.svg +1 -0
- package/extensions/magpie/icons/githubcopilot.svg +1 -0
- package/extensions/magpie/icons/glama.svg +1 -0
- package/extensions/magpie/icons/gmicloud.svg +1 -0
- package/extensions/magpie/icons/google-color.svg +1 -0
- package/extensions/magpie/icons/googlecloud-color.svg +1 -0
- package/extensions/magpie/icons/goose.svg +1 -0
- package/extensions/magpie/icons/grok.svg +1 -0
- package/extensions/magpie/icons/groq.svg +1 -0
- package/extensions/magpie/icons/hanako.png +0 -0
- package/extensions/magpie/icons/hermes.svg +1 -0
- package/extensions/magpie/icons/huawei-color.svg +1 -0
- package/extensions/magpie/icons/huaweicloud-color.svg +1 -0
- package/extensions/magpie/icons/huggingface-color.svg +1 -0
- package/extensions/magpie/icons/hunyuan-color.svg +1 -0
- package/extensions/magpie/icons/hyperbolic-color.svg +1 -0
- package/extensions/magpie/icons/icon-512.png +0 -0
- package/extensions/magpie/icons/iflytekcloud-color.svg +1 -0
- package/extensions/magpie/icons/inference.svg +1 -0
- package/extensions/magpie/icons/infinigence-color.svg +1 -0
- package/extensions/magpie/icons/internlm-color.svg +1 -0
- package/extensions/magpie/icons/jcode.svg +1 -0
- package/extensions/magpie/icons/jina.svg +1 -0
- package/extensions/magpie/icons/kilo.svg +1 -0
- package/extensions/magpie/icons/kilocode.svg +1 -0
- package/extensions/magpie/icons/kimi-code-desktop.png +0 -0
- package/extensions/magpie/icons/kimi.svg +1 -0
- package/extensions/magpie/icons/kiro-color.svg +1 -0
- package/extensions/magpie/icons/kling-color.svg +1 -0
- package/extensions/magpie/icons/lambda.svg +1 -0
- package/extensions/magpie/icons/leptonai-color.svg +1 -0
- package/extensions/magpie/icons/liquid.svg +1 -0
- package/extensions/magpie/icons/liveagent-color.svg +1 -0
- package/extensions/magpie/icons/llmapi.svg +1 -0
- package/extensions/magpie/icons/lmstudio.svg +1 -0
- package/extensions/magpie/icons/lody.png +0 -0
- package/extensions/magpie/icons/longcat.svg +1 -0
- package/extensions/magpie/icons/magpie.svg +1 -0
- package/extensions/magpie/icons/meta-color.svg +1 -0
- package/extensions/magpie/icons/metaai-color.svg +1 -0
- package/extensions/magpie/icons/microsoft-color.svg +1 -0
- package/extensions/magpie/icons/mimocode.svg +1 -0
- package/extensions/magpie/icons/minimax-color.svg +1 -0
- package/extensions/magpie/icons/mistermorph-color.svg +1 -0
- package/extensions/magpie/icons/mistral-color.svg +1 -0
- package/extensions/magpie/icons/mlx-serve.png +0 -0
- package/extensions/magpie/icons/modelscope-color.svg +1 -0
- package/extensions/magpie/icons/monica-color.svg +1 -0
- package/extensions/magpie/icons/moonshot.svg +1 -0
- package/extensions/magpie/icons/morph-color.svg +1 -0
- package/extensions/magpie/icons/mothx.png +0 -0
- package/extensions/magpie/icons/nebius.svg +1 -0
- package/extensions/magpie/icons/newapi-color.svg +1 -0
- package/extensions/magpie/icons/nousresearch.svg +1 -0
- package/extensions/magpie/icons/nova-color.svg +1 -0
- package/extensions/magpie/icons/novita-color.svg +1 -0
- package/extensions/magpie/icons/nvidia-color.svg +1 -0
- package/extensions/magpie/icons/ollama.svg +1 -0
- package/extensions/magpie/icons/omlx.svg +1 -0
- package/extensions/magpie/icons/omo.svg +1 -0
- package/extensions/magpie/icons/omp.svg +1 -0
- package/extensions/magpie/icons/openai.svg +1 -0
- package/extensions/magpie/icons/openchamber.svg +11 -0
- package/extensions/magpie/icons/openclaw.svg +1 -0
- package/extensions/magpie/icons/opencode.svg +1 -0
- package/extensions/magpie/icons/openmausbot.svg +1 -0
- package/extensions/magpie/icons/openrouter.svg +1 -0
- package/extensions/magpie/icons/openwebui.svg +1 -0
- package/extensions/magpie/icons/parasail.svg +1 -0
- package/extensions/magpie/icons/penguin-color.svg +1 -0
- package/extensions/magpie/icons/perplexity-color.svg +1 -0
- package/extensions/magpie/icons/phala-color.svg +1 -0
- package/extensions/magpie/icons/pi.svg +1 -0
- package/extensions/magpie/icons/pipellm-color.svg +5 -0
- package/extensions/magpie/icons/poe.svg +1 -0
- package/extensions/magpie/icons/ppio-color.svg +1 -0
- package/extensions/magpie/icons/prime-agent.svg +1 -0
- package/extensions/magpie/icons/qiniu-color.svg +1 -0
- package/extensions/magpie/icons/qoder.svg +1 -0
- package/extensions/magpie/icons/qwen-color.svg +1 -0
- package/extensions/magpie/icons/qwenpaw.svg +1 -0
- package/extensions/magpie/icons/raycast.svg +1 -0
- package/extensions/magpie/icons/reasonix-color.svg +48 -0
- package/extensions/magpie/icons/reka.svg +1 -0
- package/extensions/magpie/icons/replicate.svg +1 -0
- package/extensions/magpie/icons/roocode.svg +1 -0
- package/extensions/magpie/icons/rtk.png +0 -0
- package/extensions/magpie/icons/sambanova-color.svg +1 -0
- package/extensions/magpie/icons/sensenova-color.svg +1 -0
- package/extensions/magpie/icons/siliconcloud-color.svg +1 -0
- package/extensions/magpie/icons/snow.png +0 -0
- package/extensions/magpie/icons/snowflake-color.svg +1 -0
- package/extensions/magpie/icons/sophnet-color.svg +1 -0
- package/extensions/magpie/icons/spark-color.svg +1 -0
- package/extensions/magpie/icons/stepfun-color.svg +1 -0
- package/extensions/magpie/icons/straico-color.svg +1 -0
- package/extensions/magpie/icons/submodel-color.svg +1 -0
- package/extensions/magpie/icons/t3code.svg +4 -0
- package/extensions/magpie/icons/targon-color.svg +1 -0
- package/extensions/magpie/icons/tencent-color.svg +1 -0
- package/extensions/magpie/icons/tencentcloud-color.svg +1 -0
- package/extensions/magpie/icons/tiangong-color.svg +1 -0
- package/extensions/magpie/icons/together-color.svg +1 -0
- package/extensions/magpie/icons/trae.svg +1 -0
- package/extensions/magpie/icons/typesafe.png +0 -0
- package/extensions/magpie/icons/upstage-color.svg +1 -0
- package/extensions/magpie/icons/venice-color.svg +1 -0
- package/extensions/magpie/icons/vercel.svg +1 -0
- package/extensions/magpie/icons/vertexai-color.svg +1 -0
- package/extensions/magpie/icons/vllm-color.svg +1 -0
- package/extensions/magpie/icons/volcengine-color.svg +1 -0
- package/extensions/magpie/icons/voyage-color.svg +1 -0
- package/extensions/magpie/icons/vscode.svg +1 -0
- package/extensions/magpie/icons/wenxin-color.svg +1 -0
- package/extensions/magpie/icons/windsurf.svg +1 -0
- package/extensions/magpie/icons/workbuddy-color.svg +1 -0
- package/extensions/magpie/icons/workersai-color.svg +1 -0
- package/extensions/magpie/icons/xai.svg +1 -0
- package/extensions/magpie/icons/xiaomimimo.svg +1 -0
- package/extensions/magpie/icons/xinference-color.svg +1 -0
- package/extensions/magpie/icons/yi.svg +1 -0
- package/extensions/magpie/icons/yuanbao-color.svg +1 -0
- package/extensions/magpie/icons/yylx.svg +5 -0
- package/extensions/magpie/icons/zai.svg +1 -0
- package/extensions/magpie/icons/zcode.png +0 -0
- package/extensions/magpie/icons/zed.svg +1 -0
- package/extensions/magpie/icons/zenmux.svg +1 -0
- package/extensions/magpie/icons/zeroone.svg +1 -0
- package/extensions/magpie/icons/zhipu-color.svg +1 -0
- package/extensions/magpie/icons/zoo-code.png +0 -0
- package/extensions/magpie/index.html +572 -0
- package/extensions/magpie/kernel.js +274 -0
- package/extensions/magpie/keyspend.js +63 -0
- package/extensions/magpie/layout.js +26 -0
- package/extensions/magpie/manifest.json +37 -0
- package/extensions/magpie/navlamp.js +47 -0
- package/extensions/magpie/omarchy.css +72 -0
- package/extensions/magpie/omarchy.js +46 -0
- package/extensions/magpie/passerrors.js +21 -0
- package/extensions/magpie/pluginpages.js +405 -0
- package/extensions/magpie/plugins/gateway/client.js +1194 -0
- package/extensions/magpie/plugins/gateway/keys.js +972 -0
- package/extensions/magpie/plugins/gateway/settings.js +459 -0
- package/extensions/magpie/plugins/library/client.js +6788 -0
- package/extensions/magpie/plugins/library/i18n.js +3228 -0
- package/extensions/magpie/plugins/library/library.css +848 -0
- package/extensions/magpie/plugins/otel/i18n.js +48 -0
- package/extensions/magpie/plugins/otel/page.js +189 -0
- package/extensions/magpie/plugins/redact/client.js +46 -0
- package/extensions/magpie/plugins/redact/demo.js +461 -0
- package/extensions/magpie/plugins/redact/i18n.js +432 -0
- package/extensions/magpie/plugins/redact/page.js +985 -0
- package/extensions/magpie/plugins/redact/redact.css +385 -0
- package/extensions/magpie/plugins/redact/settings.js +248 -0
- package/extensions/magpie/plugins/redact/xq_dark.jpg +0 -0
- package/extensions/magpie/plugins/redact/xq_dark.webm +0 -0
- package/extensions/magpie/plugins/redact/xq_light.jpg +0 -0
- package/extensions/magpie/plugins/redact/xq_light.webm +0 -0
- package/extensions/magpie/plugins/routing/client.js +8593 -0
- package/extensions/magpie/plugins/routing/i18n.js +2696 -0
- package/extensions/magpie/plugins/routing/routing.css +1111 -0
- package/extensions/magpie/plugins/search/settings.js +460 -0
- package/extensions/magpie/plugins/sessions/client.js +1622 -0
- package/extensions/magpie/plugins/sessions/i18n.js +360 -0
- package/extensions/magpie/plugins/sessions/sessions.css +181 -0
- package/extensions/magpie/plugins/sessions/settings.js +100 -0
- package/extensions/magpie/plugins/usage/client.js +150 -0
- package/extensions/magpie/plugins/usage/i18n.js +984 -0
- package/extensions/magpie/plugins/usage/page.js +4307 -0
- package/extensions/magpie/plugins.css +319 -0
- package/extensions/magpie/plugins.js +1926 -0
- package/extensions/magpie/profilerename.js +27 -0
- package/extensions/magpie/purposes.js +2 -0
- package/extensions/magpie/quitask.js +79 -0
- package/extensions/magpie/quotaall.js +142 -0
- package/extensions/magpie/ratewindows.js +123 -0
- package/extensions/magpie/registry.js +87 -0
- package/extensions/magpie/resetask.js +137 -0
- package/extensions/magpie/ruleedit.js +53 -0
- package/extensions/magpie/scrollends.js +91 -0
- package/extensions/magpie/settingshints.js +75 -0
- package/extensions/magpie/signsheets.js +86 -0
- package/extensions/magpie/start.js +26 -0
- package/extensions/magpie/syncfiles.js +216 -0
- package/extensions/magpie/theme.js +29 -0
- package/extensions/magpie/traywindows.js +41 -0
- package/extensions/magpie/webfonts.js +130 -0
- package/extensions/magpie/whatsnew.js +252 -0
- package/extensions/magpie.zip +0 -0
- package/knowledge/apps/baijiahao.md +30 -0
- package/knowledge/apps/bilibili.md +1 -0
- package/knowledge/apps/dedao.md +33 -0
- package/knowledge/apps/feishu.md +35 -0
- package/knowledge/apps/gmail.md +33 -0
- package/knowledge/apps/jike.md +31 -0
- package/knowledge/apps/kuaishou.md +34 -0
- package/knowledge/apps/linkedin.md +33 -0
- package/knowledge/apps/qqmail.md +30 -0
- package/knowledge/apps/telegram.md +27 -0
- package/knowledge/apps/toutiao.md +32 -0
- package/knowledge/apps/uber-eats.md +26 -0
- package/knowledge/apps/uber.md +27 -0
- package/knowledge/apps/whatsapp.md +27 -0
- package/knowledge/apps/x.md +32 -0
- package/knowledge/apps/xiaohongshu.md +1 -0
- package/knowledge/apps/zhihu.md +1 -0
- package/knowledge/sites/bilibili.com/SITE.md +50 -0
- package/knowledge/sites/bilibili.com/references/view-fields.md +17 -0
- package/knowledge/sites/github.com/SITE.md +51 -0
- package/knowledge/sites/github.com/references/repo-fields.md +13 -0
- package/knowledge/sites/x.com/SITE.md +47 -0
- package/knowledge/sites/xiaohongshu.com/SITE.md +48 -0
- package/knowledge/sites/xiaohongshu.com/references/note-fields.md +18 -0
- package/knowledge/sites/youtube.com/SITE.md +49 -0
- package/knowledge/sites/youtube.com/references/innertube-fields.md +14 -0
- package/knowledge/sites/zhihu.com/SITE.md +47 -0
- package/knowledge/sites/zhihu.com/references/api-fields.md +21 -0
- package/lib/mobile/extension-catalog.js +41 -1
- package/lib/mobile/extension-data.js +224 -0
- package/lib/mobile/extension-dev.js +3 -1
- package/lib/mobile/file-ops.js +252 -0
- package/lib/mobile/history-derive.js +80 -4
- package/lib/mobile/host-bridge/endpoints.js +48 -6
- package/lib/mobile/host-bridge/event-synthesis.js +33 -6
- package/lib/mobile/jobs-control.js +118 -0
- package/lib/mobile/memory.js +635 -0
- package/lib/mobile/model-badges.js +77 -0
- package/lib/mobile/pet-tools.js +50 -4
- package/lib/mobile/pets.js +214 -18
- package/lib/mobile/phone/access.js +85 -0
- package/lib/mobile/phone/evidence.js +228 -0
- package/lib/mobile/phone/gate.js +290 -0
- package/lib/mobile/phone/grounding.js +314 -0
- package/lib/mobile/phone/guard.js +465 -0
- package/lib/mobile/phone/irreversible.js +88 -8
- package/lib/mobile/phone/knowledge-tools.js +665 -0
- package/lib/mobile/phone/learn.js +329 -0
- package/lib/mobile/phone/redact.js +237 -0
- package/lib/mobile/phone/risk.js +95 -0
- package/lib/mobile/phone/routes.js +28 -1
- package/lib/mobile/phone/service.js +23 -0
- package/lib/mobile/phone/site-commands.js +271 -0
- package/lib/mobile/phone/step-summary.js +201 -0
- package/lib/mobile/phone/stop-summary.js +235 -0
- package/lib/mobile/phone/tool-groups.js +125 -0
- package/lib/mobile/phone/tools.js +589 -0
- package/lib/mobile/phone/untrusted.js +65 -0
- package/lib/mobile/phone-knowledge.js +20 -4
- package/lib/mobile/schedule-edit.js +500 -0
- package/lib/mobile/schedule.js +5 -0
- package/lib/mobile/send-continuation.js +52 -0
- package/lib/mobile/session-models.js +27 -31
- package/lib/mobile/session-send.js +12 -12
- package/lib/mobile/skill-import.js +338 -0
- package/lib/mobile/skill-store.js +524 -0
- package/lib/routes/mobile-api.js +42 -0
- package/package.json +7 -6
- package/skills/skill-authoring/SKILL.md +46 -0
- package/skills/skill-authoring/references/examples.md +82 -0
- package/skills/skill-authoring/references/frontmatter-and-fields.md +46 -0
- package/skills/skill-authoring/scripts/check_skill.py +167 -0
- package/skills/skill-authoring/scripts/manifest.json +3 -0
- package/knowledge/sites/bilibili.com.md +0 -27
- package/knowledge/sites/github.com.md +0 -27
- package/knowledge/sites/x.com.md +0 -28
- package/knowledge/sites/xiaohongshu.com.md +0 -27
- package/knowledge/sites/youtube.com.md +0 -28
- package/knowledge/sites/zhihu.com.md +0 -27
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 与模型无关的字面核查:回答里的引文、带单位/货币的数、日期时刻,必须能在**本次读到的
|
|
5
|
+
* 材料原文**里找到。
|
|
6
|
+
*
|
|
7
|
+
* 只核它核得准的——「有没有这句 / 有没有这个数」;**不核**一个值是不是属于回答说的那个
|
|
8
|
+
* 东西(哪个页面、哪个商品、哪一行)。语义归属要看懂上下文,那交给核查模型,不由这里判。
|
|
9
|
+
*
|
|
10
|
+
* 口径照 Mika `core/verify/Grounding.kt` 收窄:引号里的原文、带单位或货币或百分号或数量级
|
|
11
|
+
* 的数、小数、三位以上整数、日期与时刻;两位以内不带单位的整数(计数、序号、排名)不核。
|
|
12
|
+
*
|
|
13
|
+
* `check({answer, evidence, goal})` 返回 `{ ok, unmet, claims, matched }`:
|
|
14
|
+
* - `claims` 是回答里可核对的具体事实,`matched` 是其中对上的条数;
|
|
15
|
+
* - `unmet` 是对不上的那几条(`{ kind, text }`),`ok` 为 `unmet` 为空。
|
|
16
|
+
*
|
|
17
|
+
* 不通过时用 `rewriteHint(結果)` 给一句「退回改写一次」的提示;`review(...)` 把这个
|
|
18
|
+
* 「改写一次、再不行标未确认」的口径也一并给定(见文件底)。
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/** 引号:中文直角 / 双引号 / 弯引号 / 直引号。空引号直接跳过。 */
|
|
22
|
+
const QUOTED = /「([^」]*)」|『([^』]*)』|“([^”]*)”|"([^"]*)"|‘([^’]*)’/g;
|
|
23
|
+
|
|
24
|
+
/** 「依据[::]」之后只核引文,其余(来源、网址、时间)不是要核对的事实。 */
|
|
25
|
+
const EVIDENCE = /依据\**\s*[::]/;
|
|
26
|
+
|
|
27
|
+
/** 数(含千分位与小数);后面紧跟的万/亿/千是数量级(千后面不能是米/克/瓦之类单位词)。 */
|
|
28
|
+
const NUMBER = /(?<!\d)(?<!\d[.,])\d+(?:[.,]\d+)*(?!\d)([ \t]*(?:[亿万]|千(?![米克瓦卡帕焦])))?/g;
|
|
29
|
+
|
|
30
|
+
/** 日期与时刻:10月23日、2026-10-23、2026/10/23、14:05、14:05:30。 */
|
|
31
|
+
const DATE = /(?<!\d)(?:\d{4}\s*[-/年]\s*\d{1,2}(?:\s*[-/月]\s*\d{1,2}\s*[日号]?)?|\d{1,2}\s*月\s*\d{1,2}\s*[日号]?|\d{1,2}\s*:\s*\d{2}(?:\s*:\s*\d{2})?)(?!\d)/g;
|
|
32
|
+
|
|
33
|
+
/** 数后面紧跟的量/单位(不含「条」「个」这类量词——那是回答自己数出来的)。 */
|
|
34
|
+
const UNIT_AFTER = /^\s*(?:%|‰|元|块|角|美元|欧元|日元|港元|英镑|℃|°|度|公里|千米|米|厘米|毫米|公斤|千克|斤|克|吨|小时|分钟|秒|毫秒|岁|英寸|寸|折|星|km|cm|mm|kg|mAh|GB|MB|KB|TB|Hz|ms)(?![A-Za-z])/;
|
|
35
|
+
|
|
36
|
+
/** 数前面的货币符号。 */
|
|
37
|
+
const CURRENCY_BEFORE = /[¥$€£]\s*$/;
|
|
38
|
+
|
|
39
|
+
/** 引用编号(@e16 / @v2)与脚注([1] / 【3】)不是回答内容,比对前去掉。 */
|
|
40
|
+
const REF_CITATION = /\(?\s*@[ev]\d+(?:\s*[,、]\s*@[ev]\d+)*\s*\)?/g;
|
|
41
|
+
const FOOTNOTE = /\[\^?\d{1,3}\]|【\d{1,3}】/g;
|
|
42
|
+
|
|
43
|
+
/** 排版强调与行内代码只是排版,不是内容(单个 * 可能是乘号,不动)。 */
|
|
44
|
+
const MARKUP = /\*\*|__|~~|`/g;
|
|
45
|
+
const ZERO_WIDTH = /[\u200B-\u200D\uFEFF\u2060]/g;
|
|
46
|
+
|
|
47
|
+
/** 屏上「当前 App:」那一行不算屏上文字。 */
|
|
48
|
+
const APP_HEADER = '当前 App:';
|
|
49
|
+
|
|
50
|
+
/** 截断标记。 */
|
|
51
|
+
const CUT = '...';
|
|
52
|
+
|
|
53
|
+
const MAGNITUDE = { 亿: 8, 万: 4, 千: 3 };
|
|
54
|
+
|
|
55
|
+
function canon(s) {
|
|
56
|
+
return String(s == null ? '' : s)
|
|
57
|
+
.normalize('NFKC')
|
|
58
|
+
.replace(ZERO_WIDTH, '')
|
|
59
|
+
.replace(MARKUP, '')
|
|
60
|
+
.replace(REF_CITATION, ' ')
|
|
61
|
+
.replace(FOOTNOTE, ' ');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** 只留字母与数字,用于「这句原文在不在这行里」。 */
|
|
65
|
+
function norm(s) {
|
|
66
|
+
return String(s == null ? '' : s).replace(/[^\p{L}\p{N}]/gu, '');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function quotes(s) {
|
|
70
|
+
const out = [];
|
|
71
|
+
QUOTED.lastIndex = 0;
|
|
72
|
+
let m;
|
|
73
|
+
while ((m = QUOTED.exec(s)) !== null) {
|
|
74
|
+
const q = m.slice(1).find((x) => typeof x === 'string' && x !== '');
|
|
75
|
+
if (q !== undefined) out.push(q);
|
|
76
|
+
}
|
|
77
|
+
return out;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** 一个数 + 数量级。scaled 是折算到基本单位后的写法(5.3万 = 53000)。 */
|
|
81
|
+
function makeNum(value, magnitude) {
|
|
82
|
+
const clean = value.replace(/,/g, '');
|
|
83
|
+
let scaled = null;
|
|
84
|
+
if (/^\d+(?:\.\d+)?$/.test(clean)) {
|
|
85
|
+
const base = Number(clean);
|
|
86
|
+
if (Number.isFinite(base)) {
|
|
87
|
+
const pow = MAGNITUDE[magnitude];
|
|
88
|
+
scaled = pow ? String(base * 10 ** pow) : String(base);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { value: clean, magnitude: magnitude || '', scaled };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function numMatches(a, b) {
|
|
95
|
+
if (a.value === b.value && (a.magnitude === '' || a.magnitude === b.magnitude)) return true;
|
|
96
|
+
return a.scaled !== null && a.scaled === b.scaled;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** 一行里的全部数(不判它们是不是「值」,只做比对底料)。 */
|
|
100
|
+
function numbersIn(s) {
|
|
101
|
+
const out = [];
|
|
102
|
+
NUMBER.lastIndex = 0;
|
|
103
|
+
let m;
|
|
104
|
+
while ((m = NUMBER.exec(s)) !== null) {
|
|
105
|
+
const mag = m[1] || '';
|
|
106
|
+
const magnitude = mag.trim();
|
|
107
|
+
const raw = m[0].slice(0, m[0].length - mag.length);
|
|
108
|
+
out.push(makeNum(raw, magnitude));
|
|
109
|
+
}
|
|
110
|
+
return out;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 回答里算作事实的数:带数量级 / 单位 / 货币的,小数,三位以上整数。
|
|
115
|
+
* 题目里给了的数(goal 里的数)视为已知,不再核(但据它算出的结果仍要在屏上读到)。
|
|
116
|
+
*/
|
|
117
|
+
function valueNumbers(line, goalValues) {
|
|
118
|
+
const out = [];
|
|
119
|
+
NUMBER.lastIndex = 0;
|
|
120
|
+
let m;
|
|
121
|
+
while ((m = NUMBER.exec(line)) !== null) {
|
|
122
|
+
const mag = m[1] || '';
|
|
123
|
+
const magnitude = mag.trim();
|
|
124
|
+
const raw = m[0].slice(0, m[0].length - mag.length);
|
|
125
|
+
const n = makeNum(raw, magnitude);
|
|
126
|
+
if (n.scaled !== null && goalValues.has(n.scaled)) continue;
|
|
127
|
+
const after = line.slice(m.index + m[0].length, m.index + m[0].length + 8);
|
|
128
|
+
const before = line.slice(0, m.index);
|
|
129
|
+
const unit = magnitude !== '' || UNIT_AFTER.test(after) || CURRENCY_BEFORE.test(before);
|
|
130
|
+
const decimal = n.value.includes('.');
|
|
131
|
+
const long = n.value.split('.')[0].length >= 3;
|
|
132
|
+
if (unit || decimal || long) out.push({ kind: 'number', text: `${n.value}${magnitude}`, num: n });
|
|
133
|
+
}
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** 一行里的日期 / 时刻(题目里已有的不算)。 */
|
|
138
|
+
function dateClaims(line, goalDigits) {
|
|
139
|
+
const out = [];
|
|
140
|
+
DATE.lastIndex = 0;
|
|
141
|
+
let m;
|
|
142
|
+
while ((m = DATE.exec(line)) !== null) {
|
|
143
|
+
const text = m[0].trim();
|
|
144
|
+
const digits = digitsOf(text);
|
|
145
|
+
if (digits.length > 0 && digits.every((d) => goalDigits.has(d))) continue;
|
|
146
|
+
out.push({ kind: 'date', text });
|
|
147
|
+
}
|
|
148
|
+
return out;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function digitsOf(s) {
|
|
152
|
+
return (String(s).match(/\d+/g) || []).map((d) => d.replace(/^0+(?=\d)/, '')).filter((d) => d !== '');
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** 把一处材料拆成「按行预处理好」的比对底料。 */
|
|
156
|
+
function prepareSources(evidence) {
|
|
157
|
+
const texts = Array.isArray(evidence)
|
|
158
|
+
? evidence
|
|
159
|
+
: (evidence && typeof evidence === 'object' && typeof evidence.text === 'string' ? [evidence.text] : []);
|
|
160
|
+
return texts
|
|
161
|
+
.filter((t) => typeof t === 'string' && t !== '')
|
|
162
|
+
.map((text) => {
|
|
163
|
+
const lines = canon(text).split('\n').filter((l) => l.trim() !== '' && !l.trim().startsWith(APP_HEADER));
|
|
164
|
+
return {
|
|
165
|
+
normLines: lines.map(norm),
|
|
166
|
+
// 每行的数、数字串、字母数字串
|
|
167
|
+
nums: lines.map((l) => numbersIn(l)),
|
|
168
|
+
digits: lines.map((l) => digitsOf(l)),
|
|
169
|
+
tokens: lines.map((l) => (l.toLowerCase().match(/[a-z0-9]+/g) || [])),
|
|
170
|
+
};
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** 引文在某处材料里:被 ... 分开的几段各对得上,而且在同一处。 */
|
|
175
|
+
function quoteInSources(quote, sources) {
|
|
176
|
+
const parts = canon(quote).split(CUT).map(norm).filter((p) => p.length >= 2);
|
|
177
|
+
if (parts.length === 0) return false;
|
|
178
|
+
return sources.some((src) => parts.every((p) => src.normLines.some((line) => line.includes(p))));
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** 数在某处材料里(按整个数比,含数量级折算)。 */
|
|
182
|
+
function numberInSources(num, sources) {
|
|
183
|
+
return sources.some((src) => src.nums.some((lineNums) => lineNums.some((n) => numMatches(num, n))));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** 日期在某处材料里:数字串窗口对上(含丢掉年份的「月日」)。 */
|
|
187
|
+
function dateInSources(text, sources) {
|
|
188
|
+
const comps = digitsOf(text);
|
|
189
|
+
if (comps.length === 0) return false;
|
|
190
|
+
const variants = [comps];
|
|
191
|
+
if (comps.length === 3 && comps[0].length === 4) variants.push(comps.slice(1));
|
|
192
|
+
return sources.some((src) => variants.some((v) => src.digits.some((line) => {
|
|
193
|
+
if (v.length > line.length) return false;
|
|
194
|
+
for (let i = 0; i + v.length <= line.length; i += 1) {
|
|
195
|
+
if (v.every((d, k) => line[i + k] === d)) return true;
|
|
196
|
+
}
|
|
197
|
+
return false;
|
|
198
|
+
})));
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* 核一遍。
|
|
203
|
+
*
|
|
204
|
+
* @param {{answer:string, evidence:(string|string[]|{text:string}), goal?:string}} input
|
|
205
|
+
* @returns {{ ok:boolean, unmet:Array<{kind:string,text:string}>, claims:Array<{kind:string,text:string}>, matched:number }}
|
|
206
|
+
*/
|
|
207
|
+
function check(input) {
|
|
208
|
+
const answer = input && typeof input.answer === 'string' ? input.answer : '';
|
|
209
|
+
const goal = input && typeof input.goal === 'string' ? input.goal : '';
|
|
210
|
+
const sources = prepareSources(input && input.evidence);
|
|
211
|
+
|
|
212
|
+
const a = canon(answer);
|
|
213
|
+
const at = EVIDENCE.exec(a);
|
|
214
|
+
const body = at ? a.slice(0, at.index) : a;
|
|
215
|
+
const basis = at ? a.slice(at.index + at[0].length) : '';
|
|
216
|
+
|
|
217
|
+
const goalText = norm(goal);
|
|
218
|
+
const goalNumbers = numbersIn(canon(goal));
|
|
219
|
+
const goalValues = new Set(goalNumbers.map((n) => n.scaled).filter((v) => v !== null));
|
|
220
|
+
const goalDigits = new Set(digitsOf(goal));
|
|
221
|
+
|
|
222
|
+
const claims = [];
|
|
223
|
+
|
|
224
|
+
// 回答正文里的引文(题目里本来有的、空的不算)。
|
|
225
|
+
const plainBody = body.replace(QUOTED, ' ');
|
|
226
|
+
for (const q of quotes(body)) {
|
|
227
|
+
if (norm(q).length < 2) continue;
|
|
228
|
+
if (norm(q) && goalText && goalText.includes(norm(q))) continue;
|
|
229
|
+
claims.push({ kind: 'quote', text: q });
|
|
230
|
+
}
|
|
231
|
+
// 「依据:」里的引文同样要核。
|
|
232
|
+
for (const q of quotes(basis)) {
|
|
233
|
+
if (norm(q).length < 2) continue;
|
|
234
|
+
claims.push({ kind: 'quote', text: q });
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// 逐行取数、取日期(正文里引号内容要遮掉,避免引文里的数被重复当成正文的事实)。
|
|
238
|
+
for (const rawLine of plainBody.split('\n')) {
|
|
239
|
+
const line = rawLine.replace(MARKUP, '');
|
|
240
|
+
for (const c of dateClaims(line, goalDigits)) claims.push(c);
|
|
241
|
+
for (const c of valueNumbers(line, goalValues)) claims.push(c);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// 去重
|
|
245
|
+
const seen = new Set();
|
|
246
|
+
const unique = claims.filter((c) => {
|
|
247
|
+
const key = `${c.kind}\u0000${c.text}`;
|
|
248
|
+
if (seen.has(key)) return false;
|
|
249
|
+
seen.add(key);
|
|
250
|
+
return true;
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
let matched = 0;
|
|
254
|
+
const unmet = [];
|
|
255
|
+
for (const c of unique) {
|
|
256
|
+
let ok;
|
|
257
|
+
if (c.kind === 'quote') ok = quoteInSources(c.text, sources);
|
|
258
|
+
else if (c.kind === 'number') ok = numberInSources(c.num || makeNum(c.text, ''), sources);
|
|
259
|
+
else ok = dateInSources(c.text, sources);
|
|
260
|
+
if (ok) matched += 1;
|
|
261
|
+
else unmet.push({ kind: c.kind, text: c.text });
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// 去掉内部字段再返回。
|
|
265
|
+
const claimsOut = unique.map((c) => ({ kind: c.kind, text: c.text }));
|
|
266
|
+
return { ok: unmet.length === 0, unmet, claims: claimsOut, matched };
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
const KIND_LABEL = { quote: '引文', number: '数', date: '日期' };
|
|
270
|
+
|
|
271
|
+
/** 给「退回改写一次」用的一句提示:把对不上的逐条列出来,让它改写或标未确认。 */
|
|
272
|
+
function rewriteHint(result) {
|
|
273
|
+
const unmet = result && Array.isArray(result.unmet) ? result.unmet : [];
|
|
274
|
+
if (unmet.length === 0) return '';
|
|
275
|
+
const items = unmet.map((u) => `- ${KIND_LABEL[u.kind] || u.kind}「${u.text}」`).join('\n');
|
|
276
|
+
return [
|
|
277
|
+
'下面这些在本次读到的材料里找不到原文:',
|
|
278
|
+
items,
|
|
279
|
+
'请改写一次:删掉,或改成材料里确实出现过的话和数;确实没法确认的,标成「未确认」。',
|
|
280
|
+
].join('\n');
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/** 最多退回改写几次。 */
|
|
284
|
+
const MAX_REWRITE = 1;
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* 交回答前的核查口径:对不上就退回改写**一次**;改写过还是一样对不上,就标未确认交出
|
|
288
|
+
* (不无限重试,也不假装通过)。
|
|
289
|
+
*
|
|
290
|
+
* @param {{answer:string, evidence:*, goal?:string, alreadyRewritten?:boolean}} input
|
|
291
|
+
* @returns {{ action:'pass'|'rewrite'|'unconfirmed', ok:boolean, unmet:Array, claims:Array, matched:number, rewriteHint:string }}
|
|
292
|
+
*/
|
|
293
|
+
function review(input) {
|
|
294
|
+
const result = check(input);
|
|
295
|
+
if (result.ok) return { ...result, action: 'pass', rewriteHint: '' };
|
|
296
|
+
const hint = rewriteHint(result);
|
|
297
|
+
if (input && input.alreadyRewritten) return { ...result, action: 'unconfirmed', rewriteHint: hint };
|
|
298
|
+
return { ...result, action: 'rewrite', rewriteHint: hint };
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
module.exports = {
|
|
302
|
+
check,
|
|
303
|
+
review,
|
|
304
|
+
rewriteHint,
|
|
305
|
+
// 守卫可直接用的纯函数与小常量:
|
|
306
|
+
canon,
|
|
307
|
+
norm,
|
|
308
|
+
quotes,
|
|
309
|
+
numbersIn,
|
|
310
|
+
valueNumbers,
|
|
311
|
+
dateClaims,
|
|
312
|
+
MAX_REWRITE,
|
|
313
|
+
CUT,
|
|
314
|
+
};
|