mirror of
https://github.com/ZhuLinsen/daily_stock_analysis
synced 2026-09-20 10:53:33 +08:00
docs: close analysis context pack P6 (#1592)
This commit is contained in:
@@ -623,6 +623,10 @@ SQLITE_WRITE_RETRY_MAX=3
|
||||
# SQLite 写入重试基础退避时间(秒,按指数退避递增)
|
||||
SQLITE_WRITE_RETRY_BASE_DELAY=0.1
|
||||
|
||||
# 分析历史快照:设为 false 时不持久化整份 context_snapshot
|
||||
# 包括 enhanced_context、market_phase_summary、AnalysisContextPack overview、diagnostics 和 raw snapshot 字段
|
||||
SAVE_CONTEXT_SNAPSHOT=true
|
||||
|
||||
# ===================================
|
||||
# 回测配置(可选)
|
||||
# ===================================
|
||||
|
||||
@@ -962,6 +962,18 @@ const settingsHelpZhCN: SettingsHelpMap = {
|
||||
impact: ['影响分析总耗时。'],
|
||||
notes: ['总耗时 ≈ 股票数 × 单股耗时 + (股票数-1) × ANALYSIS_DELAY。'],
|
||||
},
|
||||
'settings.system.SAVE_CONTEXT_SNAPSHOT': {
|
||||
title: '保存分析上下文快照',
|
||||
summary: '控制是否将分析历史的整份 context_snapshot 持久化到数据库。',
|
||||
usage: '默认开启。关闭后,新历史记录不会保存 enhanced_context、market_phase_summary、AnalysisContextPack overview 或运行诊断快照等 context_snapshot 内容。',
|
||||
valueNotes: [
|
||||
'关闭后,新历史记录的历史详情、completed 任务状态和 Web 报告页无法读取低敏输入数据块摘要。',
|
||||
'该开关不关闭当次 AnalysisContextPack 构建,也不关闭 LLM Prompt 中的低敏 pack summary。',
|
||||
'CLI 的 --no-context-snapshot 与设为 false 的持久化效果一致。',
|
||||
],
|
||||
impact: ['影响历史透明度、回测/诊断可用的上下文快照信息和 Web 报告页的数据来源摘要。'],
|
||||
notes: ['若需要完全关闭 P3-P5 pack 接入,需要回滚相关代码;当前没有运行时 pack 总开关。'],
|
||||
},
|
||||
'settings.system.market_review': {
|
||||
title: '大盘分析',
|
||||
summary: '控制大盘分析功能的开关、覆盖市场和配色方案。',
|
||||
@@ -1876,6 +1888,18 @@ const settingsHelpEnUS: SettingsHelpMap = {
|
||||
impact: ['Affects total analysis time.'],
|
||||
notes: ['Total time ≈ stock count × per-stock time + (count-1) × ANALYSIS_DELAY.'],
|
||||
},
|
||||
'settings.system.SAVE_CONTEXT_SNAPSHOT': {
|
||||
title: 'Save Context Snapshot',
|
||||
summary: 'Controls whether the full analysis history context_snapshot is persisted to the database.',
|
||||
usage: 'Enabled by default. When disabled, new history records do not persist enhanced_context, market_phase_summary, AnalysisContextPack overview, diagnostic snapshots, or other context_snapshot content.',
|
||||
valueNotes: [
|
||||
'When disabled, history detail, completed task status, and Web report pages cannot read low-sensitivity input-block summaries from persisted records.',
|
||||
'This switch does not disable AnalysisContextPack construction for the current run and does not remove the low-sensitivity pack summary from LLM prompts.',
|
||||
'The CLI --no-context-snapshot flag has the same persistence effect as setting this to false.',
|
||||
],
|
||||
impact: ['Affects historical transparency, diagnostics that rely on context snapshots, and Web report data-source summaries.'],
|
||||
notes: ['To disable the P3-P5 pack integration itself, roll back the related code; there is no runtime pack master switch.'],
|
||||
},
|
||||
'settings.system.market_review': {
|
||||
title: 'Market Review',
|
||||
summary: 'Controls the market review feature: on/off, coverage region, and color scheme.',
|
||||
|
||||
@@ -132,6 +132,7 @@ const fieldTitleMap: Record<string, string> = {
|
||||
MARKET_REVIEW_REGION: '大盘复盘市场',
|
||||
MARKET_REVIEW_COLOR_SCHEME: '大盘复盘涨跌颜色',
|
||||
ANALYSIS_DELAY: '分析启动延迟(秒)',
|
||||
SAVE_CONTEXT_SNAPSHOT: '保存分析上下文快照',
|
||||
SCHEDULE_TIME: '定时任务时间',
|
||||
DEBUG: '调试模式',
|
||||
HTTP_PROXY: 'HTTP 代理',
|
||||
@@ -278,6 +279,7 @@ const fieldDescriptionMap: Record<string, string> = {
|
||||
MARKET_REVIEW_REGION: '大盘复盘默认市场区域(如 cn/us/hk)。',
|
||||
MARKET_REVIEW_COLOR_SCHEME: '控制大盘复盘指数涨跌幅图标颜色:green_up 为绿涨红跌,red_up 为红涨绿跌。',
|
||||
ANALYSIS_DELAY: '启动任务前的延迟秒数,可用于等待依赖服务就绪。',
|
||||
SAVE_CONTEXT_SNAPSHOT: '控制是否持久化整份分析历史 context_snapshot;关闭后不会保存低敏输入概览、市场阶段摘要和增强上下文,但不影响当次分析的 pack 构建或 Prompt 摘要。',
|
||||
SCHEDULE_TIME: '每日定时任务执行时间,格式为 HH:MM。',
|
||||
DEBUG: '启用调试模式,输出更多诊断日志。',
|
||||
HTTP_PROXY: '网络代理地址,可留空。',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { getSettingsHelpContent } from '../src/locales/settingsHelp';
|
||||
import { getFieldDescriptionZh, getFieldOptionLabelZh, getFieldTitleZh } from '../src/utils/systemConfigI18n';
|
||||
|
||||
const requiredLocalizedKeys = [
|
||||
@@ -65,6 +66,7 @@ const requiredLocalizedKeys = [
|
||||
'MARKET_REVIEW_ENABLED',
|
||||
'MARKET_REVIEW_REGION',
|
||||
'ANALYSIS_DELAY',
|
||||
'SAVE_CONTEXT_SNAPSHOT',
|
||||
'DEBUG',
|
||||
'AGENT_NL_ROUTING',
|
||||
'AGENT_DEEP_RESEARCH_BUDGET',
|
||||
@@ -139,3 +141,21 @@ describe('systemConfigI18n option label localization', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('SAVE_CONTEXT_SNAPSHOT settings help contract', () => {
|
||||
it('describes the persistence boundary without implying old records are changed', () => {
|
||||
const help = getSettingsHelpContent('settings.system.SAVE_CONTEXT_SNAPSHOT', undefined, 'zh-CN');
|
||||
const text = [
|
||||
help?.summary,
|
||||
help?.usage,
|
||||
...(help?.valueNotes ?? []),
|
||||
...(help?.impact ?? []),
|
||||
...(help?.notes ?? []),
|
||||
].join('\n');
|
||||
|
||||
expect(text).toContain('新历史记录');
|
||||
expect(text).toContain('不关闭当次 AnalysisContextPack 构建');
|
||||
expect(text).toContain('不关闭 LLM Prompt');
|
||||
expect(text).not.toContain('旧记录');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
|
||||
<!-- 每条独立一行追加到本段末尾,无需分类标题,合并时冲突最小 -->
|
||||
- [改进] #1386 P6 复用市场阶段与 AnalysisContextPack 公开摘要联动告警、持仓手动分析、历史、回测和通知展示,不新增数据库迁移。
|
||||
|
||||
- [文档] 明确 AnalysisContextPack P6 文档、迁移与回滚边界,并同步既有 `SAVE_CONTEXT_SNAPSHOT` 到 `.env.example`、配置注册表、Web 设置帮助和完整指南。
|
||||
|
||||
## [3.20.0] - 2026-06-03
|
||||
|
||||
### 发布亮点
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
| [Bot 命令与接入](bot-command.md) | Bot 命令、Webhook、平台接入和回调说明 |
|
||||
| [Bot 平台配置](bot/) | 飞书、钉钉、Discord 等 Bot 配置截图和补充说明 |
|
||||
| [实时告警中心](alerts.md) | EventMonitor 基线、Web 规则管理、通知结果、冷却状态和 Phase 边界 |
|
||||
| [分析上下文包契约、运行态消费与可见性](analysis-context-pack.md) | AnalysisContextPack 首版范围、字段质量状态、P1/P2 内部契约、P3 Prompt 摘要消费、P4 历史/API/Web 低敏可见性、P5 数据质量评分与源码锚点 |
|
||||
| [分析上下文包契约、运行态消费与可见性](analysis-context-pack.md) | AnalysisContextPack 首版范围、字段质量状态、P1/P2 内部契约、P3 Prompt 摘要消费、P4 历史/API/Web 低敏可见性、P5 数据质量评分、P6 迁移回滚与源码锚点 |
|
||||
| [图片识别 Prompt](image-extract-prompt.md) | 图片识别股票信息的 Prompt 与使用边界 |
|
||||
| [OpenClaw Skill 集成](openclaw-skill-integration.md) | OpenClaw / Skill 外部集成说明 |
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ This is the entry point for project documentation. The README covers the project
|
||||
| [Bot Commands (EN)](bot-command_EN.md) | Bot commands, webhooks, platform integration, and callback behavior |
|
||||
| [Bot Platform Docs](bot/) <sub><sub></sub></sub> (Chinese-only) | Feishu, DingTalk, Discord, and related Bot configuration screenshots and notes |
|
||||
| [Real-Time Alert Center](alerts.md) <sub><sub></sub></sub> (Chinese-only) | EventMonitor baseline, Web rule management, notification attempts, cooldown state, and phase boundaries |
|
||||
| [Analysis Context Pack Contract, Runtime Consumption, And Visibility](analysis-context-pack.md) <sub><sub></sub></sub> (Chinese-only) | AnalysisContextPack first-scope boundaries, field quality states, P1/P2 internal contracts, P3 prompt-summary consumption, P4 history/API/Web low-sensitivity visibility, P5 data-quality scoring, and source anchors |
|
||||
| [Analysis Context Pack Contract, Runtime Consumption, And Visibility](analysis-context-pack.md) <sub><sub></sub></sub> (Chinese-only) | AnalysisContextPack first-scope boundaries, field quality states, P1/P2 internal contracts, P3 prompt-summary consumption, P4 history/API/Web low-sensitivity visibility, P5 data-quality scoring, and P6 migration/rollback notes, plus source anchors |
|
||||
| [Image Extraction Prompt](image-extract-prompt.md) <sub><sub></sub></sub> (Chinese-only) | Prompt and boundaries for extracting stock information from images |
|
||||
| [OpenClaw Skill Integration](openclaw-skill-integration.md) <sub><sub></sub></sub> (Chinese-only) | OpenClaw / Skill external integration notes |
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# AnalysisContextPack:P0 盘点、P1/P2 契约、P3 Runtime Consumption、P4 可见性、P5 数据质量与 P6 联动
|
||||
# AnalysisContextPack:P0 盘点、P1/P2 契约、P3 Runtime Consumption、P4 可见性、P5 数据质量、#1386 P6 联动与 #1389 P6 迁移回滚
|
||||
|
||||
本页是 Issue #1389 的专题文档,用于记录当前 DSA 分析上下文的真实来源、消费路径、字段状态边界,以及 `AnalysisContextPack` 内部契约、builder、运行态消费、低敏可见性和数据质量评分边界。P0 负责现状盘点和契约边界;P1 只新增内部 schema/envelope、block catalog、类型约定和脱敏序列化;P2 只从 pipeline 已有 artifacts 组装 pack;P3 只把低敏摘要接入普通分析和 Agent 初始 Prompt;P4 只把低敏 overview 接入历史详情、同步分析响应、completed task status 和 Web 报告页;P5 在同一 `PACK_VERSION = "1.0"` 内补齐数据质量评分、`fetch_failed` 状态、Prompt 数据限制和 overview 低敏展示;#1386 P6 复用同一公开 overview 做告警、持仓、历史、回测和通知联动,并在手动持仓分析时加入可选辅助 `portfolio` block。
|
||||
本页是 Issue #1389 的专题文档,用于记录当前 DSA 分析上下文的真实来源、消费路径、字段状态边界,以及 `AnalysisContextPack` 内部契约、builder、运行态消费、低敏可见性、数据质量评分、告警/持仓/历史/回测联动、迁移和回滚边界。P0 负责现状盘点和契约边界;P1 只新增内部 schema/envelope、block catalog、类型约定和脱敏序列化;P2 只从 pipeline 已有 artifacts 组装 pack;P3 只把低敏摘要接入普通分析和 Agent 初始 Prompt;P4 只把低敏 overview 接入历史详情、同步分析响应、completed task status 和 Web 报告页;P5 在同一 `PACK_VERSION = "1.0"` 内补齐数据质量评分、`fetch_failed` 状态、Prompt 数据限制和 overview 低敏展示;#1386 P6 复用同一公开 overview 做告警、持仓、历史、回测和通知联动,并在手动持仓分析时加入可选辅助 `portfolio` block;#1389 P6 只补齐文档、配置可见性、迁移和回滚说明,不新增 pack runtime、pack feature flag、DB migration 或 schema 版本。
|
||||
|
||||
## 术语与边界
|
||||
|
||||
@@ -109,12 +109,12 @@ P4 把 P3 已构建的 `AnalysisContextPack` 投影为公共低敏 `analysis_con
|
||||
|
||||
overview 不输出 `blocks.*.items`、`items.value`、`news.content`、`trend_result`、`chip`、`fundamental_context` 原始 payload,也不输出 `api_key`、`token`、`cookie`、`webhook_url`、`password`、`secret`、`authorization`、`sendkey`、`license_key` 等敏感键或值。
|
||||
|
||||
P4 持久化面只在 `analysis_history.context_snapshot` 顶层写入 `analysis_context_pack_overview`。运行态 prompt 字段仍会从 `enhanced_context` 和 history snapshot 中剥离:`market_phase_context`、`analysis_context_pack`、`analysis_context_pack_summary` 不进入公开历史详情或任务状态。`SAVE_CONTEXT_SNAPSHOT=false` 时不持久化 overview,旧记录或缺少 overview 的记录继续返回空字段,不影响历史详情读取。
|
||||
P4 持久化面只在 `analysis_history.context_snapshot` 顶层写入 `analysis_context_pack_overview`。运行态 prompt 字段仍会从 `enhanced_context` 和 history snapshot 中剥离:`market_phase_context`、`analysis_context_pack`、`analysis_context_pack_summary` 不进入公开历史详情或任务状态。`SAVE_CONTEXT_SNAPSHOT=false` 时不持久化整份 `analysis_history.context_snapshot`,因此也不会落库 overview、`market_phase_summary`、`enhanced_context` 或 raw snapshot 字段;旧记录或缺少 overview 的记录继续返回空字段,不影响历史详情读取。
|
||||
|
||||
公共 API 字段固定为 `report.details.analysis_context_pack_overview`,Web 端经深度 camelCase 后读取 `analysisContextPackOverview`。接线面包括:
|
||||
|
||||
- `GET /api/v1/history/{record_id}` 历史详情。
|
||||
- 同步 `POST /api/v1/analysis/analyze` 返回的 `AnalysisResultResponse.report.details`。
|
||||
- 同步 `POST /api/v1/analysis/analyze` 返回的 `AnalysisResultResponse.report.details`,但 overview 依赖已持久化的 `analysis_history.context_snapshot`;`SAVE_CONTEXT_SNAPSHOT=false` 时,新记录不保证返回 overview。
|
||||
- completed `GET /api/v1/analysis/status/{task_id}`,包括内存队列 enrichment 和 DB completed fallback。
|
||||
|
||||
API 返回给 Web 的 `details.context_snapshot` 会通过 `sanitize_context_snapshot_for_api()` 剥离顶层 `analysis_context_pack_overview`,避免 raw snapshot 面板重复展示或被当作完整上下文导出;overview 只从 `extract_analysis_context_pack_overview()` 单独取出。Agent 路径与普通分析路径写入同一 overview 形状,Agent 无新闻计数时 `metadata.news_result_count` 可为空。
|
||||
@@ -156,6 +156,55 @@ overview 只扩展现有公开面:`analysis_context_pack_overview.data_quality
|
||||
- 回测 phase filter 只基于公开 summary 做 bucket:`premarket` 保持 premarket,`intraday|lunch_break|closing_auction` 归入 intraday,`postmarket` 保持 postmarket,`non_trading|missing|invalid` 归入 unknown。带 phase 过滤时 repository 先按 SQL 条件批量读取结果和 snapshot,服务层 bucket 后再分页和统计,避免 API 层分页后临时过滤。
|
||||
- 通知摘要只消费 `market_phase_summary` 与 `analysis_context_pack_overview.data_quality`,输出阶段、trigger source、partial-bar warning、质量等级和前两条 limitations;不输出 raw pack、`analysis_context_pack_summary` Prompt 字符串、新闻正文或持仓敏感细节。
|
||||
|
||||
## P6 文档、迁移与回滚
|
||||
|
||||
P6 不改变 P1-P5 的运行时行为,只把已经落地的契约、可见性、配置、迁移和回滚边界写成稳定文档。它不新增 pack enable/disable feature flag,不升级 `PACK_VERSION = "1.0"`,不新增 API 参数,不改变报告 JSON schema,也不做数据库迁移。
|
||||
|
||||
四个数据面必须分开理解:
|
||||
|
||||
| 数据面 | 位置 | 可见性 | P6 边界 |
|
||||
| --- | --- | --- | --- |
|
||||
| 内部完整 pack | `AnalysisContextPack` / `AnalysisContextBuilder` 产物 | 仅内部运行态使用 | 不作为公共 API,不写入历史,不承诺外部稳定 wire contract。 |
|
||||
| LLM 低敏摘要 | `analysis_context_pack_summary` | 普通分析、single Agent、multi-agent Prompt | 只包含 subject、pack version、block status/source/warnings/missing reason、新闻结果数和数据限制;不包含 `items.value`、新闻正文、趋势/筹码/基本面 raw payload、secret、token 或 webhook。 |
|
||||
| 公共低敏 overview | `report.details.analysis_context_pack_overview` | 历史详情、同步分析响应、completed task status、Web 报告页 | 只输出白名单字段和 `data_quality` 低敏评分;不输出完整 pack、Prompt summary 或 raw payload。 |
|
||||
| 历史上下文快照 | `analysis_history.context_snapshot` | 持久化后供历史/API/Web/诊断读取 | `details.context_snapshot` 经 `sanitize_context_snapshot_for_api()` 剥离 `analysis_context_pack_overview` 和 `market_phase_summary`,避免 raw 面板重复公开稳定摘要。 |
|
||||
|
||||
摘要可见性矩阵:
|
||||
|
||||
| 消费面 | 暴露内容 | 不暴露内容 |
|
||||
| --- | --- | --- |
|
||||
| LLM Prompt | `analysis_context_pack_summary` 低敏状态摘要和数据限制 | 完整 pack、`items.value`、新闻正文、趋势/筹码/基本面 raw payload、secret/token/webhook |
|
||||
| `GET /api/v1/history/{record_id}` | `report.details.analysis_context_pack_overview` | 完整 pack、Prompt summary、raw `analysis_context_pack_overview` duplicate |
|
||||
| 同步 `POST /api/v1/analysis/analyze` | `report.details.analysis_context_pack_overview`,前提是本次历史已持久化 `analysis_history.context_snapshot` | 完整 pack、Prompt summary |
|
||||
| completed `GET /api/v1/analysis/status/{task_id}` | `status.result.report.details.analysis_context_pack_overview` | 完整 pack、Prompt summary |
|
||||
| Web 报告页 | 默认折叠的 `AnalysisContextSummary`,展示 block 状态、来源、缺失原因、质量分和限制 | 完整 pack、raw payload、Prompt summary |
|
||||
| raw `details.context_snapshot` | 剥离后的历史快照 | 顶层 `analysis_context_pack_overview`、`market_phase_summary` |
|
||||
| 通知、Bot、Desktop 专属展示 | P6 不新增专属展示 | 完整 pack、Prompt summary、raw payload |
|
||||
|
||||
字段质量状态全集保持为 `available`、`missing`、`not_supported`、`fallback`、`stale`、`estimated`、`partial`、`fetch_failed`。这些状态解释输入数据质量,不表示分析任务、告警、回测或通知投递本身成功或失败。
|
||||
|
||||
脱敏边界:
|
||||
|
||||
- 完整 `AnalysisContextPack` 不进入公共 API、Web、通知、Bot 或 Desktop 专属展示。
|
||||
- `AnalysisContextPack.to_safe_dict()` 只作为内部安全序列化 helper;公共 overview 仍必须通过 `render_analysis_context_pack_overview()` 投影。
|
||||
- `analysis_context_pack_summary` 与 overview 都不得输出 `items.value`、新闻正文、`trend_result`、`chip`、`fundamental_context` 原始 payload、API key、token、cookie、完整 webhook URL、邮箱密码、secret、authorization、sendkey 或 license key。
|
||||
- 已持久化 overview 再读取时必须经过 `extract_analysis_context_pack_overview()` / persisted sanitizer;API 透明度面板必须继续通过 `sanitize_context_snapshot_for_api()` 剥离顶层稳定摘要。
|
||||
|
||||
迁移边界:
|
||||
|
||||
- P6 不做 DB migration;旧历史记录缺少 `analysis_context_pack_overview` 或 `data_quality` 时返回空字段,报告仍正常读取。
|
||||
- `SAVE_CONTEXT_SNAPSHOT=true` 是默认行为,会继续把 `analysis_history.context_snapshot` 作为历史透明度和诊断来源持久化。
|
||||
- `SAVE_CONTEXT_SNAPSHOT=false` 或 CLI `--no-context-snapshot` 会停止持久化整份 `analysis_history.context_snapshot`;换言之,新历史不持久化整份 `analysis_history.context_snapshot`,包括 `enhanced_context`、`market_phase_summary`、`analysis_context_pack_overview`、`diagnostics`、`realtime_quote_raw` 和其他 raw snapshot 字段。
|
||||
- 关闭持久化不影响当次 `AnalysisContextPack` 构建、`analysis_context_pack_summary` 注入 Prompt,也不影响内存中的 `result.diagnostic_context_snapshot`。
|
||||
|
||||
回滚方式:
|
||||
|
||||
| 手段 | 作用 | 不能做什么 |
|
||||
| --- | --- | --- |
|
||||
| 发布或代码回滚 P3-P5 相关改动 | 移除 pack prompt summary、overview 和数据质量接入 | - |
|
||||
| `SAVE_CONTEXT_SNAPSHOT=false` 或 `--no-context-snapshot` | 停止保存新的历史 `context_snapshot`,从而不再从新历史公开 overview / phase summary / raw snapshot | 不能关闭当次 pack 构建或 LLM Prompt 中的低敏 summary |
|
||||
| 运行时 pack 总开关 | 当前不存在 | 不能通过 env 一键关闭 P3-P5 pack 接入;需要代码回滚或后续单独设计 |
|
||||
|
||||
## 字段质量状态
|
||||
|
||||
未来 pack 的字段质量状态在 P0 先固定七词;P5 在同一 1.0 umbrella 内追加 `fetch_failed`。它们描述字段或数据块的质量,不描述业务流程是否成功。
|
||||
|
||||
@@ -123,6 +123,7 @@ daily_stock_analysis/
|
||||
| `REPORT_INTEGRITY_RETRY` | 完整性校验重试次数(默认 `1`,`0` 表示仅占位不重试) | 可选 |
|
||||
| `REPORT_HISTORY_COMPARE_N` | 历史信号对比条数,`0` 关闭(默认),`>0` 启用 | 可选 |
|
||||
| `ANALYSIS_DELAY` | 个股分析和大盘分析之间的延迟(秒),避免API限流,如 `10` | 可选 |
|
||||
| `SAVE_CONTEXT_SNAPSHOT` | 是否保存分析历史 `context_snapshot`,默认 `true`;设为 `false` 或使用 `--no-context-snapshot` 时不持久化整份上下文快照 | 可选 |
|
||||
| `MERGE_EMAIL_NOTIFICATION` | 个股与大盘复盘合并推送(默认 false),减少邮件数量、降低垃圾邮件风险;与 `SINGLE_STOCK_NOTIFY` 互斥(单股模式下合并不生效) | 可选 |
|
||||
| `MARKDOWN_TO_IMAGE_CHANNELS` | 将 Markdown 转为图片发送的渠道(用逗号分隔):telegram,wechat,custom,email,slack;单股推送需同时配置且安装转图工具 | 可选 |
|
||||
| `NOTIFICATION_REPORT_CHANNELS` | report 路由渠道(单股推送、聚合日报、大盘复盘、合并推送等);留空表示所有已配置渠道 | 可选 |
|
||||
@@ -414,6 +415,7 @@ daily_stock_analysis/
|
||||
| `SCHEDULE_ENABLED` | 启用定时任务 | `false` |
|
||||
| `SCHEDULE_TIME` | 定时执行时间 | `18:00` |
|
||||
| `LOG_DIR` | 日志目录 | `./logs` |
|
||||
| `SAVE_CONTEXT_SNAPSHOT` | 保存分析历史 `context_snapshot`;设为 `false` 时新历史不保存 enhanced_context、market_phase_summary、AnalysisContextPack overview 或诊断快照,但不关闭当次 Prompt 低敏摘要 | `true` |
|
||||
|
||||
---
|
||||
|
||||
@@ -763,7 +765,7 @@ P1a 本身不改变 Prompt 文案、API/Web/Bot 参数、报告结构、history/
|
||||
|
||||
P1b 将 P1a 的 runtime `market_phase_context` 投影为稳定、低敏、可公开的 `market_phase_summary`,并写入 `analysis_history.context_snapshot` 顶层。历史详情、同步分析响应和 completed `/api/v1/analysis/status/{task_id}` 都通过 `report.meta.market_phase_summary` 返回同一份市场阶段元信息;completed 任务状态不新增 `TaskStatus` 顶层字段,只通过 `status.result.report.meta.market_phase_summary` 间接暴露。
|
||||
|
||||
`market_phase_summary` 只包含市场、阶段、市场本地时间、session date、effective daily-bar date、交易日/开市/partial-bar 标记、开收盘分钟数、触发来源、分析意图和 warning code。它不暴露完整 `market_phase_context`,也不加入 quote freshness、fallback、stale 或 data_quality scoring 字段。`report.details.analysis_context_pack_overview` 仍表示 #1389 输入数据块质量摘要;API 返回的 `details.context_snapshot` 会剥离顶层 `market_phase_summary` 和 `analysis_context_pack_overview`,避免 raw snapshot 重复展示这些稳定公开字段。`SAVE_CONTEXT_SNAPSHOT=false` 或旧历史记录缺少 summary 时字段为空,报告仍正常返回。
|
||||
`market_phase_summary` 只包含市场、阶段、市场本地时间、session date、effective daily-bar date、交易日/开市/partial-bar 标记、开收盘分钟数、触发来源、分析意图和 warning code。它不暴露完整 `market_phase_context`,也不加入 quote freshness、fallback、stale 或 data_quality scoring 字段。`report.details.analysis_context_pack_overview` 仍表示 #1389 输入数据块质量摘要;API 返回的 `details.context_snapshot` 会剥离顶层 `market_phase_summary` 和 `analysis_context_pack_overview`,避免 raw snapshot 重复展示这些稳定公开字段。`SAVE_CONTEXT_SNAPSHOT=false` 时不持久化整份 `analysis_history.context_snapshot`,旧历史记录缺少 summary 时字段为空,报告仍正常返回。
|
||||
|
||||
P1b 不改 Prompt、不新增 `analysis_phase` 请求参数、不做 Web 阶段标签或页面展示,也不覆盖 pending/processing TaskPanel、SSE 进行中事件、Bot、通知、`market_review` 或 P3 盘中数据质量字段。
|
||||
|
||||
@@ -803,9 +805,9 @@ P3 当时不新增 API/Web/Bot 参数,不写入 history/task status/report met
|
||||
|
||||
#### AnalysisContextPack 低敏可见性(Issue #1389 P4)
|
||||
|
||||
P4 新增 `report.details.analysis_context_pack_overview`,历史详情、同步分析响应和 completed `/api/v1/analysis/status/{task_id}` 都会返回同一份低敏 overview;Web 端报告页在“策略点位”和“资讯”之后展示默认折叠的数据块摘要,折叠头部展示可用数、缺失数、非零的其他状态计数和触发来源,展开后展示数据块状态、来源、warning、missing reason、状态计数和新闻结果数。API 返回的 `details.context_snapshot` 会剥离顶层 `analysis_context_pack_overview`,避免透明度面板重复展示 raw snapshot。
|
||||
P4 新增 `report.details.analysis_context_pack_overview`,历史详情和 completed `/api/v1/analysis/status/{task_id}` 会从已持久化的 `context_snapshot` 返回同一份低敏 overview;同步分析响应也会读取本次已落库的 `analysis_history.context_snapshot` 提取 overview,因此 `SAVE_CONTEXT_SNAPSHOT=false` 时新记录不保证返回该字段。Web 端报告页在“策略点位”和“资讯”之后展示默认折叠的数据块摘要,折叠头部展示可用数、缺失数、非零的其他状态计数和触发来源,展开后展示数据块状态、来源、warning、missing reason、状态计数和新闻结果数。API 返回的 `details.context_snapshot` 会剥离顶层 `analysis_context_pack_overview`,避免透明度面板重复展示 raw snapshot。
|
||||
|
||||
该 overview 不包含完整 pack、`analysis_context_pack_summary` Prompt 字符串、`items.value`、新闻正文、`trend_result`、筹码或基本面原始 payload。`SAVE_CONTEXT_SNAPSHOT=false` 或旧历史记录缺少 overview 时字段为空,报告仍正常返回。本阶段不覆盖 pending/processing TaskPanel、SSE 进行中事件、通知摘要、Bot/Desktop 专属展示、`market_review` overview 或数据质量评分。
|
||||
该 overview 不包含完整 pack、`analysis_context_pack_summary` Prompt 字符串、`items.value`、新闻正文、`trend_result`、筹码或基本面原始 payload。`SAVE_CONTEXT_SNAPSHOT=false` 时不持久化整份 `analysis_history.context_snapshot`,因此不会从新历史记录读取 overview;旧历史记录缺少 overview 时字段为空,报告仍正常返回。本阶段不覆盖 pending/processing TaskPanel、SSE 进行中事件、通知摘要、Bot/Desktop 专属展示、`market_review` overview 或数据质量评分。
|
||||
|
||||
#### AnalysisContextPack 数据质量评分与 Prompt 数据限制(Issue #1389 P5)
|
||||
|
||||
@@ -815,6 +817,14 @@ P5 在不修改 `PACK_VERSION = "1.0"`、不新增数据源和不改变报告 JS
|
||||
|
||||
历史详情、同步分析响应和 completed 任务状态继续只通过 `report.details.analysis_context_pack_overview` 暴露低敏字段;P5 只在该 overview 下新增 `data_quality`,包含 score、level、block_scores 和 limitations,不重复公开 `warnings`。Web 报告页仍默认折叠展示数据块摘要,折叠头部新增质量分/等级,展开后展示限制说明和 `fetch_failed` 状态;`details.context_snapshot` 继续剥离顶层 `analysis_context_pack_overview`。
|
||||
|
||||
#### AnalysisContextPack 文档、迁移与回滚(Issue #1389 P6)
|
||||
|
||||
P6 只做文档与配置可见性收口,不新增 pack runtime、不新增 pack enable/disable feature flag、不修改 `PACK_VERSION = "1.0"`、不新增 API 参数、不改变报告 JSON schema,也不做数据库迁移。完整契约、字段状态、低敏摘要可见性、脱敏边界、迁移和回滚说明见 [AnalysisContextPack 专题文档](analysis-context-pack.md)。
|
||||
|
||||
`SAVE_CONTEXT_SNAPSHOT` 是既有环境变量,P6 只是把它同步到 `.env.example`、配置注册表和 Web 设置帮助。默认 `true`;设为 `false` 或 CLI 使用 `--no-context-snapshot` 时,新历史记录不再持久化整份 `analysis_history.context_snapshot`,包括 `enhanced_context`、`market_phase_summary`、`analysis_context_pack_overview`、诊断快照和 raw snapshot 字段。该设置不关闭当次 `AnalysisContextPack` 构建,不移除 Prompt 中的低敏 `analysis_context_pack_summary`,也不改变分析结果 JSON schema 或 API 请求参数。
|
||||
|
||||
当前没有运行时 pack 总开关;如果需要关闭 P3-P5 的 pack Prompt 摘要、overview 或数据质量接入,只能通过发布回滚或代码回滚完成。旧历史记录没有 `analysis_context_pack_overview` / `data_quality` 时继续返回空字段,报告读取保持兼容。
|
||||
|
||||
#### 盘中决策护栏与质量校验(Issue #1386 P5)
|
||||
|
||||
P5 在个股分析报告的 `dashboard.phase_decision` 中追加阶段化决策字段:`phase_context`、`action_window`、`immediate_action`、`watch_conditions`、`next_check_time`、`confidence_reason` 和 `data_limitations`。该字段只作为报告 JSON 的向后兼容扩展进入历史 `raw_result`;不新增 `analysis_phase` API 参数、不改变 Web 阶段入口、不新增配置项,也不影响每日收盘复盘默认行为。
|
||||
@@ -1341,7 +1351,7 @@ FastAPI 提供 RESTful API 服务,支持配置管理和触发分析。
|
||||
> 说明:`GET /api/v1/history/{record_id}/diagnostics` 支持历史记录主键 ID 或 `query_id`,返回 `normal/degraded/failed/unknown` 摘要、关键链路组件和可复制的脱敏 `copy_text`;旧报告缺少诊断快照时返回 `unknown`,不影响报告读取。
|
||||
> 说明:`GET /api/v1/history` 的列表摘要可按 `stock_code` 分页查询同一股票历史,并返回趋势判断、分析摘要、模型名与分析时价格/涨跌幅等可选字段;旧记录缺少快照字段时返回空值。Web 报告页的“历史趋势”抽屉复用该接口加载同股历史。
|
||||
> 说明(Issue #1520):列表中的模型名展示字段仅来源于历史快照中的 `model_used`,仅用于历史回溯展示,不影响运行时模型模型路由(`litellm_model`、`llm_model_list`)、Provider、Base URL 与配置迁移/清理语义。回退方式为回退本次提交,现网历史查询/抽屉/接口链路兼容性保持不变。
|
||||
> 说明:历史详情、同步分析响应和 completed 任务状态会在 `report.details.analysis_context_pack_overview` 返回低敏输入数据块 overview;`details.context_snapshot` 会剥离该顶层字段,不返回完整 `AnalysisContextPack` 或 Prompt summary。
|
||||
> 说明:历史详情、同步分析响应和 completed 任务状态会在 `report.details.analysis_context_pack_overview` 返回低敏输入数据块 overview;其中同步分析响应依赖本次已持久化的 `analysis_history.context_snapshot`,`SAVE_CONTEXT_SNAPSHOT=false` 时新记录不保证返回 overview。`details.context_snapshot` 会剥离该顶层字段,不返回完整 `AnalysisContextPack` 或 Prompt summary。
|
||||
|
||||
> 兼容性审计证据:
|
||||
> - 官方来源:LiteLLM OpenAI-compatible provider 文档 <https://docs.litellm.ai/docs/providers/openai_compatible>;OpenAI Chat API 文档 <https://platform.openai.com/docs/api-reference/chat/create>;DeepSeek API 文档 <https://api-docs.deepseek.com/>。
|
||||
|
||||
@@ -123,6 +123,7 @@ Go to your forked repo → `Settings` → `Secrets and variables` → `Actions`
|
||||
| `REPORT_INTEGRITY_RETRY` | Integrity retry count (default `1`, `0` = placeholder only) | Optional |
|
||||
| `REPORT_HISTORY_COMPARE_N` | History signal comparison count, `0` off (default), `>0` enable | Optional |
|
||||
| `ANALYSIS_DELAY` | Delay between stock analysis and market review (seconds) to avoid API rate limits, e.g., `10` | Optional |
|
||||
| `SAVE_CONTEXT_SNAPSHOT` | Whether to persist analysis-history `context_snapshot`; defaults to `true`. Set to `false` or use `--no-context-snapshot` to stop persisting the full snapshot | Optional |
|
||||
| `NOTIFICATION_REPORT_CHANNELS` | Report route channels for single-stock, aggregate daily, market review, merged push, and Feishu document success notifications. Empty means all configured channels | Optional |
|
||||
| `NOTIFICATION_ALERT_CHANNELS` | Alert route channels for EventMonitor notifications. Empty means all configured channels | Optional |
|
||||
| `NOTIFICATION_SYSTEM_ERROR_CHANNELS` | Reserved system_error route channels. No automatic system error producer is added in P3; empty means all configured channels | Optional |
|
||||
@@ -346,6 +347,7 @@ For the notification baseline, diagnostics, and deployment notes, see [Notificat
|
||||
| `SCHEDULE_RUN_IMMEDIATELY` | Run once immediately when scheduler mode starts; when unset it keeps following the legacy `RUN_IMMEDIATELY` runtime override | `true` |
|
||||
| `RUN_IMMEDIATELY` | Run once immediately for non-scheduler startup; also acts as the legacy fallback when `SCHEDULE_RUN_IMMEDIATELY` is unset | `true` |
|
||||
| `LOG_DIR` | Log directory | `./logs` |
|
||||
| `SAVE_CONTEXT_SNAPSHOT` | Persist analysis-history `context_snapshot`. When false, new history records do not save enhanced_context, market_phase_summary, AnalysisContextPack overview, or diagnostic snapshots, but current-run prompt summaries remain enabled | `true` |
|
||||
|
||||
> Behavior notes:
|
||||
> - When `TICKFLOW_API_KEY` is configured, CN market review first tries TickFlow for main indices. Market breadth also tries TickFlow only when the current TickFlow plan supports universe queries.
|
||||
@@ -640,7 +642,7 @@ P1a itself does not change prompt wording, API/Web/Bot parameters, report schema
|
||||
|
||||
P1b projects the P1a runtime `market_phase_context` into a stable, low-sensitivity, public `market_phase_summary` and stores it at the top level of `analysis_history.context_snapshot`. History detail, sync analysis responses, and completed `/api/v1/analysis/status/{task_id}` responses return the same market-phase metadata at `report.meta.market_phase_summary`; completed task status does not add a top-level `TaskStatus` field and only exposes it through `status.result.report.meta.market_phase_summary`.
|
||||
|
||||
`market_phase_summary` only contains market, phase, market-local time, session date, effective daily-bar date, trading-day / market-open / partial-bar flags, open/close minute estimates, trigger source, analysis intent, and warning codes. It does not expose the full `market_phase_context`, and it does not add quote freshness, fallback, stale, or data-quality scoring fields. `report.details.analysis_context_pack_overview` remains the #1389 input data-block quality overview. API `details.context_snapshot` strips the top-level `market_phase_summary` and `analysis_context_pack_overview` so raw snapshots do not duplicate these stable public fields. When `SAVE_CONTEXT_SNAPSHOT=false` or older history records lack the summary, the field is empty and the report still loads.
|
||||
`market_phase_summary` only contains market, phase, market-local time, session date, effective daily-bar date, trading-day / market-open / partial-bar flags, open/close minute estimates, trigger source, analysis intent, and warning codes. It does not expose the full `market_phase_context`, and it does not add quote freshness, fallback, stale, or data-quality scoring fields. `report.details.analysis_context_pack_overview` remains the #1389 input data-block quality overview. API `details.context_snapshot` strips the top-level `market_phase_summary` and `analysis_context_pack_overview` so raw snapshots do not duplicate these stable public fields. When `SAVE_CONTEXT_SNAPSHOT=false`, the full `analysis_history.context_snapshot` is not persisted; when older history records lack the summary, the field is empty and the report still loads.
|
||||
|
||||
P1b does not change prompts, does not add an `analysis_phase` request parameter, does not add Web phase labels or rendering, and does not cover pending/processing TaskPanel state, in-progress SSE events, Bot, notifications, `market_review`, or P3 intraday data-quality fields.
|
||||
|
||||
@@ -680,9 +682,9 @@ P3 itself did not add API/Web/Bot parameters, persist fields into history/task s
|
||||
|
||||
### AnalysisContextPack Low-Sensitivity Visibility (Issue #1389 P4)
|
||||
|
||||
P4 adds `report.details.analysis_context_pack_overview`. History detail, sync analysis responses, and completed `/api/v1/analysis/status/{task_id}` responses now return the same low-sensitivity overview; the Web report page renders a collapsed data-block summary after Strategy and News, with available/missing counts, non-zero other status counts, and trigger source in the header and data-block status, source, warnings, missing reasons, status counts, and news result count after expansion. API `details.context_snapshot` strips the top-level `analysis_context_pack_overview` so the raw snapshot panel does not duplicate the public overview.
|
||||
P4 adds `report.details.analysis_context_pack_overview`. History detail and completed `/api/v1/analysis/status/{task_id}` responses read the same low-sensitivity overview from the persisted `context_snapshot`; sync analysis responses also extract the overview from the just-persisted `analysis_history.context_snapshot`, so new records do not guarantee this field when `SAVE_CONTEXT_SNAPSHOT=false`. The Web report page renders a collapsed data-block summary after Strategy and News, with available/missing counts, non-zero other status counts, and trigger source in the header and data-block status, source, warnings, missing reasons, status counts, and news result count after expansion. API `details.context_snapshot` strips the top-level `analysis_context_pack_overview` so the raw snapshot panel does not duplicate the public overview.
|
||||
|
||||
The overview does not include the full pack, the `analysis_context_pack_summary` prompt string, `items.value`, news body text, `trend_result`, chip, or fundamentals raw payloads. When `SAVE_CONTEXT_SNAPSHOT=false` or older history records lack the overview, the field is empty and the report still loads. This phase does not cover pending/processing TaskPanel, in-progress SSE events, notification summaries, Bot/Desktop-specific rendering, `market_review` overview, or data-quality scoring.
|
||||
The overview does not include the full pack, the `analysis_context_pack_summary` prompt string, `items.value`, news body text, `trend_result`, chip, or fundamentals raw payloads. When `SAVE_CONTEXT_SNAPSHOT=false`, the full `analysis_history.context_snapshot` is not persisted, so new history records cannot provide the overview; older records without the overview keep returning an empty field and the report still loads. This phase does not cover pending/processing TaskPanel, in-progress SSE events, notification summaries, Bot/Desktop-specific rendering, `market_review` overview, or data-quality scoring.
|
||||
|
||||
### AnalysisContextPack Data Quality Scoring and Prompt Limitations (Issue #1389 P5)
|
||||
|
||||
@@ -692,6 +694,14 @@ P5 adds lightweight data-quality scoring and model-readable data limitations to
|
||||
|
||||
History detail, sync analysis responses, and completed task status responses still expose only `report.details.analysis_context_pack_overview`; P5 only adds a nested `data_quality` object with score, level, block_scores, and limitations, and does not duplicate `warnings`. The Web report page remains collapsed by default, adds quality score/level to the header, and shows limitations plus `fetch_failed` status after expansion; API `details.context_snapshot` continues to strip the top-level `analysis_context_pack_overview`.
|
||||
|
||||
### AnalysisContextPack Documentation, Migration, and Rollback (Issue #1389 P6)
|
||||
|
||||
P6 is a documentation and configuration-visibility closure only. It does not add pack runtime behavior, does not add a pack enable/disable feature flag, does not change `PACK_VERSION = "1.0"`, does not add API parameters, does not change the report JSON schema, and does not run a database migration. See the [AnalysisContextPack topic document](analysis-context-pack.md) for the full contract, field states, low-sensitivity visibility, redaction boundary, migration notes, and rollback path.
|
||||
|
||||
`SAVE_CONTEXT_SNAPSHOT` is an existing environment variable; P6 only exposes it through `.env.example`, the config registry, and Web settings help. It defaults to `true`. When set to `false`, or when the CLI uses `--no-context-snapshot`, new history records no longer persist the full `analysis_history.context_snapshot`, including `enhanced_context`, `market_phase_summary`, `analysis_context_pack_overview`, diagnostic snapshots, and raw snapshot fields. This setting does not disable current-run `AnalysisContextPack` construction, does not remove the low-sensitivity `analysis_context_pack_summary` from prompts, and does not change report JSON schemas or API request parameters.
|
||||
|
||||
There is no runtime pack master switch. Disabling the P3-P5 pack prompt summary, overview, or data-quality integration requires a release rollback or code rollback. Older history records without `analysis_context_pack_overview` / `data_quality` continue to return empty fields and remain readable.
|
||||
|
||||
### Intraday Decision Guardrails and Quality Checks (Issue #1386 P5)
|
||||
|
||||
P5 adds a phase-aware decision block under `dashboard.phase_decision` for individual stock analysis reports: `phase_context`, `action_window`, `immediate_action`, `watch_conditions`, `next_check_time`, `confidence_reason`, and `data_limitations`. This is a backward-compatible report JSON addition stored in historical `raw_result`; it does not add an `analysis_phase` API parameter, change Web phase entrypoints, add configuration, or change the default post-market daily review behavior.
|
||||
@@ -1173,7 +1183,7 @@ FastAPI provides RESTful API service for configuration management and triggering
|
||||
> Note: `GET /api/v1/history/{record_id}/diagnostics` accepts either the history primary key ID or `query_id`, and returns a `normal/degraded/failed/unknown` summary, key pipeline components, and sanitized `copy_text`. Older reports without `context_snapshot.diagnostics` return `unknown` without affecting normal report reads.
|
||||
> Note: `GET /api/v1/history` list summaries can be paginated by `stock_code` for same-stock history and now include optional trend, summary, model, and analysis-time price/change fields. Older rows without persisted snapshots return empty values. The Web report page's "History Trend" drawer reuses this endpoint.
|
||||
> Issue #1520 compatibility note: The `model`/`model_used` returned here is read-only historical snapshot metadata from each record, used only for trend drawer/history display. It does not alter runtime model/model-provider/base URL resolution, config migration, or cleanup semantics in the analysis path. Rollback is by reverting this commit; history query, API response shapes, and UI drawer consumption remain compatible.
|
||||
> Note: history detail, sync analysis responses, and completed task status responses expose a low-sensitivity input data-block overview at `report.details.analysis_context_pack_overview`; `details.context_snapshot` strips that top-level field and does not return the full `AnalysisContextPack` or prompt summary.
|
||||
> Note: history detail, sync analysis responses, and completed task status responses expose a low-sensitivity input data-block overview at `report.details.analysis_context_pack_overview`; sync analysis responses depend on the just-persisted `analysis_history.context_snapshot`, so new records do not guarantee the overview when `SAVE_CONTEXT_SNAPSHOT=false`. `details.context_snapshot` strips that top-level field and does not return the full `AnalysisContextPack` or prompt summary.
|
||||
|
||||
> Compatibility audit evidence:
|
||||
> - Official references: LiteLLM OpenAI-compatible provider documentation <https://docs.litellm.ai/docs/providers/openai_compatible>, OpenAI Chat API <https://platform.openai.com/docs/api-reference/chat/create>, and DeepSeek API docs <https://api-docs.deepseek.com/>.
|
||||
|
||||
@@ -2981,6 +2981,37 @@ _FIELD_DEFINITIONS: Dict[str, Dict[str, Any]] = {
|
||||
],
|
||||
"warning_codes": [],
|
||||
},
|
||||
"SAVE_CONTEXT_SNAPSHOT": {
|
||||
"title": "Save Context Snapshot",
|
||||
"description": "Persist the full analysis_history.context_snapshot for history/API/Web transparency. Disable only to stop storing snapshots; it does not disable AnalysisContextPack prompt summaries during the current run.",
|
||||
"category": "system",
|
||||
"data_type": "boolean",
|
||||
"ui_control": "switch",
|
||||
"is_sensitive": False,
|
||||
"is_required": False,
|
||||
"is_editable": True,
|
||||
"default_value": "true",
|
||||
"options": [],
|
||||
"validation": {},
|
||||
"display_order": 52,
|
||||
"help_key": "settings.system.SAVE_CONTEXT_SNAPSHOT",
|
||||
"examples": [
|
||||
"SAVE_CONTEXT_SNAPSHOT=true",
|
||||
"SAVE_CONTEXT_SNAPSHOT=false",
|
||||
"python main.py --no-context-snapshot",
|
||||
],
|
||||
"docs": [
|
||||
{
|
||||
"label": "AnalysisContextPack P6 文档、迁移与回滚",
|
||||
"href": "https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/docs/analysis-context-pack.md#p6-文档迁移与回滚",
|
||||
},
|
||||
{
|
||||
"label": "完整指南:其他配置",
|
||||
"href": "https://github.com/ZhuLinsen/daily_stock_analysis/blob/main/docs/full-guide.md#其他配置",
|
||||
},
|
||||
],
|
||||
"warning_codes": [],
|
||||
},
|
||||
"DEBUG": {
|
||||
"title": "Debug Mode",
|
||||
"description": "Enable debug mode with verbose logging.",
|
||||
|
||||
@@ -31,6 +31,7 @@ def test_analysis_context_pack_doc_has_required_sections() -> None:
|
||||
"## P3 Runtime Consumption",
|
||||
"## P4 历史记录、任务状态与 Web 可见性",
|
||||
"## P5 数据质量评分与 Prompt 数据限制",
|
||||
"## P6 文档、迁移与回滚",
|
||||
"## 字段质量状态",
|
||||
"## 现有状态映射",
|
||||
"## 七路径盘点",
|
||||
@@ -297,6 +298,7 @@ def test_analysis_context_pack_doc_defines_p4_visibility_contract() -> None:
|
||||
"`analysisContextPackOverview`",
|
||||
"`GET /api/v1/history/{record_id}`",
|
||||
"同步 `POST /api/v1/analysis/analyze`",
|
||||
"overview 依赖已持久化的 `analysis_history.context_snapshot`",
|
||||
"completed `GET /api/v1/analysis/status/{task_id}`",
|
||||
"`sanitize_context_snapshot_for_api()`",
|
||||
"`extract_analysis_context_pack_overview()`",
|
||||
@@ -304,6 +306,9 @@ def test_analysis_context_pack_doc_defines_p4_visibility_contract() -> None:
|
||||
"`trend_result`",
|
||||
"`fundamental_context`",
|
||||
"`SAVE_CONTEXT_SNAPSHOT=false`",
|
||||
"不持久化整份 `analysis_history.context_snapshot`",
|
||||
"`market_phase_summary`",
|
||||
"`enhanced_context`",
|
||||
"`AnalysisContextSummary`",
|
||||
"位置在策略点位和资讯之后、运行诊断之前",
|
||||
"默认折叠",
|
||||
@@ -345,6 +350,37 @@ def test_analysis_context_pack_doc_defines_p5_data_quality_contract() -> None:
|
||||
assert token in section
|
||||
|
||||
|
||||
def test_analysis_context_pack_doc_defines_p6_migration_and_rollback_contract() -> None:
|
||||
section = _section(_read_doc(), "P6 文档、迁移与回滚")
|
||||
|
||||
for token in (
|
||||
"四个数据面",
|
||||
"内部完整 pack",
|
||||
"`analysis_context_pack_summary`",
|
||||
"`analysis_context_pack_overview`",
|
||||
"`analysis_history.context_snapshot`",
|
||||
"摘要可见性矩阵",
|
||||
"`SAVE_CONTEXT_SNAPSHOT=true`",
|
||||
"`SAVE_CONTEXT_SNAPSHOT=false`",
|
||||
"`--no-context-snapshot`",
|
||||
"不持久化整份 `analysis_history.context_snapshot`",
|
||||
"本次历史已持久化 `analysis_history.context_snapshot`",
|
||||
"`enhanced_context`",
|
||||
"`market_phase_summary`",
|
||||
"`diagnostics`",
|
||||
"`realtime_quote_raw`",
|
||||
"不影响当次 `AnalysisContextPack` 构建",
|
||||
"不影响内存中的 `result.diagnostic_context_snapshot`",
|
||||
"当前不存在",
|
||||
"运行时 pack 总开关",
|
||||
"发布或代码回滚",
|
||||
"secret",
|
||||
"token",
|
||||
"webhook",
|
||||
):
|
||||
assert token in section
|
||||
|
||||
|
||||
def test_analysis_context_pack_doc_maps_existing_status_terms() -> None:
|
||||
section = _section(_read_doc(), "现有状态映射")
|
||||
|
||||
@@ -392,19 +428,20 @@ def test_analysis_context_pack_doc_updates_indexes_and_changelog() -> None:
|
||||
changelog = (PROJECT_ROOT / "docs" / "CHANGELOG.md").read_text(encoding="utf-8")
|
||||
|
||||
assert "[分析上下文包契约、运行态消费与可见性](analysis-context-pack.md)" in index
|
||||
assert "P1/P2 内部契约、P3 Prompt 摘要消费、P4 历史/API/Web 低敏可见性、P5 数据质量评分" in index
|
||||
assert "P1/P2 内部契约、P3 Prompt 摘要消费、P4 历史/API/Web 低敏可见性、P5 数据质量评分、P6 迁移回滚" in index
|
||||
assert (
|
||||
"[Analysis Context Pack Contract, Runtime Consumption, And Visibility](analysis-context-pack.md) "
|
||||
"<sub><sub></sub></sub> "
|
||||
"<sub><sub></sub></sub> "
|
||||
"(Chinese-only)"
|
||||
) in index_en
|
||||
assert "P1/P2 internal contracts, P3 prompt-summary consumption, P4 history/API/Web low-sensitivity visibility, P5 data-quality scoring" in index_en
|
||||
assert "P1/P2 internal contracts, P3 prompt-summary consumption, P4 history/API/Web low-sensitivity visibility, P5 data-quality scoring, and P6 migration/rollback notes" in index_en
|
||||
assert "新增 AnalysisContextPack P0 上下文盘点" in changelog
|
||||
assert "新增 AnalysisContextPack P1 内部契约与脱敏序列化测试" in changelog
|
||||
assert "新增 AnalysisContextPack P2 builder" in changelog
|
||||
assert "普通分析与 Agent 运行时 Prompt 接入 AnalysisContextPack 低敏摘要" in changelog
|
||||
assert "AnalysisContextPack P4 低敏 overview 接入历史详情" in changelog
|
||||
assert "AnalysisContextPack P5 增加数据质量评分" in changelog
|
||||
assert "明确 AnalysisContextPack P6 文档、迁移与回滚边界" in changelog
|
||||
assert "#1386 P5 为个股分析报告新增 `dashboard.phase_decision`" in changelog
|
||||
assert "优化 Web 报告详情页信息层级" in changelog
|
||||
|
||||
@@ -422,6 +459,8 @@ def test_full_guides_clarify_pack_summary_does_not_replace_legacy_payload_channe
|
||||
assert "折叠头部展示可用数、缺失数、非零的其他状态计数和触发来源" in guide
|
||||
assert "Web 报告页在策略点位和资讯之后默认折叠展示数据块状态" in guide
|
||||
assert "`details.context_snapshot` 会剥离顶层 `analysis_context_pack_overview`" in guide
|
||||
assert "同步分析响应也会读取本次已落库的 `analysis_history.context_snapshot` 提取 overview" in guide
|
||||
assert "`SAVE_CONTEXT_SNAPSHOT=false` 时新记录不保证返回该字段" in guide
|
||||
assert "AnalysisContextPack 数据质量评分与 Prompt 数据限制(Issue #1389 P5)" in guide
|
||||
assert "盘中决策护栏与质量校验(Issue #1386 P5)" in guide
|
||||
assert "`dashboard.phase_decision`" in guide
|
||||
@@ -429,16 +468,23 @@ def test_full_guides_clarify_pack_summary_does_not_replace_legacy_payload_channe
|
||||
assert "折叠头部新增质量分/等级" in guide
|
||||
assert "`report.meta.market_phase_summary`" in guide
|
||||
assert "`details.context_snapshot` 会剥离顶层 `market_phase_summary`" in guide
|
||||
assert "AnalysisContextPack 文档、迁移与回滚(Issue #1389 P6)" in guide
|
||||
assert "`SAVE_CONTEXT_SNAPSHOT` 是既有环境变量" in guide
|
||||
assert "不持久化整份 `analysis_history.context_snapshot`" in guide
|
||||
assert "不关闭当次 `AnalysisContextPack` 构建" in guide
|
||||
assert "当前没有运行时 pack 总开关" in guide
|
||||
|
||||
assert "in this new pack-summary section" in guide_en
|
||||
assert "not full `news.content`" in guide_en
|
||||
assert "Existing `news_context`, Agent pre-fetched JSON, and `enhanced_context` raw-payload channels keep their pre-P3 behavior" in guide_en
|
||||
assert "`report.details.analysis_context_pack_overview`" in guide_en
|
||||
assert "completed `/api/v1/analysis/status/{task_id}`" in guide_en
|
||||
assert "the Web report page renders a collapsed data-block summary after Strategy and News" in guide_en
|
||||
assert "The Web report page renders a collapsed data-block summary after Strategy and News" in guide_en
|
||||
assert "available/missing counts, non-zero other status counts, and trigger source" in guide_en
|
||||
assert "the Web report page shows the data-block summary collapsed after Strategy and News" in guide_en
|
||||
assert "API `details.context_snapshot` strips the top-level `analysis_context_pack_overview`" in guide_en
|
||||
assert "sync analysis responses also extract the overview from the just-persisted `analysis_history.context_snapshot`" in guide_en
|
||||
assert "new records do not guarantee this field when `SAVE_CONTEXT_SNAPSHOT=false`" in guide_en
|
||||
assert "AnalysisContextPack Data Quality Scoring and Prompt Limitations (Issue #1389 P5)" in guide_en
|
||||
assert "Intraday Decision Guardrails and Quality Checks (Issue #1386 P5)" in guide_en
|
||||
assert "`dashboard.phase_decision`" in guide_en
|
||||
@@ -446,3 +492,8 @@ def test_full_guides_clarify_pack_summary_does_not_replace_legacy_payload_channe
|
||||
assert "adds quality score/level to the header" in guide_en
|
||||
assert "`report.meta.market_phase_summary`" in guide_en
|
||||
assert "API `details.context_snapshot` strips the top-level `market_phase_summary`" in guide_en
|
||||
assert "AnalysisContextPack Documentation, Migration, and Rollback (Issue #1389 P6)" in guide_en
|
||||
assert "`SAVE_CONTEXT_SNAPSHOT` is an existing environment variable" in guide_en
|
||||
assert "the full `analysis_history.context_snapshot` is not persisted" in guide_en
|
||||
assert "does not disable current-run `AnalysisContextPack` construction" in guide_en
|
||||
assert "There is no runtime pack master switch" in guide_en
|
||||
|
||||
@@ -259,6 +259,7 @@ class TestSettingsHelpMetadata(unittest.TestCase):
|
||||
"DEBUG",
|
||||
"MAX_WORKERS",
|
||||
"ANALYSIS_DELAY",
|
||||
"SAVE_CONTEXT_SNAPSHOT",
|
||||
"MARKET_REVIEW_ENABLED",
|
||||
"MARKET_REVIEW_REGION",
|
||||
"MARKET_REVIEW_COLOR_SCHEME",
|
||||
@@ -300,6 +301,21 @@ class TestSettingsHelpMetadata(unittest.TestCase):
|
||||
self.assertEqual(field["category"], "system")
|
||||
self.assertNotEqual(field["display_order"], 9000)
|
||||
|
||||
def test_save_context_snapshot_is_explicitly_registered(self):
|
||||
field = get_field_definition("SAVE_CONTEXT_SNAPSHOT")
|
||||
|
||||
self.assertEqual(field["category"], "system")
|
||||
self.assertEqual(field["data_type"], "boolean")
|
||||
self.assertEqual(field["ui_control"], "switch")
|
||||
self.assertFalse(field["is_sensitive"])
|
||||
self.assertTrue(field["is_editable"])
|
||||
self.assertEqual(field["default_value"], "true")
|
||||
self.assertEqual(field["display_order"], 52)
|
||||
self.assertEqual(field["help_key"], "settings.system.SAVE_CONTEXT_SNAPSHOT")
|
||||
self.assertTrue(field.get("examples"))
|
||||
self.assertTrue(field.get("docs"))
|
||||
self.assertIn("analysis-context-pack.md#p6-", field["docs"][0]["href"])
|
||||
|
||||
def test_restart_warning_codes_match_runtime_behavior(self):
|
||||
restart_required_keys = (
|
||||
"RUN_IMMEDIATELY",
|
||||
|
||||
Reference in New Issue
Block a user