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.
- app/__init__.py +16 -0
- app/api/__init__.py +32 -0
- app/api/dependencies.py +185 -0
- app/api/main.py +301 -0
- app/api/middleware/__init__.py +34 -0
- app/api/middleware/exception_handler.py +126 -0
- app/api/middleware/request_logging.py +97 -0
- app/api/middleware/token_auth.py +215 -0
- app/api/models/__init__.py +151 -0
- app/api/models/connection_rules.py +98 -0
- app/api/models/files.py +99 -0
- app/api/models/full_validation.py +554 -0
- app/api/models/project.py +117 -0
- app/api/models/projects.py +80 -0
- app/api/models/schema.py +121 -0
- app/api/models/v2_responses.py +46 -0
- app/api/models/validation.py +303 -0
- app/api/models/workspace.py +118 -0
- app/api/routers/__init__.py +56 -0
- app/api/routers/ai/__init__.py +36 -0
- app/api/routers/ai/chat.py +243 -0
- app/api/routers/ai/generate.py +156 -0
- app/api/routers/ai/hardware.py +199 -0
- app/api/routers/ai/jobs.py +544 -0
- app/api/routers/ai/migrate.py +471 -0
- app/api/routers/ai/models.py +352 -0
- app/api/routers/ai/ollama.py +108 -0
- app/api/routers/ai/providers.py +491 -0
- app/api/routers/ai/router.py +44 -0
- app/api/routers/ai/stream.py +281 -0
- app/api/routers/ai/utils.py +182 -0
- app/api/routers/core/__init__.py +34 -0
- app/api/routers/core/connection_rules.py +188 -0
- app/api/routers/core/data_sources.py +374 -0
- app/api/routers/core/regex.py +333 -0
- app/api/routers/core/reporting.py +263 -0
- app/api/routers/files/__init__.py +24 -0
- app/api/routers/files/ops.py +179 -0
- app/api/routers/files/transfer.py +101 -0
- app/api/routers/preview/__init__.py +35 -0
- app/api/routers/preview/content_mode.py +264 -0
- app/api/routers/preview/header_row.py +154 -0
- app/api/routers/preview/models.py +81 -0
- app/api/routers/preview/path_mode.py +440 -0
- app/api/routers/preview/router.py +30 -0
- app/api/routers/project/__init__.py +61 -0
- app/api/routers/project/base.py +111 -0
- app/api/routers/project/constraint.py +345 -0
- app/api/routers/project/full_config.py +411 -0
- app/api/routers/project/full_config_writer.py +327 -0
- app/api/routers/project/helpers.py +167 -0
- app/api/routers/project/inspection_fix.py +330 -0
- app/api/routers/project/manifest.py +605 -0
- app/api/routers/project/models.py +177 -0
- app/api/routers/project/pattern.py +268 -0
- app/api/routers/project/regex.py +358 -0
- app/api/routers/project/scanner.py +157 -0
- app/api/routers/project/schema.py +567 -0
- app/api/routers/project/schema_helpers.py +149 -0
- app/api/routers/project/settings.py +399 -0
- app/api/routers/project/template.py +325 -0
- app/api/routers/project/validation.py +227 -0
- app/api/routers/project/view.py +177 -0
- app/api/routers/project/workspaces.py +167 -0
- app/api/routers/projects/__init__.py +25 -0
- app/api/routers/projects/create.py +121 -0
- app/api/routers/projects/open.py +103 -0
- app/api/routers/projects/scan.py +100 -0
- app/api/routers/validation/__init__.py +39 -0
- app/api/routers/validation/common.py +263 -0
- app/api/routers/validation/content_mode.py +401 -0
- app/api/routers/validation/history.py +235 -0
- app/api/routers/validation/inline_mode.py +196 -0
- app/api/routers/validation/path_mode.py +314 -0
- app/api/routers/validation/router.py +51 -0
- app/api/services/full_validation_response_builder.py +412 -0
- app/api/services/io_error_messages.py +41 -0
- app/api/services/preview_service.py +248 -0
- app/cli/__init__.py +18 -0
- app/cli/__main__.py +30 -0
- app/cli/shared_services/__init__.py +42 -0
- app/cli/shared_services/config_ops.py +581 -0
- app/cli/shared_services/generation_ops.py +160 -0
- app/cli/shared_services/project_ops.py +288 -0
- app/cli/shell/__init__.py +48 -0
- app/cli/shell/commands/__init__.py +63 -0
- app/cli/shell/commands/ai/__init__.py +260 -0
- app/cli/shell/commands/ai/chat.py +331 -0
- app/cli/shell/commands/ai/delete.py +165 -0
- app/cli/shell/commands/ai/diff.py +70 -0
- app/cli/shell/commands/ai/display.py +428 -0
- app/cli/shell/commands/ai/executor.py +225 -0
- app/cli/shell/commands/ai/executor_utils.py +271 -0
- app/cli/shell/commands/ai/generate.py +285 -0
- app/cli/shell/commands/ai/interaction.py +262 -0
- app/cli/shell/commands/ai/migrate.py +281 -0
- app/cli/shell/commands/ai/resolver.py +224 -0
- app/cli/shell/commands/ai/status.py +101 -0
- app/cli/shell/commands/ai/switch.py +158 -0
- app/cli/shell/commands/ai/utils.py +52 -0
- app/cli/shell/commands/base.py +343 -0
- app/cli/shell/commands/config/__init__.py +131 -0
- app/cli/shell/commands/config/base.py +80 -0
- app/cli/shell/commands/config/check.py +246 -0
- app/cli/shell/commands/config/edit.py +148 -0
- app/cli/shell/commands/config/get.py +111 -0
- app/cli/shell/commands/config/init.py +123 -0
- app/cli/shell/commands/config/inspect.py +164 -0
- app/cli/shell/commands/config/list.py +104 -0
- app/cli/shell/commands/config/set.py +119 -0
- app/cli/shell/commands/config/show.py +150 -0
- app/cli/shell/commands/exit.py +67 -0
- app/cli/shell/commands/help.py +104 -0
- app/cli/shell/commands/infer_schema.py +156 -0
- app/cli/shell/commands/open.py +201 -0
- app/cli/shell/commands/project.py +215 -0
- app/cli/shell/commands/provider.py +619 -0
- app/cli/shell/commands/system.py +170 -0
- app/cli/shell/commands/validate.py +455 -0
- app/cli/shell/completer.py +231 -0
- app/cli/shell/config_storage.py +191 -0
- app/cli/shell/exceptions.py +90 -0
- app/cli/shell/formatter.py +371 -0
- app/cli/shell/interactive_menu.py +348 -0
- app/cli/shell/main.py +286 -0
- app/cli/shell/parser.py +266 -0
- app/cli/start.py +180 -0
- app/cli_main.py +52 -0
- app/mcp_server.py +311 -0
- app/shared/core/__init__.py +18 -0
- app/shared/core/app_version.py +59 -0
- app/shared/core/config/__init__.py +119 -0
- app/shared/core/config/server.py +193 -0
- app/shared/core/data_source/__init__.py +106 -0
- app/shared/core/data_source/loader.py +348 -0
- app/shared/core/data_source/loaders/__init__.py +213 -0
- app/shared/core/data_source/loaders/base.py +215 -0
- app/shared/core/data_source/loaders/converter.py +337 -0
- app/shared/core/data_source/loaders/csv_loader.py +252 -0
- app/shared/core/data_source/loaders/excel_loader.py +666 -0
- app/shared/core/data_source/loaders/extractor.py +268 -0
- app/shared/core/data_source/loaders/json_loader.py +354 -0
- app/shared/core/data_source/loaders/registry.py +88 -0
- app/shared/core/data_source/loaders/sql_loader.py +313 -0
- app/shared/core/data_source/loaders/strategies/__init__.py +100 -0
- app/shared/core/data_source/loaders/strategies/array_parser.py +277 -0
- app/shared/core/data_source/loaders/strategies/lines_parser.py +355 -0
- app/shared/core/data_source/loaders/strategies/object_parser.py +278 -0
- app/shared/core/data_source/schema_info.py +50 -0
- app/shared/core/data_source/specs/__init__.py +128 -0
- app/shared/core/data_source/specs/base.py +258 -0
- app/shared/core/data_source/specs/csv_source.py +137 -0
- app/shared/core/data_source/specs/excel_source.py +141 -0
- app/shared/core/data_source/specs/file_base.py +252 -0
- app/shared/core/data_source/specs/json_source.py +226 -0
- app/shared/core/data_source/specs/sql_source.py +161 -0
- app/shared/core/encoding.py +36 -0
- app/shared/core/io/__init__.py +24 -0
- app/shared/core/io/yaml.py +379 -0
- app/shared/core/manifest_schema/__init__.py +52 -0
- app/shared/core/manifest_schema/types.py +99 -0
- app/shared/core/manifest_schema/version.py +175 -0
- app/shared/core/patterns/__init__.py +24 -0
- app/shared/core/patterns/loader.py +134 -0
- app/shared/core/patterns/writer.py +244 -0
- app/shared/core/project/__init__.py +47 -0
- app/shared/core/project/constraint/builders/__init__.py +50 -0
- app/shared/core/project/constraint/builders/base.py +100 -0
- app/shared/core/project/constraint/builders/composite.py +77 -0
- app/shared/core/project/constraint/builders/conditional.py +67 -0
- app/shared/core/project/constraint/builders/foreign_key.py +53 -0
- app/shared/core/project/constraint/builders/registry.py +64 -0
- app/shared/core/project/constraint/builders/scripted.py +51 -0
- app/shared/core/project/constraint/builders/single_column.py +86 -0
- app/shared/core/project/constraint/builders/unique.py +53 -0
- app/shared/core/project/constraint/factory.py +170 -0
- app/shared/core/project/constraint/reader.py +214 -0
- app/shared/core/project/constraint/registry.py +233 -0
- app/shared/core/project/constraint/types/__init__.py +63 -0
- app/shared/core/project/constraint/types/constraint_file.py +261 -0
- app/shared/core/project/constraint/types/refs.py +460 -0
- app/shared/core/project/constraint/types.py +28 -0
- app/shared/core/project/constraint/writer.py +181 -0
- app/shared/core/project/loader/__init__.py +56 -0
- app/shared/core/project/loader/loader.py +30 -0
- app/shared/core/project/loader/loader_parts/config_inspector.py +137 -0
- app/shared/core/project/loader/loader_parts/embedded_constraints.py +224 -0
- app/shared/core/project/loader/loader_parts/file_loaders.py +58 -0
- app/shared/core/project/loader/loader_parts/inspection_ids.py +85 -0
- app/shared/core/project/loader/loader_parts/inspector_helpers.py +312 -0
- app/shared/core/project/loader/loader_parts/inspector_id_checks.py +274 -0
- app/shared/core/project/loader/loader_parts/inspector_reference_checks.py +690 -0
- app/shared/core/project/loader/loader_parts/inspector_uniqueness_checks.py +286 -0
- app/shared/core/project/loader/loader_parts/loading_error_messages.py +298 -0
- app/shared/core/project/loader/loader_parts/main.py +432 -0
- app/shared/core/project/loader/loader_parts/path_validation.py +117 -0
- app/shared/core/project/loader/loader_parts/runtime.py +125 -0
- app/shared/core/project/loader/types.py +246 -0
- app/shared/core/project/manifest/coverage.py +391 -0
- app/shared/core/project/manifest/reader.py +260 -0
- app/shared/core/project/manifest/types.py +91 -0
- app/shared/core/project/manifest/types_parts/__init__.py +60 -0
- app/shared/core/project/manifest/types_parts/constants.py +40 -0
- app/shared/core/project/manifest/types_parts/data_source.py +68 -0
- app/shared/core/project/manifest/types_parts/info.py +59 -0
- app/shared/core/project/manifest/types_parts/manifest.py +294 -0
- app/shared/core/project/manifest/types_parts/refs.py +153 -0
- app/shared/core/project/manifest/types_parts/settings.py +92 -0
- app/shared/core/project/manifest/types_parts/settings_file_processing.py +64 -0
- app/shared/core/project/manifest/types_parts/settings_script_security.py +78 -0
- app/shared/core/project/manifest/types_parts/settings_validation.py +83 -0
- app/shared/core/project/manifest/types_parts/template.py +66 -0
- app/shared/core/project/manifest/writer.py +262 -0
- app/shared/core/project/manual_data/__init__.py +27 -0
- app/shared/core/project/manual_data/types.py +75 -0
- app/shared/core/project/regex/reader.py +197 -0
- app/shared/core/project/regex/types.py +405 -0
- app/shared/core/project/regex/writer.py +123 -0
- app/shared/core/project/schema/reader.py +170 -0
- app/shared/core/project/schema/types.py +47 -0
- app/shared/core/project/schema/types_parts/__init__.py +36 -0
- app/shared/core/project/schema/types_parts/column.py +174 -0
- app/shared/core/project/schema/types_parts/column_utils.py +72 -0
- app/shared/core/project/schema/types_parts/constraint.py +165 -0
- app/shared/core/project/schema/types_parts/schema_id.py +66 -0
- app/shared/core/project/schema/types_parts/source.py +255 -0
- app/shared/core/project/schema/types_parts/source_options.py +347 -0
- app/shared/core/project/schema/types_parts/table.py +230 -0
- app/shared/core/project/schema/writer.py +139 -0
- app/shared/core/project/schema_ref_check.py +95 -0
- app/shared/core/project/template/__init__.py +27 -0
- app/shared/core/project/template/expander.py +263 -0
- app/shared/core/project/template/reader.py +120 -0
- app/shared/core/project/template/types.py +114 -0
- app/shared/core/project/transform/reader.py +76 -0
- app/shared/core/project/transform/types.py +116 -0
- app/shared/core/project/transform/writer.py +84 -0
- app/shared/core/pydantic_messages.py +59 -0
- app/shared/core/reporter/__init__.py +46 -0
- app/shared/core/reporter/reporter.py +220 -0
- app/shared/core/reporter/reporters/__init__.py +65 -0
- app/shared/core/reporter/reporters/base.py +188 -0
- app/shared/core/reporter/reporters/dingtalk_app_reporter.py +274 -0
- app/shared/core/reporter/reporters/email_reporter.py +271 -0
- app/shared/core/reporter/reporters/feishu_app_reporter.py +467 -0
- app/shared/core/reporter/reporters/local_file_reporter.py +208 -0
- app/shared/core/reporter/reporters/wecom_app_reporter.py +268 -0
- app/shared/core/utils/__init__.py +18 -0
- app/shared/core/utils/path_utils.py +60 -0
- app/shared/core/utils/regex_extract.py +113 -0
- app/shared/domain/__init__.py +114 -0
- app/shared/domain/constraints/__init__.py +76 -0
- app/shared/domain/constraints/allowed_values.py +211 -0
- app/shared/domain/constraints/base.py +141 -0
- app/shared/domain/constraints/charset.py +337 -0
- app/shared/domain/constraints/composite.py +174 -0
- app/shared/domain/constraints/condition_registry.py +130 -0
- app/shared/domain/constraints/conditional.py +629 -0
- app/shared/domain/constraints/date_logic.py +731 -0
- app/shared/domain/constraints/foreign_key.py +261 -0
- app/shared/domain/constraints/key_normalization.py +56 -0
- app/shared/domain/constraints/not_null.py +185 -0
- app/shared/domain/constraints/range.py +360 -0
- app/shared/domain/constraints/regex.py +218 -0
- app/shared/domain/constraints/scripted.py +276 -0
- app/shared/domain/constraints/unique.py +233 -0
- app/shared/domain/data_engine.py +384 -0
- app/shared/domain/data_types.py +113 -0
- app/shared/domain/data_types_parts/__init__.py +67 -0
- app/shared/domain/data_types_parts/base.py +204 -0
- app/shared/domain/data_types_parts/composite.py +250 -0
- app/shared/domain/data_types_parts/expression.py +202 -0
- app/shared/domain/data_types_parts/extracted.py +106 -0
- app/shared/domain/data_types_parts/json_types.py +234 -0
- app/shared/domain/data_types_parts/scalars.py +719 -0
- app/shared/domain/data_types_parts/sequence.py +129 -0
- app/shared/domain/dataset_schema.py +48 -0
- app/shared/domain/eval_sandbox.py +63 -0
- app/shared/domain/expression_system.py +366 -0
- app/shared/domain/regex_flags.py +53 -0
- app/shared/domain/schema/builder.py +223 -0
- app/shared/domain/schema/models.py +339 -0
- app/shared/domain/transforms/__init__.py +28 -0
- app/shared/domain/transforms/aggregate.py +141 -0
- app/shared/domain/transforms/base.py +171 -0
- app/shared/domain/transforms/cast_type.py +120 -0
- app/shared/domain/transforms/concat.py +103 -0
- app/shared/domain/transforms/conditional_assign.py +114 -0
- app/shared/domain/transforms/date_format.py +81 -0
- app/shared/domain/transforms/digits.py +77 -0
- app/shared/domain/transforms/drop_duplicates.py +94 -0
- app/shared/domain/transforms/fill_na.py +94 -0
- app/shared/domain/transforms/filter_rows.py +97 -0
- app/shared/domain/transforms/lookup.py +78 -0
- app/shared/domain/transforms/lower_case.py +70 -0
- app/shared/domain/transforms/map_value.py +90 -0
- app/shared/domain/transforms/math_expr.py +112 -0
- app/shared/domain/transforms/modulo.py +82 -0
- app/shared/domain/transforms/regex_extract.py +103 -0
- app/shared/domain/transforms/registry.py +95 -0
- app/shared/domain/transforms/replace.py +88 -0
- app/shared/domain/transforms/sort_rows.py +94 -0
- app/shared/domain/transforms/string_split.py +84 -0
- app/shared/domain/transforms/strip.py +73 -0
- app/shared/domain/transforms/substring.py +92 -0
- app/shared/domain/transforms/upper_case.py +70 -0
- app/shared/domain/transforms/weighted_sum.py +104 -0
- app/shared/domain/validation_constraints.py +69 -0
- app/shared/services/__init__.py +62 -0
- app/shared/services/ai/__init__.py +48 -0
- app/shared/services/ai/agent/__init__.py +40 -0
- app/shared/services/ai/agent/chat_tools/__init__.py +47 -0
- app/shared/services/ai/agent/chat_tools/apply_actions.py +592 -0
- app/shared/services/ai/agent/chat_tools/ask_user.py +237 -0
- app/shared/services/ai/agent/chat_tools/read_canvas.py +140 -0
- app/shared/services/ai/agent/chat_tools/read_project.py +160 -0
- app/shared/services/ai/agent/chat_tools/read_table.py +301 -0
- app/shared/services/ai/agent/chat_tools/schemas.py +105 -0
- app/shared/services/ai/agent/chat_tools/validate_table.py +131 -0
- app/shared/services/ai/agent/executor.py +554 -0
- app/shared/services/ai/agent/memory.py +256 -0
- app/shared/services/ai/agent/planner.py +282 -0
- app/shared/services/ai/agent/tool_registry.py +296 -0
- app/shared/services/ai/agent/tools/__init__.py +32 -0
- app/shared/services/ai/agent/tools/config_generate.py +133 -0
- app/shared/services/ai/agent/tools/config_refine.py +109 -0
- app/shared/services/ai/agent/tools/config_validate.py +403 -0
- app/shared/services/ai/agent/tools/merge_results.py +136 -0
- app/shared/services/ai/agent/tools/plan_chunks.py +79 -0
- app/shared/services/ai/agent/tools/script_parse.py +359 -0
- app/shared/services/ai/agent/types.py +138 -0
- app/shared/services/ai/chat_agent_runner.py +596 -0
- app/shared/services/ai/chat_orchestrator.py +725 -0
- app/shared/services/ai/failure_messages.py +65 -0
- app/shared/services/ai/job_storage.py +274 -0
- app/shared/services/ai/migrate_service.py +550 -0
- app/shared/services/ai/streaming/__init__.py +65 -0
- app/shared/services/ai/streaming/event_journal.py +197 -0
- app/shared/services/ai/streaming/orchestrator.py +262 -0
- app/shared/services/ai/streaming/pending_interaction_store.py +227 -0
- app/shared/services/ai/streaming/sse_response.py +148 -0
- app/shared/services/ai/streaming/types.py +73 -0
- app/shared/services/ai/types.py +213 -0
- app/shared/services/ai/utils.py +322 -0
- app/shared/services/diff/config_diff.py +320 -0
- app/shared/services/hardware.py +237 -0
- app/shared/services/llm/__init__.py +62 -0
- app/shared/services/llm/actions/__init__.py +42 -0
- app/shared/services/llm/actions/_canvas_validator.py +147 -0
- app/shared/services/llm/actions/_constraint_validator.py +401 -0
- app/shared/services/llm/actions/_regex_validator.py +85 -0
- app/shared/services/llm/actions/_schema_validator.py +82 -0
- app/shared/services/llm/actions/_settings_validator.py +76 -0
- app/shared/services/llm/actions/_transform_validator.py +78 -0
- app/shared/services/llm/actions/action_handlers.py +400 -0
- app/shared/services/llm/actions/action_parser.py +63 -0
- app/shared/services/llm/actions/action_processor.py +468 -0
- app/shared/services/llm/actions/action_validator.py +311 -0
- app/shared/services/llm/actions/diff_compute.py +195 -0
- app/shared/services/llm/actions/regex_handlers.py +284 -0
- app/shared/services/llm/actions/registry.py +336 -0
- app/shared/services/llm/actions/schema_handlers.py +335 -0
- app/shared/services/llm/actions/settings_handlers.py +180 -0
- app/shared/services/llm/actions/specs.py +259 -0
- app/shared/services/llm/actions/transform_handlers.py +279 -0
- app/shared/services/llm/actions/validation_types.py +147 -0
- app/shared/services/llm/cache/__init__.py +18 -0
- app/shared/services/llm/cache/response_cache.py +80 -0
- app/shared/services/llm/chat/__init__.py +35 -0
- app/shared/services/llm/chat/chat_system_prompt.py +561 -0
- app/shared/services/llm/chat/response_parser.py +296 -0
- app/shared/services/llm/config/__init__.py +45 -0
- app/shared/services/llm/config/crypto.py +135 -0
- app/shared/services/llm/config/loader.py +258 -0
- app/shared/services/llm/config/models.py +202 -0
- app/shared/services/llm/config/presets.py +128 -0
- app/shared/services/llm/config_generator.py +163 -0
- app/shared/services/llm/constraints/__init__.py +41 -0
- app/shared/services/llm/constraints/constraint_builder.py +177 -0
- app/shared/services/llm/constraints/constraint_deletion.py +84 -0
- app/shared/services/llm/constraints/constraint_id.py +174 -0
- app/shared/services/llm/constraints/frontend_instructions.py +333 -0
- app/shared/services/llm/constraints/inline_batch.py +279 -0
- app/shared/services/llm/discovery/__init__.py +35 -0
- app/shared/services/llm/discovery/scanner.py +181 -0
- app/shared/services/llm/generation/__init__.py +42 -0
- app/shared/services/llm/generation/agent_wiring.py +156 -0
- app/shared/services/llm/generation/config_builder.py +386 -0
- app/shared/services/llm/generation/errors.py +36 -0
- app/shared/services/llm/generation/existing_config.py +99 -0
- app/shared/services/llm/generation/profiler.py +279 -0
- app/shared/services/llm/generation/prompt_builder.py +199 -0
- app/shared/services/llm/generation/response_parser.py +144 -0
- app/shared/services/llm/generation/service.py +622 -0
- app/shared/services/llm/models.py +104 -0
- app/shared/services/llm/providers/__init__.py +48 -0
- app/shared/services/llm/providers/base.py +310 -0
- app/shared/services/llm/providers/cached_provider.py +90 -0
- app/shared/services/llm/providers/ollama.py +498 -0
- app/shared/services/llm/providers/openai.py +334 -0
- app/shared/services/llm/providers/registry.py +108 -0
- app/shared/services/llm/schema_resolver.py +141 -0
- app/shared/services/llm/suggestion_utils.py +219 -0
- app/shared/services/llm/validate_executor.py +163 -0
- app/shared/services/llm/yaml_io.py +406 -0
- app/shared/services/preview/__init__.py +18 -0
- app/shared/services/preview/loader.py +145 -0
- app/shared/services/preview/path_validation.py +138 -0
- app/shared/services/project_loader.py +57 -0
- app/shared/services/schema_inference.py +260 -0
- app/shared/services/schema_runtime_builder.py +120 -0
- app/shared/services/validation/__init__.py +52 -0
- app/shared/services/validation/chunked_loader.py +509 -0
- app/shared/services/validation/dag/__init__.py +35 -0
- app/shared/services/validation/dag/builder.py +141 -0
- app/shared/services/validation/dag/executor.py +225 -0
- app/shared/services/validation/dag/sorter.py +77 -0
- app/shared/services/validation/data_loader.py +231 -0
- app/shared/services/validation/engine.py +446 -0
- app/shared/services/validation/executor.py +1030 -0
- app/shared/services/validation/extractors.py +266 -0
- app/shared/services/validation/history.py +209 -0
- app/shared/services/validation/json_payload.py +136 -0
- app/shared/services/validation/loader.py +152 -0
- app/shared/services/validation/memory_monitor.py +179 -0
- app/shared/services/validation/postprocess.py +208 -0
- app/shared/services/validation/progress.py +64 -0
- app/shared/services/validation/report_export.py +222 -0
- app/shared/services/validation/resolver.py +180 -0
- app/shared/services/validation/service.py +418 -0
- app/shared/services/validation/types.py +238 -0
- app/shared/services/validation/validators/__init__.py +36 -0
- app/shared/services/validation/validators/adapter.py +182 -0
- app/shared/services/validation/validators/base.py +332 -0
- app/shared/services/validation/validators/composite.py +233 -0
- app/shared/services/validation/validators/date_logic.py +276 -0
- app/start_server.py +133 -0
- precis_cli-0.1.3.dist-info/METADATA +180 -0
- precis_cli-0.1.3.dist-info/RECORD +442 -0
- precis_cli-0.1.3.dist-info/WHEEL +5 -0
- precis_cli-0.1.3.dist-info/entry_points.txt +4 -0
- precis_cli-0.1.3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,148 @@
|
|
|
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 SSE 响应封装
|
|
17
|
+
|
|
18
|
+
把 EventJournal 的事件序列转换为 SSE (Server-Sent Events) 帧流。
|
|
19
|
+
支持断线续传(Last-Event-ID)和已完成任务的完整回放。
|
|
20
|
+
|
|
21
|
+
SSE 帧格式:
|
|
22
|
+
id: 5
|
|
23
|
+
event: delta
|
|
24
|
+
data: {"text": "你好"}
|
|
25
|
+
|
|
26
|
+
(空行分隔帧)
|
|
27
|
+
|
|
28
|
+
设计要点:
|
|
29
|
+
- 续传: 先从 journal 读取 id > last_event_id 的事件快速回放,再切到实时推送
|
|
30
|
+
- 终止: 遇到终止事件(completed/error/cancelled)后自动结束流
|
|
31
|
+
- 心跳: 每隔一段时间发 :keep-alive 注释行,防止代理超时断开
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
from __future__ import annotations
|
|
35
|
+
|
|
36
|
+
import asyncio
|
|
37
|
+
import json
|
|
38
|
+
import logging
|
|
39
|
+
from collections.abc import AsyncIterator
|
|
40
|
+
from typing import Any, cast
|
|
41
|
+
|
|
42
|
+
from .event_journal import EventJournal
|
|
43
|
+
|
|
44
|
+
logger = logging.getLogger(__name__)
|
|
45
|
+
|
|
46
|
+
# 默认实时等待超时(秒):无新事件时的心跳间隔
|
|
47
|
+
DEFAULT_LIVE_TIMEOUT = 15.0
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def format_sse_event(
|
|
51
|
+
event_id: int | None,
|
|
52
|
+
event: str | None,
|
|
53
|
+
data: dict[str, Any] | None,
|
|
54
|
+
heartbeat: bool = False,
|
|
55
|
+
) -> str:
|
|
56
|
+
"""
|
|
57
|
+
@methoddesc 格式化一个 SSE 帧
|
|
58
|
+
|
|
59
|
+
参数:
|
|
60
|
+
event_id: 事件 id,None 则不输出 id 行
|
|
61
|
+
event: 事件类型,None 则不输出 event 行(默认 message)
|
|
62
|
+
data: 事件数据(将被 JSON 序列化),None 则不输出 data 行
|
|
63
|
+
heartbeat: True 时返回心跳注释行(:keep-alive),忽略其他参数
|
|
64
|
+
|
|
65
|
+
返回:
|
|
66
|
+
SSE 帧字符串(以 \\n\\n 结尾)
|
|
67
|
+
"""
|
|
68
|
+
if heartbeat:
|
|
69
|
+
return ":keep-alive\n\n"
|
|
70
|
+
|
|
71
|
+
lines: list[str] = []
|
|
72
|
+
if event_id is not None:
|
|
73
|
+
lines.append(f"id: {event_id}")
|
|
74
|
+
if event is not None:
|
|
75
|
+
lines.append(f"event: {event}")
|
|
76
|
+
if data is not None:
|
|
77
|
+
lines.append(f"data: {json.dumps(data, ensure_ascii=False)}")
|
|
78
|
+
return "\n".join(lines) + "\n\n"
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
async def sse_event_stream(
|
|
82
|
+
journal: EventJournal,
|
|
83
|
+
last_event_id: int,
|
|
84
|
+
live_timeout: float = DEFAULT_LIVE_TIMEOUT,
|
|
85
|
+
event_queue: asyncio.Queue[dict[str, Any]] | None = None,
|
|
86
|
+
) -> AsyncIterator[str]:
|
|
87
|
+
"""
|
|
88
|
+
@methoddesc 生成 SSE 事件流
|
|
89
|
+
|
|
90
|
+
流程:
|
|
91
|
+
1. 从 journal 回放 id > last_event_id 的已有事件(快速,无延时)
|
|
92
|
+
2. 若回放的最后一条已是终止事件,直接结束(任务已完成的重连场景)
|
|
93
|
+
3. 否则切到实时模式: 从 event_queue 等待新事件,超时发心跳
|
|
94
|
+
4. 收到终止事件后结束
|
|
95
|
+
|
|
96
|
+
参数:
|
|
97
|
+
journal: 事件日志
|
|
98
|
+
last_event_id: 客户端最后收到的事件 id(0 表示从头)
|
|
99
|
+
live_timeout: 实时模式心跳间隔(秒)
|
|
100
|
+
event_queue: 实时事件队列,None 时只回放不实时(适合已完成任务)
|
|
101
|
+
|
|
102
|
+
返回:
|
|
103
|
+
AsyncIterator[str]: SSE 帧字符串
|
|
104
|
+
"""
|
|
105
|
+
# 阶段 1: 回放 journal 中已有事件(从 last_event_id+1 开始)
|
|
106
|
+
replayed = journal.read_since(last_event_id)
|
|
107
|
+
terminated = False
|
|
108
|
+
for eid, event, data in replayed:
|
|
109
|
+
yield format_sse_event(event_id=eid, event=event, data=data)
|
|
110
|
+
|
|
111
|
+
# 记录回放水位:emit 先写 journal 再入队,回放期间队列中可能已积压同批事件,
|
|
112
|
+
# 实时消费时跳过 id <= 水位的事件,避免回放与实时重叠导致重复投递
|
|
113
|
+
last_replayed_id = replayed[-1][0] if replayed else last_event_id
|
|
114
|
+
|
|
115
|
+
# 阶段 2: 若回放的最后一条是终止事件,任务已结束,直接关闭流
|
|
116
|
+
from .types import TERMINAL_EVENTS
|
|
117
|
+
|
|
118
|
+
if replayed and replayed[-1][1] in TERMINAL_EVENTS:
|
|
119
|
+
return
|
|
120
|
+
|
|
121
|
+
# 若 journal 整体已终止(但 replayed 为空,即 last_event_id 已是最新),也关闭
|
|
122
|
+
if journal.is_terminated() and not replayed:
|
|
123
|
+
return
|
|
124
|
+
|
|
125
|
+
# 阶段 3: 实时模式(需要 event_queue)
|
|
126
|
+
if event_queue is None:
|
|
127
|
+
# 无队列(纯回放模式),若未终止则等待 journal 出现终止事件(轮询)
|
|
128
|
+
# 这种情况通常用于测试或已完成任务的重连
|
|
129
|
+
return
|
|
130
|
+
|
|
131
|
+
while not terminated:
|
|
132
|
+
try:
|
|
133
|
+
entry = await asyncio.wait_for(event_queue.get(), timeout=live_timeout)
|
|
134
|
+
except TimeoutError:
|
|
135
|
+
# 心跳: 防止代理超时
|
|
136
|
+
yield format_sse_event(event_id=None, event=None, data=None, heartbeat=True)
|
|
137
|
+
continue
|
|
138
|
+
|
|
139
|
+
rt_eid = cast("int | None", entry.get("id"))
|
|
140
|
+
rt_event = cast("str | None", entry.get("event"))
|
|
141
|
+
rt_data = cast("dict[str, Any] | None", entry.get("data"))
|
|
142
|
+
# 跳过回放阶段已投递过的事件(含已回放的终止事件——阶段 2 未退出说明该终止事件
|
|
143
|
+
# 必然也在回放末尾被投递过,直接丢弃即可,不会漏终止信号)
|
|
144
|
+
if isinstance(rt_eid, int) and rt_eid <= last_replayed_id:
|
|
145
|
+
continue
|
|
146
|
+
yield format_sse_event(event_id=rt_eid, event=rt_event, data=rt_data)
|
|
147
|
+
if rt_event in TERMINAL_EVENTS:
|
|
148
|
+
terminated = True
|
|
@@ -0,0 +1,73 @@
|
|
|
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 流式事件类型与常量
|
|
17
|
+
|
|
18
|
+
定义统一的 SSE 事件类型常量与终止事件集合。
|
|
19
|
+
三个场景(chat/generate/migrate)共享同一套事件类型。
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
# 非终止事件类型
|
|
25
|
+
EVENT_STARTED = "started" # 任务启动,携带 job_id/kind
|
|
26
|
+
EVENT_PROGRESS = "progress" # 阶段进度(画像/分块/合并等),仅 generate/migrate
|
|
27
|
+
EVENT_TURN_START = "turn_start" # Agent 新一轮开始
|
|
28
|
+
EVENT_DELTA = "delta" # 流式文本块(增量,前端累积)
|
|
29
|
+
EVENT_TOOL_CALL = "tool_call" # 工具调用开始
|
|
30
|
+
EVENT_TOOL_RESULT = "tool_result" # 工具执行完成
|
|
31
|
+
|
|
32
|
+
# 非终止事件类型:流式画布生长(Agent 模式)
|
|
33
|
+
# apply_actions 落盘后,逐条 emit 单条 frontend_instruction,
|
|
34
|
+
# 前端收到即立即执行 processFrontendInstructions + fitView,实现画布实时生长。
|
|
35
|
+
# completed 事件仍携带全量 instructions 作为兜底。
|
|
36
|
+
EVENT_FRONTEND_INSTRUCTION = "frontend_instruction" # 单条前端指令已落盘
|
|
37
|
+
|
|
38
|
+
# 非终止事件类型:apply_actions 两阶段确认
|
|
39
|
+
EVENT_APPLY_PENDING = "apply_pending" # dry-run diff 已就绪,等待用户确认
|
|
40
|
+
EVENT_APPLY_CONFIRMED = "apply_confirmed" # 用户确认,已落盘
|
|
41
|
+
EVENT_APPLY_REJECTED = "apply_rejected" # 用户拒绝,未落盘
|
|
42
|
+
|
|
43
|
+
# 非终止事件类型:ask_user 交互问答
|
|
44
|
+
EVENT_USER_INPUT_REQUESTED = "user_input_requested" # agent 提问,等待用户输入
|
|
45
|
+
EVENT_USER_RESPONDED = "user_responded" # 用户已回答(或超时/skip),前端清态
|
|
46
|
+
|
|
47
|
+
# 终止事件类型(发出后关闭 SSE 连接)
|
|
48
|
+
EVENT_COMPLETED = "completed" # 成功完成(含完整快照)
|
|
49
|
+
EVENT_ERROR = "error" # 失败
|
|
50
|
+
EVENT_CANCELLED = "cancelled" # 软取消确认
|
|
51
|
+
|
|
52
|
+
# 终止事件集合:用于 is_terminated 判定
|
|
53
|
+
# 注意: apply_pending/confirmed/rejected 是非终止事件,不加入此集合
|
|
54
|
+
TERMINAL_EVENTS: frozenset[str] = frozenset({EVENT_COMPLETED, EVENT_ERROR, EVENT_CANCELLED})
|
|
55
|
+
|
|
56
|
+
__all__ = [
|
|
57
|
+
"EVENT_STARTED",
|
|
58
|
+
"EVENT_PROGRESS",
|
|
59
|
+
"EVENT_TURN_START",
|
|
60
|
+
"EVENT_DELTA",
|
|
61
|
+
"EVENT_TOOL_CALL",
|
|
62
|
+
"EVENT_TOOL_RESULT",
|
|
63
|
+
"EVENT_FRONTEND_INSTRUCTION",
|
|
64
|
+
"EVENT_APPLY_PENDING",
|
|
65
|
+
"EVENT_APPLY_CONFIRMED",
|
|
66
|
+
"EVENT_APPLY_REJECTED",
|
|
67
|
+
"EVENT_USER_INPUT_REQUESTED",
|
|
68
|
+
"EVENT_USER_RESPONDED",
|
|
69
|
+
"EVENT_COMPLETED",
|
|
70
|
+
"EVENT_ERROR",
|
|
71
|
+
"EVENT_CANCELLED",
|
|
72
|
+
"TERMINAL_EVENTS",
|
|
73
|
+
]
|
|
@@ -0,0 +1,213 @@
|
|
|
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 AI 服务类型定义模块
|
|
17
|
+
|
|
18
|
+
功能概述:
|
|
19
|
+
- 定义 AI 配置生成所需的数据类型(ProfilingOptions、GenerateOptions 等)
|
|
20
|
+
- 提供 LLM Provider 配置和 Chat 相关数据类
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
from dataclasses import dataclass, field
|
|
26
|
+
from typing import Any
|
|
27
|
+
|
|
28
|
+
# =============================================================================
|
|
29
|
+
# 模块常量
|
|
30
|
+
# =============================================================================
|
|
31
|
+
|
|
32
|
+
# Precis V2 项目清单文件名
|
|
33
|
+
# 所有 V2 项目使用统一的清单文件名称,便于识别和加载
|
|
34
|
+
V2_MANIFEST_FILENAME = "project.precis.yaml"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# =============================================================================
|
|
38
|
+
# 数据画像选项
|
|
39
|
+
# =============================================================================
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@dataclass(frozen=True)
|
|
43
|
+
class ProfilingOptions:
|
|
44
|
+
"""
|
|
45
|
+
@classdesc 数据画像选项配置类
|
|
46
|
+
|
|
47
|
+
用于控制数据分析和样本提取的行为参数。这些选项决定了:
|
|
48
|
+
- 从每个数据文件读取多少行进行分析
|
|
49
|
+
- 每列提取多少样本值用于了解数据分布
|
|
50
|
+
- 最多处理多少个数据文件
|
|
51
|
+
- 单元格文本截断到多长
|
|
52
|
+
|
|
53
|
+
设计考虑:
|
|
54
|
+
- 使用 frozen=True 确保实例不可变,天然线程安全
|
|
55
|
+
- 所有字段有默认值,支持最小化配置
|
|
56
|
+
- 数值型默认值经过实践验证,在内存使用和分析精度间取得平衡
|
|
57
|
+
|
|
58
|
+
Attributes:
|
|
59
|
+
sample_rows: 从每个数据文件读取的最大行数
|
|
60
|
+
用于生成数据画像供 AI 分析
|
|
61
|
+
默认值 50 行 - 在内存使用和代表性之间取得平衡
|
|
62
|
+
较大值可获得更准确的分析,但消耗更多内存
|
|
63
|
+
sample_values_per_column: 每列提取的样本值数量
|
|
64
|
+
用于了解数据分布和枚举值
|
|
65
|
+
默认值 10 个样本
|
|
66
|
+
对于枚举型字段可适当增加
|
|
67
|
+
max_files: 最多处理的数据文件数量
|
|
68
|
+
防止资源耗尽和过长处理时间
|
|
69
|
+
默认值 50 个文件
|
|
70
|
+
批量处理大量文件时可调整
|
|
71
|
+
max_cell_chars: 单个单元格文本的最大保留字符数
|
|
72
|
+
超过部分将被截断为 "..."
|
|
73
|
+
默认值 200 字符
|
|
74
|
+
长文本分析可适当增加
|
|
75
|
+
|
|
76
|
+
Example:
|
|
77
|
+
>>> # 使用默认选项
|
|
78
|
+
>>> opts = ProfilingOptions()
|
|
79
|
+
>>>
|
|
80
|
+
>>> # 自定义选项
|
|
81
|
+
>>> opts = ProfilingOptions(
|
|
82
|
+
... sample_rows=100,
|
|
83
|
+
... sample_values_per_column=20,
|
|
84
|
+
... max_files=10,
|
|
85
|
+
... max_cell_chars=500
|
|
86
|
+
... )
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
sample_rows: int = 50
|
|
90
|
+
sample_values_per_column: int = 10
|
|
91
|
+
max_files: int = 50
|
|
92
|
+
max_cell_chars: int = 200
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# =============================================================================
|
|
96
|
+
# 配置生成选项
|
|
97
|
+
# =============================================================================
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
@dataclass(frozen=True)
|
|
101
|
+
class GenerateOptions:
|
|
102
|
+
"""
|
|
103
|
+
@classdesc 配置生成选项配置类
|
|
104
|
+
|
|
105
|
+
用于控制 V2 配置生成的行为参数。这些选项决定:
|
|
106
|
+
- 生成哪些类型的配置(schema、约束、正则节点)
|
|
107
|
+
- 如何处理现有配置(保留或覆盖)
|
|
108
|
+
- 使用哪个 AI 模型
|
|
109
|
+
- 仅处理哪些文件
|
|
110
|
+
|
|
111
|
+
设计考虑:
|
|
112
|
+
- 使用 frozen=True 确保实例不可变,天然线程安全
|
|
113
|
+
- 生成类选项默认为 True,保留现有配置默认为 True
|
|
114
|
+
- 提供细粒度控制能力
|
|
115
|
+
|
|
116
|
+
Attributes:
|
|
117
|
+
generate_schemas: 是否生成表结构定义(schema)
|
|
118
|
+
启用后将为每个数据文件创建 TableSchemaFileV2
|
|
119
|
+
包含列名、数据类型等信息
|
|
120
|
+
默认值 True
|
|
121
|
+
generate_constraints: 是否生成约束规则
|
|
122
|
+
启用后将调用 AI 生成约束建议
|
|
123
|
+
注意:当前版本约束生成功能未完全实现
|
|
124
|
+
默认值 True
|
|
125
|
+
generate_regex_nodes: 是否生成正则节点
|
|
126
|
+
启用后将调用 AI 生成正则建议
|
|
127
|
+
注意:当前版本正则节点生成功能未完全实现
|
|
128
|
+
默认值 True
|
|
129
|
+
keep_existing: 是否保留现有配置
|
|
130
|
+
True 时会合并现有配置,新生成内容将追加到现有内容
|
|
131
|
+
False 时会清空并重新生成所有内容
|
|
132
|
+
适用于增量更新特定文件的场景
|
|
133
|
+
默认值 True
|
|
134
|
+
model: 使用的 Ollama 模型名称
|
|
135
|
+
用于生成约束和正则节点建议
|
|
136
|
+
未指定时使用环境变量 PRECIS_OLLAMA_MODEL
|
|
137
|
+
需要确保指定的模型已在本地安装
|
|
138
|
+
默认值 None(使用环境变量)
|
|
139
|
+
target_files: 仅处理指定的数据文件列表
|
|
140
|
+
用于增量更新特定文件
|
|
141
|
+
如果为 None 或空列表,则处理所有文件
|
|
142
|
+
路径应为绝对路径或相对于工作目录的路径
|
|
143
|
+
默认值 None(处理所有文件)
|
|
144
|
+
|
|
145
|
+
Example:
|
|
146
|
+
>>> # 使用默认选项
|
|
147
|
+
>>> opts = GenerateOptions()
|
|
148
|
+
>>>
|
|
149
|
+
>>> # 仅生成 schema
|
|
150
|
+
>>> opts = GenerateOptions(
|
|
151
|
+
... generate_schemas=True,
|
|
152
|
+
... generate_constraints=False,
|
|
153
|
+
... generate_regex_nodes=False
|
|
154
|
+
... )
|
|
155
|
+
>>>
|
|
156
|
+
>>> # 使用特定模型并处理指定文件
|
|
157
|
+
>>> opts = GenerateOptions(
|
|
158
|
+
... model="qwen:7b",
|
|
159
|
+
... target_files=["/data/users.csv", "/data/orders.csv"]
|
|
160
|
+
... )
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
generate_schemas: bool = True
|
|
164
|
+
generate_constraints: bool = True
|
|
165
|
+
generate_regex_nodes: bool = True
|
|
166
|
+
keep_existing: bool = True
|
|
167
|
+
model: str | None = None
|
|
168
|
+
target_files: list[str] | None = None
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
# =============================================================================
|
|
172
|
+
# AI Chat 相关类型
|
|
173
|
+
# =============================================================================
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
@dataclass
|
|
177
|
+
class ChatContext:
|
|
178
|
+
"""
|
|
179
|
+
@classdesc AI Chat 上下文数据类
|
|
180
|
+
|
|
181
|
+
用于传递项目上下文信息给 AI。
|
|
182
|
+
|
|
183
|
+
Attributes:
|
|
184
|
+
has_context: 是否有上下文
|
|
185
|
+
selected_nodes: 选中的节点列表
|
|
186
|
+
project_overview: 项目概览(表结构和约束)
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
has_context: bool = False
|
|
190
|
+
selected_nodes: list[dict[str, Any]] = field(default_factory=list)
|
|
191
|
+
project_overview: dict[str, Any] = field(default_factory=dict)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
@dataclass
|
|
195
|
+
class ChatResult:
|
|
196
|
+
"""
|
|
197
|
+
@classdesc AI Chat 执行结果数据类
|
|
198
|
+
|
|
199
|
+
统一 API 和 CLI 的结果格式。
|
|
200
|
+
|
|
201
|
+
Attributes:
|
|
202
|
+
success: 是否成功
|
|
203
|
+
reply: AI 回复文本
|
|
204
|
+
actions: 解析出的动作列表
|
|
205
|
+
frontend_instructions: 前端渲染指令
|
|
206
|
+
error: 错误信息(如果有)
|
|
207
|
+
"""
|
|
208
|
+
|
|
209
|
+
success: bool
|
|
210
|
+
reply: str
|
|
211
|
+
actions: list[dict[str, Any]] = field(default_factory=list)
|
|
212
|
+
frontend_instructions: list[Any] = field(default_factory=list)
|
|
213
|
+
error: str | None = None
|