@v587d/capital-generation 0.0.0-stage → 2.6.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 +794 -0
- package/LICENSE +21 -0
- package/README.md +116 -2
- package/assets/cg-icon.png +0 -0
- package/capital-config/client.js +28 -0
- package/capital-config/client.src.cjs +388 -0
- package/capital-config/index.js +113 -0
- package/capital-config/package.json +36 -0
- package/capital-watchlist/client.js +182 -0
- package/capital-watchlist/client.src.cjs +1229 -0
- package/capital-watchlist/index.js +772 -0
- package/capital-watchlist/package.json +37 -0
- package/chart-ui/README.md +112 -0
- package/chart-ui/client.js +16 -0
- package/chart-ui/client.src.cjs +126 -0
- package/chart-ui/index.js +205 -0
- package/chart-ui/package.json +30 -0
- package/cordis.patch.yml +72 -0
- package/lib/agents/bash-guard.d.ts +55 -0
- package/lib/agents/bash-guard.js +162 -0
- package/lib/agents/root-tool-policy.d.ts +164 -0
- package/lib/agents/root-tool-policy.js +309 -0
- package/lib/chart/artifact-ref.d.ts +65 -0
- package/lib/chart/artifact-ref.js +107 -0
- package/lib/chart/downsample.d.ts +8 -0
- package/lib/chart/downsample.js +53 -0
- package/lib/chart/errors.d.ts +16 -0
- package/lib/chart/errors.js +15 -0
- package/lib/chart/events.d.ts +120 -0
- package/lib/chart/events.js +471 -0
- package/lib/chart/html.d.ts +21 -0
- package/lib/chart/html.js +154 -0
- package/lib/chart/runtime.d.ts +20 -0
- package/lib/chart/runtime.js +270 -0
- package/lib/chart/series.d.ts +102 -0
- package/lib/chart/series.js +424 -0
- package/lib/chart/source-token.d.ts +64 -0
- package/lib/chart/source-token.js +217 -0
- package/lib/chart/spec.d.ts +58 -0
- package/lib/chart/spec.js +265 -0
- package/lib/chart/tool.d.ts +86 -0
- package/lib/chart/tool.js +288 -0
- package/lib/chart/vendor/LICENSE +201 -0
- package/lib/chart/vendor/VERSION.json +8 -0
- package/lib/chart/vendor/lightweight-charts.standalone.production.js +7 -0
- package/lib/data-collector/args.d.ts +38 -0
- package/lib/data-collector/args.js +114 -0
- package/lib/data-collector/dataset-tools.d.ts +3 -0
- package/lib/data-collector/dataset-tools.js +421 -0
- package/lib/data-collector/describe.d.ts +99 -0
- package/lib/data-collector/describe.js +256 -0
- package/lib/data-collector/hub.d.ts +187 -0
- package/lib/data-collector/hub.js +469 -0
- package/lib/data-collector/query-time.d.ts +58 -0
- package/lib/data-collector/query-time.js +101 -0
- package/lib/data-collector/query.d.ts +57 -0
- package/lib/data-collector/query.js +473 -0
- package/lib/data-collector/store.d.ts +499 -0
- package/lib/data-collector/store.js +1486 -0
- package/lib/data-collector/time-axis.d.ts +169 -0
- package/lib/data-collector/time-axis.js +419 -0
- package/lib/data-collector/tools.d.ts +32 -0
- package/lib/data-collector/tools.js +216 -0
- package/lib/index.d.ts +275 -0
- package/lib/index.js +458 -0
- package/lib/net/eastmoney-client.d.ts +104 -0
- package/lib/net/eastmoney-client.js +118 -0
- package/lib/net/throttle.d.ts +16 -0
- package/lib/net/throttle.js +34 -0
- package/lib/ocr/client.d.ts +82 -0
- package/lib/ocr/client.js +281 -0
- package/lib/ocr/markdown.d.ts +75 -0
- package/lib/ocr/markdown.js +209 -0
- package/lib/ocr/store.d.ts +119 -0
- package/lib/ocr/store.js +226 -0
- package/lib/sources/eastmoney-http.d.ts +2 -0
- package/lib/sources/eastmoney-http.js +1253 -0
- package/lib/sources/fuyao-core.d.ts +52 -0
- package/lib/sources/fuyao-core.js +96 -0
- package/lib/sources/fuyao-rest.d.ts +14 -0
- package/lib/sources/fuyao-rest.js +2057 -0
- package/lib/sources/security-code.d.ts +27 -0
- package/lib/sources/security-code.js +104 -0
- package/lib/sources/security-identity.d.ts +24 -0
- package/lib/sources/security-identity.js +89 -0
- package/lib/sources/tencent-http.d.ts +2 -0
- package/lib/sources/tencent-http.js +1053 -0
- package/lib/sources/wind-mcp.d.ts +8 -0
- package/lib/sources/wind-mcp.js +593 -0
- package/lib/time/tools.d.ts +74 -0
- package/lib/time/tools.js +464 -0
- package/lib/tool-exec.d.ts +29 -0
- package/lib/tool-exec.js +17 -0
- package/lib/web-retriever/engines.d.ts +61 -0
- package/lib/web-retriever/engines.js +202 -0
- package/lib/web-retriever/html-markdown.d.ts +50 -0
- package/lib/web-retriever/html-markdown.js +321 -0
- package/lib/web-retriever/local-fetch.d.ts +121 -0
- package/lib/web-retriever/local-fetch.js +562 -0
- package/lib/web-retriever/retriever.d.ts +58 -0
- package/lib/web-retriever/retriever.js +94 -0
- package/lib/web-retriever/sources.d.ts +235 -0
- package/lib/web-retriever/sources.js +961 -0
- package/lib/web-retriever/tools.d.ts +50 -0
- package/lib/web-retriever/tools.js +1029 -0
- package/lib/web-retriever/wind-client.d.ts +69 -0
- package/lib/web-retriever/wind-client.js +311 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +76 -4
- package/preset/capital-generation/README.md +161 -0
- package/preset/capital-generation/agent.patch.yml +509 -0
- package/preset/capital-generation/skills/capital-chart-protocol/SKILL.md +137 -0
- package/preset/capital-generation/skills/capital-data-protocol/SKILL.md +416 -0
- package/preset/capital-generation/skills/capital-orchestration/SKILL.md +174 -0
- package/preset/capital-generation/skills/capital-visualization-protocol/SKILL.md +296 -0
- package/preset/capital-generation/skills/capital-web-protocol/SKILL.md +240 -0
|
@@ -0,0 +1,499 @@
|
|
|
1
|
+
import { type QueryResult, type QuerySpec } from './query.js';
|
|
2
|
+
/**
|
|
3
|
+
* Phase 1/2 workspace-local Dataset store(设计约定见 AGENTS.md「数据布局」)。
|
|
4
|
+
*
|
|
5
|
+
* 原始 Dataset 只由宿主写入,Dataset/Profile 都通过 createIfAbsent 发布。
|
|
6
|
+
* Agent 只能使用 dataset_id 和 opaque artifact_ref,不能传入真实路径。
|
|
7
|
+
*/
|
|
8
|
+
export declare const WORKSPACE_DATA_DIR = "capital-data";
|
|
9
|
+
export declare const DATASETS_SUBDIR = "capital-data/datasets";
|
|
10
|
+
export declare const PROFILES_SUBDIR = "capital-data/profiles";
|
|
11
|
+
export declare const RAW_FILE = "raw.json";
|
|
12
|
+
export declare const MANIFEST_FILE = "manifest.json";
|
|
13
|
+
export declare const PROFILE_FILE = "profile.json";
|
|
14
|
+
export declare const DEFAULT_RETENTION_MS: number;
|
|
15
|
+
export declare const MAX_RAW_READ_BYTES: number;
|
|
16
|
+
export declare const MAX_PROFILE_BYTES: number;
|
|
17
|
+
/** 类别事实:最多跟踪多少个不同取值;超过则 distinct_count 记 null 并标记 truncated。 */
|
|
18
|
+
export declare const MAX_CATEGORY_DISTINCT = 2000;
|
|
19
|
+
/** `top_values` 只展示前 N 个高频取值,其余由 truncated 显式披露。 */
|
|
20
|
+
export declare const MAX_CATEGORY_TOP_VALUES = 5;
|
|
21
|
+
/** 结构摘要:路径条目上限与递归深度上限,保证 profile 体积有界。 */
|
|
22
|
+
export declare const MAX_STRUCTURE_ENTRIES = 24;
|
|
23
|
+
/**
|
|
24
|
+
* 文档型 Dataset(顶层对象、没有行数组,如财务指标 / 回测结果)交给 data_junior 的
|
|
25
|
+
* 内容预算(Unicode 码点数)。取值必须留在 preset 的工具结果剪枝阈值(8192)以内:
|
|
26
|
+
* 超过就会被剪掉中间段,而不是被完整读到。长数组按下面的档位逐级截断,截断了什么
|
|
27
|
+
* 一律写进 `omitted`,不做静默省略。
|
|
28
|
+
*/
|
|
29
|
+
export declare const MAX_DOCUMENT_CHARS = 6000;
|
|
30
|
+
/**
|
|
31
|
+
* 呈现层(图表)一次性读取行集的上限。超过就拒绝,而不是把几百 MB 拉进宿主内存:
|
|
32
|
+
* 图表是**有界呈现**,不是通用分析通道。
|
|
33
|
+
*/
|
|
34
|
+
export declare const MAX_PRESENTATION_ROWS = 200000;
|
|
35
|
+
export declare const ARTIFACT_SCHEME = "workspace://";
|
|
36
|
+
export interface DatasetRef {
|
|
37
|
+
dataset_id: string;
|
|
38
|
+
task_id: string | null;
|
|
39
|
+
session_id: string;
|
|
40
|
+
artifact_ref: string;
|
|
41
|
+
format: 'json' | 'json_rows';
|
|
42
|
+
capability: string;
|
|
43
|
+
source_label: string;
|
|
44
|
+
schema: object | null;
|
|
45
|
+
row_count: number | null;
|
|
46
|
+
captured_at: number;
|
|
47
|
+
retention_until: number;
|
|
48
|
+
params_digest: string;
|
|
49
|
+
}
|
|
50
|
+
export type DatasetShape = 'array' | 'envelope_item' | 'document' | 'none';
|
|
51
|
+
export interface DatasetInspection extends DatasetRef {
|
|
52
|
+
query_access: {
|
|
53
|
+
/** true = 宿主可读取并产出事实(rows 可 query,document 只能 profile)。 */
|
|
54
|
+
readable: boolean;
|
|
55
|
+
shape: DatasetShape;
|
|
56
|
+
reason?: string;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export interface ProfileRef {
|
|
60
|
+
profile_id: string;
|
|
61
|
+
dataset_id: string;
|
|
62
|
+
task_id: string | null;
|
|
63
|
+
session_id: string;
|
|
64
|
+
artifact_ref: string;
|
|
65
|
+
created_at: number;
|
|
66
|
+
retention_until: number;
|
|
67
|
+
}
|
|
68
|
+
export type ProfileObservedType = 'missing' | 'null' | 'boolean' | 'integer' | 'number' | 'string' | 'object' | 'array' | 'mixed';
|
|
69
|
+
export type ProfileContractType = 'string' | 'number' | 'integer' | 'boolean' | 'object' | 'array' | 'json';
|
|
70
|
+
export interface ProfileColumn {
|
|
71
|
+
contract_type: ProfileContractType | null;
|
|
72
|
+
inferred_type: ProfileObservedType;
|
|
73
|
+
observed_types: Partial<Record<ProfileObservedType, number>>;
|
|
74
|
+
missing_count: number;
|
|
75
|
+
null_count: number;
|
|
76
|
+
non_null_count: number;
|
|
77
|
+
invalid_count: number;
|
|
78
|
+
nullable: boolean;
|
|
79
|
+
contract_nullable?: boolean;
|
|
80
|
+
required?: boolean;
|
|
81
|
+
allow_numeric_string?: boolean;
|
|
82
|
+
numeric_string_count?: number;
|
|
83
|
+
}
|
|
84
|
+
export interface ProfileValidationViolation {
|
|
85
|
+
column: string;
|
|
86
|
+
rule: 'required' | 'nullable' | 'type';
|
|
87
|
+
expected: string | boolean;
|
|
88
|
+
observed: string;
|
|
89
|
+
invalid_count: number;
|
|
90
|
+
severity: 'error' | 'warning';
|
|
91
|
+
}
|
|
92
|
+
export interface ProfileValidation {
|
|
93
|
+
status: 'pass' | 'fail';
|
|
94
|
+
violations: ProfileValidationViolation[];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Profile 的职责:把「原始行」翻译成模型可以安全引用的事实。
|
|
98
|
+
*
|
|
99
|
+
* 除了逐列的类型与缺失统计(Phase 1),Phase 2 起补齐四类事实,它们对应
|
|
100
|
+
* Fuyao 数据里最常见的四类问题:
|
|
101
|
+
* - `statistics` 加 `count` / `sum`:回答「合计多少、覆盖多少条」;
|
|
102
|
+
* - `categories`:字符串列的 distinct 与高频取值,回答「有哪些类别、分布如何」;
|
|
103
|
+
* - `time_facts`:时间列的覆盖范围 + 首行/末行的数值,回答「最新值、区间涨跌」——
|
|
104
|
+
* 只报 min/max 会被模型讲成「先涨到最高再回落」,这是实测过的失真来源;
|
|
105
|
+
* - `structure`:单元格里的数组/对象展开成有界路径摘要,回答「里面有几层、
|
|
106
|
+
* 多少个叶子」,避免只报一句「这一格是 object」。
|
|
107
|
+
*/
|
|
108
|
+
export interface ProfileStatistic {
|
|
109
|
+
count?: number;
|
|
110
|
+
sum?: number | null;
|
|
111
|
+
min?: number | null;
|
|
112
|
+
max?: number | null;
|
|
113
|
+
mean?: number | null;
|
|
114
|
+
p25?: number | null;
|
|
115
|
+
p50?: number | null;
|
|
116
|
+
p75?: number | null;
|
|
117
|
+
}
|
|
118
|
+
export interface ProfileCategoryValue {
|
|
119
|
+
value: string;
|
|
120
|
+
count: number;
|
|
121
|
+
}
|
|
122
|
+
export interface ProfileCategory {
|
|
123
|
+
/** 精确去重数;超过枚举上限时为 null(此时 truncated=true)。 */
|
|
124
|
+
distinct_count: number | null;
|
|
125
|
+
top_values: ProfileCategoryValue[];
|
|
126
|
+
/** true = 还有未展示的取值,`top_values` 不是全部。 */
|
|
127
|
+
truncated: boolean;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* 时间轴的**语义**(形态 + 该列自身观测到的时区偏移)。
|
|
131
|
+
*
|
|
132
|
+
* 存在的理由:`date_ms` 这类列的取值是 epoch 毫秒,模型既无法直接读出"这是哪一天",
|
|
133
|
+
* 也无法把"近 1 个月"翻译回毫秒;没有这一块事实,它只能自己推算——实测单步
|
|
134
|
+
* 41,961 字符的思考里绝大部分是时间戳算术(真机会话 1e44050e)。
|
|
135
|
+
* 块内只放**观测到的**事实,不做猜测:推断不出就报 `unknown`。
|
|
136
|
+
*/
|
|
137
|
+
export interface ProfileTimeAxis {
|
|
138
|
+
column: string;
|
|
139
|
+
value_format: 'epoch_ms' | 'date_string' | 'unknown';
|
|
140
|
+
/** 该列的取值按哪个时区解释(epoch_ms 且能推断时才有)。 */
|
|
141
|
+
time_zone?: string;
|
|
142
|
+
/** 上面的时区的 `+08:00` 形态;`time_zone` 已是 `UTC+08:00` 时不重复(避免同一事实写两遍)。 */
|
|
143
|
+
utc_offset?: string;
|
|
144
|
+
/** 取值对齐到当地午夜、日历日,还是无法判断。 */
|
|
145
|
+
aligned_to?: 'local_midnight' | 'calendar_day' | 'unknown';
|
|
146
|
+
}
|
|
147
|
+
/** 一个可直接使用的分析窗口:日历区间 + 该列里真正的查询边界。 */
|
|
148
|
+
export interface ProfileTimeWindow {
|
|
149
|
+
name: string;
|
|
150
|
+
start_date: string;
|
|
151
|
+
end_date: string;
|
|
152
|
+
/** `>= value_ge` 即"从这个窗口的第一天开始"(epoch 轴为当地午夜)。 */
|
|
153
|
+
value_ge: number | string;
|
|
154
|
+
/** `<= value_le` 即"到这个窗口的最后一天结束"。 */
|
|
155
|
+
value_le: number | string;
|
|
156
|
+
/** 该窗口在 Dataset 里**真实存在**的首末日期;起点落在非交易日时这里是下一个交易日。 */
|
|
157
|
+
data_from: string | null;
|
|
158
|
+
data_to: string | null;
|
|
159
|
+
}
|
|
160
|
+
export interface ProfileTimeFacts {
|
|
161
|
+
time_column: string;
|
|
162
|
+
/** 文件顺序是否随时间递增;null = 时间列有缺失,无法判断。 */
|
|
163
|
+
ordered_ascending: boolean | null;
|
|
164
|
+
/** 时间列的最小/最大值(覆盖范围),原值不改写。 */
|
|
165
|
+
covered_from: unknown;
|
|
166
|
+
covered_to: unknown;
|
|
167
|
+
/** 覆盖范围的人类可读日期;只对 epoch_ms 轴出现(date_string 轴本身可读)。 */
|
|
168
|
+
covered_from_iso?: string;
|
|
169
|
+
covered_to_iso?: string;
|
|
170
|
+
/** 时间轴语义:形态与时区偏移。 */
|
|
171
|
+
axis: ProfileTimeAxis;
|
|
172
|
+
/** 常用窗口(近 1 月 / 近 3 月 / 近 1 年 / 年初至今)的现成边界。 */
|
|
173
|
+
windows?: ProfileTimeWindow[];
|
|
174
|
+
/** 首行与末行的「时间列 + 数值列」取值(文件顺序),用于首末值与区间变化。 */
|
|
175
|
+
first: Record<string, unknown>;
|
|
176
|
+
last: Record<string, unknown>;
|
|
177
|
+
}
|
|
178
|
+
export interface ProfileStructureField {
|
|
179
|
+
name: string;
|
|
180
|
+
type: string;
|
|
181
|
+
}
|
|
182
|
+
export interface ProfileStructure {
|
|
183
|
+
type: 'array' | 'object';
|
|
184
|
+
/** 该路径在数据中出现的次数(行内多次出现会累加)。 */
|
|
185
|
+
occurrences: number;
|
|
186
|
+
/** 未抽样时,所有出现位置的元素总数;对象路径不返回该字段。 */
|
|
187
|
+
total_elements?: number;
|
|
188
|
+
/** 该路径受上限影响时,实际检查到的元素/对象数量;存在时不代表完整数量。 */
|
|
189
|
+
sampled_elements?: number;
|
|
190
|
+
/** 数组:空数组的出现次数与长度极值。 */
|
|
191
|
+
empty_count: number;
|
|
192
|
+
min_length: number;
|
|
193
|
+
max_length: number;
|
|
194
|
+
/** 对象:直接字段名与观察到的类型(有界)。 */
|
|
195
|
+
fields: ProfileStructureField[];
|
|
196
|
+
}
|
|
197
|
+
export interface ProfilePayload {
|
|
198
|
+
row_count: number;
|
|
199
|
+
columns: string[];
|
|
200
|
+
quality: {
|
|
201
|
+
missing_values: number;
|
|
202
|
+
duplicate_rows: number;
|
|
203
|
+
time_ordered: boolean | null;
|
|
204
|
+
};
|
|
205
|
+
statistics?: Record<string, ProfileStatistic>;
|
|
206
|
+
categories?: Record<string, ProfileCategory>;
|
|
207
|
+
time_facts?: ProfileTimeFacts;
|
|
208
|
+
structure?: Record<string, ProfileStructure>;
|
|
209
|
+
schema?: Record<string, ProfileColumn>;
|
|
210
|
+
validation?: ProfileValidation;
|
|
211
|
+
warnings: string[];
|
|
212
|
+
}
|
|
213
|
+
export type DatasetStoreErrorCode = 'workspace_not_writable' | 'session_unavailable' | 'session_cwd_unavailable' | 'sandbox_policy_unavailable' | 'filesystem_unavailable' | 'dataset_write_failed' | 'dataset_id_invalid' | 'dataset_not_found' | 'dataset_expired' | 'dataset_session_mismatch' | 'dataset_manifest_invalid' | 'dataset_format_unsupported' | 'dataset_not_row_readable' | 'dataset_too_large' | 'profile_invalid' | 'profile_too_large' | 'profile_dataset_mismatch' | 'workspace_path_invalid' | 'workspace_file_invalid';
|
|
214
|
+
export declare class DatasetStoreError extends Error {
|
|
215
|
+
readonly code: DatasetStoreErrorCode;
|
|
216
|
+
constructor(code: DatasetStoreErrorCode, detail: string);
|
|
217
|
+
}
|
|
218
|
+
export interface SessionLike {
|
|
219
|
+
readonly id: string;
|
|
220
|
+
readonly header?: {
|
|
221
|
+
readonly cwd?: string;
|
|
222
|
+
readonly parentSession?: string;
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
export interface SandboxPolicyResultLike {
|
|
226
|
+
readonly mode?: string;
|
|
227
|
+
readonly workspaceRoot?: string;
|
|
228
|
+
readonly sessionId?: string;
|
|
229
|
+
}
|
|
230
|
+
export interface SandboxPolicyLike {
|
|
231
|
+
resolve?(request: {
|
|
232
|
+
session?: SessionLike;
|
|
233
|
+
}): SandboxPolicyResultLike;
|
|
234
|
+
}
|
|
235
|
+
export interface FsTargetLike {
|
|
236
|
+
readonly targetKey: unknown;
|
|
237
|
+
readonly displayPath: string;
|
|
238
|
+
}
|
|
239
|
+
export interface FsLike {
|
|
240
|
+
resolve(path: string, opts?: {
|
|
241
|
+
cwd?: string;
|
|
242
|
+
signal?: AbortSignal;
|
|
243
|
+
}): Promise<FsTargetLike>;
|
|
244
|
+
contains?(parent: FsTargetLike, child: FsTargetLike): boolean;
|
|
245
|
+
stat?(target: FsTargetLike, signal?: AbortSignal): Promise<{
|
|
246
|
+
type: 'file' | 'directory' | 'other';
|
|
247
|
+
size?: number;
|
|
248
|
+
} | undefined>;
|
|
249
|
+
writeText(target: FsTargetLike, content: string, expected?: {
|
|
250
|
+
kind: 'createIfAbsent';
|
|
251
|
+
} | {
|
|
252
|
+
kind: 'replaceIfVersion';
|
|
253
|
+
version: unknown;
|
|
254
|
+
}, signal?: AbortSignal, sandboxPolicy?: SandboxPolicyResultLike): Promise<unknown>;
|
|
255
|
+
readText(target: FsTargetLike, signal?: AbortSignal): Promise<string>;
|
|
256
|
+
/**
|
|
257
|
+
* 原样读字节(本地 PDF / 图片交给外部解析服务时用)。宿主把上限放在这道缝上:
|
|
258
|
+
* 超过 `maxBytes` 抛 `FS_TOO_LARGE`,**不会**返回截断结果。
|
|
259
|
+
*/
|
|
260
|
+
readBytes?(target: FsTargetLike, signal: AbortSignal | undefined, maxBytes: number): Promise<Uint8Array>;
|
|
261
|
+
listDir(target: FsTargetLike, signal?: AbortSignal): Promise<Array<{
|
|
262
|
+
name: string;
|
|
263
|
+
type: 'file' | 'directory' | 'other';
|
|
264
|
+
target: FsTargetLike;
|
|
265
|
+
}>>;
|
|
266
|
+
}
|
|
267
|
+
export interface ProfileDatasetInput {
|
|
268
|
+
session: SessionLike;
|
|
269
|
+
dataset_id: string;
|
|
270
|
+
task_id?: string;
|
|
271
|
+
time_column?: string;
|
|
272
|
+
primary_key?: string;
|
|
273
|
+
signal?: AbortSignal;
|
|
274
|
+
}
|
|
275
|
+
export interface QueryDatasetInput {
|
|
276
|
+
session: SessionLike;
|
|
277
|
+
dataset_id: string;
|
|
278
|
+
query: QuerySpec;
|
|
279
|
+
signal?: AbortSignal;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* 时间轴探针结果:形态 + 已出现的日期 + 列清单。
|
|
283
|
+
*
|
|
284
|
+
* 三条消费路径共用同一份事实,避免"谁猜时间列"出现第二套判据:
|
|
285
|
+
* ① `query_dataset` 的日期筛选归一;② `resolve_data_time_range` 的数据集模式;
|
|
286
|
+
* ③ 报错信息里列出可选列。
|
|
287
|
+
*/
|
|
288
|
+
export interface TimeAxisSnapshot {
|
|
289
|
+
dataset_id: string;
|
|
290
|
+
columns: string[];
|
|
291
|
+
axis: ProfileTimeAxis;
|
|
292
|
+
/** 探针看到的日期(升序、去重);用于把窗口夹到真实存在的交易日。 */
|
|
293
|
+
dates: string[];
|
|
294
|
+
}
|
|
295
|
+
export interface ProfileDatasetResult extends ProfileRef {
|
|
296
|
+
row_count: number;
|
|
297
|
+
columns: string[];
|
|
298
|
+
quality: ProfilePayload['quality'];
|
|
299
|
+
statistics?: ProfilePayload['statistics'];
|
|
300
|
+
categories?: ProfilePayload['categories'];
|
|
301
|
+
time_facts?: ProfilePayload['time_facts'];
|
|
302
|
+
structure?: ProfilePayload['structure'];
|
|
303
|
+
schema?: ProfilePayload['schema'];
|
|
304
|
+
validation?: ProfilePayload['validation'];
|
|
305
|
+
warnings: string[];
|
|
306
|
+
/** 仅文档型 Dataset:有界内容,不随 profile 持久化。 */
|
|
307
|
+
document?: ProfileDocument;
|
|
308
|
+
}
|
|
309
|
+
export interface ProfileDocument {
|
|
310
|
+
/** 有界后的文档内容;连最小档位都放不下时为 null。 */
|
|
311
|
+
content: unknown;
|
|
312
|
+
truncated: boolean;
|
|
313
|
+
/** 被截断的数组路径与省略条数,逐个披露,不做静默省略。 */
|
|
314
|
+
omitted: Array<{
|
|
315
|
+
path: string;
|
|
316
|
+
kept: number;
|
|
317
|
+
omitted: number;
|
|
318
|
+
}>;
|
|
319
|
+
}
|
|
320
|
+
export interface FindDatasetInput {
|
|
321
|
+
session: SessionLike;
|
|
322
|
+
capability: string;
|
|
323
|
+
params_digest: string;
|
|
324
|
+
signal?: AbortSignal;
|
|
325
|
+
}
|
|
326
|
+
export interface SaveDatasetInput {
|
|
327
|
+
session: SessionLike;
|
|
328
|
+
capability: string;
|
|
329
|
+
task_id?: string;
|
|
330
|
+
params_digest: string;
|
|
331
|
+
source_label: string;
|
|
332
|
+
format: 'json' | 'json_rows';
|
|
333
|
+
schema: object | null;
|
|
334
|
+
row_count: number | null;
|
|
335
|
+
data: unknown;
|
|
336
|
+
/** Host-only row array key for envelope-shaped json_rows data. */
|
|
337
|
+
row_key?: string;
|
|
338
|
+
signal?: AbortSignal;
|
|
339
|
+
}
|
|
340
|
+
export interface WriteProfileInput {
|
|
341
|
+
session: SessionLike;
|
|
342
|
+
dataset_id: string;
|
|
343
|
+
task_id?: string;
|
|
344
|
+
profile: unknown;
|
|
345
|
+
signal?: AbortSignal;
|
|
346
|
+
}
|
|
347
|
+
export interface WorkspaceDatasetStoreOptions {
|
|
348
|
+
fs?: FsLike;
|
|
349
|
+
sandboxPolicy?: SandboxPolicyLike;
|
|
350
|
+
retentionMs?: number;
|
|
351
|
+
now?: () => number;
|
|
352
|
+
newId?: (prefix: string) => string;
|
|
353
|
+
}
|
|
354
|
+
export declare const DATASET_ID_PATTERN: RegExp;
|
|
355
|
+
/**
|
|
356
|
+
* 规范化并校验 workspace **相对**路径。
|
|
357
|
+
*
|
|
358
|
+
* 拒绝:空串、绝对路径(含 Windows 盘符)、任何 `..` 段、反斜杠(本仓统一 `/`)。
|
|
359
|
+
* 这里只做形态校验;真正的沙箱归属由 `resolveContained` 证明。两道关卡都要过——
|
|
360
|
+
* 形态校验是为了给出可读错误,归属校验才是安全边界。
|
|
361
|
+
*/
|
|
362
|
+
export declare function normalizeWorkspaceRelativePath(value: string): string;
|
|
363
|
+
export declare class WorkspaceDatasetStore {
|
|
364
|
+
private readonly fs;
|
|
365
|
+
private readonly sandboxPolicy;
|
|
366
|
+
private readonly retentionMs;
|
|
367
|
+
private readonly now;
|
|
368
|
+
private readonly newId;
|
|
369
|
+
constructor(options?: WorkspaceDatasetStoreOptions);
|
|
370
|
+
save(input: SaveDatasetInput): Promise<DatasetRef>;
|
|
371
|
+
readRef(datasetId: string, session: SessionLike, signal?: AbortSignal): Promise<DatasetRef | undefined>;
|
|
372
|
+
listRefs(session: SessionLike, signal?: AbortSignal): Promise<DatasetRef[]>;
|
|
373
|
+
findLatest(input: FindDatasetInput): Promise<DatasetRef | undefined>;
|
|
374
|
+
inspectDataset(datasetId: string, session: SessionLike, signal?: AbortSignal): Promise<DatasetInspection>;
|
|
375
|
+
profileDataset(input: ProfileDatasetInput): Promise<ProfileDatasetResult>;
|
|
376
|
+
queryDataset(input: QueryDatasetInput): Promise<QueryResult>;
|
|
377
|
+
/**
|
|
378
|
+
* 时间轴只读探针(`query_dataset` 的日期归一边界与 `resolve_data_time_range` 的数据集模式共用)。
|
|
379
|
+
*
|
|
380
|
+
* 只读前 {@link MAX_AXIS_PROBE_ROWS} 行推断形态与偏移:时间列一定在每行都出现,日线数据
|
|
381
|
+
* 的有序性也让前若干行足以定出粒度;这样这个探针**可以随查询逐次调用**,
|
|
382
|
+
* 代价与"读一份 16MB raw.json 只为一个问题"不同量级。
|
|
383
|
+
*/
|
|
384
|
+
describeTimeAxis(input: {
|
|
385
|
+
session: SessionLike;
|
|
386
|
+
dataset_id: string;
|
|
387
|
+
time_column?: string;
|
|
388
|
+
signal?: AbortSignal;
|
|
389
|
+
}): Promise<TimeAxisSnapshot | undefined>;
|
|
390
|
+
writeProfile(input: WriteProfileInput): Promise<ProfileRef>;
|
|
391
|
+
/**
|
|
392
|
+
* 宿主内部**呈现层**读取有界行集(图表用)。
|
|
393
|
+
*
|
|
394
|
+
* 契约(不可违反):
|
|
395
|
+
* - 返回值**不得**进入任何 Agent 消息、工具结果或模型上下文;调用方只能在宿主进程内
|
|
396
|
+
* 把它变成有界可视化载荷(见 src/chart/series.ts)。
|
|
397
|
+
* - 这是唯一一处把原始 rows 交给 store 之外代码的入口,因此命名、文档与调用点都必须是
|
|
398
|
+
* "呈现"语义。需要数值结论一律走 profile_dataset / query_dataset。
|
|
399
|
+
* - session 作用域与 profile/query 同源(`sessionScopeFor` 取父会话),所以主 Agent
|
|
400
|
+
* 用自己会话即可读到自己子 Agent 采到的 Dataset。
|
|
401
|
+
*/
|
|
402
|
+
readPresentationRows(input: {
|
|
403
|
+
session: SessionLike;
|
|
404
|
+
dataset_id: string;
|
|
405
|
+
signal?: AbortSignal;
|
|
406
|
+
maxRows?: number;
|
|
407
|
+
}): Promise<{
|
|
408
|
+
ref: DatasetRef;
|
|
409
|
+
rows: unknown[];
|
|
410
|
+
}>;
|
|
411
|
+
/**
|
|
412
|
+
* 宿主内部读取 workspace 内的**文本**文件(图表 spec、OCR 产物、用户本地数据)。
|
|
413
|
+
*
|
|
414
|
+
* 这是 workspace 读取的**唯一**实现:`readWorkspaceJson` / `readWorkspaceBytes` 都从
|
|
415
|
+
* `workspaceFileTarget` 取归属与体积闸门,不各自再写一遍路径校验(§9.7——同一个事实
|
|
416
|
+
* 有两份实现就一定会漂移)。
|
|
417
|
+
*/
|
|
418
|
+
readWorkspaceText(input: {
|
|
419
|
+
session: SessionLike;
|
|
420
|
+
path: string;
|
|
421
|
+
signal?: AbortSignal;
|
|
422
|
+
maxBytes?: number;
|
|
423
|
+
}): Promise<string>;
|
|
424
|
+
/**
|
|
425
|
+
* 宿主内部读取 workspace 内的**原始字节**(本地 PDF / 图片上传给外部解析服务的入口)。
|
|
426
|
+
*
|
|
427
|
+
* 上限必须显式给出:这道缝后面的调用方要把字节整个装进内存,没有默认值可兜。
|
|
428
|
+
* `fs.readBytes` 缺席(载体未挂载该能力)时**响亮失败**,不回退成 `readText`——
|
|
429
|
+
* 二进制走文本读取会得到被解码污染的字节。
|
|
430
|
+
*/
|
|
431
|
+
readWorkspaceBytes(input: {
|
|
432
|
+
session: SessionLike;
|
|
433
|
+
path: string;
|
|
434
|
+
signal?: AbortSignal;
|
|
435
|
+
maxBytes: number;
|
|
436
|
+
}): Promise<Uint8Array>;
|
|
437
|
+
private workspaceFileTarget;
|
|
438
|
+
/** 宿主内部呈现层读取 workspace 内的 JSON 文件(用户本地数据直接可视化的入口)。 */
|
|
439
|
+
readWorkspaceJson(input: {
|
|
440
|
+
session: SessionLike;
|
|
441
|
+
path: string;
|
|
442
|
+
signal?: AbortSignal;
|
|
443
|
+
}): Promise<unknown>;
|
|
444
|
+
/**
|
|
445
|
+
* 宿主内部**产物层**把一组文本文件写进 workspace 的一个子目录(图表与 OCR 产物用)。
|
|
446
|
+
*
|
|
447
|
+
* 走与 Dataset 落盘完全相同的沙箱策略与归属校验;默认 `createIfAbsent`,保证不会静默
|
|
448
|
+
* 覆盖已有产物(图表 id 唯一,重复即 bug,应当响亮失败)。
|
|
449
|
+
*
|
|
450
|
+
* `overwrite: true` 是给**内容寻址产物**重跑用的(OCR:上次在两个文件之间被中断,
|
|
451
|
+
* 半件产物必须能被下一次解析自愈)。它不是"跳过幂等"的口子:幂等判断在调用方,
|
|
452
|
+
* 只有已经决定重新生成时才传。
|
|
453
|
+
*
|
|
454
|
+
* 返回值同时给出**相对路径**(可以进 Agent 消息、可以 present 给用户)与**绝对路径**
|
|
455
|
+
* (只供宿主内部使用,例如登记给 host 平面的取数路由)。这个区分是本仓的数据纪律:
|
|
456
|
+
* 绝对路径不出宿主进程。
|
|
457
|
+
*/
|
|
458
|
+
writeWorkspaceFiles(input: {
|
|
459
|
+
session: SessionLike;
|
|
460
|
+
dir: string;
|
|
461
|
+
files: Array<{
|
|
462
|
+
name: string;
|
|
463
|
+
content: string;
|
|
464
|
+
}>;
|
|
465
|
+
signal?: AbortSignal;
|
|
466
|
+
overwrite?: boolean;
|
|
467
|
+
}): Promise<Array<{
|
|
468
|
+
name: string;
|
|
469
|
+
path: string;
|
|
470
|
+
absolutePath: string;
|
|
471
|
+
}>>;
|
|
472
|
+
private requireRef;
|
|
473
|
+
private requireStoredRef;
|
|
474
|
+
/**
|
|
475
|
+
* 读取原始 Dataset。返回两种形状之一:
|
|
476
|
+
* - `rows`:顶层数组或 manifest 声明的行数组键,可 profile、可 query;
|
|
477
|
+
* - `document`:顶层对象且没有行数组(财务指标、回测结果这类),可 profile
|
|
478
|
+
* (宿主算结构摘要 + 有界内容),不可 query。
|
|
479
|
+
* 判定放在读取时而不是复用 manifest 的 `format`:`format` 只记录写入时的粗略
|
|
480
|
+
* 形状,真正的形状以文件内容为准。
|
|
481
|
+
*/
|
|
482
|
+
private readRaw;
|
|
483
|
+
private resolveContained;
|
|
484
|
+
private assertContained;
|
|
485
|
+
private writeContext;
|
|
486
|
+
private readRoot;
|
|
487
|
+
private mapWriteError;
|
|
488
|
+
}
|
|
489
|
+
/** 行内取列值:`present=false` 表示该列在这行不存在(缺失),与显式 null 区分开。 */
|
|
490
|
+
export interface ProfileCell {
|
|
491
|
+
present: boolean;
|
|
492
|
+
value: unknown;
|
|
493
|
+
}
|
|
494
|
+
export declare function provideWorkspaceDatasetStore(ctx: import('@deepseek-ai/cordis').Context, options?: WorkspaceDatasetStoreOptions): WorkspaceDatasetStore;
|
|
495
|
+
declare module '@deepseek-ai/cordis' {
|
|
496
|
+
interface Context {
|
|
497
|
+
datasetStore: WorkspaceDatasetStore;
|
|
498
|
+
}
|
|
499
|
+
}
|