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,114 @@
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
+ - 定义模板内部节点 (TemplateNode)
21
+ - 定义模板文件根模型 (TemplateFile)
22
+
23
+ 架构设计:
24
+ - TemplateFile 是 *.template.yaml 文件解析后的根 Pydantic 模型
25
+ - 模板内节点 ID 为局部命名空间,展开时映射为全局 ID
26
+ - 模板节点存完整默认值,无参数占位符替换机制
27
+ - 展开后用户直接在画布上编辑内部节点
28
+
29
+ 输入示例:
30
+ TemplateFile(
31
+ id="age_check",
32
+ name="年龄校验",
33
+ nodes=[
34
+ TemplateNode(id="md1", kind="manualData", type="ManualData", column_name="age", rows=[["18"]]),
35
+ TemplateNode(id="check_range", kind="constraint", type="Range", input_from_node="md1", params={"min": 0, "max": 120}),
36
+ ],
37
+ )
38
+ """
39
+
40
+ from __future__ import annotations
41
+
42
+ from typing import Any, Literal
43
+
44
+ from pydantic import BaseModel, Field
45
+
46
+
47
+ class TemplateNode(BaseModel):
48
+ """@classdesc 模板内部 DAG 节点
49
+
50
+ 字段说明:
51
+ - id: 模板内局部 ID(展开时映射为 {instance_id}__{local_id})
52
+ - kind: 节点类型分类(transform/constraint/regex/manualData)
53
+ - type: 具体类型名称(如 StringSplit/Range/NotNull 等);manualData kind 时固定为 "ManualData"
54
+ - input_from_node: 上游节点 ID(仅支持模板内部节点引用)
55
+ - input_column: 输入列名
56
+ - params: 转换/约束参数(完整默认值)
57
+ - output_columns: 输出列名列表
58
+ - refs: 约束引用区
59
+ - enabled: 是否启用
60
+ - description: 描述
61
+ - column_name: manualData 专用 — 列名
62
+ - rows: manualData 专用 — 占位数据(二维字符串数组)
63
+ - column_data_type: manualData 专用 — 列数据类型
64
+ """
65
+
66
+ id: str
67
+ kind: Literal["transform", "constraint", "regex", "manualData"]
68
+ type: str
69
+ input_from_node: str | None = None
70
+ input_column: str | None = None
71
+ params: dict[str, Any] = Field(default_factory=dict)
72
+ output_columns: list[str] = Field(default_factory=list)
73
+ refs: dict[str, Any] = Field(default_factory=dict)
74
+ description: str | None = None
75
+ enabled: bool = True
76
+ # manualData 专用字段
77
+ column_name: str = ""
78
+ rows: list[list[str]] = Field(default_factory=list)
79
+ column_data_type: str = "string"
80
+
81
+
82
+ class TemplateParameter(BaseModel):
83
+ """@classdesc 模板参数声明
84
+
85
+ 字段说明:
86
+ - name: 参数名(对应节点值中的 {{name}} 占位符)
87
+ - default: 参数默认值(实例未提供该参数时使用)
88
+ """
89
+
90
+ name: str
91
+ default: Any = None
92
+
93
+
94
+ class TemplateFile(BaseModel):
95
+ """@classdesc 模板定义文件根模型
96
+
97
+ 对应 *.template.yaml 文件的结构。
98
+ 展开时由 expander 将节点映射为标准的 TransformFile/ConstraintFile/RegexNodeFile/ManualDataFile。
99
+
100
+ 字段说明:
101
+ - version: 配置版本号(固定为 2)
102
+ - id: 模板唯一标识
103
+ - name: 模板显示名称
104
+ - description: 模板描述
105
+ - parameters: 参数声明列表(展开时对节点值中的 {{param}} 占位符做替换)
106
+ - nodes: 内部 DAG 节点列表
107
+ """
108
+
109
+ version: int = Field(2, description="配置版本号(固定为 2)")
110
+ id: str = Field(..., description="模板唯一标识")
111
+ name: str = Field(..., description="模板显示名称")
112
+ description: str | None = Field(None, description="模板描述")
113
+ parameters: list[TemplateParameter] = Field(default_factory=list, description="参数声明列表")
114
+ nodes: list[TemplateNode] = Field(default_factory=list, description="内部 DAG 节点列表")
@@ -0,0 +1,76 @@
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 Transform 配置文件读取模块
18
+
19
+ 功能概述:
20
+ - 读取并解析 .transform.yaml 配置文件
21
+ - 使用 Pydantic 模型进行数据验证
22
+
23
+ 输入示例:
24
+ transform_path = Path("/path/to/project/transforms/split.yaml")
25
+
26
+ # 文件内容:
27
+ # version: 2
28
+ # id: split_name
29
+ # type: StringSplit
30
+ # enabled: true
31
+ # input_column: full_name
32
+ # params:
33
+ # delimiter: " "
34
+ # output_columns: [first_name, last_name]
35
+
36
+ 输出示例:
37
+ TransformFile(
38
+ version=2,
39
+ id="split_name",
40
+ type="StringSplit",
41
+ enabled=True,
42
+ input_column="full_name",
43
+ params={"delimiter": " "},
44
+ output_columns=["first_name", "last_name"]
45
+ )
46
+ """
47
+
48
+ from __future__ import annotations
49
+
50
+ from pathlib import Path
51
+
52
+ import yaml
53
+
54
+ from .types import TransformFile
55
+
56
+
57
+ def load_transform(transform_path: Path) -> TransformFile:
58
+ """@methoddesc 加载 Transform 配置文件
59
+
60
+ 输入示例:
61
+ transform_path = Path("/path/to/project/transforms/split.yaml")
62
+
63
+ 输出示例:
64
+ TransformFile(
65
+ version=2,
66
+ id="split_name",
67
+ type="StringSplit",
68
+ enabled=True,
69
+ input_column="full_name",
70
+ params={"delimiter": " "},
71
+ output_columns=["first_name", "last_name"]
72
+ )
73
+ """
74
+ with open(transform_path, encoding="utf-8") as f:
75
+ raw = yaml.safe_load(f) or {}
76
+ return TransformFile.model_validate(raw)
@@ -0,0 +1,116 @@
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
+ - 定义 Transform 节点的数据模型 (TransformFile)
21
+ - 支持 StringSplit、RegexExtract、MathExpr、DateFormat 等转换类型
22
+ - 使用 Pydantic BaseModel 进行数据验证
23
+
24
+ 架构设计:
25
+ - 统一入口: TransformFile 作为所有功能节点的根模型
26
+ - 类型区分: type 字段标识具体转换逻辑
27
+ - 参数灵活: params 为 Dict,各子类型自行定义内部结构
28
+
29
+ 输入示例:
30
+ TransformFile(
31
+ version=2,
32
+ id="split_id_card",
33
+ type="StringSplit",
34
+ input_from_node="source_users_01",
35
+ input_column="id_card",
36
+ params={
37
+ "strategy": "fixed_position",
38
+ "ranges": [
39
+ {"name": "region_code", "start": 0, "end": 6},
40
+ {"name": "birth_date", "start": 6, "end": 14},
41
+ ]
42
+ },
43
+ output_columns=["region_code", "birth_date"]
44
+ )
45
+ """
46
+
47
+ from __future__ import annotations
48
+
49
+ from typing import Any, Literal
50
+
51
+ from pydantic import BaseModel, Field
52
+
53
+
54
+ class TransformFile(BaseModel):
55
+ """
56
+ @classdesc 单条功能/转换节点文件内容。
57
+
58
+ 支持类型(22 种):
59
+ - 多列输出: StringSplit, RegexExtract
60
+ - 单列输出(行数不变): MathExpr, DateFormat, Lookup, Strip, UpperCase, LowerCase,
61
+ Replace, FillNA, CastType, Concat, Substring, ConditionalAssign,
62
+ Digits, WeightedSum, Modulo, MapValue
63
+ - 行数改变: FilterRows, DropDuplicates, Aggregate, SortRows
64
+ (运行器已在 transforms/registry.py 注册;行位重排对约束错误 row_index
65
+ 语义的影响见 docs/contracts/validate-json-v1.md)
66
+
67
+ 输入接口:
68
+ - input_from_node: 上游节点 ID(优先)
69
+ - input_column: 上游节点中的目标列名
70
+
71
+ 输出接口:
72
+ - output_columns: 转换后产生的列名列表
73
+ """
74
+
75
+ version: int = Field(2, description="配置版本号(固定为 2)")
76
+ id: str = Field(..., description="转换节点 ID(稳定标识)")
77
+ type: Literal[
78
+ "StringSplit",
79
+ "RegexExtract",
80
+ "MathExpr",
81
+ "DateFormat",
82
+ "Lookup",
83
+ "Strip",
84
+ "UpperCase",
85
+ "LowerCase",
86
+ "Replace",
87
+ "FillNA",
88
+ "FilterRows",
89
+ "DropDuplicates",
90
+ "CastType",
91
+ "Concat",
92
+ "Substring",
93
+ "Aggregate",
94
+ "ConditionalAssign",
95
+ "SortRows",
96
+ "Digits",
97
+ "WeightedSum",
98
+ "Modulo",
99
+ "MapValue",
100
+ ] = Field(..., description="转换类型")
101
+ enabled: bool = Field(True, description="是否启用")
102
+ description: str | None = Field(None, description="描述")
103
+
104
+ # 输入接口
105
+ input_from_node: str | None = Field(None, description="上游数据流节点 ID")
106
+ input_column: str | None = Field(None, description="上游节点中的目标列名")
107
+
108
+ # 功能参数(因类型而异,各子类型自行约定结构)
109
+ params: dict[str, Any] = Field(default_factory=dict, description="转换参数(因类型而异)")
110
+
111
+ # 输出定义
112
+ output_columns: list[str] = Field(default_factory=list, description="转换后产生的列名列表")
113
+
114
+
115
+ # 兼容别名
116
+ TransformFileV2 = TransformFile
@@ -0,0 +1,84 @@
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
+ """@fileoverview Transform 节点写入模块
17
+
18
+ 功能概述:
19
+ - 写入 *.transform.yaml 文件
20
+ - 优化字段顺序,提升 YAML 可读性
21
+
22
+ 架构设计:
23
+ - 唯一入口: 封装 Pydantic 模型到 YAML 文件的转换逻辑
24
+ - 字段排序: 按重要程度分组(核心 / 可选 / 内部)
25
+ - 一致性: 与 schema/writer.py、regex/writer.py 保持一致的排序策略
26
+
27
+ 输入示例:
28
+ transform = TransformFile(
29
+ version=2,
30
+ id="cast_price",
31
+ type="CastType",
32
+ input_column="price",
33
+ params={"target_type": "decimal"},
34
+ output_columns=["price"],
35
+ )
36
+
37
+ 输出示例:
38
+ save_transform(transform, "transforms/cast_price.transform.yaml")
39
+ """
40
+
41
+ from __future__ import annotations
42
+
43
+ from pathlib import Path
44
+ from typing import TYPE_CHECKING
45
+
46
+ from app.shared.core.io.yaml import write_yaml_atomic
47
+
48
+ from .types import TransformFile
49
+
50
+ if TYPE_CHECKING:
51
+ from .types import TransformFile
52
+
53
+
54
+ def save_transform(transform: TransformFile, transform_path: str | Path) -> None:
55
+ """
56
+ @methoddesc 保存 Transform 节点到 YAML 文件。
57
+
58
+ 字段顺序优化(按重要程度分组):
59
+ L1(核心):type, description, params, input_from_node, input_column
60
+ L2(可选):enabled, output_columns
61
+ L3(内部):version, id
62
+
63
+ :param transform: TransformFile 对象,包含转换节点的完整配置
64
+ :param transform_path: 保存路径,可以是相对路径或绝对路径
65
+ :raises IOError: 文件写入失败时抛出
66
+ """
67
+ data = transform.model_dump()
68
+
69
+ ordered = {
70
+ # L1 - 核心字段
71
+ "type": data["type"],
72
+ "description": data.get("description"),
73
+ "input_from_node": data.get("input_from_node"),
74
+ "input_column": data.get("input_column"),
75
+ "params": data.get("params", {}),
76
+ # L2 - 可选配置
77
+ "enabled": data.get("enabled", True),
78
+ "output_columns": data.get("output_columns", []),
79
+ # L3 - 内部字段
80
+ "version": data["version"],
81
+ "id": data["id"],
82
+ }
83
+
84
+ write_yaml_atomic(Path(transform_path), ordered)
@@ -0,0 +1,59 @@
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 Pydantic 校验消息的中文本地化(单一事实源)
18
+
19
+ Pydantic 的校验消息默认是英文("Input should be a valid integer" 等),
20
+ 直接透给用户属于黑话。本模块提供常见消息的中文映射(子串替换,保留
21
+ 位置与字段等上下文),供 422 全局 handler 与 LLM 动作 spec 校验共用。
22
+ 未命中的消息保留原文,不会显示空白。
23
+ """
24
+
25
+ from __future__ import annotations
26
+
27
+ # 英文片段 → 中文(按出现顺序做子串替换)
28
+ _PATTERNS: list[tuple[str, str]] = [
29
+ ("Input should be a valid integer", "应为整数"),
30
+ ("Input should be a valid number", "应为数字"),
31
+ ("Input should be a valid string", "应为文本"),
32
+ ("Input should be a valid boolean", "应为 true/false"),
33
+ ("Input should be a valid dictionary", "应为对象"),
34
+ ("Input should be a valid list", "应为列表"),
35
+ ("Input should be a valid date", "应为日期"),
36
+ ("Input should be a valid email address", "应为有效的邮箱地址"),
37
+ ("Input should be a valid URL", "应为有效的 URL"),
38
+ ("Field required", "缺少必填字段"),
39
+ ("Extra inputs are not permitted", "存在不允许的多余字段"),
40
+ ("Input should be greater than or equal to", "不能小于"),
41
+ ("Input should be less than or equal to", "不能大于"),
42
+ ("String should have at least 1 character", "内容不能为空"),
43
+ ("Input should be a valid enumeration value", "取值不在允许范围内"),
44
+ ("Unable to extract tag using discriminator", "数据结构与预期的不一致"),
45
+ ]
46
+
47
+
48
+ def localize_pydantic_msg(msg: str) -> str:
49
+ """将一条 Pydantic 校验消息中的常见英文片段替换为中文。
50
+
51
+ Args:
52
+ msg: Pydantic 的 msg 字段原文
53
+
54
+ Returns:
55
+ 本地化后的消息(未命中的片段保持原文)
56
+ """
57
+ for en, zh in _PATTERNS:
58
+ msg = msg.replace(en, zh)
59
+ return msg
@@ -0,0 +1,46 @@
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
+ - 通过 ReportService 统一管理和调度所有报告器
23
+
24
+ 架构设计:
25
+ - 策略模式 (Strategy Pattern): 各报告器继承自 Reporter 抽象基类,实现统一的 configure() 和 report() 接口
26
+ - 注册表模式: ReportService 维护报告者注册表,根据配置动态激活对应的报告器
27
+ - 统一入口: 外部通过 ReportService 调用,无需关心底层具体报告器的实现细节
28
+
29
+ 输入示例:
30
+ 通过 ReportService 传入错误列表:
31
+ errors = [
32
+ {
33
+ "error_type": "TypeValidationError",
34
+ "row_index": 2,
35
+ "column": "age",
36
+ "value": "abc",
37
+ "error_message": "必须是整数"
38
+ }
39
+ ]
40
+
41
+ 输出示例:
42
+ 各报告器将错误信息发送到对应渠道:
43
+ - 本地文件: 生成 JSON 日志文件到 logs/error_report_20240115_143052.json
44
+ - 邮件: 发送 HTML 格式邮件到指定收件箱
45
+ - 企业微信/飞书/钉钉: 推送 Markdown/卡片消息到对应应用
46
+ """