@v587d/capital-generation 2.12.0 → 2.13.1
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/CHANGELOG.md +29 -0
- package/README.md +70 -70
- package/automation/builtins.js +147 -0
- package/automation/calendar-source.js +361 -0
- package/automation/calendar.js +66 -0
- package/automation/client.js +351 -0
- package/automation/client.src.cjs +2734 -0
- package/automation/defaults.js +75 -0
- package/automation/index.js +188 -0
- package/automation/owner.js +222 -0
- package/automation/package.json +51 -0
- package/automation/policy.js +105 -0
- package/automation/redact.js +25 -0
- package/automation/route.js +241 -0
- package/automation/runner.js +912 -0
- package/automation/scheduler.js +513 -0
- package/automation/schema.js +375 -0
- package/automation/service.js +338 -0
- package/automation/settings.js +48 -0
- package/automation/store.js +732 -0
- package/automation/time.js +220 -0
- package/automation/workspaces.js +154 -0
- package/chart-ui/package.json +1 -1
- package/config/client.js +4 -2
- package/config/client.src.cjs +90 -1
- package/config/index.js +15 -0
- package/config/package.json +1 -1
- package/cordis.patch.yml +8 -0
- package/lib/index.d.ts +38 -0
- package/lib/index.js +16 -0
- package/lib/sources/wind-mcp.js +3 -3
- package/lib/web-retriever/local-fetch.d.ts +1 -1
- package/lib/web-retriever/local-fetch.js +1 -1
- package/lib/web-retriever/wind-client.d.ts +1 -1
- package/lib/web-retriever/wind-client.js +1 -1
- package/package.json +5 -2
- package/watchlist/package.json +1 -1
package/config/client.src.cjs
CHANGED
|
@@ -63,6 +63,15 @@ const DOC_URLS = {
|
|
|
63
63
|
|
|
64
64
|
/** Render order = array order; one list drives status, refs, drafts and event refresh. */
|
|
65
65
|
const CREDENTIAL_FIELDS = ['fuyao', 'ftshare', 'anysearch', 'wind', 'paddleocr']
|
|
66
|
+
const AUTOMATION_FIELDS = ['tickMs', 'runTimeoutMinutes', 'idleTimeoutMinutes', 'maxSteps', 'maxToolCalls', 'inAppNotifications']
|
|
67
|
+
const AUTOMATION_DEFAULTS = {
|
|
68
|
+
tickMs: 60_000,
|
|
69
|
+
runTimeoutMinutes: 30,
|
|
70
|
+
idleTimeoutMinutes: 5,
|
|
71
|
+
maxSteps: 300,
|
|
72
|
+
maxToolCalls: 1_200,
|
|
73
|
+
inAppNotifications: true,
|
|
74
|
+
}
|
|
66
75
|
const SELECTED_SKILL_FIELDS = SELECTED_SKILL_CATALOG.map(({ key }) => key)
|
|
67
76
|
// Stable orders: facet counts change with the other dimension, but chips must not jump under the cursor.
|
|
68
77
|
const SELECTED_SKILL_TRAITS = selectedSkillTraitOrder()
|
|
@@ -92,6 +101,14 @@ const zh = {
|
|
|
92
101
|
anysearchHint: 'AnySearch 网页搜索 / 提取接口。保存后新自动模式会话生效。',
|
|
93
102
|
localFetchLabel: '允许启动本地提取网页内容',
|
|
94
103
|
localFetchHint: '开启后本地抓取兜底(回执来源 local-http)。保存后新自动模式会话生效。',
|
|
104
|
+
automationTitle: '投研自动化',
|
|
105
|
+
automationHint: '调度器与无人值守运行的默认上限;任务详情里的设置优先。改动在下一个 tick 生效。',
|
|
106
|
+
automationTick: '调度间隔(毫秒)',
|
|
107
|
+
automationRunTimeout: 'wall-clock 上限(分钟)',
|
|
108
|
+
automationIdleTimeout: '空闲超时(分钟)',
|
|
109
|
+
automationMaxSteps: '最大步骤',
|
|
110
|
+
automationMaxToolCalls: '最大工具调用',
|
|
111
|
+
automationInApp: '写入应用内通知',
|
|
95
112
|
windLabel: 'Wind Alice API Key',
|
|
96
113
|
windHint: 'Wind 金融信披类文档检索接口。保存后新自动模式会话生效。',
|
|
97
114
|
paddleocrLabel: 'PaddleOCR 文档解析 Token',
|
|
@@ -139,6 +156,14 @@ const en = {
|
|
|
139
156
|
anysearchHint: 'AnySearch web search / extract interface. Takes effect in new Auto mode sessions.',
|
|
140
157
|
localFetchLabel: 'Allow local web page extraction',
|
|
141
158
|
localFetchHint: 'When on, a failed fetch falls back to local direct fetching (receipt via: local-http). Takes effect in new Auto mode sessions.',
|
|
159
|
+
automationTitle: 'Research automation',
|
|
160
|
+
automationHint: 'Scheduler and unattended-run defaults; per-task limits win. Changes apply on the next tick.',
|
|
161
|
+
automationTick: 'Tick interval (ms)',
|
|
162
|
+
automationRunTimeout: 'Wall-clock limit (minutes)',
|
|
163
|
+
automationIdleTimeout: 'Idle timeout (minutes)',
|
|
164
|
+
automationMaxSteps: 'Max steps',
|
|
165
|
+
automationMaxToolCalls: 'Max tool calls',
|
|
166
|
+
automationInApp: 'Write in-app notifications',
|
|
142
167
|
windLabel: 'Wind Alice API Key',
|
|
143
168
|
windHint: 'Wind financial disclosure document retrieval interface. Takes effect in new Auto mode sessions.',
|
|
144
169
|
paddleocrLabel: 'PaddleOCR document token',
|
|
@@ -205,6 +230,8 @@ function installStyles() {
|
|
|
205
230
|
.capital-config-secret-row label { flex: 0 1 auto; }
|
|
206
231
|
.capital-config-secret-row label ~ span { order: 1; margin-left: auto; }
|
|
207
232
|
.capital-config-field { display: flex; flex-direction: column; gap: 6px; padding: 12px 0; border-top: 0.5px solid var(--dsw-alias-border-l2); }
|
|
233
|
+
.capital-config-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 8px; }
|
|
234
|
+
.capital-config-field input[type="number"] { width: 100%; box-sizing: border-box; padding: 6px 8px; border: .5px solid var(--dsw-alias-border-l1); border-radius: 8px; background: var(--dsw-alias-bg-module-platform); color: var(--dsw-alias-label-primary); font: inherit; font-size: 12px; }
|
|
208
235
|
.capital-config-selected-mode { padding: 12px 14px; border: 0.5px solid var(--dsw-alias-border-l1); border-radius: 10px; background: var(--dsw-alias-bg-layer-2); }
|
|
209
236
|
.capital-config-switch-row { align-items: center; gap: 12px; display: flex; }
|
|
210
237
|
.capital-config-switch-text { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 4px; }
|
|
@@ -274,6 +301,8 @@ class CapitalCardController {
|
|
|
274
301
|
this.selectedSkillFailed = new Set()
|
|
275
302
|
this.selectedSkillsModeWriting = false
|
|
276
303
|
this.selectedSkillsModeFailed = false
|
|
304
|
+
this.automationWriting = new Set()
|
|
305
|
+
this.automationFailed = new Set()
|
|
277
306
|
// Row count is external: null = unknown, never 0; fetch only after the card is shown.
|
|
278
307
|
this.bundleRows = null
|
|
279
308
|
this.rowsRequested = false
|
|
@@ -323,6 +352,12 @@ class CapitalCardController {
|
|
|
323
352
|
writing: this.selectedSkillsModeWriting,
|
|
324
353
|
failed: this.selectedSkillsModeFailed,
|
|
325
354
|
},
|
|
355
|
+
automation: Object.fromEntries(AUTOMATION_FIELDS.map((field) => [field, {
|
|
356
|
+
value: snapshot.value?.automation?.[field] ?? AUTOMATION_DEFAULTS[field],
|
|
357
|
+
on: snapshot.value?.automation?.[field] !== false,
|
|
358
|
+
writing: this.automationWriting.has(field),
|
|
359
|
+
failed: this.automationFailed.has(field),
|
|
360
|
+
}])),
|
|
326
361
|
// `count === null` means unknown, not zero: the card decides whether to draw it.
|
|
327
362
|
components: { count: this.bundleRows },
|
|
328
363
|
}
|
|
@@ -436,6 +471,27 @@ class CapitalCardController {
|
|
|
436
471
|
this.store.set(this.projection())
|
|
437
472
|
}
|
|
438
473
|
|
|
474
|
+
async writeAutomation(field, value) {
|
|
475
|
+
if (!AUTOMATION_FIELDS.includes(field) || this.automationWriting.has(field)) return
|
|
476
|
+
const snapshot = this.scope.getSnapshot()
|
|
477
|
+
if (snapshot.status !== 'ready' || !snapshot.writable) return
|
|
478
|
+
const next = field === 'inAppNotifications' ? value === true : Number(value)
|
|
479
|
+
if (field !== 'inAppNotifications' && !Number.isFinite(next)) return
|
|
480
|
+
this.automationWriting.add(field)
|
|
481
|
+
this.automationFailed.delete(field)
|
|
482
|
+
this.store.set(this.projection())
|
|
483
|
+
try {
|
|
484
|
+
const current = this.scope.getSnapshot().value?.automation ?? { ...AUTOMATION_DEFAULTS }
|
|
485
|
+
await this.scope.mutate([{ op: 'set', path: ['automation'], value: { ...AUTOMATION_DEFAULTS, ...current, [field]: next } }])
|
|
486
|
+
} catch {
|
|
487
|
+
// The landed check below reports the failure.
|
|
488
|
+
}
|
|
489
|
+
this.automationWriting.delete(field)
|
|
490
|
+
const landed = this.scope.getSnapshot().value?.automation?.[field] ?? AUTOMATION_DEFAULTS[field]
|
|
491
|
+
if (landed !== next) this.automationFailed.add(field)
|
|
492
|
+
this.store.set(this.projection())
|
|
493
|
+
}
|
|
494
|
+
|
|
439
495
|
/**
|
|
440
496
|
* Count comes only from `pluginManager.listBundles()`. Merge in-flight reads;
|
|
441
497
|
* failures are not cached (the next tab switch retries); push only on change.
|
|
@@ -476,6 +532,7 @@ class CapitalCardController {
|
|
|
476
532
|
},
|
|
477
533
|
...this.model.actions(),
|
|
478
534
|
toggleLocalFetch: (value) => this.toggleLocalFetch(value),
|
|
535
|
+
writeAutomation: (field, value) => this.writeAutomation(field, value),
|
|
479
536
|
toggleSelectedSkill: (field, value) => this.toggleSelectedSkill(field, value),
|
|
480
537
|
toggleSelectedSkillsMode: (auto) => this.toggleSelectedSkillsMode(auto),
|
|
481
538
|
ensureBundleRows: () => this.ensureBundleRows(),
|
|
@@ -732,6 +789,38 @@ function CapitalCard(props) {
|
|
|
732
789
|
),
|
|
733
790
|
state.localFetch?.failed ? h('p', { role: 'status', className: 'capital-config-write-failed' }, t('saveFailed')) : null,
|
|
734
791
|
)
|
|
792
|
+
const automationNumber = (field, label, min, max) => h('label', { className: 'capital-config-field' },
|
|
793
|
+
h('span', { className: 'capital-config-switch-label' }, t(label)),
|
|
794
|
+
h('input', {
|
|
795
|
+
type: 'number',
|
|
796
|
+
min,
|
|
797
|
+
max,
|
|
798
|
+
defaultValue: state.automation?.[field]?.value,
|
|
799
|
+
disabled: disabled || state.saving,
|
|
800
|
+
onBlur: (event) => props.writeAutomation(field, event.target.value),
|
|
801
|
+
}),
|
|
802
|
+
state.automation?.[field]?.failed ? h('p', { role: 'status', className: 'capital-config-write-failed' }, t('saveFailed')) : null,
|
|
803
|
+
)
|
|
804
|
+
const automationSection = h('div', { className: 'capital-config-field' },
|
|
805
|
+
h('span', { className: 'capital-config-switch-label' }, t('automationTitle')),
|
|
806
|
+
h('p', { className: 'capital-config-hint' }, t('automationHint')),
|
|
807
|
+
h('div', { className: 'capital-config-grid' },
|
|
808
|
+
automationNumber('tickMs', 'automationTick', 30000, 3600000),
|
|
809
|
+
automationNumber('runTimeoutMinutes', 'automationRunTimeout', 5, 120),
|
|
810
|
+
automationNumber('idleTimeoutMinutes', 'automationIdleTimeout', 1, 30),
|
|
811
|
+
automationNumber('maxSteps', 'automationMaxSteps', 10, 2000),
|
|
812
|
+
automationNumber('maxToolCalls', 'automationMaxToolCalls', 10, 6000),
|
|
813
|
+
),
|
|
814
|
+
h('label', { className: 'capital-config-switch-row' },
|
|
815
|
+
h('span', { className: 'capital-config-switch-label' }, t('automationInApp')),
|
|
816
|
+
h('input', {
|
|
817
|
+
type: 'checkbox',
|
|
818
|
+
checked: state.automation?.inAppNotifications?.on !== false,
|
|
819
|
+
disabled: disabled || state.saving,
|
|
820
|
+
onChange: (event) => props.writeAutomation('inAppNotifications', event.target.checked),
|
|
821
|
+
}),
|
|
822
|
+
),
|
|
823
|
+
)
|
|
735
824
|
const modeSection = h('div', { className: 'capital-config-selected-mode' },
|
|
736
825
|
h('div', { className: 'capital-config-switch-row' },
|
|
737
826
|
h('div', { className: 'capital-config-switch-text' },
|
|
@@ -826,7 +915,7 @@ function CapitalCard(props) {
|
|
|
826
915
|
if (next === 'skills') setPinnedSkills(enabledKeys())
|
|
827
916
|
},
|
|
828
917
|
}),
|
|
829
|
-
panel('sources', [form, localFetchSection]),
|
|
918
|
+
panel('sources', [form, localFetchSection, automationSection]),
|
|
830
919
|
panel('skills', autoMode
|
|
831
920
|
? [modeSection]
|
|
832
921
|
: [modeSection, h('div', { className: 'capital-config-skills-browser' },
|
package/config/index.js
CHANGED
|
@@ -76,6 +76,21 @@ export const Config = z.object({
|
|
|
76
76
|
selectedSkills: SelectedSkillsSchema.default(SELECTED_SKILL_DEFAULTS).description('Explicitly selected community methods; default off, each visible only to the Capital role(s) that own it'),
|
|
77
77
|
fuyaoCredentialRef: z.string().default('FUYAO_API_KEY').volatile().description('Fuyao credentials 引用名'),
|
|
78
78
|
ftshareCredentialRef: z.string().default('FTSHARE_API_KEY').volatile().description('FTShare(非凸科技)credentials 引用名'),
|
|
79
|
+
automation: z.object({
|
|
80
|
+
tickMs: z.number().default(60_000).volatile().description('投研自动化调度间隔毫秒(30000–3600000)'),
|
|
81
|
+
runTimeoutMinutes: z.number().default(30).volatile().description('单次运行 wall-clock 上限分钟(5–120)'),
|
|
82
|
+
idleTimeoutMinutes: z.number().default(5).volatile().description('单次运行空闲超时分钟(1–30)'),
|
|
83
|
+
maxSteps: z.number().default(300).volatile().description('单次运行最大步骤数(10–2000)'),
|
|
84
|
+
maxToolCalls: z.number().default(1_200).volatile().description('单次运行最大工具调用数(10–6000)'),
|
|
85
|
+
inAppNotifications: z.boolean().default(true).volatile().description('是否写入应用内通知'),
|
|
86
|
+
}).default({
|
|
87
|
+
tickMs: 60_000,
|
|
88
|
+
runTimeoutMinutes: 30,
|
|
89
|
+
idleTimeoutMinutes: 5,
|
|
90
|
+
maxSteps: 300,
|
|
91
|
+
maxToolCalls: 1_200,
|
|
92
|
+
inAppNotifications: true,
|
|
93
|
+
}).description('投研自动化默认值;任务级覆盖优先'),
|
|
79
94
|
retriever: z.object({
|
|
80
95
|
baseURL: z.string().default('').volatile().description('AnySearch API 地址'),
|
|
81
96
|
credentialRef: z.string().default('ANYSEARCH_API_KEY').volatile().description('AnySearch credentials 引用名'),
|
package/config/package.json
CHANGED
package/cordis.patch.yml
CHANGED
|
@@ -54,6 +54,14 @@
|
|
|
54
54
|
- id: capital-watchlist
|
|
55
55
|
name: './watchlist/index.js'
|
|
56
56
|
|
|
57
|
+
# ── CapGen 投研自动化 (host plane) ─────────────────────────────────────────────
|
|
58
|
+
# Independent from the official `ui-schedule` row: no `schedules` main/sidebar id, no
|
|
59
|
+
# turnTail, no right-sidebar kind. The page is host-plane for the same injection reason
|
|
60
|
+
# as chart-ui; `name` stays a literal path-like relative path (see the three pitfalls above).
|
|
61
|
+
- insert:
|
|
62
|
+
- id: capital-automation
|
|
63
|
+
name: './automation/index.js'
|
|
64
|
+
|
|
57
65
|
# ── Cross-preset runtime / policy (0.2.1) ─────────────────────────────────────
|
|
58
66
|
# Root and role presets mount separately, so apply() runs several times per process. Shared state
|
|
59
67
|
# (chart source tokens, chart artifacts) and the agent/created listeners (root convergence, shell
|
package/lib/index.d.ts
CHANGED
|
@@ -13,6 +13,14 @@ export interface Config {
|
|
|
13
13
|
selectedSkillsMode?: SelectedSkillsMode;
|
|
14
14
|
fuyaoCredentialRef?: string;
|
|
15
15
|
ftshareCredentialRef?: string;
|
|
16
|
+
automation?: {
|
|
17
|
+
tickMs?: number;
|
|
18
|
+
runTimeoutMinutes?: number;
|
|
19
|
+
idleTimeoutMinutes?: number;
|
|
20
|
+
maxSteps?: number;
|
|
21
|
+
maxToolCalls?: number;
|
|
22
|
+
inAppNotifications?: boolean;
|
|
23
|
+
};
|
|
16
24
|
retriever?: RetrieverConfig;
|
|
17
25
|
}
|
|
18
26
|
export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
@@ -25,6 +33,21 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
25
33
|
selectedSkillsMode: z<"manual" | "auto", "manual" | "auto", "defined">;
|
|
26
34
|
fuyaoCredentialRef: z<string, string, "defined">;
|
|
27
35
|
ftshareCredentialRef: z<string, string, "defined">;
|
|
36
|
+
automation: z<Schemastery.ObjectS<NoInfer<{
|
|
37
|
+
tickMs: z<number, number, "defined">;
|
|
38
|
+
runTimeoutMinutes: z<number, number, "defined">;
|
|
39
|
+
idleTimeoutMinutes: z<number, number, "defined">;
|
|
40
|
+
maxSteps: z<number, number, "defined">;
|
|
41
|
+
maxToolCalls: z<number, number, "defined">;
|
|
42
|
+
inAppNotifications: z<boolean, boolean, "defined">;
|
|
43
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
44
|
+
tickMs: z<number, number, "defined">;
|
|
45
|
+
runTimeoutMinutes: z<number, number, "defined">;
|
|
46
|
+
idleTimeoutMinutes: z<number, number, "defined">;
|
|
47
|
+
maxSteps: z<number, number, "defined">;
|
|
48
|
+
maxToolCalls: z<number, number, "defined">;
|
|
49
|
+
inAppNotifications: z<boolean, boolean, "defined">;
|
|
50
|
+
}>>, "defined">;
|
|
28
51
|
retriever: z<Schemastery.ObjectS<NoInfer<{
|
|
29
52
|
baseURL: z<string, string, "defined">;
|
|
30
53
|
credentialRef: z<string, string, "defined">;
|
|
@@ -112,6 +135,21 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
112
135
|
selectedSkillsMode: z<"manual" | "auto", "manual" | "auto", "defined">;
|
|
113
136
|
fuyaoCredentialRef: z<string, string, "defined">;
|
|
114
137
|
ftshareCredentialRef: z<string, string, "defined">;
|
|
138
|
+
automation: z<Schemastery.ObjectS<NoInfer<{
|
|
139
|
+
tickMs: z<number, number, "defined">;
|
|
140
|
+
runTimeoutMinutes: z<number, number, "defined">;
|
|
141
|
+
idleTimeoutMinutes: z<number, number, "defined">;
|
|
142
|
+
maxSteps: z<number, number, "defined">;
|
|
143
|
+
maxToolCalls: z<number, number, "defined">;
|
|
144
|
+
inAppNotifications: z<boolean, boolean, "defined">;
|
|
145
|
+
}>>, Schemastery.ObjectT<NoInfer<{
|
|
146
|
+
tickMs: z<number, number, "defined">;
|
|
147
|
+
runTimeoutMinutes: z<number, number, "defined">;
|
|
148
|
+
idleTimeoutMinutes: z<number, number, "defined">;
|
|
149
|
+
maxSteps: z<number, number, "defined">;
|
|
150
|
+
maxToolCalls: z<number, number, "defined">;
|
|
151
|
+
inAppNotifications: z<boolean, boolean, "defined">;
|
|
152
|
+
}>>, "defined">;
|
|
115
153
|
retriever: z<Schemastery.ObjectS<NoInfer<{
|
|
116
154
|
baseURL: z<string, string, "defined">;
|
|
117
155
|
credentialRef: z<string, string, "defined">;
|
package/lib/index.js
CHANGED
|
@@ -48,6 +48,14 @@ const RetrieverSchema = z.object({
|
|
|
48
48
|
paddleOcr: PaddleOcrSchema.default({ ...PADDLE_OCR_DEFAULTS })
|
|
49
49
|
.description('PaddleOCR 文档解析(ocr 工具)配置;Token 走 credentials 引用 PADDLE_OCR_TOKEN'),
|
|
50
50
|
});
|
|
51
|
+
const AutomationSchema = z.object({
|
|
52
|
+
tickMs: z.number().default(60_000).description('投研自动化调度间隔毫秒(30000–3600000)'),
|
|
53
|
+
runTimeoutMinutes: z.number().default(30).description('单次运行 wall-clock 上限分钟(5–120)'),
|
|
54
|
+
idleTimeoutMinutes: z.number().default(5).description('单次运行空闲超时分钟(1–30)'),
|
|
55
|
+
maxSteps: z.number().default(300).description('单次运行最大步骤数(10–2000)'),
|
|
56
|
+
maxToolCalls: z.number().default(1_200).description('单次运行最大工具调用数(10–6000)'),
|
|
57
|
+
inAppNotifications: z.boolean().default(true).description('是否写入应用内通知'),
|
|
58
|
+
});
|
|
51
59
|
// Derive toggles from the catalog: a hand-copied list silently drops defaults at the entry→plugin boundary.
|
|
52
60
|
const SelectedSkillsSchema = z.object(Object.fromEntries(SELECTED_SKILL_CATALOG.map(({ key, name }) => [
|
|
53
61
|
key,
|
|
@@ -67,6 +75,14 @@ export const Config = z.object({
|
|
|
67
75
|
ftshareCredentialRef: z.string()
|
|
68
76
|
.default('FTSHARE_API_KEY')
|
|
69
77
|
.description('FTShare(非凸科技)credentials 引用名,空 = FTSHARE_API_KEY'),
|
|
78
|
+
automation: AutomationSchema.default({
|
|
79
|
+
tickMs: 60_000,
|
|
80
|
+
runTimeoutMinutes: 30,
|
|
81
|
+
idleTimeoutMinutes: 5,
|
|
82
|
+
maxSteps: 300,
|
|
83
|
+
maxToolCalls: 1_200,
|
|
84
|
+
inAppNotifications: true,
|
|
85
|
+
}).description('投研自动化默认值;任务级覆盖优先'),
|
|
70
86
|
retriever: RetrieverSchema.default({ baseURL: '', credentialRef: 'ANYSEARCH_API_KEY', windDocs: { endpoint: '', credentialRef: 'WIND_API_KEY', timeoutMs: 60000 }, localFetch: { ...LOCAL_FETCH_DEFAULTS }, paddleOcr: { ...PADDLE_OCR_DEFAULTS } })
|
|
71
87
|
.description('web_retriever 配置(可选;缺省使用 AnySearch 默认地址与凭据名)'),
|
|
72
88
|
});
|
package/lib/sources/wind-mcp.js
CHANGED
|
@@ -462,8 +462,8 @@ function createWindSource(options) {
|
|
|
462
462
|
execute: (request, signal) => options.execute(client, normalize(request.params), signal),
|
|
463
463
|
};
|
|
464
464
|
}
|
|
465
|
-
const EDB_SEARCH_DESCRIPTION = 'Wind EDB(经济数据库)指标**检索**:只找指标不取数,一行一个候选指标(code/name/unit/freq/source + 该序列的起止与更新日期)。这是 fuyao 与东财都没有的面:宏观、行业、汇率、全球序列。⛔ question 走后端 NER,字面请求不等于字面结果——实测「人民币兑美元汇率 指标」回的是**美元兑人民币**(source 为 美联储 / 台湾统计局),先核对 name 与 source 再取数。键集随指标族变化:实测汇率类没有 unit/magnitude/currency 三个键,缺的一律 null
|
|
466
|
-
const EDB_QUERY_DESCRIPTION = 'Wind EDB 时间序列**取数**:上游回 {meta, date[], value[]} 并行数组,本能力转置成**一行一个观测期**(meta 逐行拼接,多指标可分次取后按 code 拼对比)。⛔ indicator 一次只填**一个**指标代码或一条中文问句:2026-10-06 实测逗号分隔的多码挂满 60 秒无应答,上游"多个代码用英文逗号分隔"的说法不成立,要多个就分次调用。start_date/end_date 必填——上游在日期区间与 observation 之间二选一,而 observation 实测"给 3 期只回 2 期"、期数不可信,本能力直接拒绝它。report_date 由上游紧凑串 20260731 归一而来,report_date_ms 按 Asia/Shanghai 零点(EDB 的日期本身没有时区)。unit 是上游单位原文;后端 INVALID 一律 null,**不得当 0
|
|
465
|
+
const EDB_SEARCH_DESCRIPTION = 'Wind EDB(经济数据库)指标**检索**:只找指标不取数,一行一个候选指标(code/name/unit/freq/source + 该序列的起止与更新日期)。这是 fuyao 与东财都没有的面:宏观、行业、汇率、全球序列。⛔ question 走后端 NER,字面请求不等于字面结果——实测「人民币兑美元汇率 指标」回的是**美元兑人民币**(source 为 美联储 / 台湾统计局),先核对 name 与 source 再取数。键集随指标族变化:实测汇率类没有 unit/magnitude/currency 三个键,缺的一律 null,不猜单位。⛔ 只在不确定指标叫什么、或需要候选清单时用:已知指标(美元指数、WTI 原油价格…)直接走 wind_edb_query 的中文问句,取数结果每行本来就带 code/name/source,不必先检索——两个能力都按次消耗上游积分,为已知指标多打一次 search 是纯浪费。没有匹配时返回 0 行,是合法空结果不是失败。';
|
|
466
|
+
const EDB_QUERY_DESCRIPTION = 'Wind EDB 时间序列**取数**:上游回 {meta, date[], value[]} 并行数组,本能力转置成**一行一个观测期**(meta 逐行拼接,多指标可分次取后按 code 拼对比)。⛔ indicator 一次只填**一个**指标代码或一条中文问句:2026-10-06 实测逗号分隔的多码挂满 60 秒无应答,上游"多个代码用英文逗号分隔"的说法不成立,要多个就分次调用。start_date/end_date 必填——上游在日期区间与 observation 之间二选一,而 observation 实测"给 3 期只回 2 期"、期数不可信,本能力直接拒绝它。report_date 由上游紧凑串 20260731 归一而来,report_date_ms 按 Asia/Shanghai 零点(EDB 的日期本身没有时区)。unit 是上游单位原文;后端 INVALID 一律 null,**不得当 0 参与计算**。已实测指标代码与同义中文问句回同一份序列(M0000612 = 中国 CPI 当月同比):indicator 直接填中文问句即可(官方口径就是自然语言取数),本能力按次消耗上游积分,已知指标不要先检索。中文问句可能命中同族多个指标(实测「黄金价格」回伦敦定盘 / COMEX / SGE 等 7 条),返回行自带 code/name/unit/source,按 name 与 source 取舍后再引用;只有不知道指标叫什么、需要候选清单时才用 wind_edb_search。';
|
|
467
467
|
const KLINE_DESCRIPTION = 'Wind K 线:单只标的按**日期区间**取 日/周/月 与 1/5/15/30 分钟。相对腾讯的增量(§6.6.1):按日期区间取 640 根之前的历史、每根带成交额/成交量/换手/均价的美股 K 线、以及分钟档;⚠️ **分钟档只有 A 股取到过行**,港股与美股的分钟到 2026-10-06 为止四次全挂、仍未证实,要港美股分时先小范围试一次。港美股日线与快照请走 tencent_*。⛔ code 必须自带交易所后缀(600519.SH / 00700.HK / AAPL.O),本能力不猜后缀——实测 AAPL.O 与 AAPL.N 回完全相同的行(后缀不参与解析),所以 BRK.B 一类双市场代码有认错标的的风险;每行的 code 只是请求写法回显,上游 K 线表里没有代码列。⛔ period 只放逐档打过真报文的七档,60 分钟实测两次都挂满超时、不提供。adjust 只有 none 与 qfq:后复权以 afdate 为锚向未来放大,锚默认成今天会得到一个逐位等于不复权却叫 hfq 的序列,所以宁可不给;qfq 的 afdate 由本能力锁成当日,因此 end_date 不得晚于当日;分钟档只允许 none。close 来自上游 MATCH 列(Wind 没有 CLOSE 列);上游多给的列不收录,行里以 output_fields 为准。数值列上游全是字符串(columns[].type 却一律写 string),解析不了即失败。time_ms 按**该行自带偏移**换算(A股/港股 +08:00、美股 -04:00 是交易所当地时间),整段按北京时间处理会让美股错位 12 小时。⚠️ volume 实测 A 股是**股**(腾讯 A 股 K 线是手,跨源先换);turnover_rate_pct 是百分数原值(0.2892 = 0.2892%),上游不给它的单位与分母口径。非交易日快回 0 行、是合法成功(实测 A 股国庆休市日 653ms 回空表);而"该日该市场分钟尚未落地"与上游故障都表现为挂到 12 秒超时(wind_upstream_timeout)——不要盲目重试同一区间,改更早日期或改走日线。积分计费:AUTH/RATE_LIMIT/后端错误一律不自动重试。';
|
|
468
468
|
export function createWindSources(resolveApiKey) {
|
|
469
469
|
return [
|
|
@@ -496,7 +496,7 @@ export function createWindSources(resolveApiKey) {
|
|
|
496
496
|
inputSchema: {
|
|
497
497
|
type: 'object',
|
|
498
498
|
properties: {
|
|
499
|
-
indicator: { type: 'string', maxLength: 200, description: '
|
|
499
|
+
indicator: { type: 'string', maxLength: 200, description: '一条中文指标问句(推荐,写清实体与口径,如「美元指数」「WTI 原油价格」),或一个已知的 EDB 指标代码(如 M0000612);一次只填一个,不接受逗号分隔的多个' },
|
|
500
500
|
start_date: { type: 'string', description: '起始日期 YYYY-MM-DD(含)' },
|
|
501
501
|
end_date: { type: 'string', description: '结束日期 YYYY-MM-DD(含)' },
|
|
502
502
|
},
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Known limit: DNS resolves per request but the IP is not pinned to the connection,
|
|
4
4
|
* so a rebinding window remains (same trade-off as dsh-search-first).
|
|
5
5
|
*/
|
|
6
|
-
export declare const LOCAL_FETCH_CLIENT_VERSION = "2.
|
|
6
|
+
export declare const LOCAL_FETCH_CLIENT_VERSION = "2.13.1";
|
|
7
7
|
export declare const LOCAL_FETCH_MAX_URL_LENGTH = 2048;
|
|
8
8
|
export type LocalFetchErrorCode = 'ABORTED' | 'TIMEOUT' | 'INVALID_URL' | 'BLOCKED_URL' | 'DNS' | 'REDIRECT' | 'HTTP' | 'TOO_LARGE' | 'UNSUPPORTED_CONTENT_TYPE';
|
|
9
9
|
export declare class LocalFetchError extends Error {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* so a rebinding window remains (same trade-off as dsh-search-first).
|
|
5
5
|
*/
|
|
6
6
|
import { htmlToMarkdown, stripInvisibleText } from './html-markdown.js';
|
|
7
|
-
export const LOCAL_FETCH_CLIENT_VERSION = '2.
|
|
7
|
+
export const LOCAL_FETCH_CLIENT_VERSION = '2.13.1';
|
|
8
8
|
export const LOCAL_FETCH_MAX_URL_LENGTH = 2048;
|
|
9
9
|
export class LocalFetchError extends Error {
|
|
10
10
|
code;
|
|
@@ -35,7 +35,7 @@ export interface WindCallResult {
|
|
|
35
35
|
code?: WindErrorCode;
|
|
36
36
|
}
|
|
37
37
|
/** Must match `package.json` version; a test pins the two together. */
|
|
38
|
-
export declare const WIND_CLIENT_VERSION = "2.
|
|
38
|
+
export declare const WIND_CLIENT_VERSION = "2.13.1";
|
|
39
39
|
export interface WindClient {
|
|
40
40
|
callTool(toolName: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<WindCallResult>;
|
|
41
41
|
}
|
|
@@ -19,7 +19,7 @@ export const WIND_SERVER_ENDPOINTS = {
|
|
|
19
19
|
analytics_data: 'https://mcp.wind.com.cn/vserver_analytics_data/mcp/',
|
|
20
20
|
};
|
|
21
21
|
/** Must match `package.json` version; a test pins the two together. */
|
|
22
|
-
export const WIND_CLIENT_VERSION = '2.
|
|
22
|
+
export const WIND_CLIENT_VERSION = '2.13.1';
|
|
23
23
|
function errorText(error) {
|
|
24
24
|
return error instanceof Error ? error.message : String(error);
|
|
25
25
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@v587d/capital-generation",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.1",
|
|
4
4
|
"description": "Capital Generation:面向中国散户的 AI 投资助手插件(自动模式 Agent Preset)",
|
|
5
5
|
"icon": "assets/cg-icon.png",
|
|
6
6
|
"author": "v587d",
|
|
@@ -106,6 +106,7 @@
|
|
|
106
106
|
"chart-ui",
|
|
107
107
|
"config",
|
|
108
108
|
"watchlist",
|
|
109
|
+
"automation",
|
|
109
110
|
"preset",
|
|
110
111
|
"selected-skills/catalog.js",
|
|
111
112
|
"selected-skills/filter.js",
|
|
@@ -136,10 +137,11 @@
|
|
|
136
137
|
},
|
|
137
138
|
"scripts": {
|
|
138
139
|
"clean": "node -e \"import('node:fs').then(({ rmSync }) => rmSync('lib', { recursive: true, force: true }))\"",
|
|
139
|
-
"build": "npm run clean && tsc && node scripts/copy-assets.mjs && npm run build:client && npm run build:config-client && npm run build:watchlist-client",
|
|
140
|
+
"build": "npm run clean && tsc && node scripts/copy-assets.mjs && npm run build:client && npm run build:config-client && npm run build:watchlist-client && npm run build:automation-client",
|
|
140
141
|
"build:client": "node scripts/build-client.mjs",
|
|
141
142
|
"build:config-client": "node scripts/build-config-client.mjs",
|
|
142
143
|
"build:watchlist-client": "node scripts/build-watchlist-client.mjs",
|
|
144
|
+
"build:automation-client": "node scripts/build-automation-client.mjs",
|
|
143
145
|
"dev": "tsc -w",
|
|
144
146
|
"vendor:charts": "node scripts/vendor-lightweight-charts.mjs",
|
|
145
147
|
"check:dsh": "node scripts/check-dsh-compat.mjs",
|
|
@@ -150,6 +152,7 @@
|
|
|
150
152
|
"smoke:fuyao": "node scripts/smoke-fuyao.mjs",
|
|
151
153
|
"smoke:wind": "node scripts/smoke-wind.mjs",
|
|
152
154
|
"smoke:local-fetch": "node scripts/smoke-local-fetch.mjs",
|
|
155
|
+
"smoke:calendar": "node scripts/smoke-calendar.mjs",
|
|
153
156
|
"contract:probe": "node scripts/contract-probe.mjs",
|
|
154
157
|
"docs:capabilities": "npm run build && node scripts/gen-capability-table.mjs",
|
|
155
158
|
"verify:sessions": "node scripts/verify-sessions.mjs",
|
package/watchlist/package.json
CHANGED