@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.
- package/dist/index.d.ts +4 -3
- package/dist/index.js +49 -6
- package/dist/index.js.map +1 -1
- package/dist/setup-api.d.ts +2 -0
- package/dist/setup-api.js +8 -0
- package/dist/setup-api.js.map +1 -0
- package/dist/src/channel.js +25 -23
- package/dist/src/channel.js.map +1 -1
- package/dist/src/core/database.js +449 -39
- package/dist/src/core/database.js.map +1 -1
- package/dist/src/dailyMorningBriefingCron.d.ts +46 -0
- package/dist/src/dailyMorningBriefingCron.js +82 -0
- package/dist/src/dailyMorningBriefingCron.js.map +1 -0
- package/dist/src/features/chartOutput.d.ts +2 -0
- package/dist/src/features/chartOutput.js +35 -0
- package/dist/src/features/chartOutput.js.map +1 -0
- package/dist/src/features/dailyMorningBriefing/schema.d.ts +56 -0
- package/dist/src/features/dailyMorningBriefing/schema.js +22 -0
- package/dist/src/features/dailyMorningBriefing/schema.js.map +1 -0
- package/dist/src/features/dailyMorningBriefing/tools.d.ts +12 -0
- package/dist/src/features/dailyMorningBriefing/tools.js +204 -0
- package/dist/src/features/dailyMorningBriefing/tools.js.map +1 -0
- package/dist/src/features/deepReasoning/schema.d.ts +43 -0
- package/dist/src/features/deepReasoning/schema.js +17 -0
- package/dist/src/features/deepReasoning/schema.js.map +1 -0
- package/dist/src/features/deepReasoning/tools.d.ts +12 -0
- package/dist/src/features/deepReasoning/tools.js +163 -0
- package/dist/src/features/deepReasoning/tools.js.map +1 -0
- package/dist/src/features/index.d.ts +2 -1
- package/dist/src/features/index.js +9 -1
- package/dist/src/features/index.js.map +1 -1
- package/dist/src/features/informationVerification/schema.d.ts +43 -0
- package/dist/src/features/informationVerification/schema.js +17 -0
- package/dist/src/features/informationVerification/schema.js.map +1 -0
- package/dist/src/features/informationVerification/tools.d.ts +12 -0
- package/dist/src/features/informationVerification/tools.js +162 -0
- package/dist/src/features/informationVerification/tools.js.map +1 -0
- package/dist/src/features/notes/schema.d.ts +136 -39
- package/dist/src/features/notes/schema.js +13 -10
- package/dist/src/features/notes/schema.js.map +1 -1
- package/dist/src/features/notes/tools.d.ts +1 -0
- package/dist/src/features/notes/tools.js +47 -14
- package/dist/src/features/notes/tools.js.map +1 -1
- package/dist/src/features/pluginInfo/schema.d.ts +79 -0
- package/dist/src/features/pluginInfo/schema.js +14 -0
- package/dist/src/features/pluginInfo/schema.js.map +1 -0
- package/dist/src/features/pluginInfo/tools.d.ts +1 -0
- package/dist/src/features/pluginInfo/tools.js +157 -2
- package/dist/src/features/pluginInfo/tools.js.map +1 -1
- package/dist/src/features/profileLibrary/schema.d.ts +34 -6
- package/dist/src/features/profileLibrary/schema.js +1 -1
- package/dist/src/features/profileLibrary/schema.js.map +1 -1
- package/dist/src/features/stockAnalysis/schema.d.ts +224 -31
- package/dist/src/features/stockAnalysis/schema.js +76 -12
- package/dist/src/features/stockAnalysis/schema.js.map +1 -1
- package/dist/src/features/stockAnalysis/tools.d.ts +6 -4
- package/dist/src/features/stockAnalysis/tools.js +389 -44
- package/dist/src/features/stockAnalysis/tools.js.map +1 -1
- package/dist/src/features/stockBasic/schema.d.ts +149 -0
- package/dist/src/features/stockBasic/schema.js +26 -0
- package/dist/src/features/stockBasic/schema.js.map +1 -0
- package/dist/src/features/stockBasic/tools.d.ts +12 -0
- package/dist/src/features/stockBasic/tools.js +124 -0
- package/dist/src/features/stockBasic/tools.js.map +1 -0
- package/dist/src/features/watchlist/logic.d.ts +3 -3
- package/dist/src/features/watchlist/logic.js +47 -46
- package/dist/src/features/watchlist/logic.js.map +1 -1
- package/dist/src/features/watchlist/schema.d.ts +89 -54
- package/dist/src/features/watchlist/schema.js +7 -4
- package/dist/src/features/watchlist/schema.js.map +1 -1
- package/dist/src/features/watchlist/tools.d.ts +106 -59
- package/dist/src/features/watchlist/tools.js +182 -104
- package/dist/src/features/watchlist/tools.js.map +1 -1
- package/dist/src/openclawConfig.d.ts +6 -0
- package/dist/src/openclawConfig.js +74 -0
- package/dist/src/openclawConfig.js.map +1 -0
- package/dist/src/openclawConstants.d.ts +4 -0
- package/dist/src/openclawConstants.js +10 -0
- package/dist/src/openclawConstants.js.map +1 -0
- package/dist/src/runtime.js +20 -0
- package/dist/src/runtime.js.map +1 -1
- package/index.ts +52 -5
- package/openclaw.plugin.json +24 -0
- package/package.json +20 -5
- package/setup-api.ts +10 -0
- package/src/channel.ts +26 -25
- package/src/core/database.ts +447 -40
- package/src/dailyMorningBriefingCron.ts +129 -0
- package/src/features/chartOutput.ts +35 -0
- package/src/features/dailyMorningBriefing/schema.ts +38 -0
- package/src/features/dailyMorningBriefing/tools.ts +246 -0
- package/src/features/deepReasoning/schema.ts +22 -0
- package/src/features/deepReasoning/tools.ts +182 -0
- package/src/features/index.ts +11 -2
- package/src/features/informationVerification/schema.ts +22 -0
- package/src/features/informationVerification/tools.ts +181 -0
- package/src/features/notes/schema.ts +17 -12
- package/src/features/notes/tools.ts +54 -17
- package/src/features/pluginInfo/schema.ts +19 -0
- package/src/features/pluginInfo/tools.ts +173 -2
- package/src/features/profileLibrary/schema.ts +1 -1
- package/src/features/stockAnalysis/schema.ts +99 -17
- package/src/features/stockAnalysis/tools.ts +447 -49
- package/src/features/stockBasic/schema.ts +33 -0
- package/src/features/stockBasic/tools.ts +157 -0
- package/src/features/watchlist/logic.ts +56 -53
- package/src/features/watchlist/schema.ts +11 -6
- package/src/features/watchlist/tools.ts +191 -106
- package/src/openclawConfig.ts +101 -0
- package/src/openclawConstants.ts +11 -0
- package/src/runtime.ts +19 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/core";
|
|
2
|
+
import { logger } from "./core/logger.js";
|
|
3
|
+
import { CHART_OUTPUT_GUIDANCE } from "./features/chartOutput.js";
|
|
4
|
+
import { HEDGEHOG_AGENT_ID } from "./openclawConstants.js";
|
|
5
|
+
|
|
6
|
+
const DAILY_MORNING_BRIEFING_CRON_ID = "hedgehog_daily_morning_briefing";
|
|
7
|
+
const DAILY_MORNING_BRIEFING_SESSION_KEY = `cron:${DAILY_MORNING_BRIEFING_CRON_ID}`;
|
|
8
|
+
const DAILY_MORNING_BRIEFING_SKILL = "hedgehog-daily-morning-briefing";
|
|
9
|
+
const DAILY_MORNING_BRIEFING_MESSAGE = JSON.stringify({
|
|
10
|
+
cw_system_prompt: [
|
|
11
|
+
"开始分析前必须先调用 save_daily_morning_briefing,参数为 {\"status\":\"generating\",\"content\":\"\"};如果返回 skipped=true,必须立即停止,不要继续调用 skill 或生成正文。",
|
|
12
|
+
`必须触发并使用 ${DAILY_MORNING_BRIEFING_SKILL} skill 生成盘前简报。`,
|
|
13
|
+
"生成成功后必须调用 save_daily_morning_briefing,参数为 {\"status\":\"completed\",\"content\":\"...\"},content 传最终完整早报正文。",
|
|
14
|
+
"生成失败后必须调用 save_daily_morning_briefing,参数为 {\"status\":\"failed\",\"content\":\"...\"},content 存放完整错误信息。",
|
|
15
|
+
"如果最终内容包含 [图表数据],正文必须已经包含所有对应图表占位符。"
|
|
16
|
+
].join("\n"),
|
|
17
|
+
cw_market: "CN",
|
|
18
|
+
cw_content: [
|
|
19
|
+
"生成每日早报"
|
|
20
|
+
].join("\n"),
|
|
21
|
+
cw_output: [
|
|
22
|
+
`输出结构以 ${DAILY_MORNING_BRIEFING_SKILL} skill 的交付模板为准。`,
|
|
23
|
+
CHART_OUTPUT_GUIDANCE
|
|
24
|
+
].join("\n")
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
type CronServiceLike = {
|
|
28
|
+
list(opts?: { includeDisabled?: boolean }): Promise<CronJobLike[]>;
|
|
29
|
+
add(input: DailyMorningBriefingCronConfig): Promise<unknown>;
|
|
30
|
+
update(id: string, patch: DailyMorningBriefingCronConfig): Promise<unknown>;
|
|
31
|
+
remove(id: string): Promise<{ ok?: boolean; removed?: boolean } | undefined>;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
type CronJobLike = {
|
|
35
|
+
id?: string;
|
|
36
|
+
name?: string;
|
|
37
|
+
sessionKey?: string;
|
|
38
|
+
schedule?: {
|
|
39
|
+
kind?: string;
|
|
40
|
+
tz?: unknown;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
type DailyMorningBriefingCronConfig = {
|
|
45
|
+
agentId: string;
|
|
46
|
+
name: string;
|
|
47
|
+
description: string;
|
|
48
|
+
enabled: boolean;
|
|
49
|
+
schedule: {
|
|
50
|
+
kind: "cron";
|
|
51
|
+
expr: string;
|
|
52
|
+
tz?: string;
|
|
53
|
+
};
|
|
54
|
+
sessionTarget: "isolated";
|
|
55
|
+
wakeMode: "now";
|
|
56
|
+
payload: {
|
|
57
|
+
kind: "agentTurn";
|
|
58
|
+
message: string;
|
|
59
|
+
timeoutSeconds: number;
|
|
60
|
+
};
|
|
61
|
+
delivery: {
|
|
62
|
+
mode: "none";
|
|
63
|
+
};
|
|
64
|
+
deleteAfterRun: false;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function buildDailyMorningBriefingCronConfig(existing?: CronJobLike): DailyMorningBriefingCronConfig {
|
|
68
|
+
const existingTz = typeof existing?.schedule?.tz === "string" && existing.schedule.tz.trim()
|
|
69
|
+
? existing.schedule.tz
|
|
70
|
+
: undefined;
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
agentId: HEDGEHOG_AGENT_ID,
|
|
74
|
+
name: DAILY_MORNING_BRIEFING_CRON_ID,
|
|
75
|
+
description: "触发 hedgehog-daily-morning-briefing skill 生成每日盘前早报并入库。",
|
|
76
|
+
enabled: true,
|
|
77
|
+
schedule: {
|
|
78
|
+
kind: "cron",
|
|
79
|
+
expr: "30 7 * * *",
|
|
80
|
+
...(existingTz ? { tz: existingTz } : {})
|
|
81
|
+
},
|
|
82
|
+
sessionTarget: "isolated",
|
|
83
|
+
wakeMode: "now",
|
|
84
|
+
payload: {
|
|
85
|
+
kind: "agentTurn",
|
|
86
|
+
message: DAILY_MORNING_BRIEFING_MESSAGE,
|
|
87
|
+
timeoutSeconds: 0
|
|
88
|
+
},
|
|
89
|
+
delivery: {
|
|
90
|
+
mode: "none"
|
|
91
|
+
},
|
|
92
|
+
deleteAfterRun: false
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function isDailyMorningBriefingCronJob(job: CronJobLike): boolean {
|
|
97
|
+
return job?.name === DAILY_MORNING_BRIEFING_CRON_ID || job?.sessionKey === DAILY_MORNING_BRIEFING_SESSION_KEY;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export async function ensureDailyMorningBriefingCron(cron: CronServiceLike | undefined): Promise<void> {
|
|
101
|
+
try {
|
|
102
|
+
if (!cron) {
|
|
103
|
+
logger.warn("Daily morning briefing cron was not scheduled because OpenClaw cron API is unavailable");
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const existingJobs = (await cron.list({ includeDisabled: true })).filter(isDailyMorningBriefingCronJob);
|
|
108
|
+
const [primaryJob, ...duplicateJobs] = existingJobs;
|
|
109
|
+
|
|
110
|
+
if (primaryJob?.id) {
|
|
111
|
+
await cron.update(primaryJob.id, buildDailyMorningBriefingCronConfig(primaryJob));
|
|
112
|
+
} else {
|
|
113
|
+
await cron.add(buildDailyMorningBriefingCronConfig());
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const duplicateIds = duplicateJobs
|
|
117
|
+
.map(job => job.id)
|
|
118
|
+
.filter((id): id is string => typeof id === "string" && id.length > 0);
|
|
119
|
+
await Promise.all(duplicateIds.map(id => cron.remove(id)));
|
|
120
|
+
} catch (e) {
|
|
121
|
+
logger.error({ err: e }, "Failed to ensure daily morning briefing cron");
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export function registerDailyMorningBriefingCron(api: OpenClawPluginApi): void {
|
|
126
|
+
api.on("gateway_start", async (_event, ctx) => {
|
|
127
|
+
await ensureDailyMorningBriefingCron(ctx.getCron?.());
|
|
128
|
+
});
|
|
129
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function ensureChartPlaceholdersInBody(content: string): string {
|
|
2
|
+
const chartDataMatch = content.match(/(?:\*\*)?\[图表数据\](?:\*\*)?/);
|
|
3
|
+
if (!chartDataMatch || typeof chartDataMatch.index !== "number") return content;
|
|
4
|
+
|
|
5
|
+
const chartDataStart = chartDataMatch.index;
|
|
6
|
+
const body = content.slice(0, chartDataStart);
|
|
7
|
+
const chartData = content.slice(chartDataStart);
|
|
8
|
+
const placeholders = Array.from(chartData.matchAll(/\{图\d+\}\s*:/g), match => match[0].replace(/\s*:$/, ""));
|
|
9
|
+
const uniquePlaceholders = [...new Set(placeholders)];
|
|
10
|
+
const missingPlaceholders = uniquePlaceholders.filter(placeholder => !body.includes(placeholder));
|
|
11
|
+
if (missingPlaceholders.length === 0) return content;
|
|
12
|
+
|
|
13
|
+
const insertion = [
|
|
14
|
+
"## 图表",
|
|
15
|
+
"",
|
|
16
|
+
...missingPlaceholders.flatMap(placeholder => [placeholder, ""])
|
|
17
|
+
].join("\n");
|
|
18
|
+
return `${body.trimEnd()}\n\n${insertion}\n${chartData.trimStart()}`;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const CHART_OUTPUT_GUIDANCE = [
|
|
22
|
+
"正文中如果生成任何图表,必须在对应分析段落先给出明确金融结论,并在结论后单独放置图表占位符,例如:",
|
|
23
|
+
"{图1}",
|
|
24
|
+
"每个图表占位符前后都必须换行;正文占位符与尾部 [图表数据] 编号必须一一对应,禁止只在尾部输出图表数据。",
|
|
25
|
+
"图表生成遵循投研可视化原则:仅在有助于趋势识别、横向比较、结构拆解或风险暴露说明时生成。",
|
|
26
|
+
"图表数据必须可追溯,来源限于工具返回、资讯原文、上下文已给出的数值,或正文已明确披露的计算结果;禁止使用示意性、编造型或装饰性数据。",
|
|
27
|
+
"图表数量控制在 1-3 张;无可靠数值数据时不生成图表。",
|
|
28
|
+
"图表标题必须明确市场、资产、指标与时间范围;xAxis、series、legend、title 必须与正文结论和数据口径一致。",
|
|
29
|
+
"图表类型只能取以下值之一:",
|
|
30
|
+
"[\"Line\",\"Bar\",\"Area\",\"Pie\",\"Donut\",\"Horizontal Bar\",\"Radar\",\"Histogram\",\"Scatter Plot\",\"Bubble\"]",
|
|
31
|
+
"图表类型选择:趋势变化用 Line 或 Area;横向比较用 Bar 或 Horizontal Bar;结构占比用 Pie 或 Donut;多维评分用 Radar;分布、相关性、离群点用 Histogram、Scatter Plot 或 Bubble。",
|
|
32
|
+
"如果生成图表,结尾追加 [图表数据],不要使用代码块,格式必须严格为:",
|
|
33
|
+
"{图1}: {\"chart\":\"Line\",\"option\":{...}};{图2}: {\"chart\":\"Bar\",\"option\":{...}}",
|
|
34
|
+
"其中 chart 必须是上面的图表类型之一,option 必须是纯 JSON,不允许 JS 函数、formatter 函数或注释。"
|
|
35
|
+
].join("\n");
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const DailyMorningBriefingStatusSchema = z.enum(["generating", "completed", "failed"]);
|
|
4
|
+
|
|
5
|
+
export const SaveDailyMorningBriefingParamsSchema = z.object({
|
|
6
|
+
id: z.string().trim().min(1).optional().describe("每日早报 ID;开始生成时不传,后续更新状态时传入"),
|
|
7
|
+
content: z.string().default("").describe("每日早报最终内容;失败时存入错误信息"),
|
|
8
|
+
status: DailyMorningBriefingStatusSchema.default("completed").describe("保存状态:generating 生成中,completed 成功,failed 失败")
|
|
9
|
+
}).refine((value) => {
|
|
10
|
+
if (value.status === "completed") return value.content.trim().length > 0;
|
|
11
|
+
return true;
|
|
12
|
+
}, {
|
|
13
|
+
message: "completed 状态必须提供 content"
|
|
14
|
+
});
|
|
15
|
+
export type SaveDailyMorningBriefingParams = z.infer<typeof SaveDailyMorningBriefingParamsSchema>;
|
|
16
|
+
|
|
17
|
+
export const QueryDailyMorningBriefingsParamsSchema = z.object({
|
|
18
|
+
market: z.string().trim().min(1).default("CN").describe("市场类型,默认 CN"),
|
|
19
|
+
page: z.number().int().min(1).default(1).describe("页码"),
|
|
20
|
+
pageSize: z.number().int().min(1).max(50).default(10).describe("每页数量,默认 10")
|
|
21
|
+
});
|
|
22
|
+
export type QueryDailyMorningBriefingsParams = z.infer<typeof QueryDailyMorningBriefingsParamsSchema>;
|
|
23
|
+
|
|
24
|
+
export const GetDailyMorningBriefingDetailParamsSchema = z.object({
|
|
25
|
+
id: z.string().trim().min(1).describe("每日早报 ID")
|
|
26
|
+
});
|
|
27
|
+
export type GetDailyMorningBriefingDetailParams = z.infer<typeof GetDailyMorningBriefingDetailParamsSchema>;
|
|
28
|
+
|
|
29
|
+
export interface DailyMorningBriefing {
|
|
30
|
+
id: string;
|
|
31
|
+
market: string;
|
|
32
|
+
briefingDate: string;
|
|
33
|
+
content: string;
|
|
34
|
+
status: string;
|
|
35
|
+
watchlistSnapshot: unknown[];
|
|
36
|
+
createdAt: string;
|
|
37
|
+
updatedAt: string;
|
|
38
|
+
}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { getDB } from "../../core/database.js";
|
|
2
|
+
import { ensureChartPlaceholdersInBody } from "../chartOutput.js";
|
|
3
|
+
import {
|
|
4
|
+
DailyMorningBriefing,
|
|
5
|
+
GetDailyMorningBriefingDetailParamsSchema,
|
|
6
|
+
QueryDailyMorningBriefingsParamsSchema,
|
|
7
|
+
SaveDailyMorningBriefingParamsSchema
|
|
8
|
+
} from "./schema.js";
|
|
9
|
+
|
|
10
|
+
interface RuntimeTool {
|
|
11
|
+
name: string;
|
|
12
|
+
label?: string;
|
|
13
|
+
description: string;
|
|
14
|
+
parameters: unknown;
|
|
15
|
+
registerTool?: boolean;
|
|
16
|
+
execute(params: unknown, ctx?: { userId: string }): Promise<string>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const DAILY_MORNING_BRIEFING_MARKET = "CN";
|
|
20
|
+
|
|
21
|
+
const SaveDailyMorningBriefingAgentToolSchema = {
|
|
22
|
+
type: "object",
|
|
23
|
+
additionalProperties: false,
|
|
24
|
+
properties: {
|
|
25
|
+
id: { type: "string", description: "每日盘前早报 ID;开始生成时不传,后续更新生成结果时必须传入开始时返回的 id" },
|
|
26
|
+
content: { type: "string", description: "每日盘前早报正文;status=generating 时为空,status=failed 时存入错误信息" },
|
|
27
|
+
status: { type: "string", enum: ["generating", "completed", "failed"], description: "保存状态:generating 表示开始生成,completed 表示生成成功,failed 表示生成失败" }
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
function normalizeMarket(market: string): string {
|
|
32
|
+
const raw = market.trim().toUpperCase();
|
|
33
|
+
if (raw === "A股" || raw === "中国股市" || raw === "MARKETS.CN") return "CN";
|
|
34
|
+
return raw || "CN";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function getLocalDateString(): string {
|
|
38
|
+
const now = new Date();
|
|
39
|
+
const year = now.getFullYear();
|
|
40
|
+
const month = String(now.getMonth() + 1).padStart(2, "0");
|
|
41
|
+
const day = String(now.getDate()).padStart(2, "0");
|
|
42
|
+
return `${year}-${month}-${day}`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function buildDailyMorningBriefingId(market: string, briefingDate: string): string {
|
|
46
|
+
return `daily_morning_briefing_${market}_${briefingDate}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function selectDailyMorningBriefing(
|
|
50
|
+
db: ReturnType<typeof getDB>,
|
|
51
|
+
id: string
|
|
52
|
+
): DailyMorningBriefing {
|
|
53
|
+
const row = db.prepare(`
|
|
54
|
+
SELECT id, market, briefingDate, content, status, watchlistSnapshot, createdAt, updatedAt
|
|
55
|
+
FROM daily_morning_briefings
|
|
56
|
+
WHERE id = ?
|
|
57
|
+
`).get(id) as (Omit<DailyMorningBriefing, "watchlistSnapshot"> & { watchlistSnapshot: string }) | undefined;
|
|
58
|
+
|
|
59
|
+
if (!row) throw new Error("daily morning briefing was not saved");
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
id: row.id,
|
|
63
|
+
market: row.market,
|
|
64
|
+
briefingDate: row.briefingDate,
|
|
65
|
+
content: row.content,
|
|
66
|
+
status: row.status,
|
|
67
|
+
watchlistSnapshot: JSON.parse(row.watchlistSnapshot || "[]"),
|
|
68
|
+
createdAt: row.createdAt,
|
|
69
|
+
updatedAt: row.updatedAt
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function selectExistingActiveDailyMorningBriefing(
|
|
74
|
+
db: ReturnType<typeof getDB>,
|
|
75
|
+
market: string,
|
|
76
|
+
briefingDate: string
|
|
77
|
+
): DailyMorningBriefing | undefined {
|
|
78
|
+
const row = db.prepare(`
|
|
79
|
+
SELECT id
|
|
80
|
+
FROM daily_morning_briefings
|
|
81
|
+
WHERE market = ?
|
|
82
|
+
AND briefingDate = ?
|
|
83
|
+
AND status IN ('generating', 'completed')
|
|
84
|
+
ORDER BY
|
|
85
|
+
CASE status WHEN 'completed' THEN 0 WHEN 'generating' THEN 1 ELSE 2 END,
|
|
86
|
+
updatedAt DESC,
|
|
87
|
+
createdAt DESC
|
|
88
|
+
LIMIT 1
|
|
89
|
+
`).get(market, briefingDate) as { id: string } | undefined;
|
|
90
|
+
return row ? selectDailyMorningBriefing(db, row.id) : undefined;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function selectGeneratingDailyMorningBriefing(
|
|
94
|
+
db: ReturnType<typeof getDB>,
|
|
95
|
+
market: string,
|
|
96
|
+
briefingDate: string
|
|
97
|
+
): DailyMorningBriefing | undefined {
|
|
98
|
+
const row = db.prepare(`
|
|
99
|
+
SELECT id
|
|
100
|
+
FROM daily_morning_briefings
|
|
101
|
+
WHERE market = ?
|
|
102
|
+
AND briefingDate = ?
|
|
103
|
+
AND status = 'generating'
|
|
104
|
+
ORDER BY updatedAt DESC, createdAt DESC
|
|
105
|
+
LIMIT 1
|
|
106
|
+
`).get(market, briefingDate) as { id: string } | undefined;
|
|
107
|
+
return row ? selectDailyMorningBriefing(db, row.id) : undefined;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function mapDailyMorningBriefingRow(row: Omit<DailyMorningBriefing, "watchlistSnapshot"> & { watchlistSnapshot: string }): DailyMorningBriefing {
|
|
111
|
+
return {
|
|
112
|
+
id: row.id,
|
|
113
|
+
market: row.market,
|
|
114
|
+
briefingDate: row.briefingDate,
|
|
115
|
+
content: row.content,
|
|
116
|
+
status: row.status,
|
|
117
|
+
watchlistSnapshot: JSON.parse(row.watchlistSnapshot || "[]"),
|
|
118
|
+
createdAt: row.createdAt,
|
|
119
|
+
updatedAt: row.updatedAt
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function mapDailyMorningBriefingSummary(row: Omit<DailyMorningBriefing, "content" | "watchlistSnapshot">): Omit<DailyMorningBriefing, "content" | "watchlistSnapshot"> {
|
|
124
|
+
return row;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function getFullWatchlistSnapshot(db: ReturnType<typeof getDB>): unknown[] {
|
|
128
|
+
const stocks = db.prepare(`
|
|
129
|
+
SELECT id, userId, stock_code, stock_name, exchange, market, sortOrder, createdAt
|
|
130
|
+
FROM watchlist
|
|
131
|
+
WHERE isDeleted = 0
|
|
132
|
+
ORDER BY userId ASC, sortOrder ASC
|
|
133
|
+
`).all() as { id: string; userId: string; stock_code: string; stock_name: string; exchange: string; market: string; sortOrder: number; createdAt: string }[];
|
|
134
|
+
|
|
135
|
+
return stocks.map(stock => {
|
|
136
|
+
const industries = db.prepare(`
|
|
137
|
+
SELECT c.name FROM industry_theme_categories c
|
|
138
|
+
JOIN watchlist_industry_items i ON c.id = i.categoryId
|
|
139
|
+
WHERE i.watchlistId = ? ORDER BY i.weight DESC
|
|
140
|
+
`).all(stock.id) as { name: string }[];
|
|
141
|
+
const themes = db.prepare(`
|
|
142
|
+
SELECT c.name FROM industry_theme_categories c
|
|
143
|
+
JOIN watchlist_theme_items t ON c.id = t.categoryId
|
|
144
|
+
WHERE t.watchlistId = ? ORDER BY t.weight DESC
|
|
145
|
+
`).all(stock.id) as { name: string }[];
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
...stock,
|
|
149
|
+
industries: industries.map(item => item.name),
|
|
150
|
+
themes: themes.map(item => item.name)
|
|
151
|
+
};
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export const dailyMorningBriefingTools: Record<string, RuntimeTool> = {
|
|
156
|
+
save_daily_morning_briefing: {
|
|
157
|
+
name: "save_daily_morning_briefing",
|
|
158
|
+
label: "保存每日盘前早报",
|
|
159
|
+
description: "保存每日盘前早报的生成进度和最终结果。生成前必须先以 status=generating、content=\"\" 调用;生成成功后以 status=completed 保存完整正文 content;生成失败后以 status=failed 保存完整错误信息。未传 id 时会自动使用当天固定记录,完成或失败时可直接更新当天早报。",
|
|
160
|
+
parameters: SaveDailyMorningBriefingAgentToolSchema,
|
|
161
|
+
registerTool: true,
|
|
162
|
+
async execute(params) {
|
|
163
|
+
const args = SaveDailyMorningBriefingParamsSchema.parse(params);
|
|
164
|
+
const db = getDB();
|
|
165
|
+
const market = DAILY_MORNING_BRIEFING_MARKET;
|
|
166
|
+
const briefingDate = getLocalDateString();
|
|
167
|
+
const id = args.id || buildDailyMorningBriefingId(market, briefingDate);
|
|
168
|
+
if (args.status === "generating") {
|
|
169
|
+
const generating = selectGeneratingDailyMorningBriefing(db, market, briefingDate);
|
|
170
|
+
if (generating) {
|
|
171
|
+
return JSON.stringify({ success: true, skipped: true, reason: "already_generating", data: generating });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const watchlistSnapshot = JSON.stringify(getFullWatchlistSnapshot(db));
|
|
176
|
+
const content = args.status === "completed" ? ensureChartPlaceholdersInBody(args.content) : args.content.trim();
|
|
177
|
+
|
|
178
|
+
const result = db.prepare(`
|
|
179
|
+
UPDATE daily_morning_briefings
|
|
180
|
+
SET content = ?,
|
|
181
|
+
status = ?,
|
|
182
|
+
watchlistSnapshot = ?,
|
|
183
|
+
updatedAt = STRFTIME('%Y-%m-%dT%H:%M:%fZ', 'NOW')
|
|
184
|
+
WHERE id = ?
|
|
185
|
+
`).run(content, args.status, watchlistSnapshot, id);
|
|
186
|
+
if (result.changes === 0) {
|
|
187
|
+
db.prepare(`
|
|
188
|
+
INSERT INTO daily_morning_briefings (id, market, briefingDate, content, status, watchlistSnapshot)
|
|
189
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
190
|
+
`).run(id, market, briefingDate, content, args.status, watchlistSnapshot);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const data = selectDailyMorningBriefing(db, id);
|
|
194
|
+
return JSON.stringify({ success: true, data });
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
query_daily_morning_briefings: {
|
|
198
|
+
name: "query_daily_morning_briefings",
|
|
199
|
+
label: "查询每日盘前早报",
|
|
200
|
+
description: "分页查询每日盘前早报记录列表。支持按市场过滤,返回记录标识、早报日期、状态和时间字段;列表结果不包含 content,详情内容请使用详情查询接口获取。",
|
|
201
|
+
parameters: QueryDailyMorningBriefingsParamsSchema,
|
|
202
|
+
registerTool: false,
|
|
203
|
+
async execute(params) {
|
|
204
|
+
const args = QueryDailyMorningBriefingsParamsSchema.parse(params ?? {});
|
|
205
|
+
const db = getDB();
|
|
206
|
+
const market = normalizeMarket(args.market);
|
|
207
|
+
const offset = (args.page - 1) * args.pageSize;
|
|
208
|
+
const total = (db.prepare(`
|
|
209
|
+
SELECT COUNT(*) AS total
|
|
210
|
+
FROM daily_morning_briefings
|
|
211
|
+
WHERE market = ?
|
|
212
|
+
`).get(market) as { total: number }).total || 0;
|
|
213
|
+
const rows = db.prepare(`
|
|
214
|
+
SELECT id, market, briefingDate, status, createdAt, updatedAt
|
|
215
|
+
FROM daily_morning_briefings
|
|
216
|
+
WHERE market = ?
|
|
217
|
+
ORDER BY briefingDate DESC, updatedAt DESC
|
|
218
|
+
LIMIT ? OFFSET ?
|
|
219
|
+
`).all(market, args.pageSize, offset) as Omit<DailyMorningBriefing, "content" | "watchlistSnapshot">[];
|
|
220
|
+
|
|
221
|
+
return JSON.stringify({
|
|
222
|
+
success: true,
|
|
223
|
+
data: rows.map(mapDailyMorningBriefingSummary),
|
|
224
|
+
pagination: {
|
|
225
|
+
page: args.page,
|
|
226
|
+
pageSize: args.pageSize,
|
|
227
|
+
total,
|
|
228
|
+
totalPages: Math.ceil(total / args.pageSize)
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
get_daily_morning_briefing_detail: {
|
|
234
|
+
name: "get_daily_morning_briefing_detail",
|
|
235
|
+
label: "查询每日盘前早报详情",
|
|
236
|
+
description: "根据每日盘前早报 ID 查询完整详情。返回早报正文 content、自选股快照 watchlistSnapshot 以及市场、日期、状态和时间等元数据;status=failed 时 content 为错误信息。",
|
|
237
|
+
parameters: GetDailyMorningBriefingDetailParamsSchema,
|
|
238
|
+
registerTool: false,
|
|
239
|
+
async execute(params) {
|
|
240
|
+
const args = GetDailyMorningBriefingDetailParamsSchema.parse(params);
|
|
241
|
+
const db = getDB();
|
|
242
|
+
const data = selectDailyMorningBriefing(db, args.id);
|
|
243
|
+
return JSON.stringify({ success: true, data });
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const BuildDeepReasoningMessageParamsSchema = z.object({
|
|
4
|
+
newsId: z.string().trim().min(1).describe("新闻 ID,例如 news-5"),
|
|
5
|
+
sourceTitle: z.string().trim().min(1).describe("新闻标题"),
|
|
6
|
+
sourceContent: z.string().trim().min(1).describe("新闻正文")
|
|
7
|
+
});
|
|
8
|
+
export type BuildDeepReasoningMessageParams = z.infer<typeof BuildDeepReasoningMessageParamsSchema>;
|
|
9
|
+
|
|
10
|
+
export const QueryDeepReasoningHistoryParamsSchema = z.object({
|
|
11
|
+
page: z.number().int().min(1).default(1).describe("页码"),
|
|
12
|
+
pageSize: z.number().int().min(1).max(50).default(10).describe("每页数量,默认 10")
|
|
13
|
+
});
|
|
14
|
+
export type QueryDeepReasoningHistoryParams = z.infer<typeof QueryDeepReasoningHistoryParamsSchema>;
|
|
15
|
+
|
|
16
|
+
export const GetDeepReasoningDetailParamsSchema = z.object({
|
|
17
|
+
id: z.string().trim().min(1).optional().describe("记录 ID"),
|
|
18
|
+
sourceId: z.string().trim().min(1).optional().describe("新闻来源 ID,例如 news-5")
|
|
19
|
+
}).refine((value) => value.id || value.sourceId, {
|
|
20
|
+
message: "id 或 sourceId 至少提供一个"
|
|
21
|
+
});
|
|
22
|
+
export type GetDeepReasoningDetailParams = z.infer<typeof GetDeepReasoningDetailParamsSchema>;
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { getDB } from "../../core/database.js";
|
|
2
|
+
import {
|
|
3
|
+
BuildDeepReasoningMessageParams,
|
|
4
|
+
BuildDeepReasoningMessageParamsSchema,
|
|
5
|
+
GetDeepReasoningDetailParamsSchema,
|
|
6
|
+
QueryDeepReasoningHistoryParamsSchema
|
|
7
|
+
} from "./schema.js";
|
|
8
|
+
|
|
9
|
+
interface RuntimeTool {
|
|
10
|
+
name: string;
|
|
11
|
+
label?: string;
|
|
12
|
+
description: string;
|
|
13
|
+
parameters: unknown;
|
|
14
|
+
registerTool?: boolean;
|
|
15
|
+
execute(params: unknown, ctx?: { userId: string }): Promise<string>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const DEEP_REASONING_SKILL = "hedgehog-news-deep-reasoning";
|
|
19
|
+
|
|
20
|
+
const BuildDeepReasoningMessageAgentToolSchema = {
|
|
21
|
+
type: "object",
|
|
22
|
+
additionalProperties: false,
|
|
23
|
+
required: ["newsId", "sourceTitle", "sourceContent"],
|
|
24
|
+
properties: {
|
|
25
|
+
newsId: { type: "string", description: "新闻 ID,例如 news-5" },
|
|
26
|
+
sourceTitle: { type: "string", description: "新闻标题" },
|
|
27
|
+
sourceContent: { type: "string", description: "新闻正文" }
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
function buildContent(args: BuildDeepReasoningMessageParams): string {
|
|
32
|
+
return [
|
|
33
|
+
"对这条新闻进行深度推演",
|
|
34
|
+
"",
|
|
35
|
+
`新闻标题:${args.sourceTitle}`,
|
|
36
|
+
"",
|
|
37
|
+
"新闻正文:",
|
|
38
|
+
args.sourceContent
|
|
39
|
+
].join("\n");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function buildDeepReasoningMessage(args: BuildDeepReasoningMessageParams): string {
|
|
43
|
+
const buildGeneratingSaveParams = () => JSON.stringify({
|
|
44
|
+
sourceId: args.newsId,
|
|
45
|
+
sourceTitle: args.sourceTitle,
|
|
46
|
+
status: "generating",
|
|
47
|
+
content: ""
|
|
48
|
+
});
|
|
49
|
+
const buildFinalSaveParams = (status: "completed" | "failed") => JSON.stringify({
|
|
50
|
+
sourceId: args.newsId,
|
|
51
|
+
status,
|
|
52
|
+
content: "..."
|
|
53
|
+
});
|
|
54
|
+
return JSON.stringify({
|
|
55
|
+
cw_system_prompt: [
|
|
56
|
+
`开始分析前必须先调用 save_article_deep_reasoning_analysis,参数为 ${buildGeneratingSaveParams()};如果返回 skipped=true,必须立即停止,不要继续调用 skill 或生成正文。`,
|
|
57
|
+
"仅允许按上述标准参数调用 save_article_deep_reasoning_analysis;如果无法提供标准参数,或参数包含标准参数以外的字段,不要调用 save_article_deep_reasoning_analysis。",
|
|
58
|
+
`必须触发并使用 ${DEEP_REASONING_SKILL} skill 生成新闻事件深度推演报告。`,
|
|
59
|
+
`生成成功后必须调用 save_article_deep_reasoning_analysis,参数为 ${buildFinalSaveParams("completed")},content 传最终完整深度推演报告正文。`,
|
|
60
|
+
`生成失败后必须调用 save_article_deep_reasoning_analysis,参数为 ${buildFinalSaveParams("failed")},content 存放完整错误信息。`
|
|
61
|
+
].join("\n"),
|
|
62
|
+
cw_context: JSON.stringify({
|
|
63
|
+
sourceId: args.newsId,
|
|
64
|
+
sourceTitle: args.sourceTitle
|
|
65
|
+
}),
|
|
66
|
+
cw_content: buildContent(args),
|
|
67
|
+
cw_output: [
|
|
68
|
+
`输出结构以 ${DEEP_REASONING_SKILL} skill 的交付模板为准。`
|
|
69
|
+
].join("\n")
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function selectGeneratingDeepReasoning(userId: string, sourceId: string) {
|
|
74
|
+
const db = getDB();
|
|
75
|
+
return db.prepare(`
|
|
76
|
+
SELECT id, sourceId, sourceTitle, status, content, createdAt, updatedAt
|
|
77
|
+
FROM news_deep_reasoning_analysis
|
|
78
|
+
WHERE userId = ? AND sourceId = ? AND status = 'generating'
|
|
79
|
+
ORDER BY updatedAt DESC, createdAt DESC
|
|
80
|
+
LIMIT 1
|
|
81
|
+
`).get(userId, sourceId);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export const deepReasoningTools: Record<string, RuntimeTool> = {
|
|
85
|
+
query_deep_reasoning_history: {
|
|
86
|
+
name: "query_deep_reasoning_history",
|
|
87
|
+
label: "查询深度推演列表",
|
|
88
|
+
description: "分页查询深度推演记录列表。返回记录标识、来源 ID、标题、状态和时间字段;列表结果不包含 content,详情请使用 get_deep_reasoning_detail 查询。",
|
|
89
|
+
parameters: QueryDeepReasoningHistoryParamsSchema,
|
|
90
|
+
registerTool: false,
|
|
91
|
+
async execute(params, ctx) {
|
|
92
|
+
const args = QueryDeepReasoningHistoryParamsSchema.parse(params ?? {});
|
|
93
|
+
const db = getDB();
|
|
94
|
+
const userId = ctx?.userId || "default";
|
|
95
|
+
const offset = (args.page - 1) * args.pageSize;
|
|
96
|
+
const rows = db.prepare(`
|
|
97
|
+
SELECT id, sourceId, sourceTitle, status, createdAt, updatedAt
|
|
98
|
+
FROM news_deep_reasoning_analysis
|
|
99
|
+
WHERE userId = ?
|
|
100
|
+
ORDER BY updatedAt DESC, createdAt DESC
|
|
101
|
+
LIMIT ? OFFSET ?
|
|
102
|
+
`).all(userId, args.pageSize, offset);
|
|
103
|
+
const countRow = db.prepare(`
|
|
104
|
+
SELECT COUNT(*) AS total FROM news_deep_reasoning_analysis WHERE userId = ?
|
|
105
|
+
`).get(userId) as { total: number };
|
|
106
|
+
const total = countRow.total || 0;
|
|
107
|
+
return JSON.stringify({
|
|
108
|
+
success: true,
|
|
109
|
+
data: rows,
|
|
110
|
+
pagination: {
|
|
111
|
+
page: args.page,
|
|
112
|
+
pageSize: args.pageSize,
|
|
113
|
+
total,
|
|
114
|
+
totalPages: Math.ceil(total / args.pageSize)
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
get_deep_reasoning_detail: {
|
|
120
|
+
name: "get_deep_reasoning_detail",
|
|
121
|
+
label: "查询深度推演详情",
|
|
122
|
+
description: "根据记录 ID 或 sourceId 查询深度推演完整详情,包含 content 正文及所有元数据。",
|
|
123
|
+
parameters: GetDeepReasoningDetailParamsSchema,
|
|
124
|
+
registerTool: false,
|
|
125
|
+
async execute(params, ctx) {
|
|
126
|
+
const args = GetDeepReasoningDetailParamsSchema.parse(params);
|
|
127
|
+
const db = getDB();
|
|
128
|
+
if (args.sourceId) {
|
|
129
|
+
const row = db.prepare(`
|
|
130
|
+
SELECT id, sourceId, sourceTitle, status, content, createdAt, updatedAt
|
|
131
|
+
FROM news_deep_reasoning_analysis
|
|
132
|
+
WHERE sourceId = ?
|
|
133
|
+
ORDER BY updatedAt DESC, createdAt DESC
|
|
134
|
+
LIMIT 1
|
|
135
|
+
`).get(args.sourceId);
|
|
136
|
+
return JSON.stringify({ success: true, data: row || null });
|
|
137
|
+
}
|
|
138
|
+
const row = db.prepare(`
|
|
139
|
+
SELECT id, sourceId, sourceTitle, status, content, createdAt, updatedAt
|
|
140
|
+
FROM news_deep_reasoning_analysis
|
|
141
|
+
WHERE id = ?
|
|
142
|
+
ORDER BY updatedAt DESC, createdAt DESC
|
|
143
|
+
LIMIT 1
|
|
144
|
+
`).get(args.id);
|
|
145
|
+
return JSON.stringify({ success: true, data: row || null });
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
build_deep_reasoning_message: {
|
|
149
|
+
name: "build_deep_reasoning_message",
|
|
150
|
+
label: "构建深度推演消息",
|
|
151
|
+
description: "根据新闻 ID、标题和正文构建用于主动 RPC 发起 Agent 新闻深度推演任务的标准消息。该工具只返回提示词消息体,不触发定时任务,也不保存分析结果。",
|
|
152
|
+
parameters: BuildDeepReasoningMessageAgentToolSchema,
|
|
153
|
+
registerTool: false,
|
|
154
|
+
async execute(params, ctx) {
|
|
155
|
+
const args = BuildDeepReasoningMessageParamsSchema.parse(params);
|
|
156
|
+
const userId = ctx?.userId || "default";
|
|
157
|
+
const generating = selectGeneratingDeepReasoning(userId, args.newsId);
|
|
158
|
+
if (generating) {
|
|
159
|
+
return JSON.stringify({
|
|
160
|
+
success: true,
|
|
161
|
+
skipped: true,
|
|
162
|
+
reason: "already_generating",
|
|
163
|
+
data: generating
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
const message = buildDeepReasoningMessage(args);
|
|
167
|
+
return JSON.stringify({
|
|
168
|
+
success: true,
|
|
169
|
+
data: {
|
|
170
|
+
message,
|
|
171
|
+
payload: JSON.parse(message),
|
|
172
|
+
sourceId: args.newsId,
|
|
173
|
+
saveParams: {
|
|
174
|
+
sourceId: args.newsId,
|
|
175
|
+
sourceTitle: args.sourceTitle
|
|
176
|
+
},
|
|
177
|
+
skill: DEEP_REASONING_SKILL
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
};
|
package/src/features/index.ts
CHANGED
|
@@ -3,6 +3,10 @@ import { profileLibraryTools } from "./profileLibrary/tools.js";
|
|
|
3
3
|
import { noteTools } from "./notes/tools.js";
|
|
4
4
|
import { stockAnalysisTools } from "./stockAnalysis/tools.js";
|
|
5
5
|
import { pluginInfoTools } from "./pluginInfo/tools.js";
|
|
6
|
+
import { dailyMorningBriefingTools } from "./dailyMorningBriefing/tools.js";
|
|
7
|
+
import { stockBasicTools } from "./stockBasic/tools.js";
|
|
8
|
+
import { informationVerificationTools } from "./informationVerification/tools.js";
|
|
9
|
+
import { deepReasoningTools } from "./deepReasoning/tools.js";
|
|
6
10
|
|
|
7
11
|
export interface RuntimeTool {
|
|
8
12
|
name: string;
|
|
@@ -10,7 +14,8 @@ export interface RuntimeTool {
|
|
|
10
14
|
description: string;
|
|
11
15
|
parameters: unknown;
|
|
12
16
|
registerTool?: boolean;
|
|
13
|
-
|
|
17
|
+
agentToolTarget?: "main";
|
|
18
|
+
execute(params: unknown, ctx?: { userId: string }): Promise<string>;
|
|
14
19
|
}
|
|
15
20
|
|
|
16
21
|
export const allFeaturesTools: Record<string, RuntimeTool> = {
|
|
@@ -18,5 +23,9 @@ export const allFeaturesTools: Record<string, RuntimeTool> = {
|
|
|
18
23
|
...profileLibraryTools,
|
|
19
24
|
...noteTools,
|
|
20
25
|
...stockAnalysisTools,
|
|
21
|
-
...pluginInfoTools
|
|
26
|
+
...pluginInfoTools,
|
|
27
|
+
...dailyMorningBriefingTools,
|
|
28
|
+
...stockBasicTools,
|
|
29
|
+
...informationVerificationTools,
|
|
30
|
+
...deepReasoningTools
|
|
22
31
|
};
|