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,165 @@
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
+ - 定义 Schema 文件中的内嵌约束 (ConstraintItem)
21
+ - 支持多种约束类型: NotNull, Unique, AllowedValues, ForeignKey 等
22
+
23
+ 架构设计:
24
+ - 统一模型: 所有约束类型使用同一个模型
25
+ - 字段可选: 根据约束类型不同,需要填写不同字段
26
+ - 简化写法: 支持 column 简写和 columns 列表
27
+
28
+ 输入示例 (schema.yaml):
29
+ constraints:
30
+ # 非空约束 (简化写法)
31
+ - id: not_null_email
32
+ type: NotNull
33
+ column: email
34
+
35
+ # 允许值约束
36
+ - id: status_allowed
37
+ type: AllowedValues
38
+ column: status
39
+ params:
40
+ allowed_values:
41
+ - active
42
+ - inactive
43
+ - pending
44
+
45
+ # 外键约束
46
+ - id: fk_orders
47
+ type: ForeignKey
48
+ from_column: user_id
49
+ to_table: users
50
+ to_column: id
51
+
52
+ 输出示例:
53
+ ConstraintItem(
54
+ id="not_null_email",
55
+ type="NotNull",
56
+ enabled=True,
57
+ column="email"
58
+ )
59
+ """
60
+
61
+ from __future__ import annotations
62
+
63
+ from typing import Any, Literal
64
+
65
+ from pydantic import BaseModel, Field, model_validator
66
+
67
+
68
+ class ConstraintItem(BaseModel):
69
+ """@classdesc 内嵌约束项
70
+
71
+ 在 Schema 文件中直接定义的约束。
72
+
73
+ 字段说明:
74
+ - id: 约束 ID (表内唯一)
75
+ - type: 约束类型
76
+ - NotNull: 非空约束
77
+ - Unique: 唯一性约束
78
+ - AllowedValues: 允许值约束
79
+ - ForeignKey: 外键约束
80
+ - Conditional: 条件约束
81
+ - Scripted: 脚本约束
82
+ - Range: 范围约束
83
+ - Charset: 字符集约束
84
+ - DateLogic: 日期逻辑约束
85
+ - enabled: 是否启用
86
+ - description: 约束描述 (可选)
87
+
88
+ # 列级约束 (二选一)
89
+ - column: 目标列名 (单列)
90
+ - columns: 目标列名列表 (多列,如联合唯一键)
91
+
92
+ # 外键约束 (仅 ForeignKey 类型)
93
+ - from_table: 源表名
94
+ - from_column: 源列名
95
+ - to_table: 目标表名
96
+ - to_column: 目标列名
97
+
98
+ # 通用参数
99
+ - params: 约束参数 (如 AllowedValues 的 allowed_values 列表)
100
+
101
+ 输入示例 (schema.yaml):
102
+ constraints:
103
+ # 非空约束 (简化写法)
104
+ - id: not_null_email
105
+ type: NotNull
106
+ column: email
107
+
108
+ # 允许值约束
109
+ - id: status_allowed
110
+ type: AllowedValues
111
+ column: status
112
+ params:
113
+ allowed_values:
114
+ - active
115
+ - inactive
116
+ - pending
117
+
118
+ # 外键约束
119
+ - id: fk_orders
120
+ type: ForeignKey
121
+ from_column: user_id
122
+ to_table: users
123
+ to_column: id
124
+
125
+ 输出示例:
126
+ ConstraintItem(
127
+ id="not_null_email",
128
+ type="NotNull",
129
+ enabled=True,
130
+ column="email"
131
+ )
132
+ """
133
+
134
+ id: str = Field(..., description="约束 ID(同一表内必须唯一)")
135
+ type: Literal[
136
+ "NotNull",
137
+ "Unique",
138
+ "AllowedValues",
139
+ "ForeignKey",
140
+ "Conditional",
141
+ "Scripted",
142
+ "Range",
143
+ "Charset",
144
+ "DateLogic",
145
+ "Composite",
146
+ ] = Field(..., description="约束类型")
147
+ enabled: bool = Field(True, description="是否启用")
148
+ description: str | None = Field(None, description="约束描述")
149
+
150
+ column: str | None = Field(None, description="目标列名(简化写法)")
151
+ columns: list[str] | None = Field(None, description="目标列名列表(多列约束)")
152
+
153
+ from_table: str | None = Field(None, description="外键源表名")
154
+ from_column: str | None = Field(None, description="外键源列名")
155
+ to_table: str | None = Field(None, description="外键目标表名")
156
+ to_column: str | None = Field(None, description="外键目标列名")
157
+
158
+ params: dict[str, Any] = Field(default_factory=dict, description="约束参数(如 allowed_values 等)")
159
+
160
+ @model_validator(mode="after")
161
+ def _validate_column_exclusivity(self) -> ConstraintItem:
162
+ """B20 修复:column 与 columns 互斥,同时填写会引发歧义。"""
163
+ if self.column is not None and self.columns is not None:
164
+ raise ValueError("column 与 columns 不可同时设置,请仅使用其一")
165
+ return self
@@ -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
+ """@fileoverview Schema ID 工具模块
17
+
18
+ 功能概述:
19
+ - 提供 Schema source 标准化函数,用于唯一性检测
20
+ - 旧版路径派生 ID 逻辑已移除,Schema ID 现在由人/AI 显式命名
21
+
22
+ 设计原则:
23
+ - Schema ID 不再从路径派生,而是由用户或 AI 显式提供
24
+ - 唯一性通过两层保证:ID 不重名 + (source.path, source.sheet) 不重复
25
+ - source 标准化逻辑集中在此处,前后端共用
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+
31
+ def normalize_source_key(path: str, sheet: str | None) -> tuple[str, str | None]:
32
+ """标准化 source 的 (path, sheet) 元组,用于唯一性检测和索引
33
+
34
+ 处理流程:
35
+ 1. 路径:反斜杠 → 正斜杠、去 ./ 前缀、pathlib 规范化、转小写
36
+ 2. sheet:strip + 转小写;空字符串/None 统一为 None
37
+
38
+ 参数:
39
+ path: 数据文件路径(相对或绝对)
40
+ sheet: Excel 工作表名(非 Excel 文件传 None)
41
+
42
+ 返回:
43
+ 标准化的 (path, sheet) 元组
44
+
45
+ 示例:
46
+ >>> normalize_source_key("data\\\\users.xlsx", "Sheet1")
47
+ ('data/users.xlsx', 'sheet1')
48
+ >>> normalize_source_key("./data/users.csv", None)
49
+ ('data/users.csv', None)
50
+ >>> normalize_source_key("data/users.xlsx", "")
51
+ ('data/users.xlsx', None)
52
+ """
53
+ from pathlib import PurePosixPath
54
+
55
+ p = str(path or "").replace("\\", "/").strip()
56
+ if p.startswith("./"):
57
+ p = p[2:]
58
+ p = str(PurePosixPath(p))
59
+ if p.startswith("./"):
60
+ p = p[2:]
61
+ p = p.lower()
62
+
63
+ s: str | None = (sheet or "").strip().lower()
64
+ s = s or None
65
+
66
+ return (p, s)
@@ -0,0 +1,255 @@
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
+ - 定义 Schema 中的数据源结构 (SourceSpec)
21
+ - 指定数据文件的路径和工作表信息
22
+ - 支持多种数据源格式:Excel、CSV、JSON 等
23
+ - 格式选项通过 FormatOptions 联合类型实现
24
+
25
+ 架构设计:
26
+ - 路径模式: 支持相对路径和绝对路径
27
+ - Excel 支持: 可指定工作表名和表头行
28
+ - 格式选项: 通过 FormatOptions 联合类型支持不同格式的特定配置
29
+
30
+ 输入示例 (schema.yaml):
31
+ # Excel 数据源
32
+ source:
33
+ mode: relative_file
34
+ path: data/users.xlsx
35
+ sheet: Sheet1
36
+ header_row: 0
37
+
38
+ # JSON 数据源
39
+ source:
40
+ mode: relative_file
41
+ path: data/users.json
42
+ options:
43
+ format: auto
44
+
45
+ # 嵌套 JSON 数据源
46
+ source:
47
+ mode: relative_file
48
+ path: data/api_response.json
49
+ options:
50
+ format: object
51
+ json_path: "$.data.items"
52
+ sep: "."
53
+
54
+ # CSV 数据源
55
+ source:
56
+ mode: relative_file
57
+ path: data/users.csv
58
+ options:
59
+ delimiter: ","
60
+ encoding: utf-8
61
+
62
+ 输出示例:
63
+ SourceSpec(
64
+ mode="relative_file",
65
+ path="data/users.xlsx",
66
+ sheet="Sheet1",
67
+ header_row=0,
68
+ options=ExcelOptions()
69
+ )
70
+
71
+ 原理说明:
72
+ 为什么需要 mode 字段?
73
+ - relative_file: 便于项目迁移,路径相对于项目根目录
74
+ - absolute_file: 用于共享数据源,多个项目共享同一文件
75
+
76
+ 为什么需要 options 字段?
77
+ - 将格式特定配置分离到独立的对象中
78
+ - 提高类型安全性,避免 JSON 配置污染 CSV/Excel schema
79
+ - 便于扩展新格式的支持
80
+ """
81
+
82
+ from __future__ import annotations
83
+
84
+ from typing import Any, Literal
85
+
86
+ from pydantic import BaseModel, Field, field_validator
87
+
88
+ from app.shared.core.utils.path_utils import normalize_to_posix
89
+
90
+ from .source_options import (
91
+ FormatOptions,
92
+ )
93
+
94
+
95
+ class SourceSpec(BaseModel):
96
+ """@classdesc 数据源规范
97
+
98
+ 指定 Schema 对应的数据文件位置。
99
+
100
+ 字段说明:
101
+ - mode: 路径模式
102
+ - relative_file: 相对于项目根目录
103
+ - absolute_file: 绝对路径
104
+ - path: 文件路径
105
+ - sheet: Excel 工作表名 (可选,仅 Excel 文件需要)
106
+ - header_row: 表头行索引 (默认 0,即第一行)
107
+ - options: 格式特定配置(JSONOptions/CSVOptions/ExcelOptions)
108
+
109
+ 输入示例 (schema.yaml):
110
+ # Excel 数据源
111
+ source:
112
+ mode: relative_file
113
+ path: data/users.xlsx
114
+ sheet: Sheet1
115
+ header_row: 0
116
+
117
+ # JSON 数据源
118
+ source:
119
+ mode: relative_file
120
+ path: data/users.json
121
+ options:
122
+ format: auto
123
+
124
+ # 嵌套 JSON 数据源
125
+ source:
126
+ mode: relative_file
127
+ path: data/api_response.json
128
+ options:
129
+ format: object
130
+ json_path: "$.data.items"
131
+ sep: "."
132
+
133
+ # CSV 数据源
134
+ source:
135
+ mode: relative_file
136
+ path: data/users.csv
137
+ options:
138
+ delimiter: ","
139
+ encoding: utf-8
140
+
141
+ 输出示例:
142
+ SourceSpec(
143
+ mode="relative_file",
144
+ path="data/users.xlsx",
145
+ sheet="Sheet1",
146
+ header_row=0,
147
+ options=ExcelOptions()
148
+ )
149
+ """
150
+
151
+ mode: Literal["relative_file", "absolute_file"] = Field(..., description="数据源模式")
152
+ path: str = Field(..., description="文件路径(相对/绝对取决于 mode)")
153
+ sheet: str | None = Field(None, description="Excel 工作表名称")
154
+ header_row: int = Field(0, ge=0, description="表头行索引(与 pandas header 语义一致)")
155
+
156
+ options: FormatOptions | None = Field(None, description="格式特定配置(JSONOptions/CSVOptions/ExcelOptions)")
157
+
158
+ @field_validator("path")
159
+ @classmethod
160
+ def normalize_path(cls, v: str) -> str:
161
+ r"""
162
+ @methoddesc 标准化路径,将反斜杠转换为正斜杠
163
+
164
+ 不同操作系统使用不同的路径分隔符:
165
+ - Windows 使用反斜杠(\)
166
+ - Linux/macOS 使用正斜杠(/)
167
+
168
+ 为了保证跨平台一致性,统一将反斜杠替换为正斜杠。
169
+
170
+ 参数说明:
171
+ :param v: 原始路径字符串
172
+ :return: 标准化后的路径字符串
173
+
174
+ 示例:
175
+ >>> normalize_path(r"data\myfile.xlsx")
176
+ 'data/myfile.xlsx'
177
+ """
178
+ return normalize_to_posix(v)
179
+
180
+ def is_json(self) -> bool:
181
+ """@methoddesc 判断数据源是否为 JSON 格式
182
+
183
+ 通过检查文件路径的后缀名来判断是否为 JSON 文件。
184
+ 支持的 JSON 扩展名包括:.json、.jsonl(JSON Lines)、.ndjson(Newline Delimited JSON)
185
+
186
+ 返回:
187
+ True 表示是 JSON 格式,False 表示不是
188
+
189
+ 示例:
190
+ >>> spec = SourceSpec(mode="relative_file", path="data/users.json")
191
+ >>> spec.is_json()
192
+ True
193
+ >>> spec = SourceSpec(mode="relative_file", path="data/users.csv")
194
+ >>> spec.is_json()
195
+ False
196
+ """
197
+ return self.path.lower().endswith((".json", ".jsonl", ".ndjson"))
198
+
199
+ def get_file_extension(self) -> str:
200
+ """@methoddesc 获取文件扩展名(小写)
201
+
202
+ 从文件路径中提取扩展名部分,用于判断文件格式。
203
+
204
+ 返回:
205
+ 小写的文件扩展名(不含点号),如果路径中没有扩展名则返回空字符串
206
+
207
+ 示例:
208
+ >>> spec = SourceSpec(mode="relative_file", path="data/users.xlsx")
209
+ >>> spec.get_file_extension()
210
+ 'xlsx'
211
+ >>> spec = SourceSpec(mode="relative_file", path="data/users")
212
+ >>> spec.get_file_extension()
213
+ ''
214
+ """
215
+ return self.path.split(".")[-1].lower() if "." in self.path else ""
216
+
217
+ def to_loader_config(self) -> dict[str, Any]:
218
+ """@methoddesc 转换为数据加载器配置字典
219
+
220
+ 将 SourceSpec 对象转换为底层数据加载器可识别的配置字典。
221
+ 加载器使用这些参数来读取和解析数据文件。
222
+
223
+ 处理流程:
224
+ 1. 构建基础配置(路径、模式、编码、表头行)
225
+ 2. 如果存在格式特定选项(options),将其配置合并到基础配置中
226
+ 3. 返回完整的加载器配置字典
227
+
228
+ 返回:
229
+ 加载器配置字典,包含以下键:
230
+ - path: 文件路径
231
+ - mode: 路径模式("relative" 或 "absolute")
232
+ - encoding: 文件编码
233
+ - header_row: 表头行索引
234
+ - 以及 format options 中的其他配置项
235
+
236
+ 示例:
237
+ >>> spec = SourceSpec(mode="relative_file", path="data/users.csv")
238
+ >>> spec.to_loader_config()
239
+ {'path': 'data/users.csv', 'mode': 'relative', 'encoding': 'utf-8', 'header_row': 0}
240
+ """
241
+ # 构建基础配置字典
242
+ config = {
243
+ "path": self.path,
244
+ # 将 mode 转换为加载器使用的格式
245
+ "mode": "relative" if self.mode == "relative_file" else "absolute",
246
+ "encoding": "utf-8",
247
+ "header_row": self.header_row,
248
+ }
249
+
250
+ # 如果存在格式特定选项,合并到配置中
251
+ # 例如 CSVOptions 会添加 delimiter、quotechar 等配置
252
+ if self.options:
253
+ config.update(self.options.to_loader_config())
254
+
255
+ return config