Commit Graph

69 Commits

Author SHA1 Message Date
0c895cf416 feat(logging): unify canonical task CoT events 2026-08-24 17:00:17 +03:00
ffa4d6a85b feat(scenarios): implement execution engine contracts 2026-08-21 16:15:40 +03:00
585a00c537 semantic-curation: fix anchors, metadata, and relations across backend + specs
- Replace legacy @PURPOSE with @BRIEF across 241 files
- Add missing [C:N] complexity tiers to function contracts in core modules
- Fix tombstone contracts: add @STATUS DEPRECATED to 5 deprecated anchors
- Resolve 7 unresolved @RELATION edges in executor.py (DictionaryManager, TranslationPreview, etc.)
- Fix flat hierarchical IDs in 4 test files (22 test functions)
- Fix invalid tags/relations in logger.py (@ADR, @CONSEQUENCES, DISABLED_BY)
- Rebuild semantic index: 9,576 contracts, 4,742 edges, 0 parse warnings
2026-08-20 11:45:15 +03:00
82a519a347 feat(scenarios): complete editor execution and analytics 2026-08-20 11:32:26 +03:00
81ba94684f feat: sed-мутации датасетов, правки миграции и фиксы
- Dataset viewer: sed-замена (find→replace) по всем/выбранным/текущим датасетам
  с обязательным визуальным предпросмотром и целями (sql/metrics/yaml); сохранение
  и выбор именованных правил (sedRules store + SedRuleEditor).
- Migration: literal-замена в dataset YAML при переносе; рескан ID чартов/датасетов
  перед миграцией + метрика средней длительности синка (GET /migration/sync-stats);
  логическая группировка опций (маппинги БД, сервер изменений, rescan) под галочками.
- Fix: дашборды хаба скрывались дефолтным профиль-фильтром show_only_slug_dashboards=true
  (теперь false); мастер миграции не грузил дашборды предзаполненного источника;
  потеря терминального task_status из-за утечки pending-корутин в /ws/logs (панель
  результата не появлялась); горизонтальный скролл в MappingTable; чистая per-env
  ошибка в mapping coverage.
- Backend: record_sync_duration + alembic-миграция sync-duration; literal_replace модуль.
2026-08-19 10:29:28 +03:00
e7d33ce4c8 chore(db): drop orphaned dataset-review and connection_configs tables
Remove dead schema left behind by removed features:
- dataset-review family (dataset_review_sessions, dataset_profiles, and
  related children) from c3ad0afc — its non-cascading FKs broke environment
  deletion with ForeignKeyViolation
- connection_configs from 74e64622

Both are unreachable from the app (no models register them).
2026-08-11 10:55:52 +03:00
9450559da5 feat(maintenance): improve event history and templates 2026-08-10 15:05:20 +03:00
512e9223e3 feat(maintenance): configurable date format for banner timestamps 2026-08-10 11:22:48 +03:00
1c577e8561 docs(semantics): normalize code contracts 2026-08-10 07:28:05 +03:00
093f7f600f fix(maintenance): harden banner lifecycle and guarded migrations
- Guard maintenance Alembic operations for create_all-only tables on clean DBs
- Add guarded verification_runs.fanout_plan_id backfill migration
- Improve maintenance banner rendering, chart management, orchestration, and API routes
- Expand assistant maintenance tool and edge-case coverage

Tests: cd backend && source .venv/bin/activate && python -m pytest -q tests/test_maintenance_api.py tests/test_maintenance_service.py tests/api/test_assistant_tool_maintenance.py tests/api/test_maintenance_routes_edge.py (77 passed)
2026-08-09 08:22:16 +03:00
066dfe3a35 fix(alembic): merge two parallel heads from o1p2q3r4s5t6
Runtime migrations failed with 'Multiple head revisions are present' because
037 T081 (p2q3r4s5t6u7 -> verification_runs.dashboard_id) and a concurrent
session-activity change (a1b2c3d4e5f7) both branched from o1p2q3r4s5t6.
The failed 'upgrade head' left dashboard_id unapplied, causing
'column verification_runs.dashboard_id does not exist' on
GET /verification/history.

Add a no-op merge revision (015281bd7759) collapsing both into a single head
so 'upgrade head' applies the verification_runs.dashboard_id column.

Verified: ScriptDirectory.get_heads() == ['015281bd7759'].
2026-08-07 16:33:30 +07:00
410afdf40e feat(037): verification pipeline automation + GET read-API (T080-T081)
Close the 037 pipeline-automation and read-API gaps found in the audit:
deploy/release hooks did not create VerificationRun, and GET endpoints for
history/detail were absent even though 039 UI and client call them.

T080 - _release_routes.py: create_release now fires best-effort
  _trigger_release_verification -> VerificationRun with trigger=release_create
  (metric+structure); verification scheduling failures never roll back the
  release transaction.
T081 - verification.py: add GET /verification/history (dashboard_id +
  environment_id filters, newest-first) and GET /verification/{run_id}
  (404 RUN_NOT_FOUND); reuse _record_to_response.
  - verification_run.py + alembic migration p2q3r4s5t6u7: nullable indexed
    dashboard_id populated from structure/visual/metric category_params.
  - verification_service.py: _derive_dashboard_id helper.

Verification: release routes (32) + verification API (8) + persistence (21)
= 53 passed; ruff clean for changed code (pre-existing RUF012/UP017 on old
lines left untouched).
2026-08-07 14:21:25 +07:00
a5e69de5ea fix(scenario): complete save flow with auto-created repo, robust approval gate, idempotent auto-start 2026-08-07 01:56:36 +07:00
6d19ecf81a fix: harden feature security and e2e integrations 2026-08-06 13:47:28 +07:00
9de74baa08 feat: dashboard testing suite — scenario UI, load testing, dataset lineage
- 039-dashboard-scenario-ui: agent workspace (WorkspaceModel, scenario
  views, parameters/baselines, artifact preview, HITL save/approval,
  evidence/VLM review, pipeline verification views) + contextVersion=2
  scenario intent + prototype.
- 040-dashboard-load-testing: capacity/matrix/profile, runner pool,
  timing, circuit breaker, PROD gate, cache/bounded/consistency,
  comparison/schedule, API + frontend + prototype.
- 041-dataset-lineage-blast-radius: usage index, severity/schema-diff,
  propagation, deprecation, fanout, API + frontend + prototype (R9
  labels/metrics/recreate).
- 036/037 amendments: dataset_updated trigger + fanout_plan_id, lineage
  deprecation gate, 040 read-model traceability.
- Includes pre-existing 042-rls-management-workspace and
  043-idm-account-integration work.
2026-08-05 18:15:30 +07:00
f9a15a0a7b feat(maintenance): opt-in auto-end at end_time via scheduler scan
Add auto_end flag to maintenance_events: when set with an end_time, a
60s APScheduler scan dispatches the end task automatically. The scan
survives restarts and is de-duped by task_id; end_time alone stays
informational. Includes alembic migration, route/schema wiring, Svelte
checkbox with validation, examples, and backend + frontend tests.
2026-08-04 16:38:20 +07:00
d54f903660 feat(maintenance): settings (timezone, height), snapshot restore, UX polish
Settings:
- display_timezone defaults to Europe/Moscow everywhere (model, service
  fallbacks, settings form); migration flips untouched 'UTC' default row.
- New banner_height setting (1-200 grid units, NULL = auto): threaded from
  settings through start/rebuild flows into MARKDOWN insert/content updates;
  settings panel gains Auto/Manual radio + number input.

Banner removal:
- update_dashboard_layout returns the pre-mutation position_json; stored on
  maintenance_dashboard_banners.original_position_json at creation.
- Removal restores the snapshot verbatim when the current layout matches the
  deterministic replay of the insert (normalize + y-shift + banner keys);
  diverged layouts (user edits during maintenance) and legacy banners fall
  back to surgical removal. Fixes layout drift from y-shift and unreverted
  ROOT->TABS -> ROOT->GRID normalization.

UX:
- StartMaintenanceForm: recent-tables chips from event history, Enter-to-
  submit, schema.table format hint, inline task progress panel (status +
  progress bar + task-log link), templates section removed, Button atoms.
- Maintenance page: environment selector + env context init.
- Events table: Active/Completed tabs with count badges.
- Backend: plugins/services report monotonic progress via
  context.logger.progress (per-dashboard) for start/end/end-all.

Tests: 203 backend (matcher, restore/fallback, height, progress) + 3645
frontend pass; migration E2E-verified (upgrade/downgrade).
2026-08-04 11:08:11 +07:00
a32ca0631b feat(037): capture, verification lifecycle, inheritance + close 036 stabilization
- Authoritative candidate capture with server-issued artifacts and raw-byte
  immutability hashing (source_response_hash server-owned)
- Closed-period lifecycle: request-hash bound approvals, persisted closure
  immutability violations, byte-for-byte catalog stability on reclosure
- Verification runs: persisted VerificationRun model + FK migration,
  publish gate (block_publish), scheduled observability runs (02:00 UTC)
- FR-013 baseline inheritance: prior_release_id migration, plan_inheritance/
  execute_inheritance classification and re-extraction, API endpoints
- Visual executor bound to release-deployment environment; caller mismatch
  rejected; visual SSIM/reconciliation modules
- Query execution decomposed: envelope/model/executor split, no direct SQL
- AgentRun approvals extracted to submodule; evidence adapter; _utils
- Dashboard testing service decomposed into 30+ modules (all <400 LOC)
- Five Feature-037 agent tools with permission guards (tools_037.py)
- API readiness endpoint; Alembic env/migrations; test fixture repos
- Specs 036/037 contracts, openapi.yaml, schema.json, tasks/traceability
  updated; semantic index rebuilt with 0 parse warnings
- Fix ADR-0003 parser ambiguity: remove [DEF🆔ADR] prose example
- Add axiom-mcp-agent-feedback.md: agent findings for MCP rework plan
- Tests: 298 service + 1464 API + 45 agent passing; ruff clean
2026-07-31 11:28:50 +03:00
d90ad81f6d feat(036): backend persistence layer — models, schemas, service, API routes 2026-07-28 08:28:24 +03:00
c30cca78f3 smoke alembic 2026-07-23 18:53:45 +03:00
d0213ff45b feat: session timeout management + LLM provider error hardening
Backend:
- Typed LLM provider exception hierarchy (auth, config, transport, rate limit)
- Permanent provider errors (401/403) propagate as ProviderAuthenticationFailure
  instead of being swallowed as UNKNOWN — Task becomes FAILED, not SUCCESS
- Provider error normalization maps SDK exceptions to typed hierarchy
- _should_retry extracted to module level for cross-method reuse
- SessionActivity model (jti, user_id, issued_at, expires_at, last_activity_at)
- Backend-enforced idle + absolute session timeout in dependencies.py
- Session policy endpoint GET /api/auth/session
- GlobalSettings extended: session_idle_timeout, session_absolute_timeout,
  session_warning_minutes
- Consolidated settings API returns session policy fields
- Alembic migration 8e9f0a1b2c3d for session_activity table

Frontend:
- Global 401 session-expired handler in api.ts with dedup guard
- Health polling stops on 401 (isDisabled=true)
- SessionTimeoutGuard component (+layout.svelte) tracks idle/absolute deadlines
- SessionTimeoutDialog modal with countdown (Continue/Logout)
- BroadcastChannel cross-tab activity sync
- Login returnUrl support (validates, prevents open redirect)
- SystemSettings card for session timeout configuration
- ROUTES.login(returnUrl?) for all login redirects
- i18n (EN/RU) for session security UI
- 3256 frontend tests pass, build clean
2026-07-23 11:27:17 +03:00
root
632b730fff chore: migrate GRACE-Poly anchors to hierarchical dotted naming
Systematic rename of all semantic anchors (#region, [DEF], @RELATION)
across 1400+ files — backend Python, frontend Svelte/TS, specs, docs:
- Flat anchors become Namespace.Module.Entity
- @RELATION references updated to match new anchor paths
- Zero business logic changes
2026-07-22 11:48:15 +03:00
49a566359a feat: translate module — runtime knobs, GRACE anchors, two-layer testing, QA fixes
Implementation:
- Performance knobs: llm_batch_max_rows, llm_concurrency, insert_concurrency,
  multi_lang_mode, batch_aggressiveness, max_in_flight_batches
- Alembic migration f7a8b9c0d1e2 (idempotent, nullable, non-destructive)
- LLM provider capabilities: throughput_class, reasoning_control,
  supports_json_object, default/max_llm_concurrency
- TargetSchemaValidationRequest with conditional validator (sqllab/direct_db)
- Scheduler: background dispatch, local imports for lazy bootstrap

GRACE-Poly compliance:
- Semantic anchors on orchestrator_aggregator, orchestrator_sql, llm_provider
- Shared module _llm_http.py: _apply_reasoning_control extraction (INV_4)
- Alembic migration anchors per C3/C1 template
- Four renamed Svelte components: RunOutcomeSummary, DetectionQualityCard,
  LanguageStatList, SourceLanguageOverride

QA (this session):
- 11 backend test regressions fixed: spec'd MagicMock null fields for new
  columns, _check_translation_cache_bulk retarget, scheduler mock wiring,
  language_detection=auto assertions, token budget constant update
- 4 frontend eslint errors fixed: SvelteSet/SvelteDate imports,
  unused lang parameter, dead isTransientError
- Production bugfix: job_to_response() mapped 6 missing fields
- Pre-existing auth test failure documented (dependencies.py untouched)
- Axiom: 6440 contracts, 0 warnings
2026-07-20 14:19:47 +03:00
8f0d123ff8 fix migration resume and release workflow 2026-07-16 12:31:59 +03:00
45ce585aba chore: commit remaining workspace updates 2026-07-16 07:53:41 +03:00
20105f51c0 feat(translate): add run preflight and focus execution UX 2026-07-16 07:52:52 +03:00
20071b8c7a security: fullstack hardening — task ownership, mapping validation, API-key scoping, test fixes
Backend:
- Add validate_mapping_database_ownership() to verify source/target UUIDs
  belong to declared environments before persisting mappings (mappings.py)
- Add API-key environment scoping to get_mappings (filter) and
  suggest_mappings_api (enforce) (mappings.py)
- Add user_id Column to TaskRecord model + Alembic migration (task.py)
- Persist task.user_id on save, restore on load (persistence.py)
- Wire current_user.id into migrate_dashboards + backup_dashboards
  task creation (_action_routes.py)
- Fix test_migration_routes.py: module-level patch leak → autouse fixture,
  SupersetClient→AsyncSupersetClient, AsyncMock for sync_environment/run
- Fix 7 Pydantic serializer warnings: 'PENDING'→TaskStatus.PENDING
  in test_tasks.py + import TaskStatus

Frontend:
- Deepen isDryRunResult(): validate selection field, risk.items entries
  (all 5 fields), and diff object uuids individually (ExecutorModel.svelte.ts)

Prior work included: task password redaction, resume ownership checks,
canonical dry-run DTO alignment, migration UI callback fixes, credential
exposure reduction, assistant dry-run await fix.
2026-07-15 23:02:23 +03:00
8f4ee25415 fix(alembic): merge three migration heads + add smoke test for chain integrity
- Created merge migration 7eaf84b7f6be joining heads:
  - 6b8ca3b7405f (previous merge of c0d1e2f3a4b5 + f2b3c4d5e6f7)
  - b4c5d6e7f8a9 (include_source_reference to translation_jobs)
  - f4a5b6c7d8e9 (preproduction validation to deployment records)

- Added smoke test (test_smoke_migration_chain.py) that:
  - Checks exactly 1 head (catches branch divergence)
  - Walks full chain verifying all down_revision links exist
  - Confirms all .py files are loaded as revisions
  - Runs WITHOUT a database (real ScriptDirectory, no mocks)
  - Catches what existing tests missed:
    * test_alembic_migrations.py skips on non-PostgreSQL
    * test_check_migration_chain.py uses mocks, not real files
2026-07-14 17:33:16 +03:00
c3ad0afc17 refactor: remove rejected dataset review feature 2026-07-14 15:56:31 +03:00
00d2619c86 fix: align DRAFT integration test with removed DRAFT check in validate_job_preconditions
- DRAFT validation was removed from orchestrator_validation.py (moved to service layer)
- Integration test expected ValueError for DRAFT jobs — fixed to test actual behavior
- 194/194 integration tests pass, 0 failures
2026-07-12 19:44:11 +03:00
24d3b7d1f9 refactor(task-manager): implement task resilience and execution lifecycle improvements
Enhance the reliability and observability of the task execution engine
by introducing retry mechanisms, idempotency, and structured progress
tracking.

- Implement centralized retry logic with exponential backoff support
  in `JobLifecycle`.
- Add `retry_task` API endpoint and `TaskManager` method for manual
  task restarts.
- Introduce task idempotency using `_idempotency_key` to prevent
  duplicate executions.
- Add `retry_count`, `max_retries`, `last_error`, and `progress` fields
  to the `Task` model and ensure persistence via `TaskPersistenceService`.
- Upgrade `SchedulerService` to use differential synchronization with
  the persistent `SQLAlchemyJobStore` for better job durability.
- Implement structured heartbeat logging to support real-time progress
  updates.
- Update project documentation and ADRs to reflect the new plugin
  runtime and task resilience patterns.
- Add comprehensive unit and integration tests for the new task
  lifecycle features.
2026-07-12 15:31:56 +03:00
0cb1f80cd6 feat(git): implement deployment tracking and enhance lifecycle UX
Introduce a deployment recording system to track dashboard versions
across environments and improve the Git management user experience.

- Add `Deployment` model and Alembic migration to persist deployment
  history.
- Implement `GitDeploymentRecorder` and `GitFingerprint` plugins to
  automate deployment logging and content hashing.
- Add `get_deployment_status` API endpoint to retrieve real-time
  environment states.
- Refactor `GitLifecycleHeader` to prioritize Call-to-Action (CTA)
  buttons and improve visual hierarchy.
- Update `GitWorkspacePanel` to emphasize version saving and
  streamline commit workflows.
- Enhance `GitEnvironmentTimeline` with deployment status integration,
  collapsible UI, and improved theme consistency.
- Add auto-navigation logic in `GitManagerModel` to guide users to
  relevant tabs based on recommended actions.
- Clean up obsolete documentation and update i18n strings for
  git visualization features.
2026-07-12 14:57:03 +03:00
81a70b8426 fix(migrations): add merge head and insert_method/connection migration
- 6b8ca3b7405f: merge heads for translation+enhancement migration chain
- c0d1e2f3a4b5: add insert_method, connection_id to translation_jobs;
  add insert_method, connection_snapshot to translation_runs
- e1f2a3b4c5d6: removed (duplicate/replaced by consolidated migration)
2026-06-11 19:12:49 +03:00
c3f0e6ef58 fix(migrations): add _table_exists guard to migrations touching create_all()-only tables
- 2df63b7ce038: was checking _column_exists but not _table_exists.
  If llm_providers/validation_policies/llm_validation_results don't
  exist (fresh DB), _column_exists returns False and add_column crashes.
  Now checks _table_exists first.
- a1b2c3d4e5f6 (20260603_add_token_limits_to_llm_providers): no guard
  at all. llm_providers is created by create_all() at runtime. Guard
  matches pattern used by ed28d34edde7, 9f8e7d6c5b4a and others.
2026-06-11 17:11:56 +03:00
4c02271d2c fix(migrations): guard f0e9d8c7b6a5 per-table for create_all()-only tables
dataset_review_sessions (and potentially other tables in FK_DEFS) are
created at runtime by init_db() → Base.metadata.create_all(), not by
Alembic migrations. On fresh databases, these tables don't exist when
migrations run, causing ALTER TABLE to crash.

Fix: check table existence before operating on each FK. If a table
doesn't exist, create_all() will create it with the correct FK
definition (the model already has ondelete='CASCADE').

This is the same pattern used by other migrations (9f8e7d6c5b4a,
ed28d34edde7, c9d8e7f6a5b4, 86c7b1d6a710) for create_all()-only tables
like llm_providers, roles, validation_policies, llm_validation_results.
2026-06-11 17:04:37 +03:00
9ecbbbe4a2 fix(migrations): create dataset_review_sessions table before f0e9d8c7b6a5 runs
- Add e1f2a3b4c5d6 migration: create dataset_review_sessions with FK
  ondelete='CASCADE' (matching the model). Previously created at runtime
  by init_db() → create_all().
- Update f0e9d8c7b6a5: change down_revision from a5b6c7d8e9f0 to
  e1f2a3b4c5d6 so the table exists when this migration runs.
- All other create_all()-only tables (llm_providers, roles,
  validation_policies, llm_validation_results) already have guards
  (_table_exists()) in their respective migrations.
2026-06-11 16:58:12 +03:00
753cfd45e4 fix(migrations): bring task_records into Alembic, remove guard workaround
- Add d1e2f3a4b5c6 migration: create task_records table matching the
  TaskRecord model (previously created at runtime by init_db() via
  Base.metadata.create_all).
- Update a5b6c7d8e9f0: down_revision now points to d1e2f3a4b5c6, so
  task_records exists when this migration runs. Remove the
  inspector.has_table() guard (no longer needed).
- create_all() in init_db() becomes a no-op for task_records — the
  table is now fully managed by Alembic.
2026-06-11 16:49:55 +03:00
0b6bf5aa9d chore: remainder — backend test infra, agent config, docker, i18n, frontend ui
- Backend: alembic env, config manager/models, dependencies, translate plugin
- Backend tests: async_sync_regression, integration tests, git services, test_agent
- Docker: docker-compose.yml updates
- Agent: qa-tester.md update, semantics-testing SKILL.md update
- Frontend: TopNavbar, sidebarNavigation, FeaturesSettings, FeatureGate
- i18n: assistant.json en/ru locale updates
- New: frontend/src/lib/components/agent/ directory
2026-06-10 15:06:36 +03:00
0c6ed93b65 feat(agent): Gradio-powered LangGraph agent chat with streaming, tool calls, file upload, conversation persistence
- Gradio 5.50.0 ChatInterface with type='messages' streaming
- LangGraph create_react_agent with InMemorySaver checkpointer
- 4 @tool functions: search_dashboards, get_health_summary, list_environments, get_task_status
- Structured ChatMessage metadata (7 discriminator types: stream_token, tool_start/end/error, confirm_required, confirm_resolved, error)
- HITL resume via second submit() with interrupt_before/Command
- Dual-identity RBAC: service JWT + user JWT for tool calls
- File upload (10 MB limit, pdfplumber/xlsx/JSON parser)
- Conversation persistence via POST /api/agent/conversations/save
- REST API: list, history, archive conversations; multi-tab gate; LLM config
- LLM provider selection via Admin -> LLM Settings (assistant_planner_provider)
- Svelte 5 AgentChatModel with stream event queue, dedup, stream_status watcher
- MarkdownRenderer using svelte-markdown with semantic Tailwind tokens
- ToolCallCard (3 states: executing/completed/failed)
- ConversationList with search, date grouping, infinite scroll
- ConnectionIndicator with Gradio health status
- /agent route with two-column layout
- Vite proxy /api/agent/gradio -> Gradio SSE
- Fixed: not_() SQLAlchemy operator, route collision with _admin_routes
- Fixed: conversation_id -> id normalization, .pyc cache staleness
- Fixed: event.data array parsing (Gradio returns [jsonStr, null])
- Requirements pinned: gradio==5.50.0, pydantic>=2.7,<=2.12.3
2026-06-10 10:27:19 +03:00
2d4caefeff fix(backend): resolve test regressions
- Remove invalid sqlite=True parameter from composite index migration
  (sqlite=True is not a valid op.create_index parameter)
- Fix test_assistant_api assertions for updated response format
- Fix test_git_status_route edge case assertions
- Fix test_audit_service expected value after metric changes
- Fix test_session_repository assertion after store refactor
2026-06-04 16:16:18 +03:00
000c2171b6 feat(backend+frontend): add is_regex support to dictionary entries
Add support for regex-based dictionary entries across the full stack:

Backend:
- DictionaryEntry model: add is_regex column (Boolean, default False)
- DictionaryEntryCRUD: validate regex on add_entry(), compile on creation
- _enforce_dictionary: match by regex pattern when is_regex=True
- dictionary_filter: support is_regex in filter/query
- metrics: include is_regex entries in metrics calculations
- Alembic migration: 20260604_add_is_regex_to_dictionary_entries
- Merge migration: 351afb8f961a (merge is_regex + composite index heads)

Frontend:
- DictionaryDetailModel: add is_regex field to DictionaryEntry interface,
  EditForm, and addForm; sync edit/add form state with backend schema
2026-06-04 16:16:02 +03:00
c297db9f6b fix: QA issues — composite index, anchors, fallbacks
- Add composite index ix_translation_records_run_source_hash
  for NOT EXISTS dedup subquery performance + Alembic migration
- Remove duplicate #endregion in orchestrator.py (INV_3)
- Replace hardcoded RU fallback 'Статус' with 'Status'
- Add early return guard to loadMoreRecords()
- Show records summary always when recordsTotal > 0
2026-06-04 13:33:17 +03:00
a064b38a4e perf(translate): fix slow translation startup — CJK estimation, output budget, provider token config
Root cause: batch sizing underestimated CJK token density (1.5→1.0 chars/token)
and ignored output budget as primary constraint, causing cascading finish_reason=length.

Changes:
- _token_budget.py: CJK_RATIO 1.5→1.0, OTHER_RATIO 2.2→1.8, safety factors 0.75/0.70
- _token_budget.py: new _compute_max_rows_by_output() — output budget is PRIMARY constraint
- _batch_sizer.py: resolve_provider_config() with DB-level context_window/max_output_tokens
- _batch_sizer.py: INPUT_SAFETY_FACTOR applied, max_rows_by_output used as row cap
- _llm_http.py: log actual usage.prompt_tokens/.completion_tokens from provider
- _llm_call.py: retry only missing rows after finish_reason=length (save partial result)
- models/llm.py + schema: provider-level context_window / max_output_tokens (nullable)
- services/llm_provider.py: get_provider_token_config() helper
- Alembic migration: add columns to llm_providers
- Svelte ProviderConfig: collapsible Advanced: Token Limits section
- 12 new tests (token budget, batch sizer, provider config)
- All 492 tests pass
2026-06-03 23:25:08 +03:00
96b6c59810 feat(backend): drop dictionary dialect columns, add allowed_languages
- Removes source_dialect and target_dialect from TerminologyDictionary model,
  schemas, routes, helper serialization, and all tests
- Adds allowed_languages config field (BCP-47 language codes) to GlobalSettings
  with validation, consolidated settings response, and API endpoint
- Adds alembic migration f1a2b3c4d5e6 to drop the two columns
2026-06-03 11:48:03 +03:00
69fb165fb5 feat(translate): add cache_hits counter — backend + frontend
Backend:
- TranslationRun model: add cache_hits Integer column (default 0)
- TranslationRunResponse schema: add cache_hits field
- _helpers.py/_run_list_routes.py/orchestrator_aggregator.py: include
  cache_hits in all run API responses
- _batch_proc.py: count pre_rows served from translation cache per
  batch, return cache_hits in batch result
- executor.py: accumulate cache_hits across batches, persist to run
- Alembic migration: dabc9709 — add cache_hits column to translation_runs

Frontend:
- translationRun.svelte.ts: add cacheHits to store state, WS handler,
  polling handler
- TranslationRunProgress.svelte: 5-col stats grid with purple Cache card
- TranslationRunGlobalIndicator.svelte: 5-col stats with Cache
- TranslationRunResult.svelte: 5-col detail stats with Cache card
- History page: cache_hits shown in run list row + detail panel

Visual: cache hits shown in purple alongside green/yellow/red metrics
(total/success/failed/skipped). Visible during run + in history.

Tests: backend 69/69 translate tests , frontend 698/698 tests ,
frontend build 
2026-06-02 11:59:57 +03:00
b6d18654d0 alembic fix 2026-06-01 16:34:07 +03:00
cd2ff6c745 feat(validation): v2 LLM dashboard validation — plugin, routes, services
Core implementation of the v2 LLM dashboard validation pipeline:
- LLM plugin with Path A (screenshots) and Path B (logs-only) execution
- Validation task management (CRUD, schedule, run)
- WebSocket task progress with Python 3.13 asyncio fix
- Cross-task runs listing (GET /validation-tasks/runs/all)
- RecordResponse schema for validation records
- JSON prompt helper, per-dashboard status aggregation
- Prompt templates with docs/git-commit/validation presets
- Migration: v2 validation models + description column
- Tests: plugin persistence, prompt templates, batch, payload, url
2026-05-31 22:32:20 +03:00
7a3d0f9766 feat(llm): auto-detect max images per request for LLM providers
Add binary-search probe endpoint POST /providers/{id}/probe-max-images
that discovers the per-request image limit by sending incrementally
more 1x1 JPEGs via the provider's own API. Result is cached in the
new max_images column on the provider config.

- LLMProviderConfig: add max_images: int | None
- LLMProvider (SQLAlchemy): add max_images column
- Migration ed28d34edde7: clean ADD COLUMN
- LLMProviderService: create/update/set_max_images
- POST /providers/{id}/probe-max-images: binary search + error parsing
- ProviderConfig.svelte: 'Detect' button in edit modal + HelpTooltip
- i18n (en/ru): 11 new keys for probe UI
2026-05-31 22:31:36 +03:00
e99ceb4081 date fx 2026-05-27 16:05:04 +03:00
7600ce4e3f fix: test assertions for molecular CoT markers, separate propagate=False to ConfigManager, fix ruff in env.py 2026-05-27 11:26:14 +03:00