precis-cli 0.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) hide show
  1. app/__init__.py +16 -0
  2. app/api/__init__.py +32 -0
  3. app/api/dependencies.py +185 -0
  4. app/api/main.py +301 -0
  5. app/api/middleware/__init__.py +34 -0
  6. app/api/middleware/exception_handler.py +126 -0
  7. app/api/middleware/request_logging.py +97 -0
  8. app/api/middleware/token_auth.py +215 -0
  9. app/api/models/__init__.py +151 -0
  10. app/api/models/connection_rules.py +98 -0
  11. app/api/models/files.py +99 -0
  12. app/api/models/full_validation.py +554 -0
  13. app/api/models/project.py +117 -0
  14. app/api/models/projects.py +80 -0
  15. app/api/models/schema.py +121 -0
  16. app/api/models/v2_responses.py +46 -0
  17. app/api/models/validation.py +303 -0
  18. app/api/models/workspace.py +118 -0
  19. app/api/routers/__init__.py +56 -0
  20. app/api/routers/ai/__init__.py +36 -0
  21. app/api/routers/ai/chat.py +243 -0
  22. app/api/routers/ai/generate.py +156 -0
  23. app/api/routers/ai/hardware.py +199 -0
  24. app/api/routers/ai/jobs.py +544 -0
  25. app/api/routers/ai/migrate.py +471 -0
  26. app/api/routers/ai/models.py +352 -0
  27. app/api/routers/ai/ollama.py +108 -0
  28. app/api/routers/ai/providers.py +491 -0
  29. app/api/routers/ai/router.py +44 -0
  30. app/api/routers/ai/stream.py +281 -0
  31. app/api/routers/ai/utils.py +182 -0
  32. app/api/routers/core/__init__.py +34 -0
  33. app/api/routers/core/connection_rules.py +188 -0
  34. app/api/routers/core/data_sources.py +374 -0
  35. app/api/routers/core/regex.py +333 -0
  36. app/api/routers/core/reporting.py +263 -0
  37. app/api/routers/files/__init__.py +24 -0
  38. app/api/routers/files/ops.py +179 -0
  39. app/api/routers/files/transfer.py +101 -0
  40. app/api/routers/preview/__init__.py +35 -0
  41. app/api/routers/preview/content_mode.py +264 -0
  42. app/api/routers/preview/header_row.py +154 -0
  43. app/api/routers/preview/models.py +81 -0
  44. app/api/routers/preview/path_mode.py +440 -0
  45. app/api/routers/preview/router.py +30 -0
  46. app/api/routers/project/__init__.py +61 -0
  47. app/api/routers/project/base.py +111 -0
  48. app/api/routers/project/constraint.py +345 -0
  49. app/api/routers/project/full_config.py +411 -0
  50. app/api/routers/project/full_config_writer.py +327 -0
  51. app/api/routers/project/helpers.py +167 -0
  52. app/api/routers/project/inspection_fix.py +330 -0
  53. app/api/routers/project/manifest.py +605 -0
  54. app/api/routers/project/models.py +177 -0
  55. app/api/routers/project/pattern.py +268 -0
  56. app/api/routers/project/regex.py +358 -0
  57. app/api/routers/project/scanner.py +157 -0
  58. app/api/routers/project/schema.py +567 -0
  59. app/api/routers/project/schema_helpers.py +149 -0
  60. app/api/routers/project/settings.py +399 -0
  61. app/api/routers/project/template.py +325 -0
  62. app/api/routers/project/validation.py +227 -0
  63. app/api/routers/project/view.py +177 -0
  64. app/api/routers/project/workspaces.py +167 -0
  65. app/api/routers/projects/__init__.py +25 -0
  66. app/api/routers/projects/create.py +121 -0
  67. app/api/routers/projects/open.py +103 -0
  68. app/api/routers/projects/scan.py +100 -0
  69. app/api/routers/validation/__init__.py +39 -0
  70. app/api/routers/validation/common.py +263 -0
  71. app/api/routers/validation/content_mode.py +401 -0
  72. app/api/routers/validation/history.py +235 -0
  73. app/api/routers/validation/inline_mode.py +196 -0
  74. app/api/routers/validation/path_mode.py +314 -0
  75. app/api/routers/validation/router.py +51 -0
  76. app/api/services/full_validation_response_builder.py +412 -0
  77. app/api/services/io_error_messages.py +41 -0
  78. app/api/services/preview_service.py +248 -0
  79. app/cli/__init__.py +18 -0
  80. app/cli/__main__.py +30 -0
  81. app/cli/shared_services/__init__.py +42 -0
  82. app/cli/shared_services/config_ops.py +581 -0
  83. app/cli/shared_services/generation_ops.py +160 -0
  84. app/cli/shared_services/project_ops.py +288 -0
  85. app/cli/shell/__init__.py +48 -0
  86. app/cli/shell/commands/__init__.py +63 -0
  87. app/cli/shell/commands/ai/__init__.py +260 -0
  88. app/cli/shell/commands/ai/chat.py +331 -0
  89. app/cli/shell/commands/ai/delete.py +165 -0
  90. app/cli/shell/commands/ai/diff.py +70 -0
  91. app/cli/shell/commands/ai/display.py +428 -0
  92. app/cli/shell/commands/ai/executor.py +225 -0
  93. app/cli/shell/commands/ai/executor_utils.py +271 -0
  94. app/cli/shell/commands/ai/generate.py +285 -0
  95. app/cli/shell/commands/ai/interaction.py +262 -0
  96. app/cli/shell/commands/ai/migrate.py +281 -0
  97. app/cli/shell/commands/ai/resolver.py +224 -0
  98. app/cli/shell/commands/ai/status.py +101 -0
  99. app/cli/shell/commands/ai/switch.py +158 -0
  100. app/cli/shell/commands/ai/utils.py +52 -0
  101. app/cli/shell/commands/base.py +343 -0
  102. app/cli/shell/commands/config/__init__.py +131 -0
  103. app/cli/shell/commands/config/base.py +80 -0
  104. app/cli/shell/commands/config/check.py +246 -0
  105. app/cli/shell/commands/config/edit.py +148 -0
  106. app/cli/shell/commands/config/get.py +111 -0
  107. app/cli/shell/commands/config/init.py +123 -0
  108. app/cli/shell/commands/config/inspect.py +164 -0
  109. app/cli/shell/commands/config/list.py +104 -0
  110. app/cli/shell/commands/config/set.py +119 -0
  111. app/cli/shell/commands/config/show.py +150 -0
  112. app/cli/shell/commands/exit.py +67 -0
  113. app/cli/shell/commands/help.py +104 -0
  114. app/cli/shell/commands/infer_schema.py +156 -0
  115. app/cli/shell/commands/open.py +201 -0
  116. app/cli/shell/commands/project.py +215 -0
  117. app/cli/shell/commands/provider.py +619 -0
  118. app/cli/shell/commands/system.py +170 -0
  119. app/cli/shell/commands/validate.py +455 -0
  120. app/cli/shell/completer.py +231 -0
  121. app/cli/shell/config_storage.py +191 -0
  122. app/cli/shell/exceptions.py +90 -0
  123. app/cli/shell/formatter.py +371 -0
  124. app/cli/shell/interactive_menu.py +348 -0
  125. app/cli/shell/main.py +286 -0
  126. app/cli/shell/parser.py +266 -0
  127. app/cli/start.py +180 -0
  128. app/cli_main.py +52 -0
  129. app/mcp_server.py +311 -0
  130. app/shared/core/__init__.py +18 -0
  131. app/shared/core/app_version.py +59 -0
  132. app/shared/core/config/__init__.py +119 -0
  133. app/shared/core/config/server.py +193 -0
  134. app/shared/core/data_source/__init__.py +106 -0
  135. app/shared/core/data_source/loader.py +348 -0
  136. app/shared/core/data_source/loaders/__init__.py +213 -0
  137. app/shared/core/data_source/loaders/base.py +215 -0
  138. app/shared/core/data_source/loaders/converter.py +337 -0
  139. app/shared/core/data_source/loaders/csv_loader.py +252 -0
  140. app/shared/core/data_source/loaders/excel_loader.py +666 -0
  141. app/shared/core/data_source/loaders/extractor.py +268 -0
  142. app/shared/core/data_source/loaders/json_loader.py +354 -0
  143. app/shared/core/data_source/loaders/registry.py +88 -0
  144. app/shared/core/data_source/loaders/sql_loader.py +313 -0
  145. app/shared/core/data_source/loaders/strategies/__init__.py +100 -0
  146. app/shared/core/data_source/loaders/strategies/array_parser.py +277 -0
  147. app/shared/core/data_source/loaders/strategies/lines_parser.py +355 -0
  148. app/shared/core/data_source/loaders/strategies/object_parser.py +278 -0
  149. app/shared/core/data_source/schema_info.py +50 -0
  150. app/shared/core/data_source/specs/__init__.py +128 -0
  151. app/shared/core/data_source/specs/base.py +258 -0
  152. app/shared/core/data_source/specs/csv_source.py +137 -0
  153. app/shared/core/data_source/specs/excel_source.py +141 -0
  154. app/shared/core/data_source/specs/file_base.py +252 -0
  155. app/shared/core/data_source/specs/json_source.py +226 -0
  156. app/shared/core/data_source/specs/sql_source.py +161 -0
  157. app/shared/core/encoding.py +36 -0
  158. app/shared/core/io/__init__.py +24 -0
  159. app/shared/core/io/yaml.py +379 -0
  160. app/shared/core/manifest_schema/__init__.py +52 -0
  161. app/shared/core/manifest_schema/types.py +99 -0
  162. app/shared/core/manifest_schema/version.py +175 -0
  163. app/shared/core/patterns/__init__.py +24 -0
  164. app/shared/core/patterns/loader.py +134 -0
  165. app/shared/core/patterns/writer.py +244 -0
  166. app/shared/core/project/__init__.py +47 -0
  167. app/shared/core/project/constraint/builders/__init__.py +50 -0
  168. app/shared/core/project/constraint/builders/base.py +100 -0
  169. app/shared/core/project/constraint/builders/composite.py +77 -0
  170. app/shared/core/project/constraint/builders/conditional.py +67 -0
  171. app/shared/core/project/constraint/builders/foreign_key.py +53 -0
  172. app/shared/core/project/constraint/builders/registry.py +64 -0
  173. app/shared/core/project/constraint/builders/scripted.py +51 -0
  174. app/shared/core/project/constraint/builders/single_column.py +86 -0
  175. app/shared/core/project/constraint/builders/unique.py +53 -0
  176. app/shared/core/project/constraint/factory.py +170 -0
  177. app/shared/core/project/constraint/reader.py +214 -0
  178. app/shared/core/project/constraint/registry.py +233 -0
  179. app/shared/core/project/constraint/types/__init__.py +63 -0
  180. app/shared/core/project/constraint/types/constraint_file.py +261 -0
  181. app/shared/core/project/constraint/types/refs.py +460 -0
  182. app/shared/core/project/constraint/types.py +28 -0
  183. app/shared/core/project/constraint/writer.py +181 -0
  184. app/shared/core/project/loader/__init__.py +56 -0
  185. app/shared/core/project/loader/loader.py +30 -0
  186. app/shared/core/project/loader/loader_parts/config_inspector.py +137 -0
  187. app/shared/core/project/loader/loader_parts/embedded_constraints.py +224 -0
  188. app/shared/core/project/loader/loader_parts/file_loaders.py +58 -0
  189. app/shared/core/project/loader/loader_parts/inspection_ids.py +85 -0
  190. app/shared/core/project/loader/loader_parts/inspector_helpers.py +312 -0
  191. app/shared/core/project/loader/loader_parts/inspector_id_checks.py +274 -0
  192. app/shared/core/project/loader/loader_parts/inspector_reference_checks.py +690 -0
  193. app/shared/core/project/loader/loader_parts/inspector_uniqueness_checks.py +286 -0
  194. app/shared/core/project/loader/loader_parts/loading_error_messages.py +298 -0
  195. app/shared/core/project/loader/loader_parts/main.py +432 -0
  196. app/shared/core/project/loader/loader_parts/path_validation.py +117 -0
  197. app/shared/core/project/loader/loader_parts/runtime.py +125 -0
  198. app/shared/core/project/loader/types.py +246 -0
  199. app/shared/core/project/manifest/coverage.py +391 -0
  200. app/shared/core/project/manifest/reader.py +260 -0
  201. app/shared/core/project/manifest/types.py +91 -0
  202. app/shared/core/project/manifest/types_parts/__init__.py +60 -0
  203. app/shared/core/project/manifest/types_parts/constants.py +40 -0
  204. app/shared/core/project/manifest/types_parts/data_source.py +68 -0
  205. app/shared/core/project/manifest/types_parts/info.py +59 -0
  206. app/shared/core/project/manifest/types_parts/manifest.py +294 -0
  207. app/shared/core/project/manifest/types_parts/refs.py +153 -0
  208. app/shared/core/project/manifest/types_parts/settings.py +92 -0
  209. app/shared/core/project/manifest/types_parts/settings_file_processing.py +64 -0
  210. app/shared/core/project/manifest/types_parts/settings_script_security.py +78 -0
  211. app/shared/core/project/manifest/types_parts/settings_validation.py +83 -0
  212. app/shared/core/project/manifest/types_parts/template.py +66 -0
  213. app/shared/core/project/manifest/writer.py +262 -0
  214. app/shared/core/project/manual_data/__init__.py +27 -0
  215. app/shared/core/project/manual_data/types.py +75 -0
  216. app/shared/core/project/regex/reader.py +197 -0
  217. app/shared/core/project/regex/types.py +405 -0
  218. app/shared/core/project/regex/writer.py +123 -0
  219. app/shared/core/project/schema/reader.py +170 -0
  220. app/shared/core/project/schema/types.py +47 -0
  221. app/shared/core/project/schema/types_parts/__init__.py +36 -0
  222. app/shared/core/project/schema/types_parts/column.py +174 -0
  223. app/shared/core/project/schema/types_parts/column_utils.py +72 -0
  224. app/shared/core/project/schema/types_parts/constraint.py +165 -0
  225. app/shared/core/project/schema/types_parts/schema_id.py +66 -0
  226. app/shared/core/project/schema/types_parts/source.py +255 -0
  227. app/shared/core/project/schema/types_parts/source_options.py +347 -0
  228. app/shared/core/project/schema/types_parts/table.py +230 -0
  229. app/shared/core/project/schema/writer.py +139 -0
  230. app/shared/core/project/schema_ref_check.py +95 -0
  231. app/shared/core/project/template/__init__.py +27 -0
  232. app/shared/core/project/template/expander.py +263 -0
  233. app/shared/core/project/template/reader.py +120 -0
  234. app/shared/core/project/template/types.py +114 -0
  235. app/shared/core/project/transform/reader.py +76 -0
  236. app/shared/core/project/transform/types.py +116 -0
  237. app/shared/core/project/transform/writer.py +84 -0
  238. app/shared/core/pydantic_messages.py +59 -0
  239. app/shared/core/reporter/__init__.py +46 -0
  240. app/shared/core/reporter/reporter.py +220 -0
  241. app/shared/core/reporter/reporters/__init__.py +65 -0
  242. app/shared/core/reporter/reporters/base.py +188 -0
  243. app/shared/core/reporter/reporters/dingtalk_app_reporter.py +274 -0
  244. app/shared/core/reporter/reporters/email_reporter.py +271 -0
  245. app/shared/core/reporter/reporters/feishu_app_reporter.py +467 -0
  246. app/shared/core/reporter/reporters/local_file_reporter.py +208 -0
  247. app/shared/core/reporter/reporters/wecom_app_reporter.py +268 -0
  248. app/shared/core/utils/__init__.py +18 -0
  249. app/shared/core/utils/path_utils.py +60 -0
  250. app/shared/core/utils/regex_extract.py +113 -0
  251. app/shared/domain/__init__.py +114 -0
  252. app/shared/domain/constraints/__init__.py +76 -0
  253. app/shared/domain/constraints/allowed_values.py +211 -0
  254. app/shared/domain/constraints/base.py +141 -0
  255. app/shared/domain/constraints/charset.py +337 -0
  256. app/shared/domain/constraints/composite.py +174 -0
  257. app/shared/domain/constraints/condition_registry.py +130 -0
  258. app/shared/domain/constraints/conditional.py +629 -0
  259. app/shared/domain/constraints/date_logic.py +731 -0
  260. app/shared/domain/constraints/foreign_key.py +261 -0
  261. app/shared/domain/constraints/key_normalization.py +56 -0
  262. app/shared/domain/constraints/not_null.py +185 -0
  263. app/shared/domain/constraints/range.py +360 -0
  264. app/shared/domain/constraints/regex.py +218 -0
  265. app/shared/domain/constraints/scripted.py +276 -0
  266. app/shared/domain/constraints/unique.py +233 -0
  267. app/shared/domain/data_engine.py +384 -0
  268. app/shared/domain/data_types.py +113 -0
  269. app/shared/domain/data_types_parts/__init__.py +67 -0
  270. app/shared/domain/data_types_parts/base.py +204 -0
  271. app/shared/domain/data_types_parts/composite.py +250 -0
  272. app/shared/domain/data_types_parts/expression.py +202 -0
  273. app/shared/domain/data_types_parts/extracted.py +106 -0
  274. app/shared/domain/data_types_parts/json_types.py +234 -0
  275. app/shared/domain/data_types_parts/scalars.py +719 -0
  276. app/shared/domain/data_types_parts/sequence.py +129 -0
  277. app/shared/domain/dataset_schema.py +48 -0
  278. app/shared/domain/eval_sandbox.py +63 -0
  279. app/shared/domain/expression_system.py +366 -0
  280. app/shared/domain/regex_flags.py +53 -0
  281. app/shared/domain/schema/builder.py +223 -0
  282. app/shared/domain/schema/models.py +339 -0
  283. app/shared/domain/transforms/__init__.py +28 -0
  284. app/shared/domain/transforms/aggregate.py +141 -0
  285. app/shared/domain/transforms/base.py +171 -0
  286. app/shared/domain/transforms/cast_type.py +120 -0
  287. app/shared/domain/transforms/concat.py +103 -0
  288. app/shared/domain/transforms/conditional_assign.py +114 -0
  289. app/shared/domain/transforms/date_format.py +81 -0
  290. app/shared/domain/transforms/digits.py +77 -0
  291. app/shared/domain/transforms/drop_duplicates.py +94 -0
  292. app/shared/domain/transforms/fill_na.py +94 -0
  293. app/shared/domain/transforms/filter_rows.py +97 -0
  294. app/shared/domain/transforms/lookup.py +78 -0
  295. app/shared/domain/transforms/lower_case.py +70 -0
  296. app/shared/domain/transforms/map_value.py +90 -0
  297. app/shared/domain/transforms/math_expr.py +112 -0
  298. app/shared/domain/transforms/modulo.py +82 -0
  299. app/shared/domain/transforms/regex_extract.py +103 -0
  300. app/shared/domain/transforms/registry.py +95 -0
  301. app/shared/domain/transforms/replace.py +88 -0
  302. app/shared/domain/transforms/sort_rows.py +94 -0
  303. app/shared/domain/transforms/string_split.py +84 -0
  304. app/shared/domain/transforms/strip.py +73 -0
  305. app/shared/domain/transforms/substring.py +92 -0
  306. app/shared/domain/transforms/upper_case.py +70 -0
  307. app/shared/domain/transforms/weighted_sum.py +104 -0
  308. app/shared/domain/validation_constraints.py +69 -0
  309. app/shared/services/__init__.py +62 -0
  310. app/shared/services/ai/__init__.py +48 -0
  311. app/shared/services/ai/agent/__init__.py +40 -0
  312. app/shared/services/ai/agent/chat_tools/__init__.py +47 -0
  313. app/shared/services/ai/agent/chat_tools/apply_actions.py +592 -0
  314. app/shared/services/ai/agent/chat_tools/ask_user.py +237 -0
  315. app/shared/services/ai/agent/chat_tools/read_canvas.py +140 -0
  316. app/shared/services/ai/agent/chat_tools/read_project.py +160 -0
  317. app/shared/services/ai/agent/chat_tools/read_table.py +301 -0
  318. app/shared/services/ai/agent/chat_tools/schemas.py +105 -0
  319. app/shared/services/ai/agent/chat_tools/validate_table.py +131 -0
  320. app/shared/services/ai/agent/executor.py +554 -0
  321. app/shared/services/ai/agent/memory.py +256 -0
  322. app/shared/services/ai/agent/planner.py +282 -0
  323. app/shared/services/ai/agent/tool_registry.py +296 -0
  324. app/shared/services/ai/agent/tools/__init__.py +32 -0
  325. app/shared/services/ai/agent/tools/config_generate.py +133 -0
  326. app/shared/services/ai/agent/tools/config_refine.py +109 -0
  327. app/shared/services/ai/agent/tools/config_validate.py +403 -0
  328. app/shared/services/ai/agent/tools/merge_results.py +136 -0
  329. app/shared/services/ai/agent/tools/plan_chunks.py +79 -0
  330. app/shared/services/ai/agent/tools/script_parse.py +359 -0
  331. app/shared/services/ai/agent/types.py +138 -0
  332. app/shared/services/ai/chat_agent_runner.py +596 -0
  333. app/shared/services/ai/chat_orchestrator.py +725 -0
  334. app/shared/services/ai/failure_messages.py +65 -0
  335. app/shared/services/ai/job_storage.py +274 -0
  336. app/shared/services/ai/migrate_service.py +550 -0
  337. app/shared/services/ai/streaming/__init__.py +65 -0
  338. app/shared/services/ai/streaming/event_journal.py +197 -0
  339. app/shared/services/ai/streaming/orchestrator.py +262 -0
  340. app/shared/services/ai/streaming/pending_interaction_store.py +227 -0
  341. app/shared/services/ai/streaming/sse_response.py +148 -0
  342. app/shared/services/ai/streaming/types.py +73 -0
  343. app/shared/services/ai/types.py +213 -0
  344. app/shared/services/ai/utils.py +322 -0
  345. app/shared/services/diff/config_diff.py +320 -0
  346. app/shared/services/hardware.py +237 -0
  347. app/shared/services/llm/__init__.py +62 -0
  348. app/shared/services/llm/actions/__init__.py +42 -0
  349. app/shared/services/llm/actions/_canvas_validator.py +147 -0
  350. app/shared/services/llm/actions/_constraint_validator.py +401 -0
  351. app/shared/services/llm/actions/_regex_validator.py +85 -0
  352. app/shared/services/llm/actions/_schema_validator.py +82 -0
  353. app/shared/services/llm/actions/_settings_validator.py +76 -0
  354. app/shared/services/llm/actions/_transform_validator.py +78 -0
  355. app/shared/services/llm/actions/action_handlers.py +400 -0
  356. app/shared/services/llm/actions/action_parser.py +63 -0
  357. app/shared/services/llm/actions/action_processor.py +468 -0
  358. app/shared/services/llm/actions/action_validator.py +311 -0
  359. app/shared/services/llm/actions/diff_compute.py +195 -0
  360. app/shared/services/llm/actions/regex_handlers.py +284 -0
  361. app/shared/services/llm/actions/registry.py +336 -0
  362. app/shared/services/llm/actions/schema_handlers.py +335 -0
  363. app/shared/services/llm/actions/settings_handlers.py +180 -0
  364. app/shared/services/llm/actions/specs.py +259 -0
  365. app/shared/services/llm/actions/transform_handlers.py +279 -0
  366. app/shared/services/llm/actions/validation_types.py +147 -0
  367. app/shared/services/llm/cache/__init__.py +18 -0
  368. app/shared/services/llm/cache/response_cache.py +80 -0
  369. app/shared/services/llm/chat/__init__.py +35 -0
  370. app/shared/services/llm/chat/chat_system_prompt.py +561 -0
  371. app/shared/services/llm/chat/response_parser.py +296 -0
  372. app/shared/services/llm/config/__init__.py +45 -0
  373. app/shared/services/llm/config/crypto.py +135 -0
  374. app/shared/services/llm/config/loader.py +258 -0
  375. app/shared/services/llm/config/models.py +202 -0
  376. app/shared/services/llm/config/presets.py +128 -0
  377. app/shared/services/llm/config_generator.py +163 -0
  378. app/shared/services/llm/constraints/__init__.py +41 -0
  379. app/shared/services/llm/constraints/constraint_builder.py +177 -0
  380. app/shared/services/llm/constraints/constraint_deletion.py +84 -0
  381. app/shared/services/llm/constraints/constraint_id.py +174 -0
  382. app/shared/services/llm/constraints/frontend_instructions.py +333 -0
  383. app/shared/services/llm/constraints/inline_batch.py +279 -0
  384. app/shared/services/llm/discovery/__init__.py +35 -0
  385. app/shared/services/llm/discovery/scanner.py +181 -0
  386. app/shared/services/llm/generation/__init__.py +42 -0
  387. app/shared/services/llm/generation/agent_wiring.py +156 -0
  388. app/shared/services/llm/generation/config_builder.py +386 -0
  389. app/shared/services/llm/generation/errors.py +36 -0
  390. app/shared/services/llm/generation/existing_config.py +99 -0
  391. app/shared/services/llm/generation/profiler.py +279 -0
  392. app/shared/services/llm/generation/prompt_builder.py +199 -0
  393. app/shared/services/llm/generation/response_parser.py +144 -0
  394. app/shared/services/llm/generation/service.py +622 -0
  395. app/shared/services/llm/models.py +104 -0
  396. app/shared/services/llm/providers/__init__.py +48 -0
  397. app/shared/services/llm/providers/base.py +310 -0
  398. app/shared/services/llm/providers/cached_provider.py +90 -0
  399. app/shared/services/llm/providers/ollama.py +498 -0
  400. app/shared/services/llm/providers/openai.py +334 -0
  401. app/shared/services/llm/providers/registry.py +108 -0
  402. app/shared/services/llm/schema_resolver.py +141 -0
  403. app/shared/services/llm/suggestion_utils.py +219 -0
  404. app/shared/services/llm/validate_executor.py +163 -0
  405. app/shared/services/llm/yaml_io.py +406 -0
  406. app/shared/services/preview/__init__.py +18 -0
  407. app/shared/services/preview/loader.py +145 -0
  408. app/shared/services/preview/path_validation.py +138 -0
  409. app/shared/services/project_loader.py +57 -0
  410. app/shared/services/schema_inference.py +260 -0
  411. app/shared/services/schema_runtime_builder.py +120 -0
  412. app/shared/services/validation/__init__.py +52 -0
  413. app/shared/services/validation/chunked_loader.py +509 -0
  414. app/shared/services/validation/dag/__init__.py +35 -0
  415. app/shared/services/validation/dag/builder.py +141 -0
  416. app/shared/services/validation/dag/executor.py +225 -0
  417. app/shared/services/validation/dag/sorter.py +77 -0
  418. app/shared/services/validation/data_loader.py +231 -0
  419. app/shared/services/validation/engine.py +446 -0
  420. app/shared/services/validation/executor.py +1030 -0
  421. app/shared/services/validation/extractors.py +266 -0
  422. app/shared/services/validation/history.py +209 -0
  423. app/shared/services/validation/json_payload.py +136 -0
  424. app/shared/services/validation/loader.py +152 -0
  425. app/shared/services/validation/memory_monitor.py +179 -0
  426. app/shared/services/validation/postprocess.py +208 -0
  427. app/shared/services/validation/progress.py +64 -0
  428. app/shared/services/validation/report_export.py +222 -0
  429. app/shared/services/validation/resolver.py +180 -0
  430. app/shared/services/validation/service.py +418 -0
  431. app/shared/services/validation/types.py +238 -0
  432. app/shared/services/validation/validators/__init__.py +36 -0
  433. app/shared/services/validation/validators/adapter.py +182 -0
  434. app/shared/services/validation/validators/base.py +332 -0
  435. app/shared/services/validation/validators/composite.py +233 -0
  436. app/shared/services/validation/validators/date_logic.py +276 -0
  437. app/start_server.py +133 -0
  438. precis_cli-0.1.3.dist-info/METADATA +180 -0
  439. precis_cli-0.1.3.dist-info/RECORD +442 -0
  440. precis_cli-0.1.3.dist-info/WHEEL +5 -0
  441. precis_cli-0.1.3.dist-info/entry_points.txt +4 -0
  442. precis_cli-0.1.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,83 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ #
3
+ # Copyright 2026 Precis Team
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ """
17
+ @fileoverview 验证设置类型定义模块
18
+
19
+ 功能概述:
20
+ - 定义数据验证相关的配置选项
21
+ - 包括自动验证、严格模式、错误处理、超时等
22
+
23
+ 架构设计:
24
+ - 类型安全: 使用 Literal 限制可选值
25
+ - 范围限制: timeout_seconds 和 batch_max_files 有取值范围
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ from typing import Literal
31
+
32
+ from pydantic import BaseModel, Field
33
+
34
+
35
+ class ValidationSettings(BaseModel):
36
+ """
37
+ @classdesc 验证设置
38
+
39
+ 定义数据验证的行为和策略。
40
+
41
+ 字段说明:
42
+ - auto_validate: 是否在连接或配置变更时自动触发校验
43
+ - strict_mode: 严格模式,任何错误都会导致校验失败
44
+ - error_handling: 遇到错误时的处理策略
45
+ - stop: 立即停止校验
46
+ - continue: 跳过错误继续校验其他数据
47
+ - report: 记录错误但继续,生成完整报告
48
+ - timeout_seconds: 单次校验最大超时时间 (1-300秒)
49
+ - batch_max_files: 批量校验的最大文件数 (1-1000)
50
+
51
+ 输入示例 (manifest.yaml):
52
+ settings:
53
+ validation:
54
+ auto_validate: true
55
+ strict_mode: false
56
+ error_handling: continue
57
+ timeout_seconds: 60
58
+ batch_max_files: 200
59
+
60
+ 输出示例:
61
+ ValidationSettings(
62
+ auto_validate=True,
63
+ strict_mode=False,
64
+ error_handling="continue",
65
+ timeout_seconds=60,
66
+ batch_max_files=200
67
+ )
68
+
69
+ 默认值:
70
+ ValidationSettings(
71
+ auto_validate=True,
72
+ strict_mode=False,
73
+ error_handling="continue",
74
+ timeout_seconds=30,
75
+ batch_max_files=100
76
+ )
77
+ """
78
+
79
+ auto_validate: bool = Field(True, description="是否在连接或配置变更时自动执行校验")
80
+ strict_mode: bool = Field(False, description="是否严格模式,发现任何错误即标记为校验失败")
81
+ error_handling: Literal["stop", "continue", "report"] = Field("continue", description="遇到校验错误时的处理策略")
82
+ timeout_seconds: int = Field(30, ge=1, le=300, description="单次校验的最大执行时间(秒)")
83
+ batch_max_files: int = Field(100, ge=1, le=1000, description="批量校验的最大文件数量")
@@ -0,0 +1,66 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ #
3
+ # Copyright 2026 Precis Team
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ """
17
+ @fileoverview 模板引用类型定义
18
+
19
+ 功能概述:
20
+ - TemplateRef: 模板定义文件的引用(id + path)
21
+ - TemplateInstanceRef: 模板实例的引用(含参数绑定值)
22
+
23
+ 架构设计:
24
+ - 与 SchemaRef / ConstraintRef 等保持一致的结构
25
+ - TemplateInstanceRef 额外包含 template_id 和 params 字段
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ from typing import Any
31
+
32
+ from pydantic import BaseModel, Field
33
+
34
+
35
+ class TemplateRef(BaseModel):
36
+ """@classdesc 模板定义文件引用
37
+
38
+ 字段说明:
39
+ - id: 模板唯一标识(必须与 .template.yaml 文件中的 id 一致)
40
+ - path: 模板文件路径(相对于 manifest 所在目录)
41
+ """
42
+
43
+ id: str
44
+ path: str
45
+
46
+
47
+ class TemplateInstanceRef(BaseModel):
48
+ """@classdesc 模板实例引用
49
+
50
+ 字段说明:
51
+ - id: 实例唯一标识(全局唯一)
52
+ - template_id: 引用的模板 ID
53
+ - enabled: 是否启用
54
+ - params: 参数绑定值(覆盖模板声明的默认值,展开时对 {{param}} 占位符做替换)
55
+ - input_from_node: 实例级上游节点 ID(通常指向 Schema,覆盖节点级 input_from_node)
56
+
57
+ 展开行为:
58
+ 加载时由 expander 将此实例展开为一组 TransformFile / ConstraintFile / RegexNodeFile / ManualDataFile,
59
+ 展开后的节点 ID 格式为 {instance_id}__{local_node_id}。
60
+ """
61
+
62
+ id: str = Field(..., description="实例 ID(全局唯一)")
63
+ template_id: str = Field(..., description="引用的模板 ID")
64
+ enabled: bool = Field(True, description="是否启用")
65
+ params: dict[str, Any] = Field(default_factory=dict, description="参数绑定值")
66
+ input_from_node: str | None = Field(None, description="实例级上游节点 ID(通常指向 Schema)")
@@ -0,0 +1,262 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ #
3
+ # Copyright 2026 Precis Team
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ """
17
+ @fileoverview 项目清单写入模块
18
+
19
+ 功能概述:
20
+ - 将项目清单写入 project.precis.yaml 文件
21
+ - 提供清单的持久化功能
22
+ - 管理清单中各种引用(schema、constraint、regex)
23
+
24
+ 架构设计:
25
+ - 写入职责: 专注于清单文件保存和引用管理
26
+ - 工具函数: 提供 ensure_*_ref 系列函数用于动态添加引用
27
+ - 完整性保证: 写入时自动排除空值字段,确保配置简洁
28
+
29
+ 输入示例:
30
+ manifest = ProjectManifest(
31
+ version=2,
32
+ project=ProjectInfo(id="my-project", name="My Project"),
33
+ schemas=[SchemaRef(id="users", path="schemas/users.schema.yaml")],
34
+ )
35
+
36
+ 输出示例:
37
+ save_manifest(manifest, "project.precis.yaml")
38
+ """
39
+
40
+ from __future__ import annotations
41
+
42
+ from pathlib import Path
43
+
44
+ from app.shared.core.io.yaml import write_yaml_atomic
45
+
46
+ from .types import ConstraintRef, ManualDataRef, ProjectManifest, RegexRef, SchemaRef
47
+
48
+
49
+ def save_manifest(manifest: ProjectManifest, manifest_path: str | Path) -> None:
50
+ """
51
+ @methoddesc 将项目清单保存到 YAML 文件。
52
+
53
+ 本函数将 ProjectManifest 对象序列化为 YAML 格式并写入指定文件。
54
+ 写入时自动排除空值字段(exclude_none=True),生成干净简洁的配置文件。
55
+
56
+ 处理流程:
57
+ 1. 路径标准化:将路径转换为 Path 对象
58
+ 2. 模型序列化:将 Pydantic 模型转换为字典(排除 None 值)
59
+ 3. YAML 写入:调用底层 YAML 工具写入文件
60
+
61
+ 参数说明:
62
+ manifest: 已构建的 ProjectManifest 对象,包含完整的项目配置。
63
+ 建议在保存前确保所有必要字段已正确填充。
64
+ manifest_path: 目标文件路径,支持字符串或 Path 对象。
65
+ 如果父目录不存在,写入前需要确保目录已创建。
66
+
67
+ 返回值:
68
+ 无返回值。函数执行完成后,清单内容已持久化到指定文件。
69
+
70
+ 异常抛出:
71
+ 可能抛出 I/O 相关异常(如权限不足、磁盘空间不足等)。
72
+
73
+ 示例:
74
+ >>> manifest = ProjectManifest(
75
+ ... version=2,
76
+ ... project=ProjectInfo(id="my-project", name="My Project"),
77
+ ... schemas=[SchemaRef(id="users", path="schemas/users.yaml")]
78
+ ... )
79
+ >>> save_manifest(manifest, "./project.precis.yaml")
80
+ >>> # 文件内容已写入
81
+ """
82
+ # 将 Pydantic 模型序列化为字典,exclude_none=True 排除空值字段
83
+ # 这样可以生成干净简洁的 YAML 配置文件
84
+ write_yaml_atomic(Path(manifest_path), manifest.model_dump(exclude_none=True))
85
+
86
+
87
+ def ensure_schema_ref(manifest: ProjectManifest, table_id: str, default_path: str | None = None) -> SchemaRef:
88
+ """
89
+ @methoddesc 确保清单中包含指定 table_id 的 schema 引用。
90
+
91
+ 本函数用于动态向清单添加 schema 引用。如果指定的 schema 引用已存在,
92
+ 直接返回现有引用;如果不存在,则创建新的引用并添加到清单中。
93
+
94
+ 处理流程:
95
+ 1. 查找现有引用:在 manifest.schemas 列表中查找匹配的 ID
96
+ 2. 存在判断:找到则直接返回,找不到则进入步骤 3
97
+ 3. 创建新引用:使用提供的 table_id 和 default_path 构建新引用
98
+ 4. 添加到清单:将新引用追加到 manifest.schemas 列表
99
+ 5. 返回引用:返回找到或创建的 SchemaRef 对象
100
+
101
+ 参数说明:
102
+ manifest: 目标 ProjectManifest 对象,引用将被添加到此清单。
103
+ table_id: Schema 文件对应的表 ID,必须与 schema 文件内部的 id 一致。
104
+ default_path: 当引用不存在时使用的默认路径。
105
+ 默认为 "schemas/{table_id}.schema.yaml"。
106
+
107
+ 返回值:
108
+ SchemaRef: 找到或创建的 schema 引用对象,包含:
109
+ - id: 表 ID
110
+ - path: schema 文件相对路径
111
+
112
+ 示例:
113
+ >>> manifest = ProjectManifest(...)
114
+ >>> # 确保 users schema 引用存在
115
+ >>> ref = ensure_schema_ref(manifest, "users")
116
+ >>> print(ref.path)
117
+ 'schemas/users.schema.yaml'
118
+ """
119
+ # Step 1: 线性查找 - 在现有 schema 引用列表中查找匹配 ID
120
+ # 使用生成器表达式配合 next() 实现高效的首次匹配查找
121
+ ref = next((s for s in manifest.schemas if s.id == table_id), None)
122
+
123
+ # Step 2: 存在则直接返回 - 无需修改清单
124
+ if ref:
125
+ return ref
126
+
127
+ # Step 3: 不存在则创建新引用 - 使用默认路径或自定义路径
128
+ # 默认路径格式: schemas/{table_id}.schema.yaml
129
+ new_ref = SchemaRef(id=table_id, path=default_path or f"schemas/{table_id}.schema.yaml")
130
+
131
+ # Step 4: 添加到清单 - 修改传入的 manifest 对象
132
+ manifest.schemas.append(new_ref)
133
+
134
+ # Step 5: 返回引用 - 供调用方使用
135
+ return new_ref
136
+
137
+
138
+ def ensure_constraint_ref(
139
+ manifest: ProjectManifest, constraint_id: str, default_path: str | None = None
140
+ ) -> ConstraintRef:
141
+ """
142
+ @methoddesc 确保清单中包含指定 constraint_id 的约束引用。
143
+
144
+ 本函数用于动态向清单添加 constraint 引用。如果指定的 constraint 引用已存在,
145
+ 直接返回现有引用;如果不存在,则创建新的引用并添加到清单中。
146
+
147
+ 处理流程:
148
+ 1. 查找现有引用:在 manifest.constraints 列表中查找匹配的 ID
149
+ 2. 存在判断:找到则直接返回,找不到则进入步骤 3
150
+ 3. 创建新引用:使用提供的 constraint_id 和 default_path 构建新引用
151
+ 4. 添加到清单:将新引用追加到 manifest.constraints 列表
152
+ 5. 返回引用:返回找到或创建的 ConstraintRef 对象
153
+
154
+ 参数说明:
155
+ manifest: 目标 ProjectManifest 对象,引用将被添加到此清单。
156
+ constraint_id: Constraint 文件对应的约束 ID,必须与 constraint 文件内部的 id 一致。
157
+ default_path: 当引用不存在时使用的默认路径。
158
+ 默认为 "constraints/{constraint_id}.constraint.yaml"。
159
+
160
+ 返回值:
161
+ ConstraintRef: 找到或创建的 constraint 引用对象,包含:
162
+ - id: 约束 ID
163
+ - path: constraint 文件相对路径
164
+
165
+ 示例:
166
+ >>> manifest = ProjectManifest(...)
167
+ >>> # 确保 email_format constraint 引用存在
168
+ >>> ref = ensure_constraint_ref(manifest, "email_format")
169
+ >>> print(ref.path)
170
+ 'constraints/email_format.constraint.yaml'
171
+ """
172
+ # Step 1: 线性查找 - 在现有 constraint 引用列表中查找匹配 ID
173
+ ref = next((c for c in manifest.constraints if c.id == constraint_id), None)
174
+
175
+ # Step 2: 存在则直接返回
176
+ if ref:
177
+ return ref
178
+
179
+ # Step 3: 不存在则创建新引用 - 使用默认路径或自定义路径
180
+ # 默认路径格式: constraints/{constraint_id}.constraint.yaml
181
+ new_ref = ConstraintRef(id=constraint_id, path=default_path or f"constraints/{constraint_id}.constraint.yaml")
182
+
183
+ # Step 4: 添加到清单
184
+ manifest.constraints.append(new_ref)
185
+
186
+ # Step 5: 返回引用
187
+ return new_ref
188
+
189
+
190
+ def ensure_regex_ref(manifest: ProjectManifest, regex_id: str, default_path: str | None = None) -> RegexRef:
191
+ """
192
+ @methoddesc 确保清单中包含指定 regex_id 的正则节点引用。
193
+
194
+ 本函数用于动态向清单添加 regex 引用。如果指定的 regex 引用已存在,
195
+ 直接返回现有引用;如果不存在,则创建新的引用并添加到清单中。
196
+
197
+ 处理流程:
198
+ 1. 查找现有引用:在 manifest.regex_nodes 列表中查找匹配的 ID
199
+ 2. 存在判断:找到则直接返回,找不到则进入步骤 3
200
+ 3. 创建新引用:使用提供的 regex_id 和 default_path 构建新引用
201
+ 4. 添加到清单:将新引用追加到 manifest.regex_nodes 列表
202
+ 5. 返回引用:返回找到或创建的 RegexRef 对象
203
+
204
+ 参数说明:
205
+ manifest: 目标 ProjectManifest 对象,引用将被添加到此清单。
206
+ regex_id: Regex 节点文件对应的 ID,必须与 regex 文件内部的 id 一致。
207
+ default_path: 当引用不存在时使用的默认路径。
208
+ 默认为 "regex/{regex_id}.regex.yaml"。
209
+
210
+ 返回值:
211
+ RegexRef: 找到或创建的 regex 引用对象,包含:
212
+ - id: 正则节点 ID
213
+ - path: regex 文件相对路径
214
+
215
+ 示例:
216
+ >>> manifest = ProjectManifest(...)
217
+ >>> # 确保 phone_number regex 引用存在
218
+ >>> ref = ensure_regex_ref(manifest, "phone_number")
219
+ >>> print(ref.path)
220
+ 'regex/phone_number.regex.yaml'
221
+ """
222
+ # Step 1: 线性查找 - 在现有 regex 引用列表中查找匹配 ID
223
+ ref = next((r for r in manifest.regex_nodes if r.id == regex_id), None)
224
+
225
+ # Step 2: 存在则直接返回
226
+ if ref:
227
+ return ref
228
+
229
+ # Step 3: 不存在则创建新引用 - 使用默认路径或自定义路径
230
+ # 默认路径格式: regex/{regex_id}.regex.yaml
231
+ new_ref = RegexRef(id=regex_id, path=default_path or f"regex/{regex_id}.regex.yaml")
232
+
233
+ # Step 4: 添加到清单
234
+ manifest.regex_nodes.append(new_ref)
235
+
236
+ # Step 5: 返回引用
237
+ return new_ref
238
+
239
+
240
+ def ensure_manual_data_ref(
241
+ manifest: ProjectManifest, manual_data_id: str, default_path: str | None = None
242
+ ) -> ManualDataRef:
243
+ """@methoddesc 确保清单中包含指定 manual_data_id 的 ManualData 引用。
244
+
245
+ 如果引用已存在则直接返回,否则创建新引用并添加到清单中。
246
+
247
+ 参数:
248
+ manifest: 目标 ProjectManifest 对象
249
+ manual_data_id: ManualData 节点 ID
250
+ default_path: 默认路径(若为 None 则自动生成)
251
+
252
+ 返回:
253
+ 找到或创建的 ManualDataRef 对象
254
+ """
255
+ ref = next((md for md in manifest.manual_data if md.id == manual_data_id), None)
256
+
257
+ if ref:
258
+ return ref
259
+
260
+ new_ref = ManualDataRef(id=manual_data_id, path=default_path or f"manual_data/{manual_data_id}.manual_data.yaml")
261
+ manifest.manual_data.append(new_ref)
262
+ return new_ref
@@ -0,0 +1,27 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ #
3
+ # Copyright 2026 Precis Team
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ """
17
+ @fileoverview ManualData 配置模块
18
+
19
+ 功能概述:
20
+ - 定义 ManualData 节点的数据模型 (ManualDataFile)
21
+ - 用于持久化画布上的内联测试数据节点
22
+
23
+ 架构设计:
24
+ - ManualDataFile 对应 manual_data/*.yaml 配置文件
25
+ - 在 manifest 中通过 ManualDataRef 引用
26
+ - 模板展开时,模板内 manualData 节点展开为 ManualDataFile
27
+ """
@@ -0,0 +1,75 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ #
3
+ # Copyright 2026 Precis Team
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ """
17
+ @fileoverview ManualData 节点配置类型定义
18
+
19
+ 功能概述:
20
+ - 定义 ManualData 节点的数据模型 (ManualDataFile)
21
+ - 支持单列内联数据的持久化
22
+
23
+ 架构设计:
24
+ - ManualDataFile 对应 manual_data/{id}.yaml 配置文件
25
+ - 在 manifest 中通过 ManualDataRef 引用
26
+ - 模板展开时,模板内 manualData 节点展开为 ManualDataFile
27
+
28
+ 输入示例:
29
+ ManualDataFile(
30
+ version=2,
31
+ id="ti1__md1",
32
+ column_name="age",
33
+ column_data_type="integer",
34
+ rows=[["18"], ["25"], ["65"]],
35
+ )
36
+ """
37
+
38
+ from __future__ import annotations
39
+
40
+ from typing import Literal
41
+
42
+ from pydantic import BaseModel, Field
43
+
44
+
45
+ class ManualDataFile(BaseModel):
46
+ """@classdesc ManualData 节点文件内容
47
+
48
+ 用于持久化画布上的内联测试数据节点。
49
+ manualData 是单列数据节点,rows 为二维数组(每行一个字段)。
50
+
51
+ 字段说明:
52
+ - version: 配置版本号(固定为 2)
53
+ - id: 节点 ID(与 manifest ref id 一致)
54
+ - column_name: 列名
55
+ - column_data_type: 列数据类型
56
+ - rows: 二维字符串数组,每行一个字段值
57
+ - enabled: 是否启用
58
+ - description: 描述
59
+ - input_from_node: 上游节点 ID(当从 Schema 列注入数据时设置)
60
+ """
61
+
62
+ version: int = Field(2, description="配置版本号(固定为 2)")
63
+ id: str = Field(..., description="节点 ID(与 manifest ref id 一致)")
64
+ column_name: str = Field("Column1", description="列名")
65
+ column_data_type: Literal["string", "integer", "float", "decimal", "boolean", "date"] = Field(
66
+ "string", description="列数据类型"
67
+ )
68
+ rows: list[list[str]] = Field(default_factory=list, description="二维字符串数组,每行一个字段值")
69
+ enabled: bool = Field(True, description="是否启用")
70
+ description: str | None = Field(None, description="描述")
71
+ input_from_node: str | None = Field(None, description="上游节点 ID(当从 Schema 列注入数据时设置)")
72
+
73
+
74
+ # 兼容别名
75
+ ManualDataFileV2 = ManualDataFile