Skip to content

Commit bd68b8f

Browse files
yjwyjw
authored andcommitted
Release young-stock-cli 0.3.7
1 parent 7cba049 commit bd68b8f

18 files changed

Lines changed: 573 additions & 113 deletions

CHANGELOG.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,46 @@
11
# Changelog
22

3+
## [0.3.7] - 2026-06-24
4+
5+
### Fixed
6+
7+
- Add explicit expert naming rules for specific `--lens` reports, including expert-specific title text and the final holding-advice heading.
8+
- Clarify `young config models --list` in README as the preferred way for Coding Plan and multi-model users to find chat-callable model IDs.
9+
- Relax `stock --llm` mechanical checks so natural single-stock reports are not blocked only because they use rating/action wording instead of fixed attitude words.
10+
- Keep `numbers_grounded` advisory for LLM reports after repair; unsupported numeric claims remain visible in metadata but no longer block otherwise complete reports.
11+
12+
## [0.3.6] - 2026-06-24
13+
14+
### Changed
15+
16+
- Replace the old quote-only `young stock` command with the former deterministic/deep single-stock analysis flow; `young analyze` is no longer registered.
17+
- Add query date and current market-stage context to query command output.
18+
19+
### Fixed
20+
21+
- Remove the invalid research-bridge setup hint from empty enhanced-evidence output and diagnostics.
22+
- Respect `--no-news` in rich single-stock extras by skipping social/event lookups while keeping quote, LHB, financial, and technical evidence paths.
23+
24+
## [0.3.5] - 2026-06-24
25+
26+
### Fixed
27+
28+
- Make `young config models --list` verify actual `chat/completions` availability before displaying model IDs, so catalog-only or inaccessible Ark models are hidden.
29+
30+
## [0.3.4] - 2026-06-24
31+
32+
### Fixed
33+
34+
- Filter non-chat and `status=Shutdown` Ark model catalog entries from `young config models --list`, and clarify model-unavailable errors when a raw catalog ID is not callable.
35+
36+
## [0.3.3] - 2026-06-24
37+
38+
### Fixed
39+
40+
- Relax LLM report mechanical checks for normal market-report wording, including common index names and localized full dates.
41+
- Accept formal daily-report synonyms such as 综合判断、综合持仓建议 and 下一交易日跟踪 without weakening unsupported financial-number checks.
42+
- Treat `numbers_grounded` as an advisory metadata check after repair instead of blocking otherwise valid LLM daily reports.
43+
344
## [0.3.2] - 2026-06-24
445

546
### Changed

README.md

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
- 默认走 HTTP-only 公共数据路径。
1919
- 浏览器兜底只在显式开关下启用。
2020
- `young daily` 的默认模式不需要 LLM。
21-
- young analyze <symbol> 默认确定性数据源;young analyze <symbol> --llm 才深度复盘;只有显式 `--lens` 才会进入 lens。
21+
- young stock <symbol> 默认确定性数据源;young stock <symbol> --llm 才深度复盘;只有显式 `--lens` 才会进入 lens。
2222
- young daily 默认确定性数据源;young daily --llm 才深度复盘;只有显式 `--lens` 才会进入 lens。
2323
- 缺失的数据保持缺失,不把空值硬写成零。
2424

@@ -39,6 +39,8 @@ young report
3939
young send
4040
```
4141

42+
如果你使用 Kimi Coding Plan、火山方舟 Ark 等 OpenAI-compatible 供应商,先配置 API key,再用 `young config models --list` 查询当前账号真正可用于 `daily --llm` / `stock --llm` 的 chat 模型;列表会过滤目录里有但不可调用的模型。
43+
4244
如果你用的是普通 Python 环境:
4345

4446
```bash
@@ -49,7 +51,7 @@ young init
4951
## 这套输出到底保证什么
5052

5153
- `young daily` 默认是确定性的 watchlist 日报,不依赖模型。
52-
- `young daily --llm``young analyze <symbol>` 才会进入证据驱动深度复盘。
54+
- `young daily --llm``young stock <symbol> --llm` 才会进入证据驱动深度复盘。
5355
- `young report` 只负责把最新已保存 Markdown 导出成 PDF,不会主动再跑一遍 LLM。
5456
- `young send` 只发送最新 Markdown 和摘要;同名 PDF 存在时才会附带。
5557
- `young config show` 会遮蔽密钥。
@@ -62,9 +64,9 @@ young init
6264
| Scope | Commands | Notes |
6365
| --- | --- | --- |
6466
| Market snapshots | `young a`, `young hk`, `young us`, `young global`, `young indices`, `young zt-pool`, `young flow` | `--refresh` bypasses cache; `--browser-fallback` is explicit. |
65-
| Single-symbol evidence | `young stock <symbol>`, `young lhb <symbol>`, `young fund <code>`, `young news 3690.HK` | `young stock` can show quote/news plus financial, social, event, and technical fallback evidence. |
67+
| Single-symbol evidence | `young stock <symbol>`, `young stock <symbol> --llm`, `young lhb <symbol>`, `young fund <code>`, `young news 3690.HK` | Plain `stock` is deterministic; add `--llm` for deep replay. `--no-news` skips news/social/event lookups where supported. |
6668
| Watchlist reports | `young daily --format summary`, `young daily --format key-points`, `young daily --format full`, `young daily --llm`, `young daily --llm --lens ...` | Plain `daily` is deterministic; `--llm` is the only deep replay entry, and `--lens` only applies when you explicitly ask for it. |
67-
| Deep analysis | `young analyze <symbol>`, `young analyze <symbol> --llm`, `young analyze <symbol> --llm --lens ...` | Plain `analyze` is deterministic; `--llm` is the deep replay entry, and `--lens` only applies when explicitly provided. |
69+
| Deep analysis | `young stock <symbol> --llm`, `young stock <symbol> --llm --lens ...` | `stock --llm` is the single-symbol deep replay entry, and `--lens` only applies when explicitly provided. |
6870
| Export & delivery | `young report`, `young send` | `report` exports PDF only; `send` uses configured channels. |
6971
| Local state | `young profile ...`, `young portfolio ...`, `young memory ...`, `young style ...` | Profiles drive reports; portfolio is a lightweight local sandbox; memory is chat memory. |
7072
| Config & support | `young config ...`, `young diagnose`, `young init`, `young guide`, `young example`, `young cache-clear`, `young update`, `young uninstall`, `young chat` | `young update/uninstall` mirror the installation path you chose. |
@@ -130,15 +132,15 @@ The default data path is built around public no-login sources. In practice, youn
130132

131133
## Method cards
132134

133-
Method cards are structural lenses, not scores. They exist to help `daily --llm` and `analyze` keep the same decision discipline.
135+
Method cards are structural lenses, not scores. They exist to help `daily --llm` and `stock --llm` keep the same decision discipline.
134136

135137
- Valuation: `DCF-lite`, `Reverse DCF`, `Comps`, `LBO-lite`, `3-statement-lite`, `SOTP-lite`
136138
- Research: `财报解读`, `业绩前瞻`, `催化剂日历`, `投资逻辑追踪`, `行业综述`, `新闻情绪归因`, `持仓风险复盘`
137139
- Decision: `IC Memo`, `Due Diligence checklist`, `Porter Five Forces`, `Unit Economics`, `VCP`, `Rebalancing Review`
138140

139141
## Daily framework: M1–M7
140142

141-
`young daily --llm``young analyze <symbol>` 共享同一套七段结构。
143+
`young daily --llm``young stock <symbol> --llm` 共享同一套七段结构。
142144

143145
| Module | Question it answers |
144146
| --- | --- |
@@ -210,6 +212,8 @@ young portfolio compare 600519 000858
210212
支持的 provider 包括 `openai``ark``kimi``moonshot``deepseek``qwen``ollama``anthropic`
211213

212214
保存或更新模型配置时必须指定 `--model`;不带 `--model` 时只允许用 `--list` 查询模型 ID,不会写入配置。
215+
`--list` 面向 `young daily --llm` / `young stock --llm` 这类 chat 工作流,会过滤 Ark 等服务返回的 `status=Shutdown` 目录项以及纯 embedding、图片、视频生成等非文本生成模型,并对候选模型做一次最小 `chat/completions` 探测;因此它比单纯查询 `/models` 慢,但只展示当前实际可调用的模型。
216+
这对使用 Coding Plan 或多模型网关的用户尤其重要:供应商控制台或 `/models` 返回的 ID 可能只是目录项,只有 `young config models --list` 通过探测后显示的模型,才适合作为 `--model``--fallback-model`
213217

214218
```bash
215219
export OPENAI_API_KEY="..."
@@ -229,9 +233,9 @@ curl -sS "$API_BASE/models" \
229233
python3 -c 'import json,sys; print("\n".join(x["id"] for x in json.load(sys.stdin).get("data", [])))'
230234
```
231235

232-
Kimi Coding Plan (`https://api.kimi.com/coding/v1`, `kimi-for-coding`) 仅支持 Kimi Code CLI、Claude Code、Roo Code 等 Coding Agents,不适用于 `young daily --llm``young chat``young analyze --llm` 这类投研/问答工作流。请改用 Kimi OpenPlatform 通用 API 或其他 OpenAI-compatible 模型。
236+
Kimi Coding Plan (`https://api.kimi.com/coding/v1`, `kimi-for-coding`) 仅支持 Kimi Code CLI、Claude Code、Roo Code 等 Coding Agents,不适用于 `young daily --llm``young chat``young stock --llm` 这类投研/问答工作流。请改用 Kimi OpenPlatform 通用 API 或其他 OpenAI-compatible 模型。
233237

234-
同一个 endpoint 需要回退模型时,可以用 `young config models ... --fallback-model X --fallback-model Y` 这样配置。只在限流、额度、瞬时服务错误或明确模型不可用时切换;认证、generic404、api_base 错误不切换。Ark 先用 `--list` 核对 model ID,即 `young config models --provider ark --list`,再填 `--model``--fallback-model`
238+
同一个 endpoint 需要回退模型时,可以用 `young config models ... --fallback-model X --fallback-model Y` 这样配置。只在限流、额度、瞬时服务错误或明确模型不可用时切换;认证、generic404、api_base 错误不切换。Ark 先用 `--list` 核对 model ID,即 `young config models --provider ark --list`,再填 `--model``--fallback-model``--list` 会过滤到 chat 可调用范围,不要直接使用 raw `/models``status=Shutdown` 的模型目录项
235239

236240
Migration notes:
237241

@@ -252,8 +256,7 @@ Migration notes:
252256
| CLI | Chat slash |
253257
| --- | --- |
254258
| `young a` | `/a` |
255-
| `young stock <symbol>` | `/stock <symbol>` |
256-
| `young analyze <symbol>` | `/analyze <symbol> [--llm] [--lens ...]` |
259+
| `young stock <symbol> [--llm] [--lens ...]` | `/stock <symbol> [--llm] [--lens ...]` |
257260
| `young fund <code>` | `/fund <code>` |
258261
| `young news 3690.HK` | `/news <query>` |
259262
| `young daily --llm` | `/daily [--llm] [--lens ...]` |
@@ -317,7 +320,7 @@ young uninstall
317320
A: No. Plain `young daily` is deterministic.
318321

319322
**Q: When should I use `--llm`?**
320-
A: When you want the deep M1–M7 replay or a single-stock deep analysis. Plain `young daily` and `young analyze <symbol>` stay deterministic unless you explicitly add `--llm`.
323+
A: When you want the deep M1–M7 replay or a single-stock deep analysis. Plain `young daily` and `young stock <symbol>` stay deterministic unless you explicitly add `--llm`.
321324

322325
**Q: Can it use a browser automatically?**
323326
A: No. Browser fallback stays explicit.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "young-stock-cli"
7-
version = "0.3.2"
7+
version = "0.3.7"
88
description = "A-share (China stock market) after-hours CLI — no login, no scraping tricks, just data."
99
readme = "README.md"
1010
requires-python = ">=3.9"

src/young_stock/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""young-stock-cli: A-share after-hours CLI."""
22

3-
__version__ = "0.3.2"
3+
__version__ = "0.3.7"

src/young_stock/_core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2309,7 +2309,7 @@ def futu_news_search(keyword: str, size: int = 10, lang: str = "en", news_type:
23092309
})
23102310
url = f"{FUTU_NEWS_URL}?{params}"
23112311
try:
2312-
req = urllib.request.Request(url, headers={"User-Agent": "young-stock-cli/0.3.2"})
2312+
req = urllib.request.Request(url, headers={"User-Agent": "young-stock-cli/0.3.7"})
23132313
with urllib.request.urlopen(req, timeout=10) as resp:
23142314
return json.loads(resp.read().decode())
23152315
except Exception as e:
@@ -2322,7 +2322,7 @@ def futu_stock_feed(keyword: str, size: int = 30) -> dict[str, Any]:
23222322
params = urllib.parse.urlencode({"keyword": keyword, "size": size})
23232323
url = f"{FUTU_FEED_URL}?{params}"
23242324
try:
2325-
req = urllib.request.Request(url, headers={"User-Agent": "young-stock-cli/0.3.2"})
2325+
req = urllib.request.Request(url, headers={"User-Agent": "young-stock-cli/0.3.7"})
23262326
with urllib.request.urlopen(req, timeout=10) as resp:
23272327
return json.loads(resp.read().decode())
23282328
except Exception as e:

src/young_stock/chat.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@
5454
**chat_style_profiles(),
5555
}
5656
READ_ONLY_SLASH_HELP = (
57-
"可用命令:/a、/stock <symbol>、/analyze <symbol> [--llm] [--lens ...]、/fund <code>、/news <query>、/daily [--llm] [--lens ...]、/report(仅导出 PDF)、/send、"
57+
"可用命令:/a、/stock <symbol> [--llm] [--lens ...]、/fund <code>、/news <query>、/daily [--llm] [--lens ...]、/report(仅导出 PDF)、/send、"
5858
"/profile list、/memory show、/memory clear、/style、/style list、/style set <name>、"
5959
"/style show、/style clear、/diagnose、/help、/clear、/exit。"
6060
)
6161
SUPPORTED_SLASH_FOR_PROMPT = (
62-
"/a, /stock <symbol>, /analyze <symbol> [--llm] [--lens ...], /fund <code>, /news <query>, /daily [--llm] [--lens ...], /report (PDF export only), /send, "
62+
"/a, /stock <symbol> [--llm] [--lens ...], /fund <code>, /news <query>, /daily [--llm] [--lens ...], /report (PDF export only), /send, "
6363
"/profile list, /memory show, /memory clear, /style, /style list, /style set <name>, "
6464
"/style show, /style clear, /diagnose, /help, /clear, /exit"
6565
)
@@ -565,7 +565,7 @@ def _build_messages(self, extra_system_messages: list[str] | None = None) -> lis
565565
"2) 未提供 Evidence Pack 时,不得编造实时行情、涨跌幅、资金流、新闻细节或结论。"
566566
"3) 用户问“今天市场怎么样”“大盘如何”等泛问题时,优先引导 /a 或 /daily。"
567567
"4) 用户要做单只股票深入分析、但你缺少足够证据时,不要直接拒绝;"
568-
"优先使用已有的 /stock <symbol>、/analyze <symbol> 或已注入的外部检索证据继续分析。"
568+
"优先使用已有的 /stock <symbol> 或已注入的外部检索证据继续分析。"
569569
"5) 如果本轮已经完成外部检索,就直接总结结果,不要要求用户自己再执行额外检索命令。"
570570
"6) /daily --llm 的深度复盘必须严格遵循 young 的 M1-M7 框架;专家视角只约束 M7,不得改写 M1-M6。"
571571
"7) 风格与长期记忆都服从本安全规则。"
@@ -622,7 +622,7 @@ def _handle_style_slash(self, args: list[str]) -> bool:
622622

623623
def _resolve_click_args(self, args: list[str]) -> tuple[list[str] | None, str | None]:
624624
root = args[0]
625-
if root in {"a", "stock", "analyze", "fund", "news", "daily", "report", "diagnose", "send"}:
625+
if root in {"a", "stock", "fund", "news", "daily", "report", "diagnose", "send"}:
626626
return args, None
627627
if root == "profile":
628628
if len(args) >= 2 and args[1] in {"list", "show"}:

0 commit comments

Comments
 (0)