@v587d/capital-generation 2.8.3 → 2.9.0
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 +54 -1
- package/README.md +40 -19
- package/chart-ui/README.md +1 -1
- package/chart-ui/client.src.cjs +7 -16
- package/chart-ui/index.js +12 -33
- package/chart-ui/package.json +2 -2
- package/config/client.js +18 -39
- package/config/client.src.cjs +79 -217
- package/config/index.js +22 -72
- package/config/package.json +2 -2
- package/cordis.patch.yml +46 -51
- package/lib/agents/bash-guard.d.ts +9 -55
- package/lib/agents/bash-guard.js +27 -67
- package/lib/agents/preset-roster.d.ts +22 -0
- package/lib/agents/preset-roster.js +87 -0
- package/lib/agents/role-tool-policy.d.ts +46 -0
- package/lib/agents/role-tool-policy.js +205 -0
- package/lib/agents/root-tool-policy.d.ts +28 -124
- package/lib/agents/root-tool-policy.js +164 -237
- package/lib/agents/selected-skills-provider.d.ts +2 -6
- package/lib/agents/selected-skills-provider.js +27 -84
- package/lib/capital-settings.d.ts +27 -0
- package/lib/capital-settings.js +23 -0
- package/lib/chart/artifact-ref.d.ts +3 -8
- package/lib/chart/artifact-ref.js +3 -8
- package/lib/chart/downsample.d.ts +2 -5
- package/lib/chart/downsample.js +3 -8
- package/lib/chart/errors.d.ts +3 -7
- package/lib/chart/errors.js +1 -2
- package/lib/chart/event-context.d.ts +8 -0
- package/lib/chart/event-context.js +39 -0
- package/lib/chart/events.d.ts +21 -78
- package/lib/chart/events.js +40 -189
- package/lib/chart/html.d.ts +2 -5
- package/lib/chart/html.js +8 -15
- package/lib/chart/runtime.d.ts +5 -18
- package/lib/chart/runtime.js +14 -34
- package/lib/chart/series.d.ts +10 -17
- package/lib/chart/series.js +22 -47
- package/lib/chart/source-token.d.ts +5 -13
- package/lib/chart/source-token.js +18 -17
- package/lib/chart/spec.d.ts +6 -12
- package/lib/chart/spec.js +7 -31
- package/lib/chart/tool.d.ts +6 -29
- package/lib/chart/tool.js +9 -23
- package/lib/chart-render-entry.d.ts +9 -0
- package/lib/chart-render-entry.js +17 -0
- package/lib/chart-source-entry.d.ts +13 -0
- package/lib/chart-source-entry.js +20 -0
- package/lib/collect-entry.d.ts +9 -0
- package/lib/collect-entry.js +10 -0
- package/lib/collector-runtime.d.ts +22 -0
- package/lib/collector-runtime.js +97 -0
- package/lib/data-collector/args.d.ts +6 -24
- package/lib/data-collector/args.js +6 -24
- package/lib/data-collector/dataset-tools.d.ts +7 -1
- package/lib/data-collector/dataset-tools.js +27 -56
- package/lib/data-collector/describe.d.ts +8 -33
- package/lib/data-collector/describe.js +17 -70
- package/lib/data-collector/hub.d.ts +27 -85
- package/lib/data-collector/hub.js +19 -85
- package/lib/data-collector/query-time.d.ts +7 -26
- package/lib/data-collector/query-time.js +8 -27
- package/lib/data-collector/store.d.ts +40 -117
- package/lib/data-collector/store.js +32 -111
- package/lib/data-collector/time-axis.d.ts +16 -76
- package/lib/data-collector/time-axis.js +25 -111
- package/lib/data-collector/tools.d.ts +6 -6
- package/lib/data-collector/tools.js +34 -43
- package/lib/dataset-read-entry.d.ts +9 -0
- package/lib/dataset-read-entry.js +7 -0
- package/lib/index.d.ts +7 -117
- package/lib/index.js +43 -422
- package/lib/net/eastmoney-client.d.ts +13 -65
- package/lib/net/eastmoney-client.js +12 -53
- package/lib/net/throttle.d.ts +2 -13
- package/lib/net/throttle.js +3 -14
- package/lib/ocr/client.d.ts +12 -21
- package/lib/ocr/client.js +23 -40
- package/lib/ocr/markdown.d.ts +20 -26
- package/lib/ocr/markdown.js +23 -36
- package/lib/ocr/store.d.ts +14 -47
- package/lib/ocr/store.js +15 -45
- package/lib/ocr-entry.d.ts +9 -0
- package/lib/ocr-entry.js +10 -0
- package/lib/policy-entry.d.ts +17 -0
- package/lib/policy-entry.js +22 -0
- package/lib/preset-claim.d.ts +22 -0
- package/lib/preset-claim.js +24 -0
- package/lib/preset-ids.d.ts +38 -0
- package/lib/preset-ids.js +46 -0
- package/lib/retriever-config.d.ts +37 -0
- package/lib/retriever-config.js +36 -0
- package/lib/retriever-runtime.d.ts +31 -0
- package/lib/retriever-runtime.js +82 -0
- package/lib/root-extras-entry.d.ts +17 -0
- package/lib/root-extras-entry.js +25 -0
- package/lib/runtime-entry.d.ts +15 -0
- package/lib/runtime-entry.js +5 -0
- package/lib/runtime.d.ts +21 -0
- package/lib/runtime.js +33 -0
- package/lib/search-entry.d.ts +9 -0
- package/lib/search-entry.js +9 -0
- package/lib/sources/eastmoney-http.js +20 -68
- package/lib/sources/ftshare-rest.d.ts +6 -34
- package/lib/sources/ftshare-rest.js +84 -292
- package/lib/sources/fuyao-core.d.ts +8 -18
- package/lib/sources/fuyao-core.js +10 -21
- package/lib/sources/fuyao-rest.d.ts +2 -6
- package/lib/sources/fuyao-rest.js +23 -102
- package/lib/sources/security-code.d.ts +6 -12
- package/lib/sources/security-code.js +6 -12
- package/lib/sources/security-identity.d.ts +1 -4
- package/lib/sources/security-identity.js +3 -8
- package/lib/sources/tencent-http.js +14 -28
- package/lib/sources/tencent-public-core.d.ts +8 -60
- package/lib/sources/tencent-public-core.js +12 -77
- package/lib/sources/wind-mcp.d.ts +0 -5
- package/lib/sources/wind-mcp.js +23 -78
- package/lib/sources-entry.d.ts +9 -0
- package/lib/sources-entry.js +9 -0
- package/lib/time/tools.d.ts +8 -31
- package/lib/time/tools.js +30 -66
- package/lib/time-entry.d.ts +9 -0
- package/lib/time-entry.js +7 -0
- package/lib/tool-exec.d.ts +45 -11
- package/lib/tool-exec.js +59 -6
- package/lib/user-customization.d.ts +14 -0
- package/lib/user-customization.js +47 -0
- package/lib/watchlist/tools.d.ts +3 -13
- package/lib/watchlist/tools.js +10 -30
- package/lib/watchlist-entry.d.ts +9 -0
- package/lib/watchlist-entry.js +6 -0
- package/lib/web-retriever/engines.d.ts +6 -11
- package/lib/web-retriever/engines.js +9 -14
- package/lib/web-retriever/html-markdown.d.ts +14 -34
- package/lib/web-retriever/html-markdown.js +39 -75
- package/lib/web-retriever/local-fetch.d.ts +22 -58
- package/lib/web-retriever/local-fetch.js +33 -77
- package/lib/web-retriever/retriever.d.ts +6 -18
- package/lib/web-retriever/retriever.js +7 -7
- package/lib/web-retriever/sources.d.ts +37 -124
- package/lib/web-retriever/sources.js +64 -196
- package/lib/web-retriever/tools.d.ts +43 -27
- package/lib/web-retriever/tools.js +99 -137
- package/lib/web-retriever/wind-client.d.ts +14 -31
- package/lib/web-retriever/wind-client.js +16 -32
- package/locale/zh.json +1 -1
- package/package.json +67 -7
- package/preset/capital-generation/README.md +87 -53
- package/preset/capital-generation/agent.patch.yml +526 -337
- package/preset/capital-generation/skills/capital-data-profile/SKILL.md +2 -2
- package/preset/capital-generation/skills/capital-data-protocol/SKILL.md +1 -1
- package/preset/capital-generation/skills/capital-equity-research/SKILL.md +1 -1
- package/preset/capital-generation/skills/capital-event-impact/SKILL.md +1 -1
- package/preset/capital-generation/skills/capital-orchestration/SKILL.md +15 -19
- package/preset/capital-generation/skills/capital-portfolio-review/SKILL.md +1 -1
- package/preset/capital-generation/skills/capital-visualization-protocol/SKILL.md +9 -12
- package/preset/capital-generation/skills/capital-web-evidence/SKILL.md +1 -1
- package/watchlist/client.js +15 -148
- package/watchlist/client.src.cjs +148 -662
- package/watchlist/holding-rules.js +11 -38
- package/watchlist/index.js +127 -397
- package/watchlist/package.json +2 -2
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Wind
|
|
3
|
-
*
|
|
4
|
-
* 线格式为 JSON-RPC 2.0(即 MCP 线协议):initialize → tools/call,无会话态、
|
|
5
|
-
* 无 SDK、无框架依赖——与 fuyao-rest / anysearch engines 同构的普通 HTTP 客户端。
|
|
6
|
-
* 协议蓝本(Wind 官方 CLI):github.com/Wind-Alice/AliceMarket 的
|
|
7
|
-
* skills/wind-mcp-skill/scripts/cli.mjs(本地参考副本在 docs/reference/,不入库)。
|
|
2
|
+
* Wind financial-document client: JSON-RPC 2.0 (MCP wire protocol) over plain
|
|
3
|
+
* HTTP. initialize -> tools/call, no session state, no SDK.
|
|
8
4
|
*/
|
|
9
5
|
export declare const DEFAULT_WIND_ENDPOINT = "https://mcp.wind.com.cn/vserver_financial_docs/mcp/";
|
|
10
6
|
export declare const WIND_REQUEST_TIMEOUT_MS = 60000;
|
|
11
7
|
export declare const WIND_MAX_CONTENT_CHARS = 20000;
|
|
12
8
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* 这里是**事实**(端点常量),不是代码搬运:上游仓库未声明 LICENSE,蓝本
|
|
16
|
-
* (官方 CLI 的 `SERVERS` 表)按惯例只作本地参考副本、不入库,见
|
|
17
|
-
* `docs/design/wind-market-source.md` §1.1。
|
|
18
|
-
*
|
|
19
|
-
* `analytics_data` 一并列出是为了记下"它存在但不可用":2026-10-05 实测连 `initialize`
|
|
20
|
-
* 都挂满 60 秒(同文档 §6.1),所以数据源侧不接它。
|
|
9
|
+
* Hosted MCP servers (`server_type` -> URL). `analytics_data` is listed to record
|
|
10
|
+
* that it exists but is unusable (initialize hangs), so no data source uses it.
|
|
21
11
|
*/
|
|
22
12
|
export declare const WIND_SERVER_ENDPOINTS: {
|
|
23
13
|
readonly stock_data: "https://mcp.wind.com.cn/vserver_stock_data/mcp/";
|
|
@@ -30,40 +20,33 @@ export declare const WIND_SERVER_ENDPOINTS: {
|
|
|
30
20
|
};
|
|
31
21
|
export type WindServerType = keyof typeof WIND_SERVER_ENDPOINTS;
|
|
32
22
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* BACKEND=接口层与业务错误;INVALID=响应不可解析。
|
|
23
|
+
* Error classes drive fallback: AUTH=missing/invalid key; RATE_LIMIT=429;
|
|
24
|
+
* NETWORK=network/5xx/timeout; BACKEND=API/business; INVALID=unparseable.
|
|
36
25
|
*/
|
|
37
26
|
export type WindErrorCode = 'AUTH' | 'RATE_LIMIT' | 'NETWORK' | 'BACKEND' | 'INVALID';
|
|
38
27
|
export interface WindCallResult {
|
|
39
28
|
ok: boolean;
|
|
40
|
-
/**
|
|
29
|
+
/** Parsed JSON result; string fields clipped to WIND_MAX_CONTENT_CHARS. */
|
|
41
30
|
data?: unknown;
|
|
42
|
-
/**
|
|
31
|
+
/** Non-JSON body passed through (<= WIND_MAX_CONTENT_CHARS). */
|
|
43
32
|
content?: string;
|
|
44
33
|
content_chars?: number;
|
|
45
34
|
error?: string;
|
|
46
35
|
code?: WindErrorCode;
|
|
47
36
|
}
|
|
48
|
-
/**
|
|
49
|
-
|
|
50
|
-
*
|
|
51
|
-
* ⚠️ 必须与 `package.json` 的 `version` 一致:嵌套包 `chart-ui/package.json` 的版本由
|
|
52
|
-
* `test/chart-composition.test.mjs` 守着(会因漂移而失败),这里原本是写死的第二处,
|
|
53
|
-
* 一次发版就得记得改两遍。所以本常量由测试一并核对(见 `test/wind-client.test.mjs`)。
|
|
54
|
-
*/
|
|
55
|
-
export declare const WIND_CLIENT_VERSION = "2.8.3";
|
|
37
|
+
/** Must match `package.json` version; a test pins the two together. */
|
|
38
|
+
export declare const WIND_CLIENT_VERSION = "2.9.0";
|
|
56
39
|
export interface WindClient {
|
|
57
40
|
callTool(toolName: string, args: Record<string, unknown>, signal?: AbortSignal): Promise<WindCallResult>;
|
|
58
41
|
}
|
|
59
42
|
export interface WindClientOptions {
|
|
60
43
|
endpoint?: string;
|
|
61
|
-
/**
|
|
44
|
+
/** Re-resolve the key on every call, never cache it. */
|
|
62
45
|
resolveApiKey: () => Promise<string | undefined>;
|
|
63
|
-
/**
|
|
46
|
+
/** Per-request timeout (initialize and tools/call separately); default 60000. */
|
|
64
47
|
timeoutMs?: number;
|
|
65
|
-
/**
|
|
48
|
+
/** Network-error retry delays; default [300, 1000], shortened only in tests. */
|
|
66
49
|
retryDelaysMs?: number[];
|
|
67
50
|
}
|
|
68
|
-
/**
|
|
51
|
+
/** Endpoint is validated at construction so config errors surface immediately. */
|
|
69
52
|
export declare function createWindClient(options: WindClientOptions): WindClient;
|
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Wind
|
|
3
|
-
*
|
|
4
|
-
* 线格式为 JSON-RPC 2.0(即 MCP 线协议):initialize → tools/call,无会话态、
|
|
5
|
-
* 无 SDK、无框架依赖——与 fuyao-rest / anysearch engines 同构的普通 HTTP 客户端。
|
|
6
|
-
* 协议蓝本(Wind 官方 CLI):github.com/Wind-Alice/AliceMarket 的
|
|
7
|
-
* skills/wind-mcp-skill/scripts/cli.mjs(本地参考副本在 docs/reference/,不入库)。
|
|
2
|
+
* Wind financial-document client: JSON-RPC 2.0 (MCP wire protocol) over plain
|
|
3
|
+
* HTTP. initialize -> tools/call, no session state, no SDK.
|
|
8
4
|
*/
|
|
9
5
|
export const DEFAULT_WIND_ENDPOINT = 'https://mcp.wind.com.cn/vserver_financial_docs/mcp/';
|
|
10
6
|
export const WIND_REQUEST_TIMEOUT_MS = 60_000;
|
|
11
7
|
export const WIND_MAX_CONTENT_CHARS = 20_000;
|
|
12
8
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* 这里是**事实**(端点常量),不是代码搬运:上游仓库未声明 LICENSE,蓝本
|
|
16
|
-
* (官方 CLI 的 `SERVERS` 表)按惯例只作本地参考副本、不入库,见
|
|
17
|
-
* `docs/design/wind-market-source.md` §1.1。
|
|
18
|
-
*
|
|
19
|
-
* `analytics_data` 一并列出是为了记下"它存在但不可用":2026-10-05 实测连 `initialize`
|
|
20
|
-
* 都挂满 60 秒(同文档 §6.1),所以数据源侧不接它。
|
|
9
|
+
* Hosted MCP servers (`server_type` -> URL). `analytics_data` is listed to record
|
|
10
|
+
* that it exists but is unusable (initialize hangs), so no data source uses it.
|
|
21
11
|
*/
|
|
22
12
|
export const WIND_SERVER_ENDPOINTS = {
|
|
23
13
|
stock_data: 'https://mcp.wind.com.cn/vserver_stock_data/mcp/',
|
|
@@ -28,14 +18,8 @@ export const WIND_SERVER_ENDPOINTS = {
|
|
|
28
18
|
economic_data: 'https://mcp.wind.com.cn/vserver_economic_data/mcp/',
|
|
29
19
|
analytics_data: 'https://mcp.wind.com.cn/vserver_analytics_data/mcp/',
|
|
30
20
|
};
|
|
31
|
-
/**
|
|
32
|
-
|
|
33
|
-
*
|
|
34
|
-
* ⚠️ 必须与 `package.json` 的 `version` 一致:嵌套包 `chart-ui/package.json` 的版本由
|
|
35
|
-
* `test/chart-composition.test.mjs` 守着(会因漂移而失败),这里原本是写死的第二处,
|
|
36
|
-
* 一次发版就得记得改两遍。所以本常量由测试一并核对(见 `test/wind-client.test.mjs`)。
|
|
37
|
-
*/
|
|
38
|
-
export const WIND_CLIENT_VERSION = '2.8.3';
|
|
21
|
+
/** Must match `package.json` version; a test pins the two together. */
|
|
22
|
+
export const WIND_CLIENT_VERSION = '2.9.0';
|
|
39
23
|
function errorText(error) {
|
|
40
24
|
return error instanceof Error ? error.message : String(error);
|
|
41
25
|
}
|
|
@@ -46,7 +30,7 @@ class WindTransportError extends Error {
|
|
|
46
30
|
this.code = code;
|
|
47
31
|
}
|
|
48
32
|
}
|
|
49
|
-
/** HTTP
|
|
33
|
+
/** HTTP status -> error class; anything else is NETWORK. */
|
|
50
34
|
const HTTP_ERROR_CODES = {
|
|
51
35
|
401: 'AUTH',
|
|
52
36
|
429: 'RATE_LIMIT',
|
|
@@ -70,7 +54,7 @@ function normalizeEndpoint(endpoint) {
|
|
|
70
54
|
}
|
|
71
55
|
return raw;
|
|
72
56
|
}
|
|
73
|
-
/**
|
|
57
|
+
/** Body may be pure JSON or SSE (last `data:` line). */
|
|
74
58
|
function parseResponsePayload(text) {
|
|
75
59
|
const trimmed = text.trim();
|
|
76
60
|
if (trimmed.startsWith('{')) {
|
|
@@ -78,7 +62,7 @@ function parseResponsePayload(text) {
|
|
|
78
62
|
return JSON.parse(trimmed);
|
|
79
63
|
}
|
|
80
64
|
catch {
|
|
81
|
-
//
|
|
65
|
+
// Not a JSON object: fall through to the SSE parse below.
|
|
82
66
|
}
|
|
83
67
|
}
|
|
84
68
|
let last;
|
|
@@ -96,7 +80,7 @@ function parseResponsePayload(text) {
|
|
|
96
80
|
}
|
|
97
81
|
throw new Error(`响应格式无法识别(既非 JSON 也非 SSE);原文前 200 字符:${text.slice(0, 200)}`);
|
|
98
82
|
}
|
|
99
|
-
/**
|
|
83
|
+
/** Deep-clip long string fields, preserving structure. */
|
|
100
84
|
function trimDeep(value, maxChars) {
|
|
101
85
|
if (typeof value === 'string')
|
|
102
86
|
return value.length > maxChars ? value.slice(0, maxChars) : value;
|
|
@@ -123,7 +107,7 @@ function firstContentText(result) {
|
|
|
123
107
|
}
|
|
124
108
|
return undefined;
|
|
125
109
|
}
|
|
126
|
-
/** JSON-RPC error
|
|
110
|
+
/** Render a JSON-RPC error field as text. */
|
|
127
111
|
function rpcErrorText(payload) {
|
|
128
112
|
if (!payload || typeof payload !== 'object' || Array.isArray(payload))
|
|
129
113
|
return undefined;
|
|
@@ -141,8 +125,8 @@ function rpcErrorText(payload) {
|
|
|
141
125
|
return JSON.stringify(error).slice(0, 2_000);
|
|
142
126
|
}
|
|
143
127
|
/**
|
|
144
|
-
*
|
|
145
|
-
*
|
|
128
|
+
* Wind wraps business errors inside content[0].text JSON, so unpack a second time:
|
|
129
|
+
* mcp_tool_error_code / error{} / data.code.
|
|
146
130
|
*/
|
|
147
131
|
function innerBusinessError(data) {
|
|
148
132
|
if (!data || typeof data !== 'object' || Array.isArray(data))
|
|
@@ -174,7 +158,7 @@ function innerBusinessError(data) {
|
|
|
174
158
|
}
|
|
175
159
|
return undefined;
|
|
176
160
|
}
|
|
177
|
-
/** JSON-RPC result
|
|
161
|
+
/** JSON-RPC result -> WindCallResult, including isError and inner business errors. */
|
|
178
162
|
function interpretResult(payload) {
|
|
179
163
|
if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
|
|
180
164
|
return { ok: false, code: 'INVALID', error: 'Wind 返回不可解析(非 JSON-RPC 对象)' };
|
|
@@ -211,7 +195,7 @@ function interpretResult(payload) {
|
|
|
211
195
|
return { ok: false, code: 'BACKEND', error: businessError };
|
|
212
196
|
return { ok: true, data: trimDeep(parsed, WIND_MAX_CONTENT_CHARS) };
|
|
213
197
|
}
|
|
214
|
-
/**
|
|
198
|
+
/** Endpoint is validated at construction so config errors surface immediately. */
|
|
215
199
|
export function createWindClient(options) {
|
|
216
200
|
const endpoint = normalizeEndpoint(options.endpoint);
|
|
217
201
|
const timeoutMs = options.timeoutMs && options.timeoutMs > 0 ? options.timeoutMs : WIND_REQUEST_TIMEOUT_MS;
|
|
@@ -256,7 +240,7 @@ export function createWindClient(options) {
|
|
|
256
240
|
signal?.removeEventListener('abort', onExternalAbort);
|
|
257
241
|
}
|
|
258
242
|
}
|
|
259
|
-
/**
|
|
243
|
+
/** Retry network errors with backoff; HTTP status errors and caller cancels do not retry. */
|
|
260
244
|
async function postRpc(method, params, apiKey, signal) {
|
|
261
245
|
let lastError;
|
|
262
246
|
for (let attempt = 1; attempt <= RETRY_ATTEMPTS; attempt += 1) {
|
package/locale/zh.json
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@v587d/capital-generation",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"description": "Capital Generation:面向中国散户的 AI
|
|
3
|
+
"version": "2.9.0",
|
|
4
|
+
"description": "Capital Generation:面向中国散户的 AI 投资助手插件(自动模式 Agent Preset)",
|
|
5
5
|
"icon": "assets/cg-icon.png",
|
|
6
6
|
"author": "v587d",
|
|
7
7
|
"license": "MIT",
|
|
@@ -22,6 +22,66 @@
|
|
|
22
22
|
"import": "./lib/index.js",
|
|
23
23
|
"default": "./lib/index.js"
|
|
24
24
|
},
|
|
25
|
+
"./runtime": {
|
|
26
|
+
"types": "./lib/runtime-entry.d.ts",
|
|
27
|
+
"import": "./lib/runtime-entry.js",
|
|
28
|
+
"default": "./lib/runtime-entry.js"
|
|
29
|
+
},
|
|
30
|
+
"./policy": {
|
|
31
|
+
"types": "./lib/policy-entry.d.ts",
|
|
32
|
+
"import": "./lib/policy-entry.js",
|
|
33
|
+
"default": "./lib/policy-entry.js"
|
|
34
|
+
},
|
|
35
|
+
"./tools/chart-render": {
|
|
36
|
+
"types": "./lib/chart-render-entry.d.ts",
|
|
37
|
+
"import": "./lib/chart-render-entry.js",
|
|
38
|
+
"default": "./lib/chart-render-entry.js"
|
|
39
|
+
},
|
|
40
|
+
"./tools/chart-source": {
|
|
41
|
+
"types": "./lib/chart-source-entry.d.ts",
|
|
42
|
+
"import": "./lib/chart-source-entry.js",
|
|
43
|
+
"default": "./lib/chart-source-entry.js"
|
|
44
|
+
},
|
|
45
|
+
"./tools/collect": {
|
|
46
|
+
"types": "./lib/collect-entry.d.ts",
|
|
47
|
+
"import": "./lib/collect-entry.js",
|
|
48
|
+
"default": "./lib/collect-entry.js"
|
|
49
|
+
},
|
|
50
|
+
"./tools/dataset-read": {
|
|
51
|
+
"types": "./lib/dataset-read-entry.d.ts",
|
|
52
|
+
"import": "./lib/dataset-read-entry.js",
|
|
53
|
+
"default": "./lib/dataset-read-entry.js"
|
|
54
|
+
},
|
|
55
|
+
"./tools/ocr": {
|
|
56
|
+
"types": "./lib/ocr-entry.d.ts",
|
|
57
|
+
"import": "./lib/ocr-entry.js",
|
|
58
|
+
"default": "./lib/ocr-entry.js"
|
|
59
|
+
},
|
|
60
|
+
"./tools/retrieve-search": {
|
|
61
|
+
"types": "./lib/search-entry.d.ts",
|
|
62
|
+
"import": "./lib/search-entry.js",
|
|
63
|
+
"default": "./lib/search-entry.js"
|
|
64
|
+
},
|
|
65
|
+
"./tools/retrieve-sources": {
|
|
66
|
+
"types": "./lib/sources-entry.d.ts",
|
|
67
|
+
"import": "./lib/sources-entry.js",
|
|
68
|
+
"default": "./lib/sources-entry.js"
|
|
69
|
+
},
|
|
70
|
+
"./tools/root-extras": {
|
|
71
|
+
"types": "./lib/root-extras-entry.d.ts",
|
|
72
|
+
"import": "./lib/root-extras-entry.js",
|
|
73
|
+
"default": "./lib/root-extras-entry.js"
|
|
74
|
+
},
|
|
75
|
+
"./tools/time": {
|
|
76
|
+
"types": "./lib/time-entry.d.ts",
|
|
77
|
+
"import": "./lib/time-entry.js",
|
|
78
|
+
"default": "./lib/time-entry.js"
|
|
79
|
+
},
|
|
80
|
+
"./tools/watchlist": {
|
|
81
|
+
"types": "./lib/watchlist-entry.d.ts",
|
|
82
|
+
"import": "./lib/watchlist-entry.js",
|
|
83
|
+
"default": "./lib/watchlist-entry.js"
|
|
84
|
+
},
|
|
25
85
|
"./package.json": "./package.json",
|
|
26
86
|
"./locale/*.json": "./locale/*.json"
|
|
27
87
|
},
|
|
@@ -79,14 +139,14 @@
|
|
|
79
139
|
},
|
|
80
140
|
"peerDependencies": {
|
|
81
141
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
82
|
-
"@deepseek-ai/dsh-skill": "0.2.
|
|
83
|
-
"@deepseek-ai/dsh-skill-filesystem": "0.2.
|
|
142
|
+
"@deepseek-ai/dsh-skill": "0.2.1-rc.2",
|
|
143
|
+
"@deepseek-ai/dsh-skill-filesystem": "0.2.1-rc.2"
|
|
84
144
|
},
|
|
85
145
|
"devDependencies": {
|
|
86
146
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
87
|
-
"@deepseek-ai/dsh-skill": "^0.2.
|
|
88
|
-
"@deepseek-ai/dsh-skill-filesystem": "^0.2.
|
|
89
|
-
"@deepseek-ai/dsh-system-prompt": "^0.2.
|
|
147
|
+
"@deepseek-ai/dsh-skill": "^0.2.1-rc.2",
|
|
148
|
+
"@deepseek-ai/dsh-skill-filesystem": "^0.2.1-rc.2",
|
|
149
|
+
"@deepseek-ai/dsh-system-prompt": "^0.2.1-rc.2",
|
|
90
150
|
"@deepseek-ai/schemastery": "^3.18.4",
|
|
91
151
|
"esbuild": "^0.28.2",
|
|
92
152
|
"js-yaml": "^5.4.1",
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# 自动模式 preset:组合设计说明
|
|
2
2
|
|
|
3
|
-
本文件是 `agent.patch.yml
|
|
3
|
+
本文件是 `agent.patch.yml`(那六颗 `@deepseek-ai/dsh-agent-preset` 声明行)的**维护者文档**(人类可读),
|
|
4
4
|
不是模型可见内容:`skill-filesystem` 只扫 `skills/`,本文件既不会进 skill 目录,也不会被注入上下文。
|
|
5
5
|
组合文件里只留"就地必需"的一行注(realm、`!!js`、disabled 行),其余设计理由都在这里。
|
|
6
6
|
|
|
7
7
|
- 本目录由 `@v587d/capital-generation` 随包分发,`agent.patch.yml` 走 `package.json` 的
|
|
8
|
-
`dsh.bundle.patch`(**数组**:主 patch +
|
|
9
|
-
`~/.dsh/.agent-presets`。
|
|
8
|
+
`dsh.bundle.patch`(**数组**:主 patch + 这一份 yml,六颗声明行都在里面)以 `trust=system`
|
|
9
|
+
挂载;**不要**手抄进 `~/.dsh/.agent-presets`。
|
|
10
10
|
- 长协议在 `skills/`(同目录),由本 preset 自己的 `skill-filesystem` 行发现;`capital-visualization-protocol` 同时供 data_junior 的 gate 和 visualization_specialist 按需加载。
|
|
11
|
-
- visualization_specialist 是 data_junior
|
|
11
|
+
- visualization_specialist 是 data_junior 委派出图的子 Agent(0.2.1 起所有子会话都是异步 continuable,没有 one-shot / 前台模式),不进入主 Agent 的 direct-child 复用清单;它只消费 chart_source_ref 并使用受控 render_chart。
|
|
12
|
+
- data_junior 的质检与可视化 gate 对每份结构化 Dataset 都执行,用户是否要图不是触发条件;显式「不要图」只收窄出图,不跳过 profile。
|
|
12
13
|
- 验证方式与"改 preset 前后的必做检查"见仓库根 `AGENTS.md` §8.3;设计理由与「不许改」全表见
|
|
13
14
|
`docs/dev/preset-persona.md`。
|
|
14
15
|
|
|
@@ -22,23 +23,27 @@
|
|
|
22
23
|
|
|
23
24
|
## 2. 人设(persona)承载与官方语义
|
|
24
25
|
|
|
25
|
-
实测 `dsh 0.
|
|
26
|
-
|
|
26
|
+
实测 `dsh 0.2.1-rc.2`(`test/persona.test.mjs` 对着本机 dsh 核对字段名),两层载体注册的是
|
|
27
|
+
**同一个 system-prompt 节名**:
|
|
27
28
|
|
|
28
29
|
| 载体 | 位置 | 字段 | 生效范围 |
|
|
29
30
|
|---|---|---|---|
|
|
30
31
|
| `dsh-system-prompt` 行 | 部署(web profile) | `personaPrefix` / `personaSuffix` | 全局 |
|
|
31
|
-
| `dsh-persona` 行 |
|
|
32
|
-
| `dsh-tool-subagent` 行 | 本 preset 委派行 | `config.persona` | 该子 Agent 自己 |
|
|
32
|
+
| `dsh-persona` 行 | **每颗 preset 自己**(根 + 五颗角色,各一行) | `prefix`(必填)/ `suffix` / `complete` / `includeRuntimeContext` | 该 preset 组出来的 agent |
|
|
33
33
|
|
|
34
34
|
- 节名是 `deployment:persona-prefix`(order 0)与 `deployment:persona-suffix`(order
|
|
35
|
-
10200)。**最近 scope 胜出 ⇒
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
10200)。**最近 scope 胜出 ⇒ 是覆盖不是追加**:0.2.1 起委派行**不再带 `config.persona`**
|
|
36
|
+
(`tool-subagent: persona is no longer supported; configure persona … in an Agent Preset and
|
|
37
|
+
select it with agentPreset`),子人设因此住在角色 preset 自己的 `dsh-persona` 行里,子 Agent
|
|
38
|
+
组出来的那一颗 generation 覆盖同名节——效果与旧写法一致:**替换**(不是扩展)主 persona。
|
|
39
|
+
- `prefix`/`suffix` 是模板,渲染时对 `{{…}}` **严格插值**:未注册或 undefined 的变量会抛错,
|
|
40
|
+
而且抛的是**整个会话的系统提示组装**,不是"这一段不显示"。可注册的变量以本机为准——
|
|
41
|
+
0.2.1 的 `dsh-agent-loop` 只注册 `provider` / `model`(0.2.0 还有的 `cwd` **已被上游删掉**,
|
|
42
|
+
真机踩过一次:`unknown prompt variable "{{cwd}}" in section "deployment:persona-prefix"`)。
|
|
43
|
+
`test/persona.test.mjs` 现读本机注册表钉这条闸门,正文里写了少掉的变量会在 `npm test` 就红。
|
|
39
44
|
- 本 preset **不设 `suffix`**:按官方语义,空模板**仍然遮蔽**部署级后缀,所以部署那句
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
"Your working directory is …" 在 Capital 会话里不出现;工作目录改由主 persona 自己用
|
|
46
|
+
**文字**说明(本会话选定的 workspace 根目录),不再引用已经不存在的变量。这是有意为之,不是漏配。
|
|
42
47
|
- `complete: true` 会把其余所有段落(身份、工具引导、后缀)一并抑制;`includeRuntimeContext:
|
|
43
48
|
false` 全有全无地关掉沙箱/审批/委派等 runtime context。本 preset 都不用。
|
|
44
49
|
- 成本:persona 正文每个请求都重复;`prefix` 变化会让 KV cache 从第一个变化 token 起失效。
|
|
@@ -51,7 +56,8 @@
|
|
|
51
56
|
而 skill 只在模型决定加载时才生效。
|
|
52
57
|
- **按需进 `skills/`**:载荷 JSON 样例、字段级规则、`error/code → 处置`表、四态事实怎么读、
|
|
53
58
|
QuerySpec 细则、检索收敛法则、官方域名核验清单、回传格式范例。
|
|
54
|
-
- **子 Agent
|
|
59
|
+
- **子 Agent 也能按需加载**:每颗角色 preset 自己挂 `@deepseek-ai/dsh-tool-skill` 行(四颗在用角色都有;预留的
|
|
60
|
+
`capital-data-analyst` declaration 已 disabled,恢复时要去掉 `disabled`),子 Agent 就同时拿到
|
|
55
61
|
目录与加载器。判据在 `dsh-tools` 的 `view()`:restriction 过滤**继承层(全局 + 全部祖先
|
|
56
62
|
scope,含 preset 层)**,只豁免"本 scope 自己注册的"工具;而 `dsh-tool-skill` 发布目录的
|
|
57
63
|
条件正是 `ctx.tools.get('skill', agent) === 该注册对象`。源码注释里记着这段历史坑
|
|
@@ -93,32 +99,54 @@
|
|
|
93
99
|
**能力目录与工具结果超过阈值时中间段被剪掉**;`test/data-collector-hub.test.mjs` 因此用
|
|
94
100
|
"目录 6144 + 单能力详情 4096"两道测试预算,让测试先失败而不是运行时静默截断。该阈值
|
|
95
101
|
**不能按 Agent 区分**(全仓只有这一个 pruner 实例),主/子 Agent 共用。
|
|
96
|
-
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
`
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
102
|
+
- **工具面 = preset 挂的行**(D0,2026-10-19):`toolFilter` 已从委派行删除,上游报错原文指明的
|
|
103
|
+
替代是「persona 与工具插件改住 Agent Preset,委派行只用 `agentPreset` 选它」——这一条我们做到底:
|
|
104
|
+
本仓当前由 preset 族行暴露的 27 颗模型工具,按族拆成
|
|
105
|
+
`@v587d/capital-generation/tools/<family>` 的 subpath 入口行
|
|
106
|
+
(`package.json` 的 `exports`),每颗 preset 只挂自己那几族,**不再有运行期名字级 allow 名单**。
|
|
107
|
+
行契约(那一行注册哪些名字)只有一份,住 `test/family-rows.mjs`:`test/family-entries.test.mjs`
|
|
108
|
+
拿它实测每个入口注册了什么,`test/persona.test.mjs` 拿它核对 YAML 的组合结果。
|
|
109
|
+
- collector:`tools/collect` + `tools/time`;junior:`tools/dataset-read` + `tools/chart-source` +
|
|
110
|
+
`tools/time`;specialist:`tools/chart-render` + `tools/time`;retriever:`tools/retrieve-search` +
|
|
111
|
+
`tools/retrieve-sources` + `tools/ocr` + `tools/time`;根:`tools/time` +
|
|
112
|
+
`tools/ocr` + `tools/watchlist` + `tools/root-extras`(最后一行一颗工具都不带,只挂精选
|
|
113
|
+
skills 的 provider 与用户自定义人设分节)。**`tools/time` 每颗 preset 都挂、且不带任何行配置**:
|
|
114
|
+
通用能力不按角色裁(2026-10-19 决策,retriever 那颗继承自 0.2.0 `toolFilter` 的
|
|
115
|
+
`localDatetime: false` 已删——行契约里没有开关,写了就是"以为裁了、其实没人读")。
|
|
116
|
+
- 运行期只剩**一格**:`tool-subagent-control` 把 `send_message` 与 `interrupt_agent` 焊在同一行,
|
|
117
|
+
而宿主没给那颗行开成员开关,叶子角色逐名 tolerant deny 减掉那个兄弟
|
|
118
|
+
(`src/agents/role-tool-policy.ts` 的 `SIBLING_DENIED_TOOLS`)。它不是工具面清单。⛔ 那一格只减
|
|
119
|
+
**被委派子会话**的可见面:手开的角色会话上 restrict 减不掉它(时机见账本 L32),所以执行期另有
|
|
120
|
+
一颗全局 `tools.guard()`(`registerRoleSiblingGuard`)兜住同一颗名字。
|
|
121
|
+
- **⛔ 行名与 deny 名的两种失效形状都是静默的**:族行名写错 / 包导出漏了 ⇒ 那一行装载失败
|
|
122
|
+
(只打一行 warn),该角色**少一整族**工具;`deny` 里的名字本作用域看不见 ⇒ 逐名跳过,只少减
|
|
123
|
+
那一个并记进 `failed`(这是它相对旧"整批 allow"的差别:错一个名字不再等于完全不收敛)。
|
|
124
|
+
两道补偿:`test/family-entries.test.mjs` 把 `package.json` 的 `exports` 与行契约对表,
|
|
125
|
+
`dc_status` 的 `agent_tool_policy` + `session_identity` 把现场带回会话侧。
|
|
126
|
+
- **⛔ 没有通用 `subagent` 行**(2026-10-18 用户决策:没有明确场景就不该有「其他」,它的 34 名
|
|
127
|
+
`deny` 名单一起删)。"谁能碰什么"因此始终是**正面清单**:deny 是 fail-open(漏写就等于有权限,
|
|
128
|
+
2026-09 的出图绕过就是这么走的),行组合是 fail-closed(多挂一行才越权)。**禁止**以任何形式
|
|
129
|
+
恢复通用委派行,也禁止把那一格兄弟 deny 长成工具面清单;回归 `test/persona.test.mjs`
|
|
130
|
+
「委派出口只有专用角色」「组合表:每颗 preset 挂的族行必须恰好是这几行」与
|
|
131
|
+
`test/role-tool-policy.test.mjs`。
|
|
132
|
+
- **出网那十三颗只由 retriever 挂的两行带出来**,其余角色没挂就拿不到;根 preset 不挂
|
|
133
|
+
`tools/retrieve-search` / `tools/retrieve-sources`,可见性在组合期封闭。
|
|
134
|
+
`src/agents/root-tool-policy.ts` 的 `RETRIEVAL_DENIED_TOOLS` / `ROOT_AGENT_DENIED_TOOLS` 作为
|
|
135
|
+
单体载体与回归兜底保留(host policy 对 root 传 `deny:false`),**新增来源只改族行与行契约**。
|
|
136
|
+
**`ocr` 那一行由根与 retriever 各挂一次**:主 Agent 要能解析用户 `@` 进来的本地文档;host 的
|
|
137
|
+
`installRootOcrGuard` 只拒它的 `url` 形态,retriever 侧拿到完整形态
|
|
138
|
+
(见 §4.3 → `docs/dev/web-retriever.md`)。
|
|
139
|
+
**宿主自己挂的 `web_search` / `web_fetch` 不由本插件注册**:2026-09-30 双端实测当时的作用域里
|
|
140
|
+
没有这两个名字,所以从 `ROOT_AGENT_DENIED_TOOLS` 清掉;但 2026-10-20 的 web profile 里 AnySearch
|
|
141
|
+
会补注册 `web_fetch`,它因此出现在所有 preset 的工具表里。**没挂行不等于看不见**:要收窄就加回根侧/
|
|
142
|
+
角色名单(逐名 restrict 容忍 absent),或关掉宿主 provider;别拿组合表当宿主工具的隔离证明。
|
|
116
143
|
- 不用 `dsh-time-context` 行:它每个 step 自动注入时钟读数,与自研 `get_local_datetime`
|
|
117
144
|
重复;时间读数只来自后者(会话组作用域内注册,主 Agent 与全部子 Agent 共享,支持
|
|
118
145
|
`timezone` 换算)。
|
|
119
|
-
- `data_analyst`
|
|
120
|
-
|
|
121
|
-
|
|
146
|
+
- `data_analyst` 的 preset 与委派行都保持 `disabled`(2026-10-18 用户要求先停用,等价于注释)。
|
|
147
|
+
恢复前置条件(缺一不可):宿主先实现 Python runner 与 coding 工具;插件注册 `read_profile`
|
|
148
|
+
(新工具必须先有族行带它、行契约同步);更新 `AGENTS.md`、`docs/dev/data-roles.md` 与
|
|
149
|
+
`test/persona.test.mjs` 的预留期断言。
|
|
122
150
|
|
|
123
151
|
## 5.1 shell 与文件口:开 read、保留 bash、不给写(2026-10-15 用户决策)
|
|
124
152
|
|
|
@@ -129,19 +157,23 @@
|
|
|
129
157
|
2026-09-30 的"主 Agent 不给 shell"):主 Agent 需要 `read` 读 skill 分册与工作区文件
|
|
130
158
|
(此前只能 `bash cat`,能力等价但绕远),shell 保留纯计算兜底。`ROOT_AGENT_DENIED_TOOLS`
|
|
131
159
|
里的 `bash` / `pwsh` 随之移出,名单改为出图三件套 + 十三个出网工具 + `write` / `edit`。
|
|
132
|
-
-
|
|
133
|
-
`
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
`
|
|
138
|
-
|
|
160
|
+
- **文件写口不开,但"不开"靠的是调用级闸门,不是行配置**:根 preset 那行 `read: true /
|
|
161
|
+
write: false / edit: false` 只决定**本层变体**——2026-10-19 实测手开 Capital 里 `write` 仍在工具表
|
|
162
|
+
中且真的落盘,缺席不等于移除(`ScopedLayers.merge` 用 global 打底,账本 L33)。所以拦下写口的只有一颗:全局 `tools.guard()`
|
|
163
|
+
(`registerFsWriteGuard`,判据 = 调用期 `composedPreset` ∈ 本插件任一 preset,fail-open,细节见
|
|
164
|
+
`docs/dev/bash-gate.md` §1.6)。`ROOT_AGENT_DENIED_TOOLS` 里的 `write` / `edit` 只在**被委派**
|
|
165
|
+
那一支减得到可见面,且生产装配以 `deny: false` 注册、不提交名单。理由:主 Agent 唯一对用户说话、
|
|
166
|
+
又会读到子 Agent 回传(含网页材料),写文件等于给"注入 → 落盘 → 被别的环节读回"开口;业务落盘
|
|
167
|
+
本来就有正路(`store.writeContext` 等工具实现)。角色一侧同一条判据:本插件的六颗 preset 一律
|
|
168
|
+
不许直接写文件,原始 rows 也永不出工具层。
|
|
139
169
|
- **平台成对挂载**:Windows 上 host 层挂的是 `pwsh-sandbox`,没有 `bash-sandbox`;只挂
|
|
140
|
-
`tool-bash` 会让名为 bash 的工具实际执行 PowerShell。所以两行互补 `disabled
|
|
141
|
-
|
|
142
|
-
|
|
170
|
+
`tool-bash` 会让名为 bash 的工具实际执行 PowerShell。所以两行互补 `disabled: !!js`。0.2.1 起
|
|
171
|
+
这份 YAML 里不再出现工具名,shell 名改为在 `src/agents/role-tool-policy.ts` 按平台取一颗
|
|
172
|
+
(`SHELL_TOOL`)进 data_junior 的清单——取错那颗会整批 restrict 报错、该角色完全不收敛,
|
|
173
|
+
所以 `test/bash-guard.test.mjs` 另钉一条"preset 挂的每一行 shell,闸门与角色工具面都必须认",
|
|
174
|
+
成对挂载与后台执行那一格仍由 `test/persona.test.mjs`「shell 行:平台成对挂载……」看着。
|
|
143
175
|
- **不给后台执行**:`enableRunInBackground: false`。本 preset 不挂 `tool-jobs`,开着后台只会让
|
|
144
|
-
模型拿到一个永远读不回来的 jobId
|
|
176
|
+
模型拿到一个永远读不回来的 jobId(本 preset 压根没挂 `tool-jobs` 那一行)。
|
|
145
177
|
- **shell 闸门只剩一层,且不是安全边界**(`src/agents/bash-guard.ts`):拦掉
|
|
146
178
|
`sandbox_permissions` / `justification`——被委派会话的审批策略由框架固定为 `never`,升级必然
|
|
147
179
|
失败,而且模型会收到「the user rejected…」这种把系统拒绝说成用户拒绝的文案;被委派或身份
|
|
@@ -160,9 +192,11 @@
|
|
|
160
192
|
## 6. 改动流程
|
|
161
193
|
|
|
162
194
|
1. 先判断内容属于"每轮硬规则"(→ persona)还是"按需协议"(→ `skills/`)。
|
|
163
|
-
2.
|
|
164
|
-
|
|
165
|
-
|
|
195
|
+
2. 专用角色**七处齐改**(判据与顺序见 `docs/dev/preset-persona.md` §8.5):角色 preset 声明行
|
|
196
|
+
(`dsh-persona` 正文:骨架 + 第一条 duty `skill <name>`;以及它自己需要的工具行)、主 preset
|
|
197
|
+
里的委派行(`provider` / `toolName` / `agentPreset`)、该角色 preset 挂哪几族行
|
|
198
|
+
(`test/family-rows.mjs` 的行契约 + `test/persona.test.mjs` 的组合表;只有同行焊死的兄弟才写
|
|
199
|
+
`src/agents/role-tool-policy.ts` 那份逐名 deny)、`skills/<name>/SKILL.md`、主 persona 的路由与复用规则、
|
|
166
200
|
`docs/dev/data-roles.md` §1.1 的角色边界、测试断言。
|
|
167
201
|
3. `npm test` 全绿 + `agentPresets.resolve('capital-generation')` 结果里没有 `broken`(挂载成功),
|
|
168
202
|
再开一个 Capital 会话确认工具表、首轮预检,以及子 Agent 是否真的按第一条 duty 先加载 skill。
|