@hedgehog-finance/hedgehog-plugin 1.0.21 → 1.0.23

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 (111) hide show
  1. package/dist/index.d.ts +4 -3
  2. package/dist/index.js +49 -6
  3. package/dist/index.js.map +1 -1
  4. package/dist/setup-api.d.ts +2 -0
  5. package/dist/setup-api.js +8 -0
  6. package/dist/setup-api.js.map +1 -0
  7. package/dist/src/channel.js +25 -23
  8. package/dist/src/channel.js.map +1 -1
  9. package/dist/src/core/database.js +449 -39
  10. package/dist/src/core/database.js.map +1 -1
  11. package/dist/src/dailyMorningBriefingCron.d.ts +46 -0
  12. package/dist/src/dailyMorningBriefingCron.js +82 -0
  13. package/dist/src/dailyMorningBriefingCron.js.map +1 -0
  14. package/dist/src/features/chartOutput.d.ts +2 -0
  15. package/dist/src/features/chartOutput.js +35 -0
  16. package/dist/src/features/chartOutput.js.map +1 -0
  17. package/dist/src/features/dailyMorningBriefing/schema.d.ts +56 -0
  18. package/dist/src/features/dailyMorningBriefing/schema.js +22 -0
  19. package/dist/src/features/dailyMorningBriefing/schema.js.map +1 -0
  20. package/dist/src/features/dailyMorningBriefing/tools.d.ts +12 -0
  21. package/dist/src/features/dailyMorningBriefing/tools.js +204 -0
  22. package/dist/src/features/dailyMorningBriefing/tools.js.map +1 -0
  23. package/dist/src/features/deepReasoning/schema.d.ts +43 -0
  24. package/dist/src/features/deepReasoning/schema.js +17 -0
  25. package/dist/src/features/deepReasoning/schema.js.map +1 -0
  26. package/dist/src/features/deepReasoning/tools.d.ts +12 -0
  27. package/dist/src/features/deepReasoning/tools.js +163 -0
  28. package/dist/src/features/deepReasoning/tools.js.map +1 -0
  29. package/dist/src/features/index.d.ts +2 -1
  30. package/dist/src/features/index.js +9 -1
  31. package/dist/src/features/index.js.map +1 -1
  32. package/dist/src/features/informationVerification/schema.d.ts +43 -0
  33. package/dist/src/features/informationVerification/schema.js +17 -0
  34. package/dist/src/features/informationVerification/schema.js.map +1 -0
  35. package/dist/src/features/informationVerification/tools.d.ts +12 -0
  36. package/dist/src/features/informationVerification/tools.js +162 -0
  37. package/dist/src/features/informationVerification/tools.js.map +1 -0
  38. package/dist/src/features/notes/schema.d.ts +136 -39
  39. package/dist/src/features/notes/schema.js +13 -10
  40. package/dist/src/features/notes/schema.js.map +1 -1
  41. package/dist/src/features/notes/tools.d.ts +1 -0
  42. package/dist/src/features/notes/tools.js +47 -14
  43. package/dist/src/features/notes/tools.js.map +1 -1
  44. package/dist/src/features/pluginInfo/schema.d.ts +79 -0
  45. package/dist/src/features/pluginInfo/schema.js +14 -0
  46. package/dist/src/features/pluginInfo/schema.js.map +1 -0
  47. package/dist/src/features/pluginInfo/tools.d.ts +1 -0
  48. package/dist/src/features/pluginInfo/tools.js +157 -2
  49. package/dist/src/features/pluginInfo/tools.js.map +1 -1
  50. package/dist/src/features/profileLibrary/schema.d.ts +34 -6
  51. package/dist/src/features/profileLibrary/schema.js +1 -1
  52. package/dist/src/features/profileLibrary/schema.js.map +1 -1
  53. package/dist/src/features/stockAnalysis/schema.d.ts +224 -31
  54. package/dist/src/features/stockAnalysis/schema.js +76 -12
  55. package/dist/src/features/stockAnalysis/schema.js.map +1 -1
  56. package/dist/src/features/stockAnalysis/tools.d.ts +6 -4
  57. package/dist/src/features/stockAnalysis/tools.js +389 -44
  58. package/dist/src/features/stockAnalysis/tools.js.map +1 -1
  59. package/dist/src/features/stockBasic/schema.d.ts +149 -0
  60. package/dist/src/features/stockBasic/schema.js +26 -0
  61. package/dist/src/features/stockBasic/schema.js.map +1 -0
  62. package/dist/src/features/stockBasic/tools.d.ts +12 -0
  63. package/dist/src/features/stockBasic/tools.js +124 -0
  64. package/dist/src/features/stockBasic/tools.js.map +1 -0
  65. package/dist/src/features/watchlist/logic.d.ts +3 -3
  66. package/dist/src/features/watchlist/logic.js +47 -46
  67. package/dist/src/features/watchlist/logic.js.map +1 -1
  68. package/dist/src/features/watchlist/schema.d.ts +89 -54
  69. package/dist/src/features/watchlist/schema.js +7 -4
  70. package/dist/src/features/watchlist/schema.js.map +1 -1
  71. package/dist/src/features/watchlist/tools.d.ts +106 -59
  72. package/dist/src/features/watchlist/tools.js +182 -104
  73. package/dist/src/features/watchlist/tools.js.map +1 -1
  74. package/dist/src/openclawConfig.d.ts +6 -0
  75. package/dist/src/openclawConfig.js +74 -0
  76. package/dist/src/openclawConfig.js.map +1 -0
  77. package/dist/src/openclawConstants.d.ts +4 -0
  78. package/dist/src/openclawConstants.js +10 -0
  79. package/dist/src/openclawConstants.js.map +1 -0
  80. package/dist/src/runtime.js +20 -0
  81. package/dist/src/runtime.js.map +1 -1
  82. package/index.ts +52 -5
  83. package/openclaw.plugin.json +24 -0
  84. package/package.json +20 -5
  85. package/setup-api.ts +10 -0
  86. package/src/channel.ts +26 -25
  87. package/src/core/database.ts +447 -40
  88. package/src/dailyMorningBriefingCron.ts +129 -0
  89. package/src/features/chartOutput.ts +35 -0
  90. package/src/features/dailyMorningBriefing/schema.ts +38 -0
  91. package/src/features/dailyMorningBriefing/tools.ts +246 -0
  92. package/src/features/deepReasoning/schema.ts +22 -0
  93. package/src/features/deepReasoning/tools.ts +182 -0
  94. package/src/features/index.ts +11 -2
  95. package/src/features/informationVerification/schema.ts +22 -0
  96. package/src/features/informationVerification/tools.ts +181 -0
  97. package/src/features/notes/schema.ts +17 -12
  98. package/src/features/notes/tools.ts +54 -17
  99. package/src/features/pluginInfo/schema.ts +19 -0
  100. package/src/features/pluginInfo/tools.ts +173 -2
  101. package/src/features/profileLibrary/schema.ts +1 -1
  102. package/src/features/stockAnalysis/schema.ts +99 -17
  103. package/src/features/stockAnalysis/tools.ts +447 -49
  104. package/src/features/stockBasic/schema.ts +33 -0
  105. package/src/features/stockBasic/tools.ts +157 -0
  106. package/src/features/watchlist/logic.ts +56 -53
  107. package/src/features/watchlist/schema.ts +11 -6
  108. package/src/features/watchlist/tools.ts +191 -106
  109. package/src/openclawConfig.ts +101 -0
  110. package/src/openclawConstants.ts +11 -0
  111. package/src/runtime.ts +19 -0
@@ -0,0 +1,149 @@
1
+ import { z } from "zod";
2
+ export declare const StockBasicItemSchema: z.ZodObject<{
3
+ act_ent_type: z.ZodDefault<z.ZodOptional<z.ZodString>>;
4
+ act_name: z.ZodDefault<z.ZodOptional<z.ZodString>>;
5
+ area: z.ZodDefault<z.ZodOptional<z.ZodString>>;
6
+ cnspell: z.ZodDefault<z.ZodOptional<z.ZodString>>;
7
+ curr_type: z.ZodDefault<z.ZodOptional<z.ZodString>>;
8
+ enname: z.ZodDefault<z.ZodOptional<z.ZodString>>;
9
+ exchange: z.ZodString;
10
+ fullname: z.ZodDefault<z.ZodOptional<z.ZodString>>;
11
+ industry: z.ZodDefault<z.ZodOptional<z.ZodString>>;
12
+ is_hs: z.ZodDefault<z.ZodOptional<z.ZodString>>;
13
+ list_date: z.ZodDefault<z.ZodOptional<z.ZodString>>;
14
+ market: z.ZodDefault<z.ZodOptional<z.ZodString>>;
15
+ name: z.ZodString;
16
+ stock_code: z.ZodString;
17
+ symbol: z.ZodString;
18
+ }, "strip", z.ZodTypeAny, {
19
+ symbol: string;
20
+ name: string;
21
+ stock_code: string;
22
+ industry: string;
23
+ market: string;
24
+ exchange: string;
25
+ act_ent_type: string;
26
+ act_name: string;
27
+ area: string;
28
+ cnspell: string;
29
+ curr_type: string;
30
+ enname: string;
31
+ fullname: string;
32
+ is_hs: string;
33
+ list_date: string;
34
+ }, {
35
+ symbol: string;
36
+ name: string;
37
+ stock_code: string;
38
+ exchange: string;
39
+ industry?: string | undefined;
40
+ market?: string | undefined;
41
+ act_ent_type?: string | undefined;
42
+ act_name?: string | undefined;
43
+ area?: string | undefined;
44
+ cnspell?: string | undefined;
45
+ curr_type?: string | undefined;
46
+ enname?: string | undefined;
47
+ fullname?: string | undefined;
48
+ is_hs?: string | undefined;
49
+ list_date?: string | undefined;
50
+ }>;
51
+ export type StockBasicItem = z.infer<typeof StockBasicItemSchema>;
52
+ export declare const SyncStockBasicParamsSchema: z.ZodObject<{
53
+ stocks: z.ZodArray<z.ZodObject<{
54
+ act_ent_type: z.ZodDefault<z.ZodOptional<z.ZodString>>;
55
+ act_name: z.ZodDefault<z.ZodOptional<z.ZodString>>;
56
+ area: z.ZodDefault<z.ZodOptional<z.ZodString>>;
57
+ cnspell: z.ZodDefault<z.ZodOptional<z.ZodString>>;
58
+ curr_type: z.ZodDefault<z.ZodOptional<z.ZodString>>;
59
+ enname: z.ZodDefault<z.ZodOptional<z.ZodString>>;
60
+ exchange: z.ZodString;
61
+ fullname: z.ZodDefault<z.ZodOptional<z.ZodString>>;
62
+ industry: z.ZodDefault<z.ZodOptional<z.ZodString>>;
63
+ is_hs: z.ZodDefault<z.ZodOptional<z.ZodString>>;
64
+ list_date: z.ZodDefault<z.ZodOptional<z.ZodString>>;
65
+ market: z.ZodDefault<z.ZodOptional<z.ZodString>>;
66
+ name: z.ZodString;
67
+ stock_code: z.ZodString;
68
+ symbol: z.ZodString;
69
+ }, "strip", z.ZodTypeAny, {
70
+ symbol: string;
71
+ name: string;
72
+ stock_code: string;
73
+ industry: string;
74
+ market: string;
75
+ exchange: string;
76
+ act_ent_type: string;
77
+ act_name: string;
78
+ area: string;
79
+ cnspell: string;
80
+ curr_type: string;
81
+ enname: string;
82
+ fullname: string;
83
+ is_hs: string;
84
+ list_date: string;
85
+ }, {
86
+ symbol: string;
87
+ name: string;
88
+ stock_code: string;
89
+ exchange: string;
90
+ industry?: string | undefined;
91
+ market?: string | undefined;
92
+ act_ent_type?: string | undefined;
93
+ act_name?: string | undefined;
94
+ area?: string | undefined;
95
+ cnspell?: string | undefined;
96
+ curr_type?: string | undefined;
97
+ enname?: string | undefined;
98
+ fullname?: string | undefined;
99
+ is_hs?: string | undefined;
100
+ list_date?: string | undefined;
101
+ }>, "many">;
102
+ }, "strip", z.ZodTypeAny, {
103
+ stocks: {
104
+ symbol: string;
105
+ name: string;
106
+ stock_code: string;
107
+ industry: string;
108
+ market: string;
109
+ exchange: string;
110
+ act_ent_type: string;
111
+ act_name: string;
112
+ area: string;
113
+ cnspell: string;
114
+ curr_type: string;
115
+ enname: string;
116
+ fullname: string;
117
+ is_hs: string;
118
+ list_date: string;
119
+ }[];
120
+ }, {
121
+ stocks: {
122
+ symbol: string;
123
+ name: string;
124
+ stock_code: string;
125
+ exchange: string;
126
+ industry?: string | undefined;
127
+ market?: string | undefined;
128
+ act_ent_type?: string | undefined;
129
+ act_name?: string | undefined;
130
+ area?: string | undefined;
131
+ cnspell?: string | undefined;
132
+ curr_type?: string | undefined;
133
+ enname?: string | undefined;
134
+ fullname?: string | undefined;
135
+ is_hs?: string | undefined;
136
+ list_date?: string | undefined;
137
+ }[];
138
+ }>;
139
+ export type SyncStockBasicParams = z.infer<typeof SyncStockBasicParamsSchema>;
140
+ export declare const GetStockBasicListParamsSchema: z.ZodOptional<z.ZodNullable<z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>>>;
141
+ export type GetStockBasicListParams = z.infer<typeof GetStockBasicListParamsSchema>;
142
+ export declare const GetStockBasicInfoParamsSchema: z.ZodObject<{
143
+ stock_code: z.ZodString;
144
+ }, "strip", z.ZodTypeAny, {
145
+ stock_code: string;
146
+ }, {
147
+ stock_code: string;
148
+ }>;
149
+ export type GetStockBasicInfoParams = z.infer<typeof GetStockBasicInfoParamsSchema>;
@@ -0,0 +1,26 @@
1
+ import { z } from "zod";
2
+ export const StockBasicItemSchema = z.object({
3
+ act_ent_type: z.string().optional().default(""),
4
+ act_name: z.string().optional().default(""),
5
+ area: z.string().optional().default(""),
6
+ cnspell: z.string().optional().default(""),
7
+ curr_type: z.string().optional().default(""),
8
+ enname: z.string().optional().default(""),
9
+ exchange: z.string().trim().min(1),
10
+ fullname: z.string().optional().default(""),
11
+ industry: z.string().optional().default(""),
12
+ is_hs: z.string().optional().default(""),
13
+ list_date: z.string().optional().default(""),
14
+ market: z.string().optional().default(""),
15
+ name: z.string().trim().min(1),
16
+ stock_code: z.string().trim().min(1),
17
+ symbol: z.string().trim().min(1)
18
+ });
19
+ export const SyncStockBasicParamsSchema = z.object({
20
+ stocks: z.array(StockBasicItemSchema).min(1)
21
+ });
22
+ export const GetStockBasicListParamsSchema = z.object({}).nullish();
23
+ export const GetStockBasicInfoParamsSchema = z.object({
24
+ stock_code: z.string().trim().min(1).describe("股票代码")
25
+ });
26
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../../src/features/stockBasic/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC/C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC3C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACvC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC5C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACzC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC3C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC3C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACxC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC5C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IACzC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACpC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAChC,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CAC5C,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;AAGpE,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,CAAC,MAAM,CAAC;IACrD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;CACrD,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ interface RuntimeTool {
2
+ name: string;
3
+ label?: string;
4
+ description: string;
5
+ parameters: unknown;
6
+ registerTool?: boolean;
7
+ execute(params: unknown, ctx?: {
8
+ userId: string;
9
+ }): Promise<string>;
10
+ }
11
+ export declare const stockBasicTools: Record<string, RuntimeTool>;
12
+ export {};
@@ -0,0 +1,124 @@
1
+ import { getDB } from "../../core/database.js";
2
+ import { GetStockBasicListParamsSchema, GetStockBasicInfoParamsSchema, SyncStockBasicParamsSchema } from "./schema.js";
3
+ const GetStockBasicInfoAgentToolSchema = {
4
+ type: "object",
5
+ additionalProperties: false,
6
+ required: ["stock_code"],
7
+ properties: {
8
+ stock_code: { type: "string", description: "股票代码,例如:000001.SZ 或 600000.SH" }
9
+ }
10
+ };
11
+ function normalizeStockBasic(stock) {
12
+ return {
13
+ ...stock,
14
+ stock_code: stock.stock_code.trim().toUpperCase().replace(/\.SS$/i, ".SH"),
15
+ symbol: stock.symbol.trim(),
16
+ exchange: stock.exchange.trim().toUpperCase(),
17
+ name: stock.name.trim(),
18
+ fullname: stock.fullname.trim(),
19
+ enname: stock.enname.trim(),
20
+ cnspell: stock.cnspell.trim().toUpperCase()
21
+ };
22
+ }
23
+ function escapeLike(value) {
24
+ return value.replace(/[\\%_]/g, "\\$&");
25
+ }
26
+ export const stockBasicTools = {
27
+ sync_stock_basic: {
28
+ name: "sync_stock_basic",
29
+ description: "批量同步证券基础资料主数据。系统以 stock_code 作为唯一标识执行新增或覆盖更新,适用于初始化或定期刷新股票代码、名称、交易所、行业、上市日期等基础字段。",
30
+ parameters: SyncStockBasicParamsSchema,
31
+ registerTool: false,
32
+ async execute(params) {
33
+ const args = SyncStockBasicParamsSchema.parse(params);
34
+ const db = getDB();
35
+ const stmt = db.prepare(`
36
+ INSERT INTO stock_basic (
37
+ stock_code,
38
+ symbol,
39
+ name,
40
+ fullname,
41
+ enname,
42
+ cnspell,
43
+ exchange,
44
+ market,
45
+ industry,
46
+ area,
47
+ curr_type,
48
+ list_date,
49
+ is_hs,
50
+ act_name,
51
+ act_ent_type
52
+ )
53
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
54
+ ON CONFLICT(stock_code) DO UPDATE SET
55
+ symbol = excluded.symbol,
56
+ name = excluded.name,
57
+ fullname = excluded.fullname,
58
+ enname = excluded.enname,
59
+ cnspell = excluded.cnspell,
60
+ exchange = excluded.exchange,
61
+ market = excluded.market,
62
+ industry = excluded.industry,
63
+ area = excluded.area,
64
+ curr_type = excluded.curr_type,
65
+ list_date = excluded.list_date,
66
+ is_hs = excluded.is_hs,
67
+ act_name = excluded.act_name,
68
+ act_ent_type = excluded.act_ent_type,
69
+ updatedAt = STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')
70
+ `);
71
+ if (db.inTransaction)
72
+ db.exec("ROLLBACK");
73
+ db.exec("BEGIN TRANSACTION");
74
+ try {
75
+ for (const rawStock of args.stocks) {
76
+ const stock = normalizeStockBasic(rawStock);
77
+ stmt.run(stock.stock_code, stock.symbol, stock.name, stock.fullname, stock.enname, stock.cnspell, stock.exchange, stock.market, stock.industry, stock.area, stock.curr_type, stock.list_date, stock.is_hs, stock.act_name, stock.act_ent_type);
78
+ }
79
+ db.exec("COMMIT");
80
+ return JSON.stringify({ success: true, synced: args.stocks.length });
81
+ }
82
+ catch (e) {
83
+ if (db.inTransaction)
84
+ db.exec("ROLLBACK");
85
+ return JSON.stringify({ success: false, error: e.message });
86
+ }
87
+ }
88
+ },
89
+ get_stock_basic_list: {
90
+ name: "get_stock_basic_list",
91
+ description: "查询证券基础资料全量列表。返回股票代码、证券简称、公司全称、交易所、市场板块、行业及上市日期等基础字段,用于前端缓存、下拉选择或基础数据校验。",
92
+ parameters: GetStockBasicListParamsSchema,
93
+ registerTool: false,
94
+ async execute(params) {
95
+ GetStockBasicListParamsSchema.parse(params);
96
+ const db = getDB();
97
+ const rows = db.prepare(`
98
+ SELECT stock_code, symbol, name, fullname, enname, cnspell, exchange, market, industry, area, curr_type, list_date, is_hs, act_name, act_ent_type, createdAt, updatedAt
99
+ FROM stock_basic
100
+ ORDER BY exchange ASC, symbol ASC
101
+ `).all();
102
+ return JSON.stringify({ success: true, data: rows });
103
+ }
104
+ },
105
+ get_stock_basic_info: {
106
+ name: "get_stock_basic_info",
107
+ label: "查询股票基本信息",
108
+ description: "根据股票代码查询证券基础资料。",
109
+ parameters: GetStockBasicInfoAgentToolSchema,
110
+ registerTool: true,
111
+ async execute(params) {
112
+ const args = GetStockBasicInfoParamsSchema.parse(params);
113
+ const db = getDB();
114
+ const code = args.stock_code.trim().toUpperCase().replace(/\.SS$/i, ".SH");
115
+ const row = db.prepare(`
116
+ SELECT stock_code, name, enname, exchange, market, industry, is_hs
117
+ FROM stock_basic
118
+ WHERE stock_code = ?
119
+ `).get(code);
120
+ return JSON.stringify({ success: true, data: row || null });
121
+ }
122
+ }
123
+ };
124
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../../src/features/stockBasic/tools.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  import { PluginRuntime } from "openclaw/plugin-sdk";
2
2
  import { StockClassification } from "../../types.js";
3
- declare function normalizeStockCodeForCache(stockCode: string, exchange?: string): string;
3
+ declare function normalizeStockCodeForCache(stock_code: string, exchange?: string): string;
4
4
  export declare const watchlistLogic: {
5
5
  _normalizeStockCodeForCache: typeof normalizeStockCodeForCache;
6
- getStockClassification(rt: PluginRuntime, stockName: string, stockCode: string, exchange: string, _userId: string): Promise<StockClassification | null>;
6
+ getStockClassification(rt: PluginRuntime, stock_name: string, stock_code: string, exchange: string, _userId: string): Promise<StockClassification | null>;
7
7
  classifyStocksTogether(rt: PluginRuntime, stocks: any[], _userId: string): Promise<StockClassification[]>;
8
8
  getBatchStockClassification(rt: PluginRuntime, stocks: any[], _userId: string, options?: {
9
9
  requireComplete?: boolean;
@@ -13,7 +13,7 @@ export declare const watchlistLogic: {
13
13
  industries: any[];
14
14
  themes: any[];
15
15
  };
16
- _autoClassifyWithAI(rt: PluginRuntime, stockName: string, stockCode: string, exchange: string): Promise<StockClassification | null>;
16
+ _autoClassifyWithAI(rt: PluginRuntime, stock_name: string, stock_code: string, exchange: string): Promise<StockClassification | null>;
17
17
  _callClassifierCompletion(rt: PluginRuntime, sessionId: string, prompt: string, timeoutMs: number): Promise<string>;
18
18
  _callClassifierAi(rt: PluginRuntime, sessionId: string, prompt: string, timeoutMs: number): Promise<string>;
19
19
  _ensureCategory(db: any, name: string, type: "industry" | "theme", userId: string): string;
@@ -19,8 +19,8 @@ const CLASSIFIER_SYSTEM_PROMPT = [
19
19
  "禁止输出推理过程、解释、Markdown 或代码块;不要思考展开,只做快速匹配。",
20
20
  "只允许根据用户消息中提供的行业/主题分类字典和股票列表输出纯 JSON 数组。"
21
21
  ].join("\n");
22
- function normalizeStockCodeForCache(stockCode, exchange) {
23
- const code = String(stockCode || "")
22
+ function normalizeStockCodeForCache(stock_code, exchange) {
23
+ const code = String(stock_code || "")
24
24
  .trim()
25
25
  .toUpperCase();
26
26
  if (/\.(SH|SS|SZ|HK|US)$/i.test(code)) {
@@ -37,18 +37,18 @@ function normalizeStockCodeForCache(stockCode, exchange) {
37
37
  return code;
38
38
  }
39
39
  }
40
- function legacyStockCodeWithoutSuffix(stockCode) {
41
- return String(stockCode || "")
40
+ function legacyStockCodeWithoutSuffix(stock_code) {
41
+ return String(stock_code || "")
42
42
  .trim()
43
43
  .toUpperCase()
44
44
  .replace(/\.(SH|SS|SZ|HK|US)$/i, "");
45
45
  }
46
- function getCachedClassificationRow(db, stockCode, exchange) {
47
- const cacheCode = normalizeStockCodeForCache(stockCode, exchange);
48
- const legacyCode = legacyStockCodeWithoutSuffix(stockCode);
46
+ function getCachedClassificationRow(db, stock_code, exchange) {
47
+ const cacheCode = normalizeStockCodeForCache(stock_code, exchange);
48
+ const legacyCode = legacyStockCodeWithoutSuffix(stock_code);
49
49
  const stmt = db.prepare(`
50
- SELECT industryJson, themeJson FROM global_stock_metadata
51
- WHERE stockCode = ? AND exchange = ?
50
+ SELECT industry_classification, theme_classification FROM stock_classification_cache
51
+ WHERE stock_code = ? AND exchange = ?
52
52
  `);
53
53
  return (stmt.get(cacheCode, exchange) || (legacyCode !== cacheCode ? stmt.get(legacyCode, exchange) : undefined));
54
54
  }
@@ -149,21 +149,21 @@ function extractJsonArray(text) {
149
149
  }
150
150
  export const watchlistLogic = {
151
151
  _normalizeStockCodeForCache: normalizeStockCodeForCache,
152
- async getStockClassification(rt, stockName, stockCode, exchange, _userId) {
152
+ async getStockClassification(rt, stock_name, stock_code, exchange, _userId) {
153
153
  const db = getDB();
154
- const cached = getCachedClassificationRow(db, stockCode, exchange);
155
- if (cached && cached.industryJson) {
154
+ const cached = getCachedClassificationRow(db, stock_code, exchange);
155
+ if (cached && cached.industry_classification) {
156
156
  try {
157
157
  return watchlistLogic._normalizeCachedClassification({
158
- industry: JSON.parse(cached.industryJson),
159
- theme: JSON.parse(cached.themeJson || '[]'),
158
+ industry: JSON.parse(cached.industry_classification),
159
+ theme: JSON.parse(cached.theme_classification || '[]'),
160
160
  weight: 50
161
161
  });
162
162
  }
163
163
  catch (e) {
164
164
  }
165
165
  }
166
- const classification = await watchlistLogic._autoClassifyWithAI(rt, stockName, stockCode, exchange);
166
+ const classification = await watchlistLogic._autoClassifyWithAI(rt, stock_name, stock_code, exchange);
167
167
  return classification;
168
168
  },
169
169
  async classifyStocksTogether(rt, stocks, _userId) {
@@ -171,12 +171,12 @@ export const watchlistLogic = {
171
171
  const results = new Array(stocks.length).fill(null);
172
172
  const pendingStocks = [];
173
173
  stocks.forEach((stock, idx) => {
174
- const cached = getCachedClassificationRow(db, stock.stockCode, stock.exchange);
175
- if (cached && cached.industryJson) {
174
+ const cached = getCachedClassificationRow(db, stock.stock_code, stock.exchange);
175
+ if (cached && cached.industry_classification) {
176
176
  try {
177
177
  results[idx] = watchlistLogic._normalizeCachedClassification({
178
- industry: JSON.parse(cached.industryJson),
179
- theme: JSON.parse(cached.themeJson || '[]'),
178
+ industry: JSON.parse(cached.industry_classification),
179
+ theme: JSON.parse(cached.theme_classification || '[]'),
180
180
  weight: 50
181
181
  });
182
182
  return;
@@ -186,8 +186,8 @@ export const watchlistLogic = {
186
186
  }
187
187
  pendingStocks.push({
188
188
  idx,
189
- stockName: stock.stockName,
190
- stockCode: stock.stockCode,
189
+ stock_name: stock.stock_name,
190
+ stock_code: stock.stock_code,
191
191
  exchange: stock.exchange
192
192
  });
193
193
  });
@@ -198,7 +198,7 @@ export const watchlistLogic = {
198
198
  if (cats.industries.length === 0) {
199
199
  throw new Error("行业分类字典为空,无法分析行业/主题关系");
200
200
  }
201
- const stocksList = pendingStocks.map(s => `- ${s.stockName} (${s.stockCode})`).join("\n");
201
+ const stocksList = pendingStocks.map(s => `- ${s.stock_name} (${s.stock_code})`).join("\n");
202
202
  const prompt = watchlistLogic._buildAiPrompt(cats.industries, cats.themes, stocksList, true);
203
203
  const sessionId = `classify-batch-${randomUUID()}`;
204
204
  const aiText = await watchlistLogic._callClassifierAi(rt, sessionId, prompt, resolveBatchClassificationTimeoutMs(pendingStocks.length));
@@ -209,7 +209,7 @@ export const watchlistLogic = {
209
209
  catch (e) {
210
210
  logger.warn({
211
211
  err: e instanceof Error ? e.message : String(e),
212
- pendingCodes: pendingStocks.map(stock => stock.stockCode),
212
+ pendingCodes: pendingStocks.map(stock => stock.stock_code),
213
213
  aiTextLength: aiText.length,
214
214
  aiText
215
215
  }, "[Watchlist] batch classification AI parse failed");
@@ -223,17 +223,17 @@ export const watchlistLogic = {
223
223
  let parsedResults;
224
224
  try {
225
225
  parsedResults = pendingStocks.map((stock, i) => {
226
- const raw = parsedByCode.get(String(stock.stockCode)) || parsed[i];
226
+ const raw = parsedByCode.get(String(stock.stock_code)) || parsed[i];
227
227
  return {
228
228
  stock,
229
- data: watchlistLogic._parseClassification(raw, cats, stock.stockName || stock.stockCode)
229
+ data: watchlistLogic._parseClassification(raw, cats, stock.stock_name || stock.stock_code)
230
230
  };
231
231
  });
232
232
  }
233
233
  catch (e) {
234
234
  logger.warn({
235
235
  err: e instanceof Error ? e.message : String(e),
236
- pendingCodes: pendingStocks.map(stock => stock.stockCode),
236
+ pendingCodes: pendingStocks.map(stock => stock.stock_code),
237
237
  aiTextLength: aiText.length,
238
238
  aiText
239
239
  }, "[Watchlist] batch classification AI semantic parse failed");
@@ -244,7 +244,7 @@ export const watchlistLogic = {
244
244
  }
245
245
  const missing = stocks.find((_, i) => !results[i]);
246
246
  if (missing) {
247
- throw new Error(`行业/主题关系分析失败: ${missing.stockName || missing.stockCode}`);
247
+ throw new Error(`行业/主题关系分析失败: ${missing.stock_name || missing.stock_code}`);
248
248
  }
249
249
  return results;
250
250
  },
@@ -255,21 +255,21 @@ export const watchlistLogic = {
255
255
  stocks.forEach((s, i) => {
256
256
  const cached = options.forceRefresh
257
257
  ? undefined
258
- : getCachedClassificationRow(db, s.stockCode, s.exchange);
259
- if (cached && cached.industryJson) {
258
+ : getCachedClassificationRow(db, s.stock_code, s.exchange);
259
+ if (cached && cached.industry_classification) {
260
260
  try {
261
261
  results[i] = watchlistLogic._normalizeCachedClassification({
262
- industry: JSON.parse(cached.industryJson),
263
- theme: JSON.parse(cached.themeJson || '[]'),
262
+ industry: JSON.parse(cached.industry_classification),
263
+ theme: JSON.parse(cached.theme_classification || '[]'),
264
264
  weight: 50
265
265
  });
266
266
  }
267
267
  catch (e) {
268
- pendingStocks.push({ idx: i, name: s.stockName, code: s.stockCode, exchange: s.exchange });
268
+ pendingStocks.push({ idx: i, name: s.stock_name, code: s.stock_code, exchange: s.exchange });
269
269
  }
270
270
  }
271
271
  else {
272
- pendingStocks.push({ idx: i, name: s.stockName, code: s.stockCode, exchange: s.exchange });
272
+ pendingStocks.push({ idx: i, name: s.stock_name, code: s.stock_code, exchange: s.exchange });
273
273
  }
274
274
  });
275
275
  if (pendingStocks.length > 0) {
@@ -309,36 +309,36 @@ export const watchlistLogic = {
309
309
  if (options.requireComplete) {
310
310
  const missing = stocks.find((_, i) => !results[i]);
311
311
  if (missing) {
312
- throw new Error(`行业/主题关系分析失败: ${missing.stockName || missing.stockCode}`);
312
+ throw new Error(`行业/主题关系分析失败: ${missing.stock_name || missing.stock_code}`);
313
313
  }
314
314
  }
315
315
  return results;
316
316
  },
317
317
  _getKnownCategories(db) {
318
- const industries = db.prepare("SELECT name FROM watchlist_categories WHERE type = 'industry'").all();
319
- const themes = db.prepare("SELECT name FROM watchlist_categories WHERE type = 'theme'").all();
318
+ const industries = db.prepare("SELECT name FROM industry_theme_categories WHERE type = 'industry'").all();
319
+ const themes = db.prepare("SELECT name FROM industry_theme_categories WHERE type = 'theme'").all();
320
320
  return {
321
321
  industries: industries.map(i => i.name),
322
322
  themes: themes.map(t => t.name)
323
323
  };
324
324
  },
325
- async _autoClassifyWithAI(rt, stockName, stockCode, exchange) {
325
+ async _autoClassifyWithAI(rt, stock_name, stock_code, exchange) {
326
326
  const db = getDB();
327
327
  const cats = watchlistLogic._getKnownCategories(db);
328
328
  if (cats.industries.length === 0) {
329
329
  return null;
330
330
  }
331
- const prompt = watchlistLogic._buildAiPrompt(cats.industries, cats.themes, `${stockName} (${stockCode})`, false);
332
- const aiText = await watchlistLogic._callClassifierAi(rt, `classify-${stockCode}`, prompt, SINGLE_CLASSIFICATION_TIMEOUT_MS);
331
+ const prompt = watchlistLogic._buildAiPrompt(cats.industries, cats.themes, `${stock_name} (${stock_code})`, false);
332
+ const aiText = await watchlistLogic._callClassifierAi(rt, `classify-${stock_code}`, prompt, SINGLE_CLASSIFICATION_TIMEOUT_MS);
333
333
  try {
334
334
  const parsed = extractJsonArray(aiText);
335
335
  const raw = parsed[0];
336
336
  if (raw) {
337
- return watchlistLogic._parseClassification(raw, cats, stockName || stockCode);
337
+ return watchlistLogic._parseClassification(raw, cats, stock_name || stock_code);
338
338
  }
339
339
  }
340
340
  catch (e) {
341
- logger.warn({ err: e instanceof Error ? e.message : String(e), stockCode, stockName }, "[Watchlist] AI 分类解析异常");
341
+ logger.warn({ err: e instanceof Error ? e.message : String(e), stock_code, stock_name }, "[Watchlist] AI 分类解析异常");
342
342
  }
343
343
  return null;
344
344
  },
@@ -355,11 +355,12 @@ export const watchlistLogic = {
355
355
  }
356
356
  }
357
357
  };
358
- const prepared = await prepareSimpleCompletionModelForAgent({
358
+ const completionModelParams = {
359
359
  cfg: embeddedCfg,
360
360
  agentId: MAIN_AGENT_ID,
361
361
  allowBundledStaticCatalogFallback: true
362
- });
362
+ };
363
+ const prepared = await prepareSimpleCompletionModelForAgent(completionModelParams);
363
364
  if ("error" in prepared) {
364
365
  throw new Error(prepared.error);
365
366
  }
@@ -409,13 +410,13 @@ export const watchlistLogic = {
409
410
  }
410
411
  },
411
412
  _ensureCategory(db, name, type, userId) {
412
- const existing = db.prepare("SELECT id FROM watchlist_categories WHERE userId = ? AND name = ? AND type = ?").get(userId, name, type);
413
+ const existing = db.prepare("SELECT id FROM industry_theme_categories WHERE userId = ? AND name = ? AND type = ?").get(userId, name, type);
413
414
  if (existing)
414
415
  return existing.id;
415
- const maxOrderRow = db.prepare("SELECT MAX(sortOrder) as max FROM watchlist_categories WHERE userId = ?").get(userId);
416
+ const maxOrderRow = db.prepare("SELECT MAX(sortOrder) as max FROM industry_theme_categories WHERE userId = ?").get(userId);
416
417
  const nextOrder = (maxOrderRow?.max || 0) + 10;
417
418
  const id = randomUUID();
418
- db.prepare(`INSERT INTO watchlist_categories (id, userId, name, type, sortOrder, weight) VALUES (?, ?, ?, ?, ?, 0)`).run(id, userId, name, type, nextOrder);
419
+ db.prepare(`INSERT INTO industry_theme_categories (id, userId, name, type, sortOrder, weight) VALUES (?, ?, ?, ?, ?, 0)`).run(id, userId, name, type, nextOrder);
419
420
  return id;
420
421
  },
421
422
  _buildSmartSortPrompt(stocks) {