argo-search 1.0.1 → 2.9.8

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.
Files changed (472) hide show
  1. package/LICENSE +201 -21
  2. package/README.en.md +735 -0
  3. package/README.es.md +777 -0
  4. package/README.ja.md +777 -0
  5. package/README.ko.md +777 -0
  6. package/README.md +778 -320
  7. package/SKILL.md +135 -0
  8. package/assets/readme/hero.svg +121 -0
  9. package/assets/readme/made-with-beautify.svg +10 -0
  10. package/assets/readme/proof-routes.svg +73 -0
  11. package/assets/readme/why-better.svg +104 -0
  12. package/assets/readme/workflow.svg +83 -0
  13. package/backends/domain_profiles.json +2356 -96
  14. package/backends/engine_registry.yaml +3428 -503
  15. package/backends/query_synonyms_cn.json +35 -0
  16. package/backends/quota_profiles.json +2488 -160
  17. package/backends/source_types_cn.json +109 -0
  18. package/backends/text_lexicon.json +44 -0
  19. package/bin/argo +772 -0
  20. package/bin/argo.js +102 -39
  21. package/config.yaml +5139 -367
  22. package/cordis.patch.yml +21 -0
  23. package/data/countries.json +40 -0
  24. package/data/lang_matrix/lang_capability.json +842 -0
  25. package/data/lang_matrix/matrix_2026-09-10.json +11921 -0
  26. package/data/regions_cn.json +1 -0
  27. package/docs/ADDING_NEW_ENGINE.md +184 -0
  28. package/docs/ARGO_INTRO.md +124 -0
  29. package/docs/DATA_SOURCE_GAPS.md +81 -0
  30. package/docs/DESIGN_LOCAL_DATA_FUSION.md +90 -0
  31. package/docs/ENGINE_CATALOG.md +575 -0
  32. package/docs/MCP_SETUP.md +108 -0
  33. package/docs/PLATFORM_PATHS.md +111 -0
  34. package/docs/RELEASE_NOTES_v2.8.0.md +71 -0
  35. package/docs/RELEASE_NOTES_v2.8.2.md +63 -0
  36. package/docs/RELEASE_NOTES_v2.8.3.md +55 -0
  37. package/docs/RELEASE_NOTES_v2.8.4.md +79 -0
  38. package/docs/RELEASE_NOTES_v2.8.5.md +102 -0
  39. package/docs/RELEASE_NOTES_v2.8.6.md +66 -0
  40. package/docs/RELEASE_NOTES_v2.8.7.md +65 -0
  41. package/docs/RELEASE_NOTES_v2.8.8.md +67 -0
  42. package/docs/RELEASE_NOTES_v2.8.9.md +67 -0
  43. package/docs/RELEASE_NOTES_v2.9.0.md +64 -0
  44. package/docs/RELEASE_NOTES_v2.9.8.md +73 -0
  45. package/docs/SEARCH_ARCHIVE.md +115 -0
  46. package/docs/assets/architecture.svg +104 -0
  47. package/docs/assets/hero.svg +98 -0
  48. package/docs/engines/bangumi.md +27 -0
  49. package/docs/engines/biorxiv.md +27 -0
  50. package/docs/engines/clawhub.md +27 -0
  51. package/docs/engines/crt_sh.md +27 -0
  52. package/docs/engines/datacite.md +27 -0
  53. package/docs/engines/deps_dev.md +27 -0
  54. package/docs/engines/douban_movie.md +27 -0
  55. package/docs/engines/endoflife.md +27 -0
  56. package/docs/engines/flk_law.md +27 -0
  57. package/docs/engines/fxtwitter.md +27 -0
  58. package/docs/engines/google_news.md +27 -0
  59. package/docs/engines/gov_regulations.md +27 -0
  60. package/docs/engines/guqian.md +27 -0
  61. package/docs/engines/hackernews.md +27 -0
  62. package/docs/engines/iplant.md +27 -0
  63. package/docs/engines/keenable.md +27 -0
  64. package/docs/engines/met_museum.md +27 -0
  65. package/docs/engines/nasa_images.md +27 -0
  66. package/docs/engines/netease_music.md +27 -0
  67. package/docs/engines/npm.md +27 -0
  68. package/docs/engines/nvd.md +27 -0
  69. package/docs/engines/openreview.md +27 -0
  70. package/docs/engines/openstd.md +27 -0
  71. package/docs/engines/parallel_free.md +27 -0
  72. package/docs/engines/people_daily.md +27 -0
  73. package/docs/engines/realtime_index.md +27 -0
  74. package/docs/engines/sec_edgar.md +27 -0
  75. package/docs/engines/seltz.md +27 -0
  76. package/docs/engines/skillsmp.md +27 -0
  77. package/docs/engines/sspai.md +27 -0
  78. package/docs/engines/std_samr.md +27 -0
  79. package/docs/engines/train.md +27 -0
  80. package/docs/engines/un_comtrade.md +27 -0
  81. package/docs/engines/wikisource.md +27 -0
  82. package/docs/engines/zdic.md +27 -0
  83. package/docs/engines/zenodo.md +27 -0
  84. package/docs/engines/zhihu_hot_app.md +27 -0
  85. package/docs//344/270/272/344/273/200/344/271/210/351/200/211/346/213/251argo.md +176 -0
  86. package/engines/README.md +10 -0
  87. package/engines/_template_cli.yaml +39 -0
  88. package/engines/_template_http.yaml +37 -0
  89. package/engines/plugins/_template_plugin.py +50 -0
  90. package/engines/specs/_cisa_kev.yaml +54 -0
  91. package/engines/specs/_osv.yaml +63 -0
  92. package/engines/specs/aljazeera.yaml +43 -0
  93. package/engines/specs/antara.yaml +43 -0
  94. package/engines/specs/artic.yaml +20 -0
  95. package/engines/specs/aviation_weather.yaml +39 -0
  96. package/engines/specs/bangumi.yaml +21 -0
  97. package/engines/specs/biorxiv.yaml +24 -0
  98. package/engines/specs/carbon_intensity.yaml +32 -0
  99. package/engines/specs/cfets.yaml +41 -0
  100. package/engines/specs/cinii.yaml +44 -0
  101. package/engines/specs/clawhub.yaml +49 -0
  102. package/engines/specs/cleveland.yaml +19 -0
  103. package/engines/specs/cn_ai_news.yaml +43 -0
  104. package/engines/specs/core.yaml +35 -0
  105. package/engines/specs/crt_sh.yaml +38 -0
  106. package/engines/specs/ct24.yaml +43 -0
  107. package/engines/specs/datacite.yaml +27 -0
  108. package/engines/specs/datagov_uk.yaml +41 -0
  109. package/engines/specs/ddgs_images.yaml +45 -0
  110. package/engines/specs/deepseek_search.yaml +74 -0
  111. package/engines/specs/deezer.yaml +20 -0
  112. package/engines/specs/defillama.yaml +38 -0
  113. package/engines/specs/deps_dev.yaml +21 -0
  114. package/engines/specs/digup.yaml +36 -0
  115. package/engines/specs/doi.yaml +39 -0
  116. package/engines/specs/douban_movie.yaml +22 -0
  117. package/engines/specs/dw_news.yaml +47 -0
  118. package/engines/specs/egov_law.yaml +21 -0
  119. package/engines/specs/elpais.yaml +43 -0
  120. package/engines/specs/endoflife.yaml +21 -0
  121. package/engines/specs/energy_charts.yaml +21 -0
  122. package/engines/specs/factcheck_org.yaml +52 -0
  123. package/engines/specs/faz.yaml +43 -0
  124. package/engines/specs/federal_register.yaml +57 -0
  125. package/engines/specs/firecrawl.yaml +53 -0
  126. package/engines/specs/flk_law.yaml +24 -0
  127. package/engines/specs/folha.yaml +43 -0
  128. package/engines/specs/france24.yaml +44 -0
  129. package/engines/specs/full_fact.yaml +47 -0
  130. package/engines/specs/fxtwitter.yaml +36 -0
  131. package/engines/specs/gbfs_nyc.yaml +32 -0
  132. package/engines/specs/gdacs.yaml +21 -0
  133. package/engines/specs/gdelt.yaml +64 -0
  134. package/engines/specs/gleif.yaml +55 -0
  135. package/engines/specs/google_news.yaml +22 -0
  136. package/engines/specs/gov_regulations.yaml +38 -0
  137. package/engines/specs/guardian_rss.yaml +59 -0
  138. package/engines/specs/hkex.yaml +40 -0
  139. package/engines/specs/hurriyet.yaml +43 -0
  140. package/engines/specs/iplant.yaml +25 -0
  141. package/engines/specs/jikan.yaml +24 -0
  142. package/engines/specs/jolpica.yaml +20 -0
  143. package/engines/specs/k10plus.yaml +20 -0
  144. package/engines/specs/keenable.yaml +44 -0
  145. package/engines/specs/keenable_free.yaml +36 -0
  146. package/engines/specs/lefigaro.yaml +43 -0
  147. package/engines/specs/listenbrainz.yaml +19 -0
  148. package/engines/specs/matichon.yaml +43 -0
  149. package/engines/specs/met_museum.yaml +21 -0
  150. package/engines/specs/nasa_images.yaml +45 -0
  151. package/engines/specs/netease_music.yaml +38 -0
  152. package/engines/specs/nhk.yaml +43 -0
  153. package/engines/specs/nhtsa_vpic.yaml +20 -0
  154. package/engines/specs/noaa_swpc.yaml +20 -0
  155. package/engines/specs/nvd.yaml +38 -0
  156. package/engines/specs/obis.yaml +20 -0
  157. package/engines/specs/opencitations.yaml +52 -0
  158. package/engines/specs/openf1.yaml +21 -0
  159. package/engines/specs/openfoodfacts.yaml +45 -0
  160. package/engines/specs/openligadb.yaml +20 -0
  161. package/engines/specs/openreview.yaml +37 -0
  162. package/engines/specs/openstd.yaml +21 -0
  163. package/engines/specs/people_daily.yaml +22 -0
  164. package/engines/specs/realtime_index.yaml +34 -0
  165. package/engines/specs/ror.yaml +20 -0
  166. package/engines/specs/satnogs.yaml +20 -0
  167. package/engines/specs/sec_edgar.yaml +46 -0
  168. package/engines/specs/shfe.yaml +39 -0
  169. package/engines/specs/skillsmp.yaml +50 -0
  170. package/engines/specs/sogou_weixin_browser.yaml +30 -0
  171. package/engines/specs/soilgrids.yaml +25 -0
  172. package/engines/specs/sspai.yaml +36 -0
  173. package/engines/specs/stackexchange.yaml +46 -0
  174. package/engines/specs/std_samr.yaml +21 -0
  175. package/engines/specs/tass.yaml +43 -0
  176. package/engines/specs/tavily_free.yaml +56 -0
  177. package/engines/specs/tle_mirror.yaml +21 -0
  178. package/engines/specs/train.yaml +37 -0
  179. package/engines/specs/tvmaze.yaml +20 -0
  180. package/engines/specs/twitter_syndication.yaml +31 -0
  181. package/engines/specs/un_comtrade.yaml +23 -0
  182. package/engines/specs/unpaywall.yaml +54 -0
  183. package/engines/specs/vnpress.yaml +43 -0
  184. package/engines/specs/weather.yaml +32 -0
  185. package/engines/specs/who_don.yaml +21 -0
  186. package/engines/specs/who_gho.yaml +20 -0
  187. package/engines/specs/wikimedia_commons.yaml +34 -0
  188. package/engines/specs/wikisource.yaml +22 -0
  189. package/engines/specs/worms.yaml +19 -0
  190. package/engines/specs/x_trending.yaml +34 -0
  191. package/engines/specs/yna.yaml +43 -0
  192. package/engines/specs/ynet.yaml +43 -0
  193. package/engines/specs/yuanbao.yaml +93 -0
  194. package/engines/specs/zbmath.yaml +40 -0
  195. package/engines/specs/zdic.yaml +22 -0
  196. package/engines/specs/zenodo.yaml +27 -0
  197. package/engines/specs/zhihu_hot_app.yaml +35 -0
  198. package/mcp/clients.yaml +106 -0
  199. package/package.json +55 -12
  200. package/packages/dsh-plugin/README.md +152 -0
  201. package/packages/dsh-plugin/cordis.patch.yml +48 -0
  202. package/packages/dsh-plugin/dsh/client.js +1533 -0
  203. package/packages/dsh-plugin/dsh/diagnostics.js +54 -0
  204. package/packages/dsh-plugin/dsh/index.js +527 -0
  205. package/packages/dsh-plugin/dsh/native-tools.mjs +749 -0
  206. package/packages/dsh-plugin/dsh/runner.js +666 -0
  207. package/packages/dsh-plugin/dsh/wide-research.js +878 -0
  208. package/packages/dsh-plugin/package.json +38 -0
  209. package/packages/dsh-plugin/scripts/sync-local.sh +70 -0
  210. package/packages/dsh-plugin/test/client.test.js +406 -0
  211. package/packages/dsh-plugin/test/config.test.js +30 -0
  212. package/packages/dsh-plugin/test/diagnostics.test.js +28 -0
  213. package/packages/dsh-plugin/test/index.test.js +1382 -0
  214. package/references/query-templates.md +96 -0
  215. package/references/query-templates.yaml +118 -0
  216. package/scripts/ab_eval.py +219 -0
  217. package/scripts/ab_eval_p0p1.py +266 -0
  218. package/scripts/adaptive.py +294 -70
  219. package/scripts/answer.py +154 -0
  220. package/scripts/archive_run.py +591 -0
  221. package/scripts/argo_engine_registry.py +172 -0
  222. package/scripts/argo_paths.py +728 -0
  223. package/scripts/article.py +136 -0
  224. package/scripts/article_meta.py +131 -0
  225. package/scripts/arxiv_source.py +201 -0
  226. package/scripts/badcase_ledger.py +252 -0
  227. package/scripts/batch_probe.py +241 -0
  228. package/scripts/benchmark.py +19 -0
  229. package/scripts/bounded_run.py +144 -0
  230. package/scripts/browser_auth.py +323 -0
  231. package/scripts/budget.py +247 -0
  232. package/scripts/budget_cli.py +93 -0
  233. package/scripts/build_release_assets.sh +65 -0
  234. package/scripts/burstiness_detector.py +147 -0
  235. package/scripts/cache.py +1066 -67
  236. package/scripts/cache_guard.py +271 -0
  237. package/scripts/cache_key_vdom.py +56 -0
  238. package/scripts/cache_similarity.py +170 -0
  239. package/scripts/caliber_isolation.py +195 -0
  240. package/scripts/calibrate_lowquality.py +210 -0
  241. package/scripts/candidate_envelope.py +366 -0
  242. package/scripts/chrome_cdp.py +871 -0
  243. package/scripts/ci_drift_gate.py +90 -0
  244. package/scripts/circuit_breaker.py +389 -0
  245. package/scripts/citations.py +334 -0
  246. package/scripts/cite_cli.py +59 -0
  247. package/scripts/cjk_tokens.py +95 -0
  248. package/scripts/clarify.py +47 -24
  249. package/scripts/cli_io.py +240 -0
  250. package/scripts/config.py +683 -45
  251. package/scripts/config_cache.py +402 -0
  252. package/scripts/conn_pool.py +220 -0
  253. package/scripts/content_boundary.py +46 -0
  254. package/scripts/content_security.py +685 -0
  255. package/scripts/content_signals.py +751 -0
  256. package/scripts/crawl.py +74 -35
  257. package/scripts/cross_lingual_trace.py +293 -0
  258. package/scripts/daemon.py +866 -0
  259. package/scripts/digup_bridge.py +214 -0
  260. package/scripts/dispatch_result.py +98 -0
  261. package/scripts/engine_admission.py +366 -0
  262. package/scripts/engine_dispatch.py +982 -0
  263. package/scripts/engine_env.py +539 -0
  264. package/scripts/engine_failure.py +411 -0
  265. package/scripts/engine_families.py +738 -0
  266. package/scripts/engine_policy.py +218 -0
  267. package/scripts/engine_requires.py +190 -0
  268. package/scripts/engine_status.py +322 -0
  269. package/scripts/engine_validate.py +638 -0
  270. package/scripts/engines.py +799 -294
  271. package/scripts/engines_base.py +1521 -0
  272. package/scripts/engines_builders.py +310 -0
  273. package/scripts/engines_builders_batch10.py +204 -0
  274. package/scripts/engines_builders_batch11.py +174 -0
  275. package/scripts/engines_builders_batch12.py +103 -0
  276. package/scripts/engines_builders_batch13.py +340 -0
  277. package/scripts/engines_builders_batch14.py +656 -0
  278. package/scripts/engines_builders_batch15.py +249 -0
  279. package/scripts/engines_builders_batch9.py +1468 -0
  280. package/scripts/engines_builders_cn.py +2283 -0
  281. package/scripts/engines_builders_data.py +2923 -0
  282. package/scripts/engines_builders_data_macro.py +775 -0
  283. package/scripts/engines_builders_feeds.py +255 -0
  284. package/scripts/engines_builders_intl.py +1239 -0
  285. package/scripts/engines_builders_keyless.py +111 -0
  286. package/scripts/engines_builders_search.py +440 -0
  287. package/scripts/engines_builders_tech.py +1359 -0
  288. package/scripts/evidence.py +620 -166
  289. package/scripts/evidence_loop.py +624 -0
  290. package/scripts/evidence_tier.py +298 -0
  291. package/scripts/except_sets.py +25 -0
  292. package/scripts/extract.py +55 -16
  293. package/scripts/fact_align.py +207 -0
  294. package/scripts/fact_crosscheck.py +230 -0
  295. package/scripts/fetch.py +25 -12
  296. package/scripts/fetch_browser.py +87 -0
  297. package/scripts/fetch_jsrun.py +122 -0
  298. package/scripts/fetch_quality.py +225 -0
  299. package/scripts/fetch_render_tinyfish.py +117 -0
  300. package/scripts/fetch_v3.py +1804 -0
  301. package/scripts/focus_extract.py +350 -0
  302. package/scripts/fulltext_store.py +169 -0
  303. package/scripts/fxtwitter_api.py +325 -0
  304. package/scripts/gen_engine_catalog.py +364 -0
  305. package/scripts/gen_native_tools.py +91 -0
  306. package/scripts/gen_routing_snapshot.py +195 -0
  307. package/scripts/health_check.py +140 -402
  308. package/scripts/health_probe.py +23 -8
  309. package/scripts/hot_state.py +134 -0
  310. package/scripts/http_client.py +1053 -0
  311. package/scripts/image_ops.py +430 -0
  312. package/scripts/image_vision/vision_probe.swift +126 -0
  313. package/scripts/install.ps1 +166 -0
  314. package/scripts/install.sh +221 -0
  315. package/scripts/job.py +1186 -0
  316. package/scripts/jump_resolver.py +235 -0
  317. package/scripts/lang_capability.py +150 -0
  318. package/scripts/lang_detect.py +289 -0
  319. package/scripts/lang_matrix_probe.py +329 -0
  320. package/scripts/lang_pref.py +311 -0
  321. package/scripts/link_source.py +340 -0
  322. package/scripts/local_image.py +970 -0
  323. package/scripts/local_seek.py +402 -0
  324. package/scripts/macro_countries.py +97 -0
  325. package/scripts/matrix_search_eval.py +1187 -0
  326. package/scripts/mcp_compact.py +234 -0
  327. package/scripts/mcp_diag.py +8 -3
  328. package/scripts/mcp_handlers.py +492 -0
  329. package/scripts/mcp_handlers_surface.py +157 -0
  330. package/scripts/mcp_launch.sh +124 -0
  331. package/scripts/mcp_local.py +241 -0
  332. package/scripts/mcp_server.py +125 -419
  333. package/scripts/mcp_setup.py +431 -0
  334. package/scripts/mcp_tools.py +331 -0
  335. package/scripts/mcp_transport.py +191 -0
  336. package/scripts/mcp_warm.py +127 -0
  337. package/scripts/min_version_scan.py +335 -0
  338. package/scripts/net_proxy.py +258 -0
  339. package/scripts/network_aware.py +152 -0
  340. package/scripts/output_transparency.py +200 -0
  341. package/scripts/paid_policy.py +98 -0
  342. package/scripts/paper.py +274 -0
  343. package/scripts/pdf_extract.py +518 -0
  344. package/scripts/phrase_filter.py +66 -0
  345. package/scripts/plan.py +422 -0
  346. package/scripts/postprocess_signals.py +150 -0
  347. package/scripts/pre-commit +48 -0
  348. package/scripts/query_enhance.py +157 -0
  349. package/scripts/query_operators.py +196 -0
  350. package/scripts/query_rewriter.py +116 -7
  351. package/scripts/query_signals.py +300 -0
  352. package/scripts/query_templates.py +167 -0
  353. package/scripts/query_understanding.py +411 -0
  354. package/scripts/query_variants.py +298 -0
  355. package/scripts/quota.py +633 -76
  356. package/scripts/rank_signals.py +775 -0
  357. package/scripts/ranking_eval.py +319 -0
  358. package/scripts/readability_extract.py +433 -0
  359. package/scripts/recompute.py +415 -0
  360. package/scripts/recovery.py +616 -0
  361. package/scripts/recovery_l0.py +160 -0
  362. package/scripts/recovery_runner.py +150 -0
  363. package/scripts/redskill/redskill_engine.py +332 -0
  364. package/scripts/regression_p0p1.py +318 -0
  365. package/scripts/replay_eval.py +658 -0
  366. package/scripts/rerank_tfidf.py +225 -0
  367. package/scripts/research.py +607 -403
  368. package/scripts/research_cli.py +361 -0
  369. package/scripts/research_dossier.py +492 -0
  370. package/scripts/research_expand.py +169 -0
  371. package/scripts/research_gates.py +272 -0
  372. package/scripts/research_report.py +209 -0
  373. package/scripts/research_strategy.py +37 -0
  374. package/scripts/research_work_packages.py +195 -0
  375. package/scripts/result_lang.py +311 -0
  376. package/scripts/retry_policy.py +76 -0
  377. package/scripts/robots_guard.py +259 -0
  378. package/scripts/route.py +921 -254
  379. package/scripts/route_bangs.py +40 -0
  380. package/scripts/route_cache.py +243 -0
  381. package/scripts/route_combo.py +917 -0
  382. package/scripts/route_domains.py +341 -0
  383. package/scripts/route_lang.py +605 -0
  384. package/scripts/route_log.py +63 -0
  385. package/scripts/route_policy.py +250 -0
  386. package/scripts/rrf_classic.py +66 -0
  387. package/scripts/screenshot.py +73 -0
  388. package/scripts/search.py +886 -406
  389. package/scripts/search_attribution.py +185 -0
  390. package/scripts/search_benchmark.py +407 -0
  391. package/scripts/search_cli.py +640 -0
  392. package/scripts/search_entry.py +395 -0
  393. package/scripts/search_output.py +690 -0
  394. package/scripts/search_pipeline.py +926 -0
  395. package/scripts/search_rank.py +991 -0
  396. package/scripts/search_types.py +129 -16
  397. package/scripts/seek_locator.py +68 -0
  398. package/scripts/semantic_evidence.py +391 -0
  399. package/scripts/serp_guard.py +336 -0
  400. package/scripts/serp_kill_log.py +74 -0
  401. package/scripts/single_flight.py +120 -0
  402. package/scripts/social_engines/__init__.py +10 -0
  403. package/scripts/social_engines/bilibili_engine.py +131 -0
  404. package/scripts/social_engines/hackernews_engine.py +113 -0
  405. package/scripts/social_engines/reddit_engine.py +172 -0
  406. package/scripts/social_engines/twitter_engine.py +397 -0
  407. package/scripts/social_engines/v2ex_engine.py +101 -0
  408. package/scripts/social_engines/weibo_engine.py +128 -0
  409. package/scripts/social_engines/xiaohongshu_engine.py +137 -0
  410. package/scripts/social_engines/zhihu_engine.py +139 -0
  411. package/scripts/social_research.py +201 -0
  412. package/scripts/sogou_weixin_browser.py +318 -0
  413. package/scripts/source_ledger.py +249 -0
  414. package/scripts/stage_timing.py +58 -0
  415. package/scripts/stats_cli.py +107 -0
  416. package/scripts/straggler_policy.py +60 -0
  417. package/scripts/stylometry_detector.py +231 -0
  418. package/scripts/sync_backends.py +353 -0
  419. package/scripts/sync_installs.py +29 -0
  420. package/scripts/template_cli.py +127 -0
  421. package/scripts/text_lexicon.py +72 -0
  422. package/scripts/tfidf_router.py +109 -37
  423. package/scripts/time_utils.py +233 -0
  424. package/scripts/topic_research_profiles.py +643 -0
  425. package/scripts/train.py +737 -0
  426. package/scripts/tweet.py +596 -0
  427. package/scripts/url_canon.py +217 -0
  428. package/scripts/url_optimize.py +56 -0
  429. package/scripts/url_safety.py +236 -0
  430. package/scripts/usage_log.py +116 -0
  431. package/scripts/usage_log_clean.py +113 -0
  432. package/scripts/v2ex_nodes.py +311 -0
  433. package/scripts/variant_recall.py +188 -0
  434. package/scripts/watch.py +205 -0
  435. package/scripts/wechat_article.py +258 -0
  436. package/scripts/wide_research.py +447 -0
  437. package/scripts/wx.py +349 -0
  438. package/scripts/x_article_fetch.py +141 -0
  439. package/scripts/x_search.py +234 -0
  440. package/scripts/x_trending.py +189 -0
  441. package/scripts/yaml_load.py +67 -0
  442. package/scripts/zhihu_quota.py +139 -0
  443. package/sub-skills/ego-search/SKILL.md +253 -0
  444. package/sub-skills/ego-search/scripts/ego_search.py +800 -0
  445. package/sub-skills/ego-search/scripts/merge.py +226 -0
  446. package/sub-skills/ego-search/scripts/quality.py +64 -0
  447. package/sub-skills/ego-search/scripts/runtime.py +172 -0
  448. package/sub-skills/ego-search/scripts/safety.py +109 -0
  449. package/sub-skills/ego-search/scripts/serp_spec.py +109 -0
  450. package/sub-skills/ego-search/scripts/webbridge_adapter.py +374 -0
  451. package/sub-skills/js-run/SKILL.md +67 -0
  452. package/sub-skills/js-run/scripts/jsrun.py +112 -0
  453. package/sub-skills/js-run/scripts/shim.js +188 -0
  454. package/sub-skills/local-search/SKILL.md +50 -53
  455. package/sub-skills/local-search/bm25.py +186 -0
  456. package/sub-skills/local-search/cli_runner.py +331 -0
  457. package/sub-skills/local-search/config.yaml +152 -55
  458. package/sub-skills/local-search/engine_registry.py +91 -26
  459. package/sub-skills/local-search/{health_check.py → local_health_check.py} +140 -10
  460. package/sub-skills/local-search/local_search_adapter.py +13 -2
  461. package/sub-skills/local-search/parse_maps.yaml +40 -42
  462. package/sub-skills/local-search/parsers.py +328 -0
  463. package/sub-skills/local-search/search_v3.py +716 -242
  464. package/sub-skills/local-search/smart_router.py +47 -7
  465. package/sub-skills/local-seek/SKILL.md +110 -0
  466. package/sub-skills/local-seek/config/domains.yaml +20 -0
  467. package/sub-skills/local-seek/scripts/eval_rank.py +216 -0
  468. package/sub-skills/local-seek/scripts/eval_seek.py +224 -0
  469. package/sub-skills/local-seek/scripts/seek.py +1465 -0
  470. package/sub-skills/local-seek/scripts/seek_frecency.py +126 -0
  471. package/sub-skills/local-seek/scripts/seek_fts.py +430 -0
  472. package/sub-skills/local-seek/scripts/seek_rank.py +197 -0
@@ -0,0 +1,322 @@
1
+ #!/usr/bin/env python3
2
+ """engine_status.py — 引擎状态聚合(list-engines --detail)
3
+
4
+ 输出每引擎:
5
+ enabled / type / cost_tier / env_ready / missing_env /
6
+ allowed_by_env / blocked / admitted / routable / health summary
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import sys
12
+ from pathlib import Path
13
+ from typing import Any, Iterable
14
+
15
+ SCRIPT_DIR = Path(__file__).resolve().parent
16
+ if str(SCRIPT_DIR) not in sys.path:
17
+ sys.path.insert(0, str(SCRIPT_DIR))
18
+
19
+ from config import load_config, get_cost_tiers # noqa: E402
20
+ from engine_env import env_status_for, is_engine_allowed_by_env # noqa: E402
21
+ from engine_requires import requires_status # noqa: E402
22
+ from engine_admission import load_admission, is_blocked, is_admitted # noqa: E402
23
+ from cli_io import dumps
24
+
25
+
26
+ def _cost_tier_of(engine_id: str, tiers: dict[str, list[str]]) -> str:
27
+ for tier in ("paid", "api", "low", "free"):
28
+ if engine_id in (tiers.get(tier) or []):
29
+ return tier
30
+ return "free"
31
+
32
+
33
+ def _all_engine_specs(cfg: dict[str, Any] | None = None) -> dict[str, dict[str, Any]]:
34
+ cfg = cfg if cfg is not None else load_config()
35
+ engines = cfg.get("engines") or {}
36
+ return {k: v for k, v in engines.items() if isinstance(v, dict)}
37
+
38
+
39
+ def _adaptive_scores_snapshot() -> dict[str, float]:
40
+ """一次取全部引擎学习分(get_ranking 单查询),避免 120+ 引擎逐个开 sqlite。"""
41
+ try:
42
+ from adaptive import get_learner
43
+ return dict(get_learner().get_ranking())
44
+ except Exception:
45
+ return {}
46
+
47
+
48
+ def _runtime_status(engine_id: str,
49
+ adaptive_scores: dict[str, float] | None = None,
50
+ spec: dict[str, Any] | None = None) -> dict[str, Any]:
51
+ """运行时状态聚合(统一健康度视图):熔断 + 学习分。
52
+
53
+ 被动读取、无网络副作用:breaker 状态读进程内存(构造时已 load 磁盘态);
54
+ adaptive 分数用调用方传入的全表快照,缺失时按中性分 0.5。
55
+ 与主动探针(health_check.check_engine)互补:本函数是「当前可用性」快照,
56
+ 探针是「立即连通性」验证,二者计算方式不同、各自保留。
57
+ """
58
+ out: dict[str, Any] = {"breaker": None, "adaptive_score": None,
59
+ "failure": None}
60
+ try:
61
+ from circuit_breaker import get_breaker
62
+ st = get_breaker().status(engine_id)
63
+ out["breaker"] = {
64
+ "state": st.get("state", "closed"),
65
+ "failures": st.get("failures", 0),
66
+ "cooldown_remain": st.get("cooldown_remain", 0),
67
+ "last_kind": st.get("last_kind"),
68
+ }
69
+ # 失败归因:熔断只回答「要不要继续用」,这里补「为什么坏」。
70
+ # 仅在确有失败记录时输出,避免给健康引擎塞噪音字段。
71
+ # 优先用失败现场记录的归因(真实 category/evidence);旧数据没有该字段
72
+ # 时才回落按 kind 文本归类(信息量有限,可能落 unknown)。
73
+ if st.get("last_kind") and int(st.get("failures") or 0) > 0:
74
+ persisted = st.get("last_attribution")
75
+ if isinstance(persisted, dict) and persisted.get("category"):
76
+ out["failure"] = persisted
77
+ else:
78
+ from engine_failure import explain as _explain_failure
79
+ out["failure"] = _explain_failure(
80
+ engine_id, spec=spec, output=str(st.get("last_kind") or ""),
81
+ )
82
+ except Exception:
83
+ pass
84
+ if adaptive_scores is not None:
85
+ out["adaptive_score"] = adaptive_scores.get(engine_id, 0.5)
86
+ elif adaptive_scores is None:
87
+ # 单引擎查询:只查一次 sqlite(批量场景必须传快照避免 N 次连接)
88
+ try:
89
+ from adaptive import get_learner
90
+ out["adaptive_score"] = get_learner().get_score(engine_id)
91
+ except Exception:
92
+ pass
93
+ return out
94
+
95
+
96
+ def _quota_exhausted_marks() -> dict[str, dict[str, Any]]:
97
+ """一次取全部「远端配额耗尽」标记,避免逐引擎查询。失败返回空。"""
98
+ try:
99
+ from quota import get_quota_manager
100
+ return get_quota_manager().remote_exhausted_marks()
101
+ except Exception:
102
+ return {}
103
+
104
+
105
+ def engine_detail(engine_id: str, spec: dict[str, Any] | None = None,
106
+ tiers: dict[str, list[str]] | None = None,
107
+ adaptive_scores: dict[str, float] | None = None,
108
+ quota_marks: dict[str, dict[str, Any]] | None = None) -> dict[str, Any]:
109
+ if spec is None:
110
+ specs = _all_engine_specs()
111
+ spec = specs.get(engine_id) or {}
112
+ tiers = tiers if tiers is not None else get_cost_tiers()
113
+ env = env_status_for(engine_id, spec)
114
+ deps = requires_status(spec)
115
+ adm = load_admission(engine_id)
116
+ blocked = is_blocked(engine_id)
117
+ admitted = is_admitted(engine_id)
118
+ config_enabled = bool(spec.get("enabled", True))
119
+ allowed = env["allowed_by_env"]
120
+ env_ok = env["env_ready"]
121
+ dep_ok = deps["dep_ready"]
122
+ # 远端配额耗尽(如博查 AI Search 403 套餐额度不足):这是源端的「现在别打」,
123
+ # 与密钥/依赖无关,也不是引擎故障。此前这类引擎一律显示 ready、
124
+ # routable=True,直到 lookup 才发现打不动——配额状态机已记下它,这里读出来。
125
+ if quota_marks is None:
126
+ quota_marks = _quota_exhausted_marks()
127
+ quota_mark = quota_marks.get(engine_id)
128
+ quota_exhausted = bool(quota_mark)
129
+ # 自动路由可用条件(含后端依赖:缺 xhs/yt-dlp 这类工具时不该进路由)
130
+ # explicit_only 排除在外:声明即「不进自动路由,只等显式 --engine」
131
+ # (--routable-only 的帮助文案与 available_engines 同一口径)。此前漏判,
132
+ # 旧显式源恰好被 env/dep 门挡住没暴露;toutiao(免 key 免依赖)把它炸出。
133
+ routable = (
134
+ config_enabled
135
+ and allowed
136
+ and env_ok
137
+ and dep_ok
138
+ and not blocked
139
+ and not quota_exhausted
140
+ and not bool(spec.get("explicit_only"))
141
+ )
142
+ status = "ready"
143
+ if not config_enabled:
144
+ status = "disabled"
145
+ elif not allowed:
146
+ status = "env_filtered"
147
+ elif not env_ok:
148
+ status = "missing_key"
149
+ elif not dep_ok:
150
+ # 后端工具缺失:密钥齐全、脚本存在,但真正干活的外部命令没有。
151
+ # 此前这类引擎一律显示 ready,调用后静默返回空,无从定位。
152
+ status = "missing_dep"
153
+ elif quota_exhausted:
154
+ status = "quota_exhausted"
155
+ elif blocked:
156
+ status = "blocked"
157
+ elif admitted:
158
+ status = "admitted"
159
+ else:
160
+ status = "ready" # 未验证但可用(兼容)
161
+
162
+ return {
163
+ "engine_id": engine_id,
164
+ "enabled": config_enabled,
165
+ "type": spec.get("type", "cli"),
166
+ "cost_tier": _cost_tier_of(engine_id, tiers),
167
+ "status": status,
168
+ # 设计上不进自动路由(需密钥的付费源 / 输入形态特殊),按 --engine 显式调用;
169
+ # 可达性检查据此区分「有意显式」与「忘了接线」。
170
+ "explicit_only": bool(spec.get("explicit_only")),
171
+ "env_ready": env_ok,
172
+ "required_env": env["required_env"],
173
+ "missing_env": env["missing_env"],
174
+ "allowed_by_env": allowed,
175
+ "blocked": blocked,
176
+ "admitted": admitted,
177
+ "routable": routable,
178
+ # 远端配额耗尽(源端明示)。配额问题既不是引擎健康问题、也不是密钥问题,
179
+ # 单列出来,到周期边界惰性自愈。
180
+ "quota_exhausted": quota_exhausted,
181
+ "quota_exhausted_until": (quota_mark or {}).get("until"),
182
+ "quota_exhausted_reason": (quota_mark or {}).get("reason") or "",
183
+ # 后端依赖(requires 声明):缺什么、怎么装。与 missing_env(密钥)互不相干。
184
+ "dep_ready": dep_ok,
185
+ "requires": deps["requires"],
186
+ "missing_deps": deps["missing_deps"],
187
+ "dep_fixes": deps["dep_fixes"],
188
+ "admission": {
189
+ "admitted_at": (adm or {}).get("admitted_at"),
190
+ "stages_passed": (adm or {}).get("stages_passed") or [],
191
+ "quality_score": (adm or {}).get("quality_score"),
192
+ "avg_latency_ms": (adm or {}).get("avg_latency_ms"),
193
+ "reason": (adm or {}).get("reason") or "",
194
+ } if adm else None,
195
+ # 统一健康度视图:熔断状态 + 学习分(被动快照,见 _runtime_status)
196
+ "runtime": _runtime_status(engine_id, adaptive_scores, spec),
197
+ }
198
+
199
+
200
+ def compact_engine_row(row: dict[str, Any]) -> dict[str, Any]:
201
+ """全量清单的瘦身投影:剥掉嵌套转储(runtime/admission),留判定面。
202
+
203
+ 为什么要压缩:--list-engines --detail 不带过滤是 232 行 × 全字段的
204
+ 诊断转储,实测 151 KB(runtime 24% + admission 7% 是大头)——Agent
205
+ 一旦把它拉进上下文就是 ~50k token。而全量清单要回答的通常只有
206
+ 「哪些源可用/为什么不可用」,判定只需要标量旗标 + 条件性细节:
207
+ failure/配额原因/缺 env 缺依赖在**非空时**才出现,健康源一行 ~150B。
208
+ 要单引擎的全量诊断(含 admission 里程碑、runtime 学习分),用
209
+ `--engine <名>` 过滤后拿完整行——按需付全量的代价。
210
+
211
+ 降级契约:本函数只做「删键」,不改任何值;未来新增顶层字段默认
212
+ 不进瘦身面(显式登记才带),宁可瘦也不要悄悄膨胀。
213
+ """
214
+ slim: dict[str, Any] = {
215
+ "engine_id": row.get("engine_id"),
216
+ "enabled": row.get("enabled"),
217
+ "type": row.get("type"),
218
+ "cost_tier": row.get("cost_tier"),
219
+ "status": row.get("status"),
220
+ "explicit_only": row.get("explicit_only"),
221
+ "env_ready": row.get("env_ready"),
222
+ "routable": row.get("routable"),
223
+ "quota_exhausted": row.get("quota_exhausted"),
224
+ "dep_ready": row.get("dep_ready"),
225
+ }
226
+ # 条件性细节:非空才出现(健康源不带这些键,输出不随异常源膨胀)
227
+ for key in ("missing_env", "missing_deps"):
228
+ if row.get(key):
229
+ slim[key] = row[key]
230
+ if row.get("quota_exhausted") and row.get("quota_exhausted_reason"):
231
+ slim["quota_exhausted_reason"] = row["quota_exhausted_reason"]
232
+ failure = (row.get("runtime") or {}).get("failure") or {}
233
+ if failure:
234
+ slim["failure"] = {"category": failure.get("category"),
235
+ "evidence": failure.get("evidence")}
236
+ return slim
237
+
238
+
239
+ def list_engines_detail(
240
+ *,
241
+ routable_only: bool = False,
242
+ include_disabled: bool = True,
243
+ engines: Iterable[str] | None = None,
244
+ ) -> list[dict[str, Any]]:
245
+ """引擎详细状态行。
246
+
247
+ engines:只保留这些 engine_id(None = 全量)。单引擎的详细行约 0.9 KB;
248
+ 全量诊断转储 2026-09-16 实测 151 KB(runtime 24% + admission 7% 是大头,
249
+ 此前误记 22 KB)——CLI 在不带 `--engine` 过滤时改出 compact_engine_row
250
+ 瘦身投影(约 1/4 体积),要全量就按引擎过滤,别把转储拉进上下文。
251
+ """
252
+ wanted = set(engines) if engines else None
253
+ cfg = load_config()
254
+ tiers = get_cost_tiers(cfg)
255
+ specs = _all_engine_specs(cfg)
256
+ adaptive_scores = _adaptive_scores_snapshot()
257
+ quota_marks = _quota_exhausted_marks()
258
+ rows = []
259
+ for name in sorted(specs.keys()):
260
+ if wanted is not None and name not in wanted:
261
+ continue
262
+ row = engine_detail(name, specs[name], tiers, adaptive_scores, quota_marks)
263
+ if not include_disabled and not row["enabled"]:
264
+ continue
265
+ if routable_only and not row["routable"]:
266
+ continue
267
+ rows.append(row)
268
+ return rows
269
+
270
+
271
+ def list_routable_engine_ids() -> list[str]:
272
+ return [r["engine_id"] for r in list_engines_detail(routable_only=True, include_disabled=False)]
273
+
274
+
275
+ def format_engines_table(rows: list[dict[str, Any]]) -> str:
276
+ lines = [
277
+ f"{'ENGINE':<22} {'STATUS':<14} {'TIER':<6} {'TYPE':<14} {'ROUTABLE':<8} {'ENV':<28} FAILURE",
278
+ "-" * 120,
279
+ ]
280
+ for r in rows:
281
+ env_note = "ok" if r["env_ready"] else ",".join(r["missing_env"][:2]) or "missing"
282
+ # 失败归因:熔断只回答「要不要继续用」,这一列补「为什么坏」。
283
+ # 归因来自引擎内失败现场记录的寄存器(engines_base.http_open /
284
+ # _http_get_raw → note_failure → 熔断持久化),此前只出现在 --json 里。
285
+ failure = r.get("runtime", {}).get("failure") or {}
286
+ fail_note = ""
287
+ # 配额耗尽优先:它是由配额状态机确认过的「源端明示额度不足」,比熔断里
288
+ # 可能陈旧的归因(旧版落的 unknown/empty)更可信,也更可行动。
289
+ if r.get("quota_exhausted"):
290
+ reason = (r.get("quota_exhausted_reason") or "").replace("\n", " ")
291
+ fail_note = f"quota_exhausted: {reason[:40]}".strip(": ")
292
+ elif failure:
293
+ cat = failure.get("category") or ""
294
+ ev = (failure.get("evidence") or "").replace("\n", " ")[:40]
295
+ fail_note = f"{cat}: {ev}".strip(": ")
296
+ lines.append(
297
+ f"{r['engine_id']:<22} {r['status']:<14} {r['cost_tier']:<6} "
298
+ f"{str(r['type']):<14} {str(r['routable']):<8} {env_note:<28} {fail_note}"
299
+ )
300
+ lines.append(f"\n总计 {len(rows)} · routable={sum(1 for r in rows if r['routable'])}")
301
+ return "\n".join(lines)
302
+
303
+
304
+ def _cli() -> None:
305
+ import argparse
306
+ parser = argparse.ArgumentParser(description="Argo 引擎状态")
307
+ parser.add_argument("--json", action="store_true")
308
+ parser.add_argument("--routable-only", action="store_true")
309
+ parser.add_argument("--engine", help="只看单个引擎")
310
+ args = parser.parse_args()
311
+ if args.engine:
312
+ rows = [engine_detail(args.engine)]
313
+ else:
314
+ rows = list_engines_detail(routable_only=args.routable_only)
315
+ if args.json:
316
+ print(dumps(rows if len(rows) != 1 else rows[0]))
317
+ else:
318
+ print(format_engines_table(rows))
319
+
320
+
321
+ if __name__ == "__main__":
322
+ _cli()