Commit Graph

173 Commits

Author SHA1 Message Date
summer-meng
1168e31626 feat(runtime): partial notify and diagnostics after scheduler timeout (#2338)
* feat(runtime): partial notify and diagnostics after scheduler timeout

After a hard timeout, scan already-saved analyses and enrich last_error
with completed/pending counts; optional push via DSA_TIMEOUT_PARTIAL_NOTIFY.

Refs #2328

* test(runtime): cover timeout partial delivery helpers

Refs #2328

* docs: document DSA_TIMEOUT_PARTIAL_NOTIFY

Refs #2328

* fix(config): use switch ui_control for timeout partial notify

DSA_TIMEOUT_PARTIAL_NOTIFY used ui_control=toggle, which SystemConfigResponse rejects and broke GET /config in backend-tests 1/3.

* docs(runtime): document timeout partial fail-open for operators

Channel exceptions are swallowed after the analysis lock is released, so they cannot keep status.running true. Collect/import failures stay in warning logs because last_error cannot distinguish them from zero completions.
2026-09-13 17:18:52 +08:00
subaoyan16
3d890a0731 fix: 将 litellm 依赖窗口收敛到已验证上界(排除 1.99.0 回归) (#2320)
* Exclude litellm 1.99.0 from allowed versions

litellm 1.99.0 (released 2026-09-01T00:42:41Z) now forwards the
prompt_cache_key argument to the OpenAI provider. The provider cache
contract test asserts the key is not passed through without verified
capture, so CI backend-tests (3/3) and the downstream backend-gate
went red on every branch right after the release, unrelated to any
code change.

Local capture server reproduction: with 1.98.0 the captured request
body carries no prompt_cache_key; with 1.99.0 it carries
prompt_cache_key=cache-key. This one-line exclusion follows the
existing quarantine pattern for 1.82.7 / 1.82.8 and keeps the tested
behaviour until the contract is adapted deliberately.

* Bound litellm below the 1.99.0 behavioral change

Pin the dependency window to a verified upper bound (latest 1.98.x)
instead of quarantining only 1.99.0, and sync every doc that hardcodes
the litellm constraint string so docs cannot drift from requirements.txt
again.

* Sync .env.example runtime constraint comment to the litellm upper bound
2026-09-01 19:22:45 +08:00
TimingAlmostMet
ac8bd29b0f feat: 自建 SearXNG 搜索超时可配置(SEARXNG_TIMEOUT_SECONDS) (#2249)
* feat: make self-hosted SearXNG search timeout configurable

SEARXNG_TIMEOUT_SECONDS (default 10s, min 1) now controls the per-search
timeout for self-hosted SearXNG instances, threaded through all three
SearchService construction sites. Public-instance timeout stays fixed.

* fix: thread SEARXNG_TIMEOUT_SECONDS through subprocess rebuild and Actions

- persist searxng_timeout_seconds in _constructor_kwargs so the bounded
  topic-news subprocess rebuild no longer silently falls back to 10s
- map SEARXNG_TIMEOUT_SECONDS (vars||secrets) in 00-daily-analysis.yml
- document the variable in full-guide/full-guide_EN data-source tables,
  add CHANGELOG entry, and add regression tests for both paths

* fix: document SearXNG timeout environment contract

* fix: register SearXNG timeout setting

* fix: keep SearXNG timeout env-only

---------

Co-authored-by: zhulinsen <42829555+ZhuLinsen@users.noreply.github.com>
Co-authored-by: zhulinsen <zhuls97@163.com>
2026-08-30 21:31:26 +08:00
sunkai174634
fb4735a105 feat: add Futu OpenD as optional HK realtime and fundamental data source (#2269)
* feat: add Futu OpenD as an optional HK realtime and fundamental data source

Add FutuFetcher and FutuFundamentalAdapter behind FUTU_OPEND_HOST/PORT,
register the settings in Config and config_registry so the Web settings
page can expose host, port and HK realtime priority, and route HK
realtime quotes through a configurable futu/longbridge/akshare/yfinance
order while keeping A-share priority untouched. Include offline tests
for the adapter, config schema and HK routing/fallback, plus docs and
CHANGELOG entries.

* fix: wire Futu fundamentals into HK pipeline and restore quote supplementation

- _fetch_offshore_fundamental_bundle() prefers the Futu fundamental
  adapter for HK when FUTU_OPEND_HOST is configured, and falls back to
  yfinance when Futu is absent or returns no usable content.
- HK realtime priority loop now supplements missing quote fields
  (volume_ratio / turnover_rate / pe/pb / market cap) from later
  configured sources instead of returning after the first non-empty
  quote, matching the US path's _supplement_quote behavior.
- capital_flow / boards blocks are filled from the Futu bundle for HK
  instead of being hard-coded not_supported; status and missing_fields
  aggregation updated accordingly.
- Add regression tests for partial-quote supplementation and Futu
  fundamental bundle routing/fallback.

* test: expect boards block ok when bundle provides belong_boards

The Futu integration made the offshore boards block data-driven instead
of hard-coded not_supported; update the existing US/HK fundamental
context test to match (belong_boards from the bundle now surface as an
ok boards block).

* fix: preserve HK fallback_from metadata and normalize Futu quote timestamps

- HK realtime priority loop now records the failed preferred source token
  and passes it as fallback_from when a later source takes over, so the
  pipeline and analysis context can mark the quote as degraded.
- Futu snapshot update_time is a naive Beijing-time (UTC+8) string; attach
  the +08:00 offset before storing provider_timestamp so stale_seconds /
  is_stale / provider_timestamp freshness semantics are correct instead of
  being parsed as UTC.
- Add regression tests for fallback_from propagation and timestamp
  normalization.

* fix: normalize Futu belong_boards to name/type/code contract

OpenD owner_plate returns plate_code / plate_name / plate_type, but DSA
downstream consumers (notification, extract_board_detail_fields, market
structure) only read name/type/code. Map the fields in
FutuFundamentalAdapter._boards so HK Futu boards are actually consumed
instead of silently dropped, and add regression tests including an
end-to-end check through extract_board_detail_fields.

* fix: merge yfinance bundle when Futu fundamental returns partial blocks

Futu partial success (e.g. statements failed but static info worked) used
to short-circuit the whole bundle, silently dropping the growth/earnings
that the existing yfinance path could still provide. Now, when Futu
returns content but is missing growth or earnings, fetch the yfinance
bundle within the remaining budget and merge the missing blocks
(growth/earnings/institution/capital_flow/belong_boards), keeping
Futu-preferred values where both exist. Add regression test for the
partial-success merge path.

* fix: use field-level checks when deciding Futu-vs-yfinance growth/earnings

The previous merge condition only checked dict truthiness, so a truthy
growth/earnings shell (all-None core values or metadata-only keys such
as report_date/period/currency) would skip the yfinance supplement and
silently downgrade existing HK fundamentals. Add _earnings_block_has_values
(a core numeric field or a populated dividend is required) and reuse the
existing _has_meaningful_payload for growth; both the missing_core check
and the merge loop now use these. Add regression test for the
all-None-shell scenario.

* fix: fill HK fundamental field gaps from yfinance instead of block-level checks

Block-level meaningful checks still skipped the yfinance supplement when
Futu hit only part of the growth/earnings fields (e.g. revenue_yoy but
None net_profit_yoy, or earnings with only basic_eps), silently dropping
fields the main branch used to provide. Replace the missing_core decision
with a per-field gap list (growth: revenue_yoy/net_profit_yoy/gross_margin;
earnings.financial_report: revenue/net_profit_parent/basic_eps/gross_profit)
and make the merge field-level: keep Futu values, fill each missing field
from yfinance. Add regression tests for partial-hit and all-None shells.

* fix: normalize Futu dividends to the repo contract and treat dividend gaps as supplement triggers

Futu OpenD dividend_list carries raw fields (statement/ex_date/record_date)
which the notification/data_processing market-structure consumers do not
read; the repo contract is ttm_cash_dividend_per_share,
ttm_dividend_yield_pct and events[].cash_dividend_per_share /
ex_dividend_date / event_date. Normalize events in
FutuFundamentalAdapter._dividends_and_splits, compute TTM count/cash and
yield from the latest quote, and teach _field_gaps/_merge_bundles to treat
a dividend block that does not satisfy the contract as a gap so yfinance
supplements it. Also dedupe FUTU_OPEND_HOST/PORT in full-guide_EN.

* fix: read dividend yield price from UnifiedRealtimeQuote objects

FutuFetcher.get_realtime_quote returns a UnifiedRealtimeQuote dataclass,
not a dict, so the yield branch in _dividends_and_splits that guarded on
isinstance(quote, dict) never ran on the live Futu path, silently dropping
ttm_dividend_yield_pct while the contract check considered the dividend
block complete. Read price via getattr(quote, 'price', None) and keep the
dict fallback for other fetchers; add a regression test driving the real
UnifiedRealtimeQuote shape.

* fix: treat dividend blocks with TTM cash but no yield as supplement gaps

The repo contract consumes ttm_cash_dividend_per_share and
ttm_dividend_yield_pct together. When the Futu dividend path has events
and TTM cash but the extra realtime price snapshot failed (quote None /
no price), ttm_dividend_yield_pct cannot be computed and the block was
previously treated as complete, so yfinance was never consulted and the
notification rendered the yield as N/A.

_dividend_contract_has_values() now requires the paired yield whenever
TTM cash is present, so _field_gaps() triggers the yfinance supplement
and _merge_bundles() replaces the incomplete dividend block.

Add regression tests for the adapter-level gap shape (quote unavailable
leaves no yield) and the manager-level supplement path (Futu cash
without yield pulls yfinance and fills the yield).

* fix: skip unconfigured Futu in HK realtime routing

When FUTU_OPEND_HOST is not configured, the HK realtime priority loop
used to still attempt the futu source, record it as the failed primary,
and attach fallback_from='futu' to a successful quote from the next
enabled source (longbridge/akshare/yfinance). Consumers then wrongly
treated an enabled source's first success as degraded fallback data,
contradicting the documented contract that Futu only participates when
OpenD is configured.

The HK loop now checks FutuFetcher.has_configured_endpoint() once and
skips the futu token entirely when it is disabled, so no fallback_from
is written. Existing configured-Futu routing tests explicitly patch the
endpoint check; a new regression test asserts an unconfigured Futu is
never called and the enriched quote carries fallback_from=None.

* fix: release cached HK Futu fundamental fetcher in DataFetcherManager.close()

The HK Futu fundamental path lazily creates and caches its own
FutuFetcher (an OpenQuoteContext-backed OpenD connection) on
_futu_fundamental_fetcher, but close() only released the TickFlow
fetcher and the default fetchers snapshot. Explicit close / reload
paths therefore left the OpenD connection hanging.

close() now takes the cached _futu_fundamental_fetcher, clears the
reference and calls its close() best-effort. A regression test injects
an observable fetcher into _futu_fundamental_fetcher and asserts
close() invokes it and clears the attribute.

---------

Co-authored-by: BayMax local review <baymax-local@invalid>
2026-08-25 22:54:01 +08:00
wvyan
5bb3139209 fix: isolate runtime scheduler with portable watchdog (#2219)
* fix: isolate runtime scheduler with portable watchdog

* fix: harden runtime scheduler watchdog shutdown

* fix: prevent scheduled analysis after shutdown

* fix: fence scheduler shutdown and harden watchdog

---------

Co-authored-by: wvyan <13724623+wvyan@users.noreply.github.com>
2026-08-24 22:43:46 +08:00
Elvis Wang
55ad446855 feat: 增加 A 股指数多数据源 fallback 路由 (#2258)
* feat: add A-share index fallback routing

* docs: clarify index priority configuration scope
2026-08-23 21:42:07 +08:00
zhulinsen
96bc532dfc fix: restore persisted runtime schedules (#2231) 2026-08-19 23:46:49 +08:00
青玉案
b740beea2a fix: 公共 SearXNG 实例发现默认关闭 (#2226)
* fix: 公共 SearXNG 实例发现默认关闭

公共实例普遍存在限流(429)、下线(503)或未开启 JSON 输出的情况,
默认开启会让未配置任何搜索 key 的用户每次分析多耗 30~60 秒,
且新闻面最终为空却不在报告中提示(详见 #2225 的实测数据)。

- .env.example: 默认值改为 false,并说明原因与推荐做法
- docs/full-guide.md、docs/full-guide_EN.md: 同步默认值与说明
- tests: 放宽段落定位断言以适配新默认值,并新增一条测试固化该默认值

* fix: 公共 SearXNG 实例发现改在运行时层面默认关闭

按 review 意见修正:仅改 .env.example 只影响复制新模板的用户,
已有安装与 GitHub Actions(未配置 Variable/Secret 时变量为空)
仍会走 default=True 的运行时分支,继续承受 30~60 秒失败重试。

- src/config.py: parse_env_bool 的 default 由 True 改为 False(真正生效处)
- src/core/config_registry.py: 示例顺序调整为 false 优先
- .github/workflows/00-daily-analysis.yml: 变量未设置时诊断显示「默认关闭」,
  与运行时行为保持一致,不再误报为已开启
- tests: 新增三条回归测试,分别锁住运行时默认值、config.py 源码中的
  default=False、以及工作流诊断文案
- docs/CHANGELOG.md: 在 [Unreleased] 追加条目

显式设为 true 的用户行为不变。27 passed

* fix: align SearXNG public instance defaults

* fix: complete SearXNG opt-in defaults

---------

Co-authored-by: Mach-Chan <zz-b240@zz-b240deMacBook-Air.local>
Co-authored-by: ZhuLinsen <zhuls97@163.com>
2026-08-19 21:59:10 +08:00
lmx-2077
cfd6b0a5fb feat(agent): per-category tool timeouts with graceful degradation (#1890) (#2134) 2026-08-17 21:41:19 +08:00
zhulinsen
3b98aa1d77 docs: update AIHubMix referral links to InferEra (#2182) 2026-08-10 21:18:03 +08:00
zhulinsen
071c5aa3c7 fix: stabilize Xiaohongshu share image caption (#2179) 2026-08-09 21:40:13 +08:00
zhulinsen
46d5bf3472 fix: 恢复桌面端报告分享图 (#2169)
* fix: enable desktop report share images

* fix: include default share image branding

* fix(review-feedback-2169): Keep custom branding paired with its QR code

* fix: show default share image nickname

* fix(review-feedback-2169): Document the atomic branding fallback

* fix(review-feedback-2169): Remove the hard-coded social account default

* fix(review-feedback-2169): Remove the bundled account QR fallback

* fix(review-feedback-2169): update docs/share-images

* fix(review-feedback-2169): [Verification blocker] 当前 Head 的阻断型 CI

* fix(review-feedback-2169): 补一条回归:用包含超长 fenced-code 行和超长原始 URL 的完整/通用报告分别走 build share image html
2026-08-09 13:53:00 +08:00
zhulinsen
4dda5d7148 feat: add explicit Responses API channel routing (#2157) 2026-08-05 19:15:08 +08:00
zhulinsen
3c849dec19 fix: 按需生成分享图并恢复基础设置中的选股开关 2026-08-02 20:59:13 +08:00
zhulinsen
e430fcfe48 fix: 收敛选股排序、缓存与热点并发契约 (#2145)
* fix: stabilize screening ranking and hotspot workflows

* fix(review-feedback-2145): Stop timed-out constituent workers before returning and Keep the

* fix: close screening review contract gaps

* fix: bound screening hotspot search workers

* fix(review-feedback-2145): [Verification blocker] 当前 Head 的阻断型 CI 已最终失败:backend-gate。请在本地运行对应

* fix: close screening contract review gaps

* fix: unify hotspot timeout contracts

* fix: bound hotspot search end to end

* fix: bound hotspot detail fallbacks
2026-08-02 18:32:30 +08:00
zhulinsen
91988da149 feat: 添加报告分享图片与 Web 一键分享 (#2146)
* feat: add report image sharing

* fix(review-feedback-2146): 评审结论 - 代码检查 :当前整个 PR 仍有 2 个未关闭的高置信度代码 blocker。最新复核摘要:基于 merge-base

* fix(review-feedback-2146): preserve the Markdown fallback for unavailable snapshots and preserve

* fix(review-feedback-2146): 补一组通知回归测试,至少覆盖

* fix(review-feedback-2146): 在源码树执行 npm ci 和 npx playwright install chromium,这与预编译 desktop 发行包环境不一致

* fix(review-feedback-2146): 评审结论 - 代码检查 :当前整个 PR 仍有 1 个未关闭的高置信度代码 blocker。最新复核摘要:基于 merge-base

* fix(review-feedback-2146): 补上明确的 CLI/Chromium 安装提示,避免当前日志和 503 文案继续把用户引向

* fix(review-feedback-2146): 补到与 docs/share-images.md 一致,直接提示 cd apps/dsa-web && npm ci 和 npx
2026-08-02 16:45:37 +08:00
zhulinsen
bcb7ae4e13 feat: 将参考 AlphaSift 的选股实现纳入主项目 (#2136)
* feat: integrate built-in stock screening engine

* test: verify screening routes via public contract

* refactor: make screening integration fully native

* fix(review-feedback-2136): [Verification blocker] 当前 Head 的阻断型 CI 已最终失败:backend-gate。请在本地运行对应

* feat: persist screening runs and reuse DSA analysis

* fix(review-feedback-2136): 对选股重排应用统一的模型参数兼容逻辑

* fix(review-feedback-2136): 将字段缺失计入数据源失败

* fix(review-feedback-2136): 评审结论 - 代码检查 :当前整个 PR 仍有 3 个未关闭的高置信度代码 blocker。最新复核摘要:当前整个 PR 仍有 3

* fix(review-feedback-2136): 延迟写入候选直到覆盖率通过校验 and 将 DSA 日线成功结果写入 last-good 缓存

* fix(review-feedback-2136): 将直连日线源纳入统一调用超时 and 将新增的选股缓存目录加入桌面更新备份

* fix(review-feedback-2136): 保留完整热点缓存而非请求切片 and 遵守 DSA 上下文声明的候选上限

* fix(review-feedback-2136): 补一条端到端回归:把真实 ScreenResult 经 ScreeningService.screen 落到 /history 和

* fix(review-feedback-2136): 补一个 refresh=true 且 live fetch 失败时返回 stale cache 的回归测试,避免当前只更新 stale
2026-08-01 14:13:23 +08:00
ObVious55
831ada5370 feat: apply Bayesian skill outcome weights (#2123)
* feat: apply Bayesian skill outcome weights

* fix: align skill auto-weight help with outcome model

* fix: limit outcome stats to requested skills
2026-07-31 19:59:48 +08:00
zhulinsen
90f62349af fix: 将 Tencent 日 K 保持为最终兜底 (#2107)
* fix: keep Tencent daily data as final fallback

* fix(review-feedback-2107): 补一个覆盖 python scripts/check env.py --fetch 或“先 import data provider 再读取
2026-07-26 20:32:12 +08:00
xushengasd
de8aa6a0ba feat: complete phase 2 multi-strategy deliberation and scheduling (#2062)
Co-authored-by: zhulinsen <42829555+ZhuLinsen@users.noreply.github.com>
2026-07-22 23:44:59 +08:00
Nicholas-Xiong
f2bfa0210f feat: 支持 TUSHARE_HTTP_URL 自定义 Tushare Pro 接入地址 (#2048)
* feat: support custom Tushare Pro endpoint via TUSHARE_HTTP_URL

Add TUSHARE_HTTP_URL so the Tushare data source can point at a self-hosted
or third-party compatible endpoint when the official api.tushare.pro is not
reachable. Defaults to the official host when unset, so behavior is
unchanged for existing users.

- data_provider/tushare_fetcher.py: add _resolve_tushare_http_url() helper
  (strip + http(s):// schema validation) and forward the resolved URL into
  _TushareHttpClient, with an info log when a custom endpoint is in use
- .env.example + .github/workflows/00-daily-analysis.yml: document and map
  TUSHARE_HTTP_URL so the new option is wired into the daily job without
  leaving a half-configured state
- tests: cover env parsing (empty/whitespace/http/https/missing schema),
  fetcher fall-through to the official host, and end-to-end POST target
- docs/CHANGELOG.md: flat [Unreleased] entries

Fixes #1985

* refactor: drop unnecessary string-literal type hint in _build_api_client

TushareHttpClient is already defined above TushareFetcher in the module
scope, so a string-literal type hint is not needed for forward reference.
Restore the bare type to match the surrounding code style and reduce the
diff against main.

* docs(tushare): 补 TUSHARE_HTTP_URL 在 full-guide 中英版本的用途/默认行为/workflow 映射说明

按 PR #2048 review 反馈补齐:
- 表格内新增 TUSHARE_HTTP_URL 行(中英文版本同步),明确默认 https://api.tushare.pro 与 http(s):// 前缀要求
- 在 GitHub Actions 段落后补充 TUSHARE_HTTP_URL 的 vars/Secrets 优先级与每日 workflow 0映射说明,与现有非敏感配置(TICKFLOW_PRIORITY)一致
- 完整环境变量列表(中英文版本)补 TUSHARE_HTTP_URL 行,默认值列填 https://api.tushare.pro
- 与代码实现一致:00-daily-analysis.yml 已用 vars.TUSHARE_HTTP_URL || secrets.TUSHARE_HTTP_URL 映射

* docs(tushare): align TUSHARE_HTTP_URL default with runtime and clarify vars/secrets precedence

Per review feedback on PR #2048: the per-repo config contract must stay
consistent across runtime, .env.example, workflow priority, tests and
both zh/en guides. Two fixes applied as a single contract update:

1. Default endpoint alignment. data_provider/tushare_fetcher.py:100,
   .env.example, and tests/test_tushare_fetcher_http_client.py all keep
   the existing official endpoint http://api.tushare.pro, but the zh/en
   full-guide rows had drifted to https://api.tushare.pro. Switching the
   documented default to HTTPS would silently change the runtime contract
   that the feat commit explicitly preserved. Revert both zh and en
   guide rows to http://api.tushare.pro so docs match runtime, .env.example
   and the test assertions.

2. vars/secrets precedence wording. The workflow uses
   'vars.TUSHARE_HTTP_URL || secrets.TUSHARE_HTTP_URL', which means a
   non-empty vars entry always wins and Secrets cannot override it. The
   zh/en notes previously suggested 'Secrets as a tamper fallback' which
   is incorrect under this precedence and can mislead users into thinking
   Secrets has override power. Replace with explicit description of the
   real semantics: vars wins when non-empty; Secrets is only selected
   when the Variable is empty; for a tamper-resistant deployment put the
   value only in Secrets and leave Variables empty.

Both zh and en guides are updated together; the same 6 contract surfaces
(runtime / .env.example / workflow priority / tests / zh guide / en guide)
now describe one consistent contract.

* docs(tushare): remove false Secret-as-tamper-guard claim, document real vars/secrets write-permission model
2026-07-22 20:54:40 +08:00
JaxonHu
d13721e817 feat: 新增富途Futu真实持仓导入支持 (#2042)
* feat: add Futu portfolio import support

* docs: condense Futu changelog entry

* fix: tighten Futu portfolio import contracts
2026-07-20 22:45:45 +08:00
Alfred
628c5b6ef7 feat: add Codex App Server agent prototype (#2004) 2026-07-19 16:31:54 +08:00
zhulinsen
e8a9ca7742 fix: harden release packages and report market context (#1994)
* fix: bundle orjson in release packages

* fix: remove duplicate decision signal excerpts

* feat: add TickFlow sector ranking fallback
2026-07-12 18:56:21 +08:00
Gach-Coder
16ff3e743f feat: 子Agent 独立超时配置(#1929) (#1961)
* feat: 子Agent 独立超时配置(#1929)

* fix: 子Agent超时钳位在无Pipeline预算时独立生效(#1929)

* test: 新增子Agent超时钳位回归测试(#1929)
2026-07-08 21:52:48 +08:00
Sam Smith
a3c039ac13 feat: add feishu file upload support for report delivery (#1932)
* feat: add feishu file upload support for report delivery

- Add FEISHU_SEND_AS_FILE config option to switch from text to file delivery
- Implement FeishuSender.send_feishu_file() with App Bot SDK upload + webhook fallback
- Integrate file upload path into pipeline dashboard notification loop
- Integrate file upload path into NotificationService.send_report()
- Add save_and_send_feishu_file() convenience wrapper
- Add .env.example entry and CHANGELOG.md record

* fix: restrict feishu file mode to report routes and wire into workflow

- Limit FEISHU_SEND_AS_FILE to route_type=None or 'report' in
  _send_to_static_channel, preventing alert/event paths from
  unexpectedly saving alerts as files (Codex review P2).
- Add FEISHU_SEND_AS_FILE env var to .github/workflows/00-daily-analysis.yml
  so the setting is available in scheduled runs (Codex review P2).
- Add 13 tests: 7 FeishuSender unit tests (send_feishu_file webhook/App Bot
  paths), 6 NotificationService integration tests (route_type filtering)

* fix: address round-2 review blockers

Correctness:
- Remove route_type=None file-mode fallback; only explicit
  route_type='report' triggers Feishu file delivery
  (api/v1/endpoints/agent.py calls send() without route_type)

Compatibility:
- Isolate CreateFileRequest/CreateFileRequestBody imports from
  CreateMessageRequest; add FEISHU_FILE_SDK_AVAILABLE flag
  so old lark-oapi without file-upload classes won't break
  existing App Bot text messaging

Test fix:
- Fix webhook test assertion: # Test Report -> **Test Report**
  (format_feishu_markdown converts markdown headings to bold)

Documentation:
- Add FEISHU_SEND_AS_FILE to docs/notifications.md config table
- Add file-send section to docs/bot/feishu-bot-config.md
  (permissions, deps, webhook fallback, route scope, CI mapping)
- Add FEISHU_SEND_AS_FILE to docs/full-guide.md and
  docs/full-guide_EN.md config tables
- Add Feishu file create OpenAPI link to docs/notifications.md

* docs: fix feishu_sender drift and document config entry boundary

- Fix outdated '本轮未改动 feishu_sender.py' line in docs/notifications.md
  (we added send_feishu_file to feishu_sender.py)
- Document FEISHU_SEND_AS_FILE as .env/Actions-only in
  docs/bot/feishu-bot-config.md (not exposed in Web/Desktop settings)

* feat: add FEISHU_SEND_AS_FILE to system_config_service env mapping

- Add FEISHU_SEND_AS_FILE -> feishu_send_as_file (bool) mapping
  alongside FEISHU_MAX_BYTES in the notification env key mapping
- Update docs/bot/feishu-bot-config.md to reflect standard config paths

* test: add non-mock SDK import smoke test for file upload classes
2026-07-06 21:26:19 +08:00
zhulinsen
c1a324d208 feat: add opt-in intelligence auto fetch (#1913)
* feat: add opt-in intelligence auto fetch

* fix(review-feedback-1913): waiting for or sharing the in-flight refresh result instead of

* fix(review-feedback-1913): 补齐 workflow 显式映射,或在文档/PR scope 中明确该开关暂不适用于仓库自带默认 workflow

* docs: clarify intelligence auto fetch workflow scope

* fix(review-feedback-1913): 修复自动刷新读取全局配置而非当前分析配置的问题
2026-07-04 15:03:05 +08:00
zhulinsen
a52c8502d7 fix: harden AlphaSift timeout handling (#1898) 2026-07-03 21:00:12 +08:00
Shlok Goyal
5a6c08b5f1 feat: 添加钉钉机器人支持 (Add DingTalk Notification Support) (#1878)
* feat: 添加钉钉机器人支持

* fix: chunk DingTalk payloads over the webhook limit

* docs: fix changelog format and update full-guide for DingTalk

* fix: reserve 1KB budget for DingTalk JSON payload overhead and add chunking unit tests

* test: add strict json payload byte assertion for DingTalk limits and truncate titles

---------

Co-authored-by: zhulinsen <42829555+ZhuLinsen@users.noreply.github.com>
2026-07-03 19:47:07 +08:00
Alfred
7b39b73b9d feat: add generation backend status diagnostics (#1883) 2026-07-03 19:34:43 +08:00
zhulinsen
fc895e3124 fix: 提升 Discord 长报告分片发送可靠性 (#1861)
* fix: improve Discord long report delivery

* fix(review-feedback-1861): Catch all requests exceptions per chunk
2026-07-01 19:07:52 +08:00
Alfred
4c678850e2 feat: add Claude Code and OpenCode generation backends (#1850)
Co-authored-by: zhulinsen <42829555+ZhuLinsen@users.noreply.github.com>
2026-06-30 22:33:02 +08:00
HyunRyeol Park
043c60378e feat: 报告输出语言新增韩语支持 (Korean report language, ko) (#1614) (#1844)
* feat(i18n): add Korean to report language label maps

Extend the report language layer with a third code `ko` so reports can
render deterministic labels in Korean. Adds `ko` to the supported list,
aliases (korean/kr/ko-kr), every translation map, the full report label
set, sentiment bands, the config registry enum and `.env.example`.
`zh`/`en` behavior is unchanged and unknown languages still fall back to
the default. Prompt and Web surfaces follow in later changes.

Refs #1614

* feat(i18n): emit Korean output directives in analysis prompts

Make the analysis and market-review prompts produce Korean output when
REPORT_LANGUAGE=ko. The decision agent now appends a Korean
output-language directive (JSON keys and decision_type enum unchanged),
and the market-review prompt reuses the English structural scaffolding
while instructing the model to write the shell, headings and conclusion
in Korean. Market-phase and context-pack prompt sections route ko to the
English structural base. The market-review payload keeps the truthful
language code via a dedicated output-language helper, leaving zh/en
behavior unchanged.

Refs #1614

* fix(i18n): localize phase and market-context guardrails for Korean

Route Korean reports through the English structural scaffolding for
market-phase and market-context prompt sections, and add Korean output,
detection markers, negations and recap patterns to the phase-decision and
daily-market-context guardrails so they operate on Korean model output.
Confidence and operation labels now flow through the shared localize
helpers. zh/en behavior is unchanged.

Refs #1614

* feat(i18n): localize Korean fallback output across analysis pipeline

Add Korean output to the deterministic strings emitted outside the LLM:
per-stock and executor output-language directives, no-API-key / backend
/ parse error fallbacks, hold-watch advice and reasons, market-review
titles and summaries, and history and notification report labels. Fund
flow, trend and confidence values now flow through the shared localize
helpers, and language-keyed advice tables no longer raise KeyError for a
third language. Structural prompt sections route ko to the English
scaffolding. zh/en output is unchanged.

Refs #1614

* feat(web): add Korean report language rendering

Extend the Web ReportLanguage type with ko and add Korean copy to the
report detail surfaces: report text, sentiment labels, market-phase
labels, analysis-context summary, market-review view, diagnostics and
news source. Run-flow chrome that is keyed by UI language falls back to
English for ko. The report-language selector is driven by the backend
config schema, so Korean appears automatically. zh/en rendering is
unchanged.

Refs #1614

* docs(i18n): document Korean report language support

Note that REPORT_LANGUAGE accepts ko in the bilingual guides and the
analyze / market-review request-language parameters, and add a
CHANGELOG entry for Korean report output.

Refs #1614

* fix(i18n): canonicalize Korean values and accept ko in API schemas

Add Korean aliases to the operation-advice, trend, confidence, chip and
bias canonical maps so Korean model output (매수/매도/보유/관망 etc.)
resolves to the correct decision_type and signal level instead of
falling back to hold or a score-band signal. Accept ko in the
analyze, market-review and decision-signal request schemas (and the
static API spec) so the typed client and backend agree and per-request
Korean analysis is not rejected with 422.

Refs #1614
2026-06-30 19:02:46 +08:00
zhulinsen
29fa05049d fix: harden AlphaSift source stability (#1832)
* fix: harden AlphaSift source stability

* docs: add data source stability diagrams

* fix(review-feedback-1832): Handle degraded EastMoney failures for the new default

* fix: allow JP KR market light snapshots

* fix(review-feedback-1832): 补充覆盖 alert 创建/校验路径的回归测试,证明 JP/KR 不会被告警路径接受
2026-06-28 20:23:02 +08:00
zariba
94cd2a4d96 feat(data): 接入 TickFlow 核心 A 股数据源 (#1790)
* feat(data): integrate TickFlow core A-share provider

* fix(data): harden TickFlow daily kline contract

* fix(web): localize TickFlow settings and run-flow coverage

* fix(web): clarify TickFlow priority settings

* chore(deps): require verified TickFlow SDK

---------

Co-authored-by: timeance <timeance@users.noreply.github.com>
2026-06-28 17:09:28 +08:00
zhulinsen
ade3b4cb6e feat: add JP KR market review support (#1822)
* feat: add JP KR market review support

* fix(review-feedback-1822): update the Market Light schema/service support before accepting these

* fix(review-feedback-1822): add JP/KR to daily market context before accepting them and update

* fix(review-feedback-1822): add English JP/KR strategy text or make the renderer language-aware

* fix(review-feedback-1822): update the prompt role/shell alongside the new accepted regions

* fix(review-feedback-1822): 修正 PR 描述中的过期验证结论,并补充/澄清 JP/KR Yahoo Finance 指数兼容性证据或在线验证边界

* fix(review-feedback-1822): 收敛 Market Light 告警契约与用户文档同步问题

* fix(review-feedback-1822): 修正后再合入

* fix(review-feedback-1822): 补齐外部 Yahoo Finance 指数接入与运行时配置变更的兼容性/迁移证据,并修正 PR 描述中与当前 CI 状态不一致的内容

* fix(review-feedback-1822): 当前 CI 状态为 failure,且阻断型 backend-gate 失败

* fix(review-feedback-1822): 修复 MARKET REVIEW REGION 逗号值在交易日过滤与配置 schema 中的契约漂移,并补充对应回归测试

* fix(review-feedback-1822): 收敛 PR 描述中的验证状态与用户可见 Web 改动证据

* fix(review-feedback-1822): 修正 PR 描述中的过期验证结论,并补充 Web 设置变更的截图或无法截图时的替代可视证据说明

* fix(review-feedback-1822): 收敛 PR 描述中的验证状态,并补齐 Web 设置变更的截图或替代可视证据

* fix(review-feedback-1822): 收敛 PR 描述后再合入

* fix(review-feedback-1822): 收敛 PR 描述中的验证状态,并补充 Web 设置变更截图或无法截图时的替代可视证据说明

* fix(review-feedback-1822): 收敛验证状态和 Web UI 可视证据,避免合入记录与实际 head 不一致

* fix(review-feedback-1822): 收敛 PR 描述中的验证状态与 Web 可视证据

* fix(review-feedback-1822): 收敛 PR 描述中的验证状态,并补齐 Web 设置变更的截图或替代可视证据说明

* fix(review-feedback-1822): 修正 PR 描述与当前 CI 事实不一致的问题,补充 Web 设置可视证据,并收敛或拆出 PR 模板改动

* fix(review-feedback-1822): 收敛 PR 描述与证据

* fix(review-feedback-1822): 修正 PR 描述与证据,使验证状态、用户可见变更证据、模板改动范围和当前 head 保持一致

* fix(review-feedback-1822): 收敛 PR 描述、补齐可视证据,并澄清/补充外部模型/API 与运行时配置迁移相关兼容性证据

* fix(review-feedback-1822): 收敛 Web/文档契约不一致、同步残留测试,并更新 PR 描述与可视证据
2026-06-28 17:03:15 +08:00
Alfred
62adb5c4ee feat: add Hermes local HTTP generation (#1824) 2026-06-28 17:02:17 +08:00
Alfred
1f91024dec feat: 新增 codex_cli 本地生成后端 Phase2 (#1769)
* feat: add codex cli generation backend

* fix: harden local CLI backend phase 2

* fix: harden local cli output file handling

* fix: tighten codex cli backend contracts

* fix: support codex cli windows smoke path

* fix: make local cli tests portable on windows

* fix: avoid duplicate codex final output accounting
2026-06-24 20:19:19 +08:00
Alfred
2f75e832e3 feat: 添加 GenerationBackend Phase 1 抽象 (#1751)
* feat: add generation backend abstraction

* fix: tighten generation backend phase1 contract

* fix: preserve market review backend config errors
2026-06-22 22:42:53 +08:00
Alfred
df09b7ccf4 feat: add provider prompt cache controls (#1744) 2026-06-22 20:50:54 +08:00
mumu
ecd026e958 fix: docker重新部署时,.env设置里的通知变量$content_jso… (#1739) (#1741)
* fix(issue-1739): [bug]-docker重新部署时,.env设置里的通知变量$content_j

* fix(review-feedback-1741): escape/unescape the braced forms too, or reject them before persisting

* fix(review-feedback-1741): preserve braced templates during env import

* fix(review-feedback-1741): 澄清外部模型/API 配置风险提示是否命中真实 diff

* fix(review-feedback-1741): limit raw parsing to CUSTOM WEBHOOK BODY TEMPLATE or re-apply the
2026-06-22 20:49:37 +08:00
mumu
f2e778c058 feat: 支持客户端多时间定时推送 (#1731)
* feat: support runtime multi-time scheduling

* fix(review-feedback-1731): 修复 and add the missing workers value here, likely None to preserve the

* fix: refine scheduler settings UI

* fix: compact scheduler time inputs

* fix(review-feedback-1731): Refresh scheduler status after saving changes

* fix(review-feedback-1731): Refresh scheduler status after env imports

* fix(review-feedback-1731): Do not mark swallowed analysis failures as success

* fix: align serve scheduler ownership

* fix: preserve runtime scheduler startup semantics

* fix: ignore immediate run when cli owns schedule

* fix(review-feedback-1731): main.py + api/app.py:--serve-only 下虽然 runtime schedule requested 被置为

* fix(review-feedback-1731): apps/dsa-desktop/main.js / main.py / api/app.py / src/services/runtime

* fix: preserve runtime scheduler ownership semantics

* fix(review-feedback-1731): 修正 Desktop 启动会自动分析/调度,以及 Web 调度开关在 runtime 状态与持久配置不一致时无法触发 reconcile 的问题

* fix: remove duplicate scheduler save diff variable

* fix: allow empty schedule times config

* fix: reject busy scheduler run-now requests

* fix(review-feedback-1731): 确认并修正 runtime scheduler 重建时可能重复注册 AGENT EVENT MONITOR ENABLED 后台任务的问题

* fix: keep runtime event monitor idempotent

* fix: preserve runtime scheduler CLI flags

* fix(review-feedback-1731): preserve schedule CLI flags in runtime runs

* fix(review-feedback-1731): 修正 --serve --schedule / --serve + SCHEDULE ENABLED=true 下 API

* fix(review-feedback-1731): 修复当前 diff 引入的运行时并发风险和 Uvicorn 兼容风险
2026-06-21 22:24:19 +08:00
mumu
626b63c144 feat: feed intelligence sources into analysis contexts (#1709)
* feat: add intelligence source ingestion baseline

* feat: feed local intelligence into analysis contexts

* fix(review-feedback-1708): Reject DNS names that resolve privately and Validate redirect targets

* fix(review-feedback-1709): 处理大盘复盘本地资讯可能被搜索结果截断掉的问题,并澄清结构化检测到的外部模型/API 或运行时配置风险是否为真实变更

* fix(review-feedback-1708): Pin DNS resolution before fetching and Stream feeds before enforcing

* fix(review-feedback-1709): filter by published at for analysis evidence, or keep missing publish

* fix(review-feedback-1708): Sanitize fetch errors before returning them and Normalize nullable

* fix(review-feedback-1709): Normalize symbol scope before lookup

* fix(review-feedback-1708): Avoid rolling back prior item inserts on duplicate races and Reject

* fix(review-feedback-1709): Use the effective news window for local evidence and add the plain

* fix(review-feedback-1708): 落地可配置 RSS/Atom 情报源、存储、查询、retention 和基础安全边界

* fix(review-feedback-1709): 补充“revert 本 PR 或移除本地资讯接入入口/清退本地资讯源配置数据”级别说明即可

* fix(review-feedback-1708): 落地 RSS/Atom 情报源的存储、拉取、查询、retention 和基础安全边界

* fix(review-feedback-1709): 补 Refs 1707

* fix(review-feedback-1709): 解决冲突后再合入

* fix(review-feedback-1709): src/services/intelligence service.py 回退了资讯源 URL 安全防护:移除了 hostname DNS

* fix: harden intelligence source ingestion

* fix(review-feedback-1709): Sanitize upstream fetch errors before returning them

* feat: add NewsNow intelligence sources

* fix(review-feedback-1709): 确认并修复

* fix(review-feedback-1709): 补一个未命中敏感规则的异常回归测试

* fix(review-feedback-1709): 处理

* docs: enhance NEWSNOW_BASE_URL compatibility guidance with official links

- Add official NewsNow GitHub deployment guide link to .env.example
- Include curl-based API contract verification example for production validation
- Update CHANGELOG.md with official repository reference and deployment recommendation
- Clarify risk of public example instance and necessity for self-hosted in production
- All HTTP 500 responses already use sanitize_diagnostic_text for privacy

Ref #1707
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix(review-feedback-1709): 补齐官方 NewsNow 实例链接文档或 API 契约确认,明确指出公开实例风险(需结合当前部署指南文档,更新 .env.example

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-19 09:42:42 +08:00
mumu
0ed601022f fix: 升级 AlphaSift 并兼容热点详情龙头股字段 (#1714)
* fix: update AlphaSift pin and hotspot detail fields

* fix(review-feedback-1714): fix still returning no concept stocks despite the leaders being
2026-06-19 09:28:32 +08:00
mumu
cd37608506 feat: add intelligence source ingestion baseline (#1708)
* feat: add intelligence source ingestion baseline

* fix(review-feedback-1708): Reject DNS names that resolve privately and Validate redirect targets

* fix(review-feedback-1708): Pin DNS resolution before fetching and Stream feeds before enforcing

* fix(review-feedback-1708): Sanitize fetch errors before returning them and Normalize nullable

* fix(review-feedback-1708): Avoid rolling back prior item inserts on duplicate races and Reject

* fix(review-feedback-1708): 落地可配置 RSS/Atom 情报源、存储、查询、retention 和基础安全边界

* fix(review-feedback-1708): 落地 RSS/Atom 情报源的存储、拉取、查询、retention 和基础安全边界
2026-06-18 21:43:33 +08:00
Alfred
4fa81a421c feat: add legacy LLM usage telemetry (#1698) 2026-06-17 18:46:01 +08:00
mumu
3b5ef16144 feat: harden AlphaSift data source routing (#1680)
* feat: harden alphasift data source routing

* fix(review-feedback-1680): Keep the sample AlphaSift pin in sync and Avoid circuit-breaking

* fix(review-feedback-1680): Defer half-open health checks until a source is attempted and Treat

* fix(review-feedback-1680): fix only bypasses this branch for fetchers that opt into allow empty

* fix(review-feedback-1680): Avoid accepting truncated Tencent histories

* fix(review-feedback-1680): 修正 .env.example 的 AlphaSift 快照源默认说明,并避免在 docs/CHANGELOG.md

* fix(review-feedback-1680): src/config.py、src/services/alphasift service.py

* fix(review-feedback-1680): requirements.txt、src/config.py、.env.example、src/services/alphasift

* fix(review-feedback-1680): 修复 TencentFetcher 对显式历史窗口的处理问题

* fix(review-feedback-1680): Check the cap was hit before rejecting Tencent history

* fix(review-feedback-1680): Use Tencent's hyphenated date format and Convert Tencent daily volume

* fix(review-feedback-1680): Accept the executor timeout argument and preserve capped windows with

* fix: limit empty daily data opt-in behavior

* docs: restore AlphaSift 3.22 changelog entry
2026-06-14 18:47:41 +08:00
mumu
ecc370e50b feat: adapt AlphaSift hotspot contract (#1675)
* feat: adapt alphasift hotspot contract

* fix(review-feedback-1675): update sample install spec with new allowed pin

* fix(review-feedback-1675): 补充 “revert 本 PR / 恢复旧 AlphaSift pin” 级别的回滚说明,并明确无关联 issue 或补充 Refs

* fix: harden alphasift hotspot metadata migration

* fix(review-feedback-1675): preserve hotspot route events in the new detail path

* fix(review-feedback-1675): 修正旧 AlphaSift pin 回滚/重装路径说明,避免运维按文档操作时被 install allow-list 拒绝

* fix(review-feedback-1675): src/services/alphasift service.py:当 AlphaSift v2 detail payload

* fix(review-feedback-1675): 补对应回归测试
2026-06-13 14:46:18 +08:00
mumu
a82ae51ca8 feat: enable daily market context by default (#1673) 2026-06-13 10:58:18 +08:00
mumu
0db0c78da8 feat: 个股分析接入当日大盘上下文 (#1623)
* feat: add daily market context for stock analysis

* fix(review-feedback-1623): Share the market context service across worker threads and Use the

* fix(review-feedback-1623): Avoid overwriting per-region context reports and Expand history lookup

* fix(review-feedback-1623): add position even though the guardrail supposedly softened the

* fix(review-feedback-1623): Avoid generating the CLI market review twice

* fix(review-feedback-1623): 修正

* fix(review-feedback-1623): 修复普通 CLI/调度运行中大盘复盘被上下文预热摘要替代的问题,并收敛 PR 描述与当前实现范围

* fix(review-feedback-1623): 修正保守护栏的误判风险,并同步收敛 PR 描述范围

* fix(review-feedback-1623): 处理并发生成大盘上下文的锁语义风险,并澄清/补充外部模型或运行时配置风险检测的依据

* fix(review-feedback-1623): 收敛大盘上下文预热对用户可见大盘复盘的行为影响,并补齐外部模型/API 与运行时配置检测风险的澄清或验证证据

* fix(review-feedback-1623): Do not skip multi-market reviews after one cached context and Do not

* fix(review-feedback-1623): Prime context with the effective trading date

* fix(review-feedback-1623): 收敛 PR 描述与实际 diff 的范围不一致,并澄清结构化检测提示的 provider/model/base

* fix(review-feedback-1623): 补一句“本 PR 不修改 LLM provider/model/base url、默认模型、配置清理或迁移逻辑”,避免后续审查继续误判

* fix(review-feedback-1623): 收敛 PR 描述与实际 diff 的范围矛盾

* fix(review-feedback-1623): 补齐这些承诺的实现

* fix(review-feedback-1623): 收敛 PR 描述与实际 diff 范围,避免以未实现能力作为验收项

* fix(review-feedback-1623): 收敛 PR 描述与实际范围,并澄清外部模型/API 与运行时配置检测风险

* fix(review-feedback-1623): Match freshly saved reviews to the target trade date

* fix(review-feedback-1623): preserve structured market-light risk signals

* fix(review-feedback-1623): Escape market-summary sentinels before prompting

* fix(review-feedback-1623): 修复同日缓存复用时把低敏摘要当完整大盘复盘输出的行为风险,并收敛 PR 描述与实际 diff

* fix(review-feedback-1623): 收敛

* fix(review-feedback-1623): 收敛 PR 描述与实际 scope

* fix(review-feedback-1623): 修正大盘复盘复用语义,并让 PR 描述与实际 scope 对齐

* fix(review-feedback-1623): 修正同日大盘上下文缓存复用语义,并让 PR 描述与实际 scope 对齐

* fix(review-feedback-1623): Disable cached market context when skipping market review

* fix(review-feedback-1623): 收敛 PR 描述与实际 scope,并补充外部模型/API 与运行时配置语义未变化的可核验证据

* fix(review-feedback-1623): 修正 PR 描述与实际 scope 的实质性不一致,并补齐或澄清 LLM/provider/model/base URL

* fix(review-feedback-1623): 修正 operation advice 契约漂移,并让 PR 描述/验收范围与当前实际 diff 对齐

* fix(review-feedback-1623): 收敛 main.py 中大盘复盘复用导致的通知/执行语义变化,并补对应回归测试

* fix(review-feedback-1623): 修复生成型大盘上下文未绑定当前 query id 的行为风险,并收敛 PR body 与实际 diff 范围

* fix(review-feedback-1623): 修复缓存语言匹配问题,并收敛 PR 描述与实际 diff/验收范围的一致性

* fix(review-feedback-1623): 收敛当前实现与描述/文档中的验收边界,并澄清 schedule/CLI 首次运行无历史大盘复盘时是否应生成并注入上下文

* fix(review-feedback-1623): 收敛 PR 描述与 docs/CHANGELOG.md 中关于验收边界的表述,避免与实际 diff 实质性矛盾

* fix(review-feedback-1623): 修正 PR 描述与实际 diff 的范围漂移

* fix(review-feedback-1623): Reuse the cached runtime market context on fallback

* fix(review-feedback-1623): PR 描述:当前完整改动文件列表没有 api/ 、apps/dsa-web/ 、日报状态表或四阶段日报持久化相关实现,但 PR

* fix(review-feedback-1623): 收敛描述范围

* fix(review-feedback-1623): 收敛并发生成复用路径的正确性风险,并修正 PR 描述的实际范围与验收项

* fix(review-feedback-1623): 收敛描述和验收范围

* fix(review-feedback-1623): PR 描述的 Background / Acceptance Criteria 仍包含独立 API、Web

* fix(review-feedback-1623): 收敛 PR 描述与实际实现边界,并补齐 LLM/provider/base url 相关兼容性说明或验证证据

* fix(review-feedback-1623): PR 描述与实际 diff 范围不一致:描述和验收项仍写有独立 API、Web

* fix(review-feedback-1623): Wait long enough for in-flight market reviews

* fix(review-feedback-1623): 修复共享 market review lock 释放后仍不生成匹配上下文的行为风险,并同步收敛 PR description 的实际范围

* fix(review-feedback-1623): 修复锁竞争 fallback 下丢失运行时服务的问题,并同步收敛 PR description 与实际 diff 范围

* fix(review-feedback-1623): 收敛 PR description 与实际改动范围

* fix(review-feedback-1623): PR 描述与实际 diff 存在实质性矛盾:描述声称提供独立 API、Web

* fix(review-feedback-1623): reuse runtime market context and handle English negations

* fix: honor daily market context config

* docs: remove unrelated changelog entries

* fix(review-feedback-1623): preserve the skipped market-review artifact

* fix(review-feedback-1623): add low position cap and are not in CONSERVATIVE TEXT MARKERS , so an
2026-06-13 10:33:04 +08:00