@zhin.js/plugin-lottery 1.1.9 → 1.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +8 -0
  2. package/commands/lottery/[[game]]/index.js +5 -4
  3. package/commands/lottery/[[game]]/index.ts +5 -4
  4. package/commands/lottery-backtest/[[game]]/index.js +9 -4
  5. package/commands/lottery-backtest/[[game]]/index.ts +8 -4
  6. package/commands/lottery-history/[game]/index.js +6 -4
  7. package/commands/lottery-history/[game]/index.ts +6 -4
  8. package/commands/lottery-stats/[game]/index.js +11 -6
  9. package/commands/lottery-stats/[game]/index.ts +11 -5
  10. package/commands/lottery-today/index.js +8 -4
  11. package/commands/lottery-today/index.ts +8 -3
  12. package/commands/lottery-train/[[game]]/index.js +4 -3
  13. package/commands/lottery-train/[[game]]/index.ts +4 -3
  14. package/lib/command-helpers.d.ts +2 -1
  15. package/lib/command-helpers.d.ts.map +1 -1
  16. package/lib/command-helpers.js +2 -1
  17. package/lib/command-helpers.js.map +1 -1
  18. package/lib/evaluate/backtest.d.ts +3 -2
  19. package/lib/evaluate/backtest.d.ts.map +1 -1
  20. package/lib/evaluate/backtest.js +12 -11
  21. package/lib/evaluate/backtest.js.map +1 -1
  22. package/lib/evaluate/tracker.d.ts +2 -1
  23. package/lib/evaluate/tracker.d.ts.map +1 -1
  24. package/lib/evaluate/tracker.js +9 -8
  25. package/lib/evaluate/tracker.js.map +1 -1
  26. package/lib/evaluate/train-weights.d.ts +3 -2
  27. package/lib/evaluate/train-weights.d.ts.map +1 -1
  28. package/lib/evaluate/train-weights.js +12 -11
  29. package/lib/evaluate/train-weights.js.map +1 -1
  30. package/lib/games/kl8-groups.d.ts +2 -0
  31. package/lib/games/kl8-groups.d.ts.map +1 -1
  32. package/lib/games/kl8-groups.js +2 -1
  33. package/lib/games/kl8-groups.js.map +1 -1
  34. package/lib/i18n.d.ts +2 -0
  35. package/lib/i18n.d.ts.map +1 -0
  36. package/lib/i18n.js +222 -0
  37. package/lib/i18n.js.map +1 -0
  38. package/lib/lottery-tool-handlers.d.ts +4 -3
  39. package/lib/lottery-tool-handlers.d.ts.map +1 -1
  40. package/lib/lottery-tool-handlers.js +12 -7
  41. package/lib/lottery-tool-handlers.js.map +1 -1
  42. package/lib/pipeline.d.ts +3 -1
  43. package/lib/pipeline.d.ts.map +1 -1
  44. package/lib/pipeline.js +9 -7
  45. package/lib/pipeline.js.map +1 -1
  46. package/lib/recommend/game-pick.d.ts +4 -2
  47. package/lib/recommend/game-pick.d.ts.map +1 -1
  48. package/lib/recommend/game-pick.js +39 -28
  49. package/lib/recommend/game-pick.js.map +1 -1
  50. package/lib/recommend/report.d.ts +4 -2
  51. package/lib/recommend/report.d.ts.map +1 -1
  52. package/lib/recommend/report.js +17 -10
  53. package/lib/recommend/report.js.map +1 -1
  54. package/lib/runtime-state.d.ts +2 -0
  55. package/lib/runtime-state.d.ts.map +1 -1
  56. package/lib/runtime-state.js.map +1 -1
  57. package/lib/stats/pro-analysis.d.ts +3 -2
  58. package/lib/stats/pro-analysis.d.ts.map +1 -1
  59. package/lib/stats/pro-analysis.js +10 -9
  60. package/lib/stats/pro-analysis.js.map +1 -1
  61. package/lib/sync/run-sync.d.ts +2 -1
  62. package/lib/sync/run-sync.d.ts.map +1 -1
  63. package/lib/sync/run-sync.js +4 -3
  64. package/lib/sync/run-sync.js.map +1 -1
  65. package/lib/types.d.ts +2 -0
  66. package/lib/types.d.ts.map +1 -1
  67. package/lib/types.js.map +1 -1
  68. package/package.json +8 -8
  69. package/plugin.js +4 -0
  70. package/skills/lottery/tools/compute-recommend/index.js +1 -1
  71. package/skills/lottery/tools/compute-recommend/index.ts +1 -1
  72. package/skills/lottery/tools/history/index.js +2 -1
  73. package/skills/lottery/tools/history/index.ts +2 -1
  74. package/skills/lottery/tools/save-prediction/index.js +1 -1
  75. package/skills/lottery/tools/save-prediction/index.ts +1 -1
  76. package/skills/lottery/tools/stats-snapshot/index.js +1 -1
  77. package/skills/lottery/tools/stats-snapshot/index.ts +1 -1
  78. package/skills/lottery/tools/sync/index.js +1 -1
  79. package/skills/lottery/tools/sync/index.ts +1 -0
  80. package/src/command-helpers.ts +3 -0
  81. package/src/evaluate/backtest.ts +13 -11
  82. package/src/evaluate/tracker.ts +10 -8
  83. package/src/evaluate/train-weights.ts +13 -11
  84. package/src/games/kl8-groups.ts +4 -1
  85. package/src/i18n.ts +222 -0
  86. package/src/lottery-tool-handlers.ts +12 -7
  87. package/src/pipeline.ts +10 -7
  88. package/src/recommend/game-pick.ts +40 -28
  89. package/src/recommend/report.ts +18 -8
  90. package/src/runtime-state.ts +2 -0
  91. package/src/stats/pro-analysis.ts +11 -7
  92. package/src/sync/run-sync.ts +5 -2
  93. package/src/types.ts +2 -0
package/README.md CHANGED
@@ -115,3 +115,11 @@ lottery:
115
115
  ## 免责声明
116
116
 
117
117
  本插件推荐仅供参考,不构成投注建议,不保证中奖。请理性购彩。
118
+
119
+ ## Language / 语言
120
+
121
+ 命令说明、即时统计、回测与训练结果支持简体中文和英文,提示中的命令会根据当前前缀与插件命名空间生成。手动新建的报告使用当前发送者语言;定时流水线使用注册时的项目语言。语言不改变玩法 ID、号码、评分、权重、开奖数据、执行时间或推送目标。
122
+
123
+ 报告保存生成时的语言及已格式化内容,再次查看不会重新推算或自动翻译;历史报告缺少语言字段时保留原中文。Agent 写入的正文、复盘说明和记忆、第三方数据均保持原样。
124
+
125
+ Command feedback and fresh statistics follow the current operation language. New scheduled reports use the project language captured at registration. Saved reports retain their original language and authored content. Localization does not alter the statistical model or imply better odds; the same disclaimer is included in both languages.
@@ -4,16 +4,17 @@ import { parseGameId } from "../../../lib/games/registry.js";
4
4
  import { buildPipelineDeps, formatPipelineReply, runLotteryPipeline, resolveLotteryConfig, } from "../../../lib/command-helpers.js";
5
5
  import { lotteryRuntimeToken } from "../../../lib/runtime-state.js";
6
6
  export default defineCommand({
7
- description: 'Run full pipeline: sync → review → recommend (manual, no push)',
7
+ description: '执行同步、复盘与推荐(手动执行,不推送)',
8
+ descriptionI18n: { en: 'Run full pipeline: sync → review → recommend (manual, no push)' },
8
9
  params: { game: { type: 'string', default: '' } },
9
- async execute({ params, config, use }) {
10
+ async execute({ params, config, use, locale }) {
10
11
  const cfg = resolveLotteryConfig(config);
11
12
  const gid = parseGameId(String(params.game ?? ''));
12
13
  const runtime = use(lotteryRuntimeToken);
13
- const out = await runLotteryPipeline(buildPipelineDeps(cfg, runtime.db), {
14
+ const out = await runLotteryPipeline(buildPipelineDeps(cfg, runtime.db, locale), {
14
15
  gameId: gid ?? undefined,
15
16
  push: false,
16
17
  });
17
- return formatPipelineReply(out);
18
+ return formatPipelineReply(out, locale);
18
19
  },
19
20
  });
@@ -10,16 +10,17 @@ import {
10
10
  import { lotteryRuntimeToken } from '../../../src/runtime-state.js';
11
11
 
12
12
  export default defineCommand<LotteryConfig>({
13
- description: 'Run full pipeline: sync → review → recommend (manual, no push)',
13
+ description: '执行同步、复盘与推荐(手动执行,不推送)',
14
+ descriptionI18n: { en: 'Run full pipeline: sync → review → recommend (manual, no push)' },
14
15
  params: { game: { type: 'string', default: '' } },
15
- async execute({ params, config, use }) {
16
+ async execute({ params, config, use, locale }) {
16
17
  const cfg = resolveLotteryConfig(config);
17
18
  const gid = parseGameId(String(params.game ?? ''));
18
19
  const runtime = use(lotteryRuntimeToken);
19
- const out = await runLotteryPipeline(buildPipelineDeps(cfg, runtime.db), {
20
+ const out = await runLotteryPipeline(buildPipelineDeps(cfg, runtime.db, locale), {
20
21
  gameId: gid ?? undefined,
21
22
  push: false,
22
23
  });
23
- return formatPipelineReply(out);
24
+ return formatPipelineReply(out, locale);
24
25
  },
25
26
  });
@@ -1,4 +1,5 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { messages as t } from "../../../lib/i18n.js";
2
3
  import { defineCommand } from 'zhin.js/command';
3
4
  import { parseGameId } from "../../../lib/games/registry.js";
4
5
  import { formatBacktestSection, runBacktestForGames, } from "../../../lib/evaluate/backtest.js";
@@ -6,9 +7,10 @@ import { resolveLotteryConfig, } from "../../../lib/command-helpers.js";
6
7
  import { lotteryEnabledGames } from "../../../lib/config.js";
7
8
  import { lotteryRuntimeToken } from "../../../lib/runtime-state.js";
8
9
  export default defineCommand({
9
- description: 'Walk-forward backtest vs random baseline',
10
+ description: '滚动回测与随机基线比较',
11
+ descriptionI18n: { en: 'Walk-forward backtest vs random baseline' },
10
12
  params: { game: { type: 'string', default: '' } },
11
- async execute({ params, config, use }) {
13
+ async execute({ params, config, use, locale, formatCommand }) {
12
14
  const { db } = use(lotteryRuntimeToken);
13
15
  const cfg = resolveLotteryConfig(config);
14
16
  const gid = parseGameId(String(params.game ?? ''));
@@ -21,7 +23,10 @@ export default defineCommand({
21
23
  historyLimit: cfg.historyLimit,
22
24
  adaptive: cfg.backtestAdaptive,
23
25
  });
24
- const text = formatBacktestSection(summaries);
25
- return text || '历史数据不足,请先执行 lottery 同步开奖';
26
+ const text = formatBacktestSection(summaries, locale);
27
+ if (text)
28
+ return text;
29
+ const command = formatCommand('lottery');
30
+ return command ? t(locale, 'syncCommand', { command }) : t(locale, 'syncRequired');
26
31
  },
27
32
  });
@@ -1,3 +1,4 @@
1
+ import { messages as t } from '../../../src/i18n.js';
1
2
  import { defineCommand } from 'zhin.js/command';
2
3
  import { parseGameId } from '../../../src/games/registry.js';
3
4
  import {
@@ -12,9 +13,10 @@ import { lotteryEnabledGames } from '../../../src/config.js';
12
13
  import { lotteryRuntimeToken } from '../../../src/runtime-state.js';
13
14
 
14
15
  export default defineCommand<LotteryConfig>({
15
- description: 'Walk-forward backtest vs random baseline',
16
+ description: '滚动回测与随机基线比较',
17
+ descriptionI18n: { en: 'Walk-forward backtest vs random baseline' },
16
18
  params: { game: { type: 'string', default: '' } },
17
- async execute({ params, config, use }) {
19
+ async execute({ params, config, use, locale, formatCommand }) {
18
20
  const { db } = use(lotteryRuntimeToken);
19
21
  const cfg = resolveLotteryConfig(config);
20
22
  const gid = parseGameId(String(params.game ?? ''));
@@ -27,7 +29,9 @@ export default defineCommand<LotteryConfig>({
27
29
  historyLimit: cfg.historyLimit,
28
30
  adaptive: cfg.backtestAdaptive,
29
31
  });
30
- const text = formatBacktestSection(summaries);
31
- return text || '历史数据不足,请先执行 lottery 同步开奖';
32
+ const text = formatBacktestSection(summaries, locale);
33
+ if (text) return text;
34
+ const command = formatCommand('lottery');
35
+ return command ? t(locale, 'syncCommand', { command }) : t(locale, 'syncRequired');
32
36
  },
33
37
  });
@@ -1,21 +1,23 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { messages as t } from "../../../lib/i18n.js";
2
3
  import { defineCommand } from 'zhin.js/command';
3
4
  import { parseGameId } from "../../../lib/games/registry.js";
4
5
  import { loadDraws } from "../../../lib/db.js";
5
6
  import { lotteryRuntimeToken } from "../../../lib/runtime-state.js";
6
7
  export default defineCommand({
7
- description: 'List historical draw results',
8
+ description: '查询历史开奖结果',
9
+ descriptionI18n: { en: 'List historical draw results' },
8
10
  params: { game: { type: 'string' } },
9
- async execute({ params, args, use }) {
11
+ async execute({ params, args, use, locale }) {
10
12
  const gid = parseGameId(String(params.game ?? ''));
11
13
  if (!gid)
12
- return '请指定玩法';
14
+ return t(locale, 'gameRequired');
13
15
  const { db } = use(lotteryRuntimeToken);
14
16
  // count 原来是第二动态段,约定式命令只支持单动态文件参数,改从 args 取
15
17
  const count = Math.min(50, Math.max(1, Number(args[0]) || 10));
16
18
  const draws = await loadDraws(db, gid, count);
17
19
  if (!draws.length)
18
- return '暂无数据';
20
+ return t(locale, 'noData');
19
21
  return draws.map((d) => `${d.issue} ${d.drawTime} ${JSON.stringify(d.numbers)}`).join('\n');
20
22
  },
21
23
  });
@@ -1,3 +1,4 @@
1
+ import { messages as t } from '../../../src/i18n.js';
1
2
  import { defineCommand } from 'zhin.js/command';
2
3
  import { parseGameId } from '../../../src/games/registry.js';
3
4
  import { loadDraws } from '../../../src/db.js';
@@ -5,16 +6,17 @@ import type { LotteryConfig } from '../../../src/command-helpers.js';
5
6
  import { lotteryRuntimeToken } from '../../../src/runtime-state.js';
6
7
 
7
8
  export default defineCommand<LotteryConfig>({
8
- description: 'List historical draw results',
9
+ description: '查询历史开奖结果',
10
+ descriptionI18n: { en: 'List historical draw results' },
9
11
  params: { game: { type: 'string' } },
10
- async execute({ params, args, use }) {
12
+ async execute({ params, args, use, locale }) {
11
13
  const gid = parseGameId(String(params.game ?? ''));
12
- if (!gid) return '请指定玩法';
14
+ if (!gid) return t(locale, 'gameRequired');
13
15
  const { db } = use(lotteryRuntimeToken);
14
16
  // count 原来是第二动态段,约定式命令只支持单动态文件参数,改从 args 取
15
17
  const count = Math.min(50, Math.max(1, Number(args[0]) || 10));
16
18
  const draws = await loadDraws(db, gid, count);
17
- if (!draws.length) return '暂无数据';
19
+ if (!draws.length) return t(locale, 'noData');
18
20
  return draws.map((d) => `${d.issue} ${d.drawTime} ${JSON.stringify(d.numbers)}`).join('\n');
19
21
  },
20
22
  });
@@ -1,4 +1,5 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { messages as t } from "../../../lib/i18n.js";
2
3
  import { defineCommand } from 'zhin.js/command';
3
4
  import { parseGameId } from "../../../lib/games/registry.js";
4
5
  import { loadDraws } from "../../../lib/db.js";
@@ -8,25 +9,29 @@ import { resolveLotteryConfig, } from "../../../lib/command-helpers.js";
8
9
  import { lotteryKl8 } from "../../../lib/config.js";
9
10
  import { lotteryRuntimeToken } from "../../../lib/runtime-state.js";
10
11
  export default defineCommand({
11
- description: 'Single-game stats snapshot',
12
+ description: '查看单玩法统计',
13
+ descriptionI18n: { en: 'Single-game stats snapshot' },
12
14
  params: { game: { type: 'string' } },
13
- async execute({ params, config, use }) {
15
+ async execute({ params, config, use, locale, formatCommand }) {
14
16
  const gid = parseGameId(String(params.game ?? ''));
15
17
  if (!gid)
16
- return '请指定玩法';
18
+ return t(locale, 'gameRequired');
17
19
  const { db } = use(lotteryRuntimeToken);
18
20
  const cfg = resolveLotteryConfig(config);
19
21
  const draws = await loadDraws(db, gid, cfg.historyLimit);
20
- if (!draws.length)
21
- return '暂无数据,请先 lottery';
22
+ if (!draws.length) {
23
+ const command = formatCommand('lottery');
24
+ return command ? t(locale, 'syncCommand', { command }) : t(locale, 'syncRequired');
25
+ }
22
26
  const kl8 = lotteryKl8(cfg);
23
27
  const pick = recommendGame(gid, draws, {
28
+ locale,
24
29
  pickCount: gid === 'kl8' ? kl8.pickCount : cfg.pickCount,
25
30
  tieSeed: 'stats',
26
31
  weights: await loadGameWeights(db, gid),
27
32
  accuracy: await loadAccuracySnapshot(db, gid),
28
33
  kl8: gid === 'kl8' ? kl8 : undefined,
29
34
  });
30
- return [formatPickLine(pick), formatPickStats(pick), `样本 ${draws.length} 期`].join('\n');
35
+ return [formatPickLine(pick), formatPickStats(pick), t(locale, 'sample', { count: draws.length })].join('\n');
31
36
  },
32
37
  });
@@ -1,3 +1,4 @@
1
+ import { messages as t } from '../../../src/i18n.js';
1
2
  import { defineCommand } from 'zhin.js/command';
2
3
  import { parseGameId } from '../../../src/games/registry.js';
3
4
  import { loadDraws } from '../../../src/db.js';
@@ -11,23 +12,28 @@ import { lotteryKl8 } from '../../../src/config.js';
11
12
  import { lotteryRuntimeToken } from '../../../src/runtime-state.js';
12
13
 
13
14
  export default defineCommand<LotteryConfig>({
14
- description: 'Single-game stats snapshot',
15
+ description: '查看单玩法统计',
16
+ descriptionI18n: { en: 'Single-game stats snapshot' },
15
17
  params: { game: { type: 'string' } },
16
- async execute({ params, config, use }) {
18
+ async execute({ params, config, use, locale, formatCommand }) {
17
19
  const gid = parseGameId(String(params.game ?? ''));
18
- if (!gid) return '请指定玩法';
20
+ if (!gid) return t(locale, 'gameRequired');
19
21
  const { db } = use(lotteryRuntimeToken);
20
22
  const cfg = resolveLotteryConfig(config);
21
23
  const draws = await loadDraws(db, gid, cfg.historyLimit);
22
- if (!draws.length) return '暂无数据,请先 lottery';
24
+ if (!draws.length) {
25
+ const command = formatCommand('lottery');
26
+ return command ? t(locale, 'syncCommand', { command }) : t(locale, 'syncRequired');
27
+ }
23
28
  const kl8 = lotteryKl8(cfg);
24
29
  const pick = recommendGame(gid, draws, {
30
+ locale,
25
31
  pickCount: gid === 'kl8' ? kl8.pickCount : cfg.pickCount,
26
32
  tieSeed: 'stats',
27
33
  weights: await loadGameWeights(db, gid),
28
34
  accuracy: await loadAccuracySnapshot(db, gid),
29
35
  kl8: gid === 'kl8' ? kl8 : undefined,
30
36
  });
31
- return [formatPickLine(pick), formatPickStats(pick), `样本 ${draws.length} 期`].join('\n');
37
+ return [formatPickLine(pick), formatPickStats(pick), t(locale, 'sample', { count: draws.length })].join('\n');
32
38
  },
33
39
  });
@@ -1,14 +1,18 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { messages as t } from "../../lib/i18n.js";
2
3
  import { defineCommand } from 'zhin.js/command';
3
4
  import { formatDailyReportText, loadTodayReport } from "../../lib/recommend/report.js";
4
5
  import { lotteryRuntimeToken } from "../../lib/runtime-state.js";
5
6
  export default defineCommand({
6
- description: 'Show today published recommendation report',
7
- async execute({ use }) {
7
+ description: '查看今日已发布的推荐报告',
8
+ descriptionI18n: { en: 'Show today published recommendation report' },
9
+ async execute({ use, locale, formatCommand }) {
8
10
  const { db } = use(lotteryRuntimeToken);
9
11
  const report = await loadTodayReport(db);
10
- if (!report)
11
- return '今日尚无推荐,可执行 lottery 或等待定时任务';
12
+ if (!report) {
13
+ const command = formatCommand('lottery');
14
+ return command ? t(locale, 'noReportCommand', { command }) : t(locale, 'noReport');
15
+ }
12
16
  return formatDailyReportText(report, '');
13
17
  },
14
18
  });
@@ -1,14 +1,19 @@
1
+ import { messages as t } from '../../src/i18n.js';
1
2
  import { defineCommand } from 'zhin.js/command';
2
3
  import { formatDailyReportText, loadTodayReport } from '../../src/recommend/report.js';
3
4
  import type { LotteryConfig } from '../../src/command-helpers.js';
4
5
  import { lotteryRuntimeToken } from '../../src/runtime-state.js';
5
6
 
6
7
  export default defineCommand<LotteryConfig>({
7
- description: 'Show today published recommendation report',
8
- async execute({ use }) {
8
+ description: '查看今日已发布的推荐报告',
9
+ descriptionI18n: { en: 'Show today published recommendation report' },
10
+ async execute({ use, locale, formatCommand }) {
9
11
  const { db } = use(lotteryRuntimeToken);
10
12
  const report = await loadTodayReport(db);
11
- if (!report) return '今日尚无推荐,可执行 lottery 或等待定时任务';
13
+ if (!report) {
14
+ const command = formatCommand('lottery');
15
+ return command ? t(locale, 'noReportCommand', { command }) : t(locale, 'noReport');
16
+ }
12
17
  return formatDailyReportText(report, '');
13
18
  },
14
19
  });
@@ -6,9 +6,10 @@ import { resolveLotteryConfig, } from "../../../lib/command-helpers.js";
6
6
  import { lotteryEnabledGames } from "../../../lib/config.js";
7
7
  import { lotteryRuntimeToken } from "../../../lib/runtime-state.js";
8
8
  export default defineCommand({
9
- description: 'Full-history weight training',
9
+ description: '使用全部历史数据训练权重',
10
+ descriptionI18n: { en: 'Full-history weight training' },
10
11
  params: { game: { type: 'string', default: '' } },
11
- async execute({ params, config, use }) {
12
+ async execute({ params, config, use, locale }) {
12
13
  const { db } = use(lotteryRuntimeToken);
13
14
  const cfg = resolveLotteryConfig(config);
14
15
  const gid = parseGameId(String(params.game ?? ''));
@@ -22,6 +23,6 @@ export default defineCommand({
22
23
  holdoutFallback: cfg.weightHoldoutFallback,
23
24
  persist: true,
24
25
  });
25
- return formatTrainReport(results);
26
+ return formatTrainReport(results, locale);
26
27
  },
27
28
  });
@@ -12,9 +12,10 @@ import { lotteryEnabledGames } from '../../../src/config.js';
12
12
  import { lotteryRuntimeToken } from '../../../src/runtime-state.js';
13
13
 
14
14
  export default defineCommand<LotteryConfig>({
15
- description: 'Full-history weight training',
15
+ description: '使用全部历史数据训练权重',
16
+ descriptionI18n: { en: 'Full-history weight training' },
16
17
  params: { game: { type: 'string', default: '' } },
17
- async execute({ params, config, use }) {
18
+ async execute({ params, config, use, locale }) {
18
19
  const { db } = use(lotteryRuntimeToken);
19
20
  const cfg = resolveLotteryConfig(config);
20
21
  const gid = parseGameId(String(params.game ?? ''));
@@ -28,6 +29,6 @@ export default defineCommand<LotteryConfig>({
28
29
  holdoutFallback: cfg.weightHoldoutFallback,
29
30
  persist: true,
30
31
  });
31
- return formatTrainReport(results);
32
+ return formatTrainReport(results, locale);
32
33
  },
33
34
  });
@@ -1,7 +1,8 @@
1
+ import type { Locale } from 'zhin.js/i18n';
1
2
  import { resolveLotteryConfig, type LotteryConfig } from './config.js';
2
3
  import type { LotteryDb } from './db.js';
3
4
  import { formatPipelineReply, runLotteryPipeline, type PipelineDeps } from './pipeline.js';
4
- export declare function buildPipelineDeps(raw: Partial<LotteryConfig> | undefined, db: LotteryDb): PipelineDeps;
5
+ export declare function buildPipelineDeps(raw: Partial<LotteryConfig> | undefined, db: LotteryDb, locale?: Locale): PipelineDeps;
5
6
  export { formatPipelineReply, runLotteryPipeline, resolveLotteryConfig };
6
7
  export type { LotteryConfig };
7
8
  //# sourceMappingURL=command-helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"command-helpers.d.ts","sourceRoot":"","sources":["../src/command-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,oBAAoB,EACpB,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAE3F,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,SAAS,EACvC,EAAE,EAAE,SAAS,GACZ,YAAY,CAmBd;AAED,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,CAAC;AACzE,YAAY,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"command-helpers.d.ts","sourceRoot":"","sources":["../src/command-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAGL,oBAAoB,EACpB,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAE3F,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,SAAS,EACvC,EAAE,EAAE,SAAS,EACb,MAAM,CAAC,EAAE,MAAM,GACd,YAAY,CAoBd;AAED,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,CAAC;AACzE,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -1,8 +1,9 @@
1
1
  import { lotteryEnabledGames, lotteryKl8, resolveLotteryConfig, } from './config.js';
2
2
  import { formatPipelineReply, runLotteryPipeline } from './pipeline.js';
3
- export function buildPipelineDeps(raw, db) {
3
+ export function buildPipelineDeps(raw, db, locale) {
4
4
  const config = resolveLotteryConfig(raw);
5
5
  return {
6
+ locale,
6
7
  db,
7
8
  enabledGames: () => lotteryEnabledGames(config),
8
9
  historyLimit: config.historyLimit,
@@ -1 +1 @@
1
- {"version":3,"file":"command-helpers.js","sourceRoot":"","sources":["../src/command-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,UAAU,EACV,oBAAoB,GAErB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAqB,MAAM,eAAe,CAAC;AAE3F,MAAM,UAAU,iBAAiB,CAC/B,GAAuC,EACvC,EAAa;IAEb,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IACzC,OAAO;QACL,EAAE;QACF,YAAY,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC;QAC/C,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC;QACvB,QAAQ,EAAE;YACR,OAAO,EAAE,MAAM,CAAC,eAAe;YAC/B,MAAM,EAAE,MAAM,CAAC,cAAc;YAC7B,YAAY,EAAE,MAAM,CAAC,oBAAoB;YACzC,UAAU,EAAE,MAAM,CAAC,kBAAkB;YACrC,QAAQ,EAAE,MAAM,CAAC,gBAAgB;SAClC;QACD,aAAa,EAAE,MAAM,CAAC,oBAAoB;QAC1C,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;QACnD,QAAQ,EAAE,IAAI;KACf,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,CAAC"}
1
+ {"version":3,"file":"command-helpers.js","sourceRoot":"","sources":["../src/command-helpers.ts"],"names":[],"mappings":"AACA,OAAO,EACL,mBAAmB,EACnB,UAAU,EACV,oBAAoB,GAErB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAqB,MAAM,eAAe,CAAC;AAE3F,MAAM,UAAU,iBAAiB,CAC/B,GAAuC,EACvC,EAAa,EACb,MAAe;IAEf,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IACzC,OAAO;QACL,MAAM;QACN,EAAE;QACF,YAAY,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,MAAM,CAAC;QAC/C,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC;QACvB,QAAQ,EAAE;YACR,OAAO,EAAE,MAAM,CAAC,eAAe;YAC/B,MAAM,EAAE,MAAM,CAAC,cAAc;YAC7B,YAAY,EAAE,MAAM,CAAC,oBAAoB;YACzC,UAAU,EAAE,MAAM,CAAC,kBAAkB;YACrC,QAAQ,EAAE,MAAM,CAAC,gBAAgB;SAClC;QACD,aAAa,EAAE,MAAM,CAAC,oBAAoB;QAC1C,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;QACnD,QAAQ,EAAE,IAAI;KACf,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type { Locale } from 'zhin.js/i18n';
1
2
  import type { GameId } from '../types.js';
2
3
  import { type LotteryDb } from '../db.js';
3
4
  import { type SimulationResult } from './adaptive-sim.js';
@@ -22,8 +23,8 @@ export interface RefreshWeightsOptions extends BacktestOptions {
22
23
  holdoutFallback?: boolean;
23
24
  }
24
25
  export declare function refreshWeightsForGames(db: LotteryDb, gameIds: GameId[], options: RefreshWeightsOptions): Promise<BacktestSummary[]>;
25
- export declare function formatBacktestLine(s: BacktestSummary): string;
26
- export declare function formatBacktestSection(summaries: BacktestSummary[]): string;
26
+ export declare function formatBacktestLine(s: BacktestSummary, locale?: Locale): string;
27
+ export declare function formatBacktestSection(summaries: BacktestSummary[], locale?: Locale): string;
27
28
  export type { TrainWeightsOptions } from './train-weights.js';
28
29
  export { trainGameWeights, trainAllGameWeights, formatTrainReport } from './train-weights.js';
29
30
  //# sourceMappingURL=backtest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"backtest.d.ts","sourceRoot":"","sources":["../../src/evaluate/backtest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrD,OAAO,EAAyB,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAIjF,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,aAAa,EAAE,YAAY,CAAC;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAE/C,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAcjC;AAED,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,EAAE,CAAC,CAQ5B;AAED,8FAA8F;AAC9F,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAYjC;AAED,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAS5B;AAWD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,CAS7D;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,MAAM,CAS1E;AAED,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"backtest.d.ts","sourceRoot":"","sources":["../../src/evaluate/backtest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrD,OAAO,EAAyB,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAIjF,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,aAAa,EAAE,YAAY,CAAC;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAE/C,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAcjC;AAED,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,eAAe,EAAE,CAAC,CAQ5B;AAED,8FAA8F;AAC9F,wBAAsB,wBAAwB,CAC5C,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAYjC;AAED,MAAM,WAAW,qBAAsB,SAAQ,eAAe;IAC5D,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,eAAe,EAAE,CAAC,CAS5B;AAWD,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,eAAe,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAS9E;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,eAAe,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAS3F;AAED,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { messages as t } from '../i18n.js';
1
2
  import { loadDraws } from '../db.js';
2
3
  import { loadGameWeights } from './tracker.js';
3
4
  import { runAdaptiveSimulation } from './adaptive-sim.js';
@@ -62,24 +63,24 @@ function signedPct(delta) {
62
63
  const v = delta * 100;
63
64
  return v >= 0 ? `+${v.toFixed(1)}` : v.toFixed(1);
64
65
  }
65
- export function formatBacktestLine(s) {
66
+ export function formatBacktestLine(s, locale) {
66
67
  const w = formatWeights(s.finalWeights);
67
68
  return [
68
- `${s.gameId}: 调优 ${pct(s.adaptiveAvgHitRate)}%`,
69
- `固定 ${pct(s.fixedAvgHitRate)}%`,
70
- `随机 ${pct(s.randomAvgHitRate)}%`,
71
- `(Δ调优-随机 ${signedPct(s.adaptiveVsRandom)}%, n=${s.periods}, 热身${s.warmupPeriods}期)`,
72
- `终权重 ${w}`,
69
+ t(locale, 'backtestAdaptive', { game: s.gameId, rate: pct(s.adaptiveAvgHitRate) }),
70
+ t(locale, 'backtestFixed', { rate: pct(s.fixedAvgHitRate) }),
71
+ t(locale, 'backtestRandom', { rate: pct(s.randomAvgHitRate) }),
72
+ t(locale, 'backtestDelta', { delta: signedPct(s.adaptiveVsRandom), count: s.periods, warmup: s.warmupPeriods }),
73
+ t(locale, 'finalWeights', { weights: w }),
73
74
  ].join(' / ');
74
75
  }
75
- export function formatBacktestSection(summaries) {
76
+ export function formatBacktestSection(summaries, locale) {
76
77
  if (!summaries.length)
77
78
  return '';
78
79
  const lines = [
79
- '【回测可信度】近 N 期 walk-forward 抽样(全量训练请用 lottery-train)',
80
- ...summaries.map(formatBacktestLine),
81
- '说明:Δ 接近 0 为正常;终权重见 lottery_model_weights。',
82
- '推荐时若近端调优输给随机,将自动回退默认 F40/O35/T25(见【权重保护】)。',
80
+ t(locale, 'backtestTitle'),
81
+ ...summaries.map(summary => formatBacktestLine(summary, locale)),
82
+ t(locale, 'backtestNote'),
83
+ t(locale, 'backtestFallback'),
83
84
  ];
84
85
  return lines.join('\n');
85
86
  }
@@ -1 +1 @@
1
- {"version":3,"file":"backtest.js","sourceRoot":"","sources":["../../src/evaluate/backtest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"backtest.js","sourceRoot":"","sources":["../../src/evaluate/backtest.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { Locale } from 'zhin.js/i18n';
1
2
  import { type DrawNumbers, type GameId, type GamePick, type HitSummary, type ScoreWeights, type AccuracySnapshot } from '../types.js';
2
3
  import { type LotteryDb } from '../db.js';
3
4
  export declare const PREDICTIONS_TABLE = "lottery_predictions";
@@ -23,5 +24,5 @@ export declare function submitAgentReview(db: LotteryDb, input: {
23
24
  }, historyLimit: number): Promise<HitSummary | null>;
24
25
  export declare function saveAgentMemory(db: LotteryDb, content: string, memoryType?: string, gameId?: string): Promise<void>;
25
26
  export declare function loadAgentMemory(db: LotteryDb, gameId?: string, limit?: number): Promise<unknown[]>;
26
- export declare function formatReviewReport(db: LotteryDb, gameId?: GameId): Promise<string>;
27
+ export declare function formatReviewReport(db: LotteryDb, gameId?: GameId, locale?: Locale): Promise<string>;
27
28
  //# sourceMappingURL=tracker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/evaluate/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,WAAW,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAuB,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE5K,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAKtE,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AACvD,eAAO,MAAM,aAAa,0BAA0B,CAAC;AACrD,eAAO,MAAM,YAAY,yBAAyB,CAAC;AAEnD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE;IAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;CAAE,GAAG,IAAI,CA6B9G;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAgB1F;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAKnF;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAuB/G;AAED,wBAAsB,6BAA6B,CACjD,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,MAAM,EACd,IAAI,OAAa,GAChB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBlG;AAED,wBAAsB,sBAAsB,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAQ/F;AAED,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,SAAS,EACb,KAAK,EAAE;IACL,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,WAAW,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,EACD,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAgE5B;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,MAAM,EACf,UAAU,SAAY,EACtB,MAAM,SAAK,GACV,OAAO,CAAC,IAAI,CAAC,CASf;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAgBpG;AAED,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyCxF"}
1
+ {"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/evaluate/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAmB,KAAK,WAAW,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,KAAK,UAAU,EAAuB,KAAK,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE5K,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAKtE,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AACvD,eAAO,MAAM,aAAa,0BAA0B,CAAC;AACrD,eAAO,MAAM,YAAY,yBAAyB,CAAC;AAEnD,wBAAgB,gBAAgB,CAAC,EAAE,EAAE;IAAE,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;CAAE,GAAG,IAAI,CA6B9G;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAgB1F;AAED,wBAAsB,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAKnF;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,YAAY,EACrB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAgBf;AAED,wBAAsB,oBAAoB,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAuB/G;AAED,wBAAsB,6BAA6B,CACjD,EAAE,EAAE,SAAS,EACb,MAAM,EAAE,MAAM,EACd,IAAI,OAAa,GAChB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED,wBAAsB,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgBlG;AAED,wBAAsB,sBAAsB,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAQ/F;AAED,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,SAAS,EACb,KAAK,EAAE;IACL,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,WAAW,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,EACD,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAgE5B;AAED,wBAAsB,eAAe,CACnC,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,MAAM,EACf,UAAU,SAAY,EACtB,MAAM,SAAK,GACV,OAAO,CAAC,IAAI,CAAC,CASf;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAgBpG;AAED,wBAAsB,kBAAkB,CAAC,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyCzG"}
@@ -1,3 +1,4 @@
1
+ import { messages as t } from '../i18n.js';
1
2
  import { DEFAULT_WEIGHTS } from '../types.js';
2
3
  import { loadDraws, parseStoredJson } from '../db.js';
3
4
  import { comparePickToDraw, tuneWeightsFromDraw, formatHitSummary } from './hit-rate.js';
@@ -226,13 +227,13 @@ export async function loadAgentMemory(db, gameId, limit = 20) {
226
227
  .sort((a, b) => String(b.created_at ?? '').localeCompare(String(a.created_at ?? '')))
227
228
  .slice(0, limit);
228
229
  }
229
- export async function formatReviewReport(db, gameId) {
230
+ export async function formatReviewReport(db, gameId, locale) {
230
231
  const predModel = db.models.get(PREDICTIONS_TABLE);
231
232
  const memModel = db.models.get(MEMORY_TABLE);
232
233
  if (!predModel)
233
- return '数据库未就绪';
234
+ return t(locale, 'dbNotReady');
234
235
  const games = gameId ? [gameId] : ['kl8', 'ssq', 'dlt', 'fc3d', 'pl3', 'pl5'];
235
- const lines = ['【彩票推荐复盘】', ''];
236
+ const lines = [t(locale, 'reviewTitle'), ''];
236
237
  for (const gid of games) {
237
238
  const weights = await loadGameWeights(db, gid);
238
239
  const snap = await loadAccuracySnapshot(db, gid);
@@ -240,16 +241,16 @@ export async function formatReviewReport(db, gameId) {
240
241
  const recent = [...preds]
241
242
  .sort((a, b) => (b.evaluated_at ?? '').localeCompare(a.evaluated_at ?? ''))
242
243
  .slice(0, 5);
243
- lines.push(`■ ${gid} 模型 ${formatWeights(weights)}`);
244
+ lines.push(t(locale, 'reviewModel', { game: gid, weights: formatWeights(weights) }));
244
245
  if (snap) {
245
- lines.push(` 累计 ${snap.evalCount} 期 平均命中 ${(snap.avgHitRate * 100).toFixed(1)}%`);
246
+ lines.push(t(locale, 'reviewRate', { count: snap.evalCount, rate: (snap.avgHitRate * 100).toFixed(1) }));
246
247
  }
247
248
  else {
248
- lines.push(' 尚无复盘数据');
249
+ lines.push(t(locale, 'reviewEmpty'));
249
250
  }
250
251
  for (const p of recent) {
251
252
  const h = parseStoredJson(p.hit_summary, { total: 0, hits: 0, rate: 0, detail: '-' });
252
- lines.push(` 第${p.actual_issue}期 ${h.detail} (${(h.rate * 100).toFixed(0)}%)`);
253
+ lines.push(t(locale, 'reviewDraw', { issue: p.actual_issue, detail: h.detail, rate: (h.rate * 100).toFixed(0) }));
253
254
  if (p.analysis?.trim())
254
255
  lines.push(` ${p.analysis.trim()}`);
255
256
  }
@@ -258,7 +259,7 @@ export async function formatReviewReport(db, gameId) {
258
259
  if (memModel) {
259
260
  const mem = await loadAgentMemory(db, gameId, 5);
260
261
  if (mem.length) {
261
- lines.push('【Agent 记忆】');
262
+ lines.push(t(locale, 'agentMemory'));
262
263
  for (const m of mem) {
263
264
  lines.push(`- [${m.game_id || 'global'}/${m.memory_type}] ${m.content}`);
264
265
  }