147d711657
feat(agent-chat): complete context guardrail event coverage
2026-07-05 14:14:42 +03:00
b773a06d52
refactor(frontend): extract BulkReplaceModal.Model — state + FSM + API
...
- BulkReplaceModalModel.svelte.ts (170 LOC): 13 state atoms,
7-state FSM (closed→configuring→previewing→confirming→applying→applied),
3 API actions (handlePreview, handleApply, loadDictionaries),
1 derived (isLargeChange), @RATIONALE/@REJECTED
- BulkReplaceModal.svelte: 461→~310 LOC (INV_7 compliance),
delegates all state/FSM/API to model, retains modal chrome + previewAfter()
- Follows TopNavbar/TranslationRunResult pattern
2026-07-05 09:21:49 +03:00
97660cb71f
refactor(frontend): extract TranslationRunResult.Model — state + API logic
...
- TranslationRunResultModel.svelte.ts (200 LOC): 16 $state atoms,
3 $derived projections, 5 API actions (loadData, handleRetry,
handleRetryInsert, loadMoreRecords, loadBatches), @RATIONALE/@REJECTED
- TranslationRunResult.svelte: 623→456 LOC (167 lines saved, -27%),
delegates all state/API to model, retains template markup and
DOM helpers (copyToClipboard)
- INV_1: 0 naked functions (all logic in model)
- Follows TopNavbar pattern — dense anchor, hierarchical ID,
BINDS_TO -> [TranslationRunResult.Model]
2026-07-05 09:16:32 +03:00
669d8185f3
refactor(frontend): add @RATIONALE/@REJECTED to 5 C:4 contracts
...
- ConfigTabForm: rationale for single-tab vs wizard; rejected multi-step
- ValidationTaskForm: rationale for multi-step wizard; rejected flat form,
tabs, dynamic schema generation
- GitWorkspacePanel: rationale for IntersectionObserver lazy diff chunking;
rejected virtual scroll, server pagination, Web Worker
- Git.ManagerModel: rationale for model-first (cross-operation invariants,
L1 testability); existing @REJECTED preserved
- AgentChat.Component: rationale for reusable component vs inline;
rejected Web Component, iframe
2026-07-05 09:00:08 +03:00
bc3e288d0b
refactor(frontend): extract TopNavbar.Model — search logic, semantic compliance
...
- Extract TopNavbarModel.svelte.ts (303 LOC) — search state, debounce,
API aggregation, drawer preference hydration
- TopNavbar.svelte: 605→389 LOC (INV_7 compliance)
- Remove duplicate JSDoc metadata (INV_4)
- Add @RATIONALE, @REJECTED, @PRE, @POST, @SIDE_EFFECT, @DATA_CONTRACT
- Replace raw Tailwind (from-sky-500/via-cyan-500/to-indigo-600 →
from-brand-gradient-from/via-brand-gradient-via/to-brand-gradient-to)
- Replace raw Tailwind focus:ring-sky-200 → focus:ring-primary-ring-light
- Fix hardcoded i18n 'Ассистент' → $t.assistant.assistant
- Add primary.ring-light token to tailwind.config.js
- Replace any types with concrete interfaces (DashboardSearchResult, etc.)
- 16 naked functions → 0 (INV_1)
2026-07-05 08:50:43 +03:00
ff60865183
feat(agent-chat): 035-agent-chat-context — контекст, guardrails, tools, database discovery
...
== User stories ==
US1: Контекст с дашборда/датасета → /agent с URL params
US2: Guardrails card — env badge, 7 risk tones, countdown, permission_denied
US3: Tools optimization — retry, timeout, summarise, RBAC + context affinity
== Backend ==
- _context.py (NEW): UIContext validation (7 checks)
- _tool_filter.py (NEW): RBAC + context affinity pipeline
- _confirmation.py: build_confirmation_contract_v2, permission_denied_payload
- tools.py: superset_list_databases, retry/summarise/timeout wrappers
- app.py: _inject_uicontext, _inject_env_id_into_tools, database
prefetch в runtime context
- _persistence.py: prefetch_databases()
- agent_superset_explore.py: GET /databases endpoint
- _llm_async_http.py, _persistence.py: fix double /v1 в LLM URL
(LM Studio Unexpected endpoint)
== Frontend ==
- AgentChatModel.svelte.ts: 5 atoms, 3 actions, countdown, context
- AgentChat.svelte: production banner, process steps, debug panel
- ConfirmationCard.svelte: 7 risk tones, permission_denied, countdown
- ToolCallCard.svelte: retrying/timeout/cancelled states
- StreamProcessor.svelte.ts: tool_retry, timeout, permission_denied
- TopNavbar: sparkles icon + Ассистент
- sidebarNavigation: AI section
- DashboardHeader, datasets/+page: contextual AI buttons
- Icon: sparkles, brain, cpu icons
- tailwind: assistant category colors
- i18n: en/ru nav keys
== Tests ==
- 159 backend agent tests (+16 US3: retry, timeout, summarise, contracts)
- 2544 frontend tests (+11 model + component tests)
- 15 JSON fixtures (10 API + 5 model)
== Specs ==
- specs/035-agent-chat-context/: spec, UX, plan, tasks, research,
data-model, contracts, quickstart, traceability, fixtures, checklists
Closes #035
2026-07-04 22:47:17 +03:00
047aff41d9
Task Status Center: save progress
2026-07-04 15:34:02 +03:00
61f3e6db75
feat: Git manager UI — панель управления Git + HelpTooltip + ReviewToggle
...
- GitManager: переработан в GitWorkspacePanel с вкладками
- Добавлен GitLifecycleHeader с быстрыми действиями
- RepositoryDashboardGrid: поддержка ReviewToggle, badges, env filter
- HelpTooltip: универсальный компонент подсказок с тестами
- GitManagerModel: доработаны экшены, добавлен isReady, loadDefaultBranch
- Локализация en/ru для Git UI
- tailwind: добавлен animation-delay-200
- ConfirmDialog: a11y-атрибуты для кнопок
2026-07-04 15:01:45 +03:00
a99c1d6d01
Improve agent UX and spec sync
2026-07-03 16:47:10 +03:00
53eb2b1cca
Improve reports UI and task drawer UX
2026-07-03 14:50:05 +03:00
33ee976c48
feat(reports): Task Status Center — unified /reports dashboard
...
Страница /reports трансформирована в Центр статусов задач:
Backend:
- GET /api/reports/summary — агрегированные счётчики тип×статус (5 корзин)
- GET/PUT /api/settings/reports — глобальные настройки отчётов
- _filter_tasks_by_rbac() — row-level фильтрация по роли
- normalize_task_report: LLM-валидация с ошибками → FAILED/PARTIAL
- get_summary(): 5 корзин pending/running/awaiting_input/success/failed
Frontend:
- TaskCenterModel.svelte.ts (400 строк) — Screen Model
- SummaryPanel — сводная панель с цветовым кодированием и active filter
- ReportCard — humanized labels, duration, task_id, failed border
- FilterBar — search + sort + time range с label'ами
- Pagination — showingText, уникальные id для select
- Quick views: «Упавшие», «В работе», «Успешные»
- TaskDrawer: scroll-to-error, footer скрыт для terminal, «Н/Д» fix
Тесты: 48 backend + 38 frontend (2521 всего)
Build: ✅ Console errors: 0
2026-07-02 18:53:58 +03:00
8c10632494
feat(semantic): curator-driven protocol hardening — decision memory + relation repair
...
- Add @RATIONALE/@REJECTED to 103+ C4/C5 contracts across backend core, services, API routes, and frontend models
- Fix 109 unresolved @RELATION edges (Auth.*, SupersetClient.*, AgentChat.*, ADR cross-refs)
- Add 13 @ingroup tags for DSA/HCA attention grouping
- Repair 29 stale graph edges via index rebuild
- Update .kilo agent prompts and skills for GRACE-Poly v2.6 compliance
- Git integration: merge routes, branch lifecycle, remote providers, UX components
- 0 broken anchor pairs, index rebuilt with 0 parse warnings
2026-07-02 08:53:19 +03:00
64564da988
fix(git): fix 17 missing async/await bugs + UX overhaul
...
Backend:
- fix 17 missing 'await' in git route handlers causing silent no-ops
(branches, diff, history, commit, push, pull, merge, promote, sync)
- fix async coroutine passed to run_blocking in git_plugin.py
Frontend:
- add collapsible 'How it works' onboarding (GitHelpPanel)
- add status legend with color-coded repository statuses
- i18n: add 50+ missing keys, replace hardcoded strings
- add Refresh button in modal header
- add PROD deploy confirmation dialog (replaces browser prompt())
- add CommitHistory to workspace tab with timeline nodes
- add post-commit success banner with next-step guidance
- increase success toast duration to 8s
- group local/remote branches in selector (optgroup)
- format last_modified dates timezone-aware
- change PROD badge from red to neutral indigo
- extract shared resolveGitStatusToken to git-utils.ts
- fix 'slug' label regression
- remove dead init_repo_button key
UI/UX audit fixes:
- add descriptions to Create/Init buttons in init panel
- add actionable CTA to server mismatch warning
- improve checkbox text phrasing
2026-07-01 20:47:25 +03:00
7613ad37ae
fix(agent): minimal safety net, zero-config router, LLM provider status UI
...
- Remove deterministic intent matching (keyword lists, infer_tool,
fast_confirmation, negation guard, classification sets)
- Embedding descriptions auto-generated from tool docstrings
- LLM provider health endpoint GET /api/agent/llm-status
- 3 error codes: LLM_PROVIDER_UNAVAILABLE, LLM_TIMEOUT, LLM_AUTH_ERROR
- Frontend banner with auto-retry 30s + input disable
- i18n for LLM status messages (assistant.json ru/en)
- 138 passing backend tests
2026-07-01 16:47:21 +03:00
12118ac4ec
fix(security): resolve Critical+High findings from module audit — agent, translate, superset_client
...
P0 — CRITICAL (CWE-798): JWT_SECRET crash-early
Replace hardcoded super-secret-key fallback with os.environ["JWT_SECRET"]
and ${JWT_SECRET:?} syntax in app.py + docker-compose files
P1 — HIGH: Frontend dependency CVEs
Upgrade svelte 5.43.8 → 5.56.4 — resolves devalue DoS (GHSA-g2pg-6438-jwpf)
and svelte XSS (GHSA-crpf-4hrx-3jrp, GHSA-m56q-vw4c-c2cp, GHSA-rcqx-6q8c-2c42)
P2 — MEDIUM: Logging hygiene + contract gaps + tool resolver refactor
Apply _redact_sensitive_fields() in middleware + event streaming
Truncate LLM error body to 100 chars
Add @RATIONALE/@REJECTED to HandleResume + SaveConversation
Refactor deterministic intent matching → LLM-driven tool resolution
P3 — LOW: Translate logging hardening
Move _sanitize_url() to _utils.py (shared, no circular imports)
Sanitize base_url before logging in _llm_call.py and _llm_async_http.py
Emit EXPLORE warning when LLM_SSL_VERIFY=false disables TLS
superset_client module: passed clean — no changes needed
2026-07-01 13:17:29 +03:00
e174c11d4a
tasks 033 updated
2026-06-30 19:05:17 +03:00
e40724a0fe
fix: timezone handling across fullstack — UTC parsing + display in configured TZ
...
Root cause: backend returned naive ISO datetimes (no Z/offset) → JS parsed them as
browser local time → 3h drift for MSK users → '3ч' instead of 'только что'.
Backend:
- schemas/agent.py: add field_serializer('Z' suffix) for ConversationItem.updated_at
and MessageItem.created_at — naive datetimes serialized as UTC
- routes/agent_conversations.py: datetime.utcnow() → datetime.now(timezone.utc) (3x)
Frontend:
- New: stores/timezone.svelte.ts — global reactive appTimezone store
- dateFormat.ts: add parseDateUTC() (appends 'Z' to naive ISO), all format*()
functions now use parseDateUTC + { timeZone: appTimezone.current }
- ~25 files: replace new Date(apiString) → parseDateUTC(apiString),
add timeZone: appTimezone.current to toLocaleString()/toLocaleDateString()
- SystemSettings.svelte + HealthCenterModel sync appTimezone to global store
- ConversationList.svelte: fix relativeTime() and date grouping (the '3ч' bug)
Verified: backend schema test, frontend 2501 tests pass, build succeeds,
browser validation on /agent and /settings.
2026-06-30 18:11:42 +03:00
131c7cdfa4
chore: remaining pre-existing changes (storage, stream processor, tests, run.sh)
2026-06-30 15:21:15 +03:00
3b4ac807a5
feat(agent+ui): fullstack agent module refactoring + UI/UX improvements
...
## Backend: agent module GRACE-Poly compliance
- Split app.py (749→~280 lines) into _tool_resolver, _confirmation, _persistence
- All 18 naked functions wrapped in #region/#endregion contracts
- Fixed @DEFGROUP→@defgroup typos; added @DATA_CONTRACT, @SIDE_EFFECT, CoT logs
- Conversation list API: added last_role, has_tool_calls, has_error, risk_level fields
- Message state detection: Russian/English error patterns (недоступен, unavailable)
- State field preserved in save_conversation messages
- HITL titles: descriptive tool names instead of generic "HITL resume"
## Backend: conversation title generation (two-layer)
- Layer 1: clean_title() — rule-based, strips file markers, pre-fetch blocks, JSON/CSV,
URLs, code; truncates at 80 chars word boundary (25 unit tests, all edge cases)
- Layer 2: generate_llm_title() — async best-effort LLM titling via /v1/chat/completions
with per-conversation lock, graceful degradation on failure
## Frontend: conversation list indicators (orthogonal system)
- Status dot (green/yellow/red/blue) per conversation state
- Icon column: tool activity, errors, waiting, completed
- Risk stripe (left border accent) + message count badge + relative time
- Fixed group labels: "Сегодня"/"Вчера" instead of "3 ч"/"5 ч"
- Hide "Окружение: —" when env is empty
## Frontend: guardrails card verification + fixes
- Confirmed all interaction modes: Enter/click confirm, Escape/click deny
- Auto-populate envId from environmentContextStore in DashboardDetailModel
- Better error message: missing_context_hint with recovery guidance
## Design system: semantic tokens
- Added category-* gradient tokens to tailwind.config.js
- Sidebar + Breadcrumbs use semantic tokens (10 categories)
- Raw Tailwind reduced from ~50 to 6 occurrences
- Added skip-to-content link in root layout (+layout.svelte)
- Added aria-label on DashboardDataGrid row checkboxes
## Protocol: INV_7 pragmatic exception
- Modules may exceed 400 lines when contract-dense (every function has #region)
- Recorded in semantics-core SKILL.md with rationale
Total: 5841+ contracts, 2993+ edges, backend 41/41, frontend 2501/2501
2026-06-30 15:21:05 +03:00
e8d6d7d0db
fix(agent): critical agent chat bugs — backend startup & frontend streaming state
...
Backend (tools.py):
- Add Python docstrings to all 17 @tool functions (LangChain ValueError)
- Add @INVARIANT ADR: docstring requirement documented in module header
- Fix 2 f-string escaped-quote syntax errors (Python 3.13)
Frontend — compile errors (+page.svelte):
- Fix mismatched <button>/</Button> tags
- Fix missing Button import for mobile sidebar close
Frontend — streaming state loss on conversation switch (AgentChatModel):
- Add _commitStreamingPartial() helper — saves in-progress text before cancelling
- selectConversation() commits partial text to OLD conversation before switching
- createConversation() commits partial text before clearing state
- loadHistory() sets _userCancelled=true to suppress fallback messages
Frontend — ConnectionManager:
- Pass error reason through onDisconnectedPermanent callback → model.error
Frontend — null safety:
- Guard _client.submit() calls against null _client in _sendNow and resumeConfirm
2026-06-30 13:25:28 +03:00
12678c637b
fix(agent-chat): streaming state leak, document parser magic bytes, HITL flow
...
### Bugfixes — Agent Chat 'Думаю' State Leak
- fix(agent-chat): loadHistory() now resets streamingState/idle + cancels stale
submission — prevents 'Думаю' state leak across conversation switches
- fix(agent-chat): onDisconnected/onDisconnectedPermanent cascade to
streamingState — prevents permanent hang on connection loss during stream
- fix(agent-chat): guard on isLoadingHistory — prevents false commit
of 'agent unavailable' fallback when switching conversations
- fix(agent-chat): remove race in _sendNow empty-response check vs Svelte
microtask (duplicate logic removed, handles correctly)
- fix(stream-processor): confirm_resolved now appends msg.text to partialText
instead of dropping it
### Bugfixes — Backend PDF Upload
- fix(document-parser): _detect_format_by_magic() — reads file header magic
bytes as fallback when Gradio loses filename
- fix(document-parser): improved name extraction — tries orig_name, path stem
- fix(document-parser): @RELATION AgentChatTypes -> AgentChat.Types
### HITL Flow & Agent Chat Improvements
- feat(agent): HITL resume confirm/deny with userId/userJwt/envId propagation
- feat(agent): confirm_required metadata fallback via aget_state() after
'Event loop is closed' error during interrupt
- feat(agent): interrupt_before re-enabled via AGENT_CONFIRM_TOOLS env var
- feat(frontend): debug panel with connection/stream state monitoring
- feat(frontend): AgentChatModel constructor options + onBeforeSend callback
- feat(frontend): crypto.randomUUID() for local conversation ID on first send
### Backend Agent Refactoring
- refactor(agent): langgraph_setup — monkey-patch for PydanticSerializationError
- refactor(agent): tools.py — dual identity headers, expanded tool set
- refactor(agent): run.py — _find_free_port, Gradio server port fallback
- refactor(agent): app.py — file size validation, message truncation, HITL path
### Frontend
- feat(dashboard-hub): DashboardHubModel with filters, pagination, git actions
- feat(ui): DateRangeFilter component
- feat(i18n): new dashboard keys; cache tooltips fix
- fix(i18n): full run tooltips — cache is NOT ignored
### Semantic Protocol
- chore(agents): update all agents with canonical format
- chore(skills): sync semantics-core, semantics-contracts, molecular-cot-logging
### Housekeeping
- chore: remove stale semantic reports (10 files, Jan 2026)
- chore: update 033-gradio-agent-chat specs, contracts, UX, tasks, tests
- chore: add .agents/ directory (mirrors .opencode/ agent layouts)
- chore: update run.sh with DEV_MODE, port management
2026-06-29 17:15:25 +03:00
550119c399
fix(translate): complete i18n for run page UX improvements
...
- Add missing i18n keys to ru/en translate.json:
run: disabled_draft, disabled_running, disabled_schema,
load_more_runs, correct, dismiss, download_csv, insert_method
preview: translation
schedule: delete_confirm
bulk_replace: confirm_count_input, dictionary,
select_dictionary, word_boundary_hint
run filters: records_filter_all/success/failed/skipped
- Add auto-expand for failed/partial runs in TranslationJobModel
- Add typed-count confirmation for bulk replace >100 changes
- Add word-boundary hint in BulkReplaceModal
- Add auto-select target language when only one exists
- Add delete confirmation in ScheduleConfig
- Add Escape/Enter keyboard handling for run dialog
- Replace emoji with Icon components in CorrectionCell
- Use semantic Tailwind tokens for insert-method badge
- Add run start date/time and pagination to run history
- Keep TranslationRunProgress visible after run completion
2026-06-19 09:55:43 +03:00
3133e50645
perf: fix translate deadlock, speed, trace_id, UI bugs — fullstack patch
...
## Backend (7 production files + 6 test files)
### P0-2: LLM output truncation cascade fix
- _token_budget.py: OUTPUT_PER_ROW_PER_LANG 120→200, OUTPUT_SAFETY_FACTOR 0.70→0.55
- Prevents finish_reason=length → split → retry cascade (3 calls → 1 call per batch)
- P2-8: added qwen-flash/qwen-plus/qwen-max/qwen-coder to PROVIDER_DEFAULTS
### P1-4/P1-5: EncryptionManager singleton
- encryption.py: get_encryption_manager() process-wide singleton
- llm_provider.py: use singleton instead of new EncryptionManager() per batch
- Eliminates ~90 redundant Fernet key validations per translation run
### P1-6: Cache-hit log aggregation
- _batch_proc.py: one log per batch (batch_rows + cache_hits) instead of per-row
- 1076 log lines → ~30 per run
### P1-7: Timezone-aware datetime fix
- scheduler.py: _ensure_aware() helper for naive DB datetime → UTC-aware
- Fixes TypeError in scheduled translation concurrency check
### P2-9: Connection test timeout
- connection_service.py: asyncio.wait_for(15s) on all dialect tests
- Prevents 2-minute UI hangs from DNS/TCP stalls
### Trace ID propagation
- middleware/trace.py: inject x-trace-id response header via ASGI send wrapper
### Test fixes & integration tests
- test_scheduler.py: AsyncMock for execute_run, mock get_async_job_runner
- test_sql_insert_service.py: AsyncMock for execute_sql
- test_token_budget.py: batch_size 50→45 for new OUTPUT_PER_ROW_PER_LANG=200
- test_encryption.py: +2 singleton tests
- test_scheduler_ensure_aware.py: +4 (naive→aware, passthrough, None, subtraction)
- test_batch_classify_persist.py: +2 cache-hit aggregation tests
- test_connection_service_edge.py: +2 timeout tests
- test_trace_middleware.py: +4 x-trace-id header tests
- test_token_budget.py: +4 qwen-flash/O200 tests
## Frontend (7 production files + 5 test files)
### Trace ID propagation
- api.ts: _captureTraceId() reads x-trace-id → setTraceId() in fetchApi/requestApi/postApi/deleteApi
### Duplicate datasource columns fetch
- ConfigTabForm.svelte: guard availableColumns.length === 0 before fetch
### Admin pages Svelte 5 runes fix
- admin/users/+page.svelte: plain let → () for all template-bound vars
- admin/roles/+page.svelte: same fix
- Both pages were stuck on «Загрузка...» due to mixed reactivity models
### Validation popover positioning
- +page.svelte: pass trigger HTMLElement instead of event
- DashboardHubModel.svelte.ts: toggleValidationPopover(HTMLElement), closeValidationPopover()
- Added X close button + click-outside overlay + i18n
### Test fixes & integration tests
- api.test.ts: mock setTraceId/getTraceId, +3 _captureTraceId tests
- provider_config.integration.test.ts: handleDelete→promptDeleteProvider
- DatasetPreview.test.ts: dashboards/ → ROUTES.dashboards
- test_config_tab_form.svelte.js: +2 columns fetch guard tests (NEW)
- admin-users.test.ts: +3 loading→table tests (NEW)
- admin-roles.test.ts: +2 loading→table tests (NEW)
## Semantic curation
- Removed @COMPLEXITY N from 6 route files + metrics.py (duplicate of [C:N])
- Added [C:N] to 2 orphan child contracts in metrics.py
- Added [C:N] + @BRIEF to 4 frontend anchors
- Fixed #region → # #region consistency in validation_tasks.py
## Verification
- Backend: 608 pytest passed (0 failures)
- Frontend: 2472 vitest passed (128 files, 0 failures)
- Frontend build: ✓ built in 18s
- Browser: dashboards, admin/users, admin/roles, validation popover — all green
2026-06-18 23:54:57 +03:00
4dce669844
fix(tests): 61 failed backend unit tests — async/await mocks, deadlock fix, SyntaxError repairs
...
Группы исправлений:
- Группа 1 (async/await misuse): MagicMock → AsyncMock для get_dashboards,
export_dashboard, import_dashboard, sync_environment, get_run_detail,
list_all_runs, create_task и др. — 23 теста
- Группа 2 (runner.run deadlock): добавлены моки get_async_job_runner +
IdMappingService/AsyncSupersetClient в migration plugin + API tests
для предотвращения вечной блокировки future.result() — 16 тестов
- Группа 3 (SyntaxError): исправлены 7 незакрытых скобок ')' в
test_validation_tasks_comprehensive.py (QA-агент оставил AsyncMock
без закрывающих скобок)
- Группа 4 (mock verification): logger mock error→explore, scheduler tests
skipped (удалён из production), dataset mapper — 11 тестов
- Группа 5 (search/assistant): MagicMock → AsyncMock — 9 тестов
- Группа 6 (extractor parsing): AsyncMock для async методов — 9 тестов
Итого: 61 ранее FAILED → 274 passed, 4 skipped, 0 failed
2026-06-18 14:41:13 +03:00
8aa5c57b60
fix(dashboard): GIT filter shows i18n labels matching table display
...
Filter dropdown showed raw backend tokens ('no_repo', 'diff') while
table cells showed i18n labels ('НЕТ РЕПО', 'ЕСТЬ ИЗМЕНЕНИЯ').
- Add getFilterOptionLabel() to DashboardsFiltersModel for label mapping
- Add getLabel prop to ColumnFilterPopover for display/value separation
- Delegate getFilterOptionLabel through DashboardHubModel
- Raw tokens remain as filter values (backend compatible)
- Labels rendered via getLabel in filter dropdown
2026-06-18 12:01:47 +03:00
5ca477983c
fix(dashboard): git filter shows 'pending' instead of 'no_repo' for dashboards without repo
...
The frontend defaulted git status to 'pending' when git_status was null,
but the backend returns 'no_repo' for such dashboards. This mismatch
caused the git filter to show 'pending' as an option that matched nothing,
making all dashboards disappear with no way to recover.
Fixed by aligning the frontend fallback to 'no_repo' to match backend.
2026-06-18 09:28:33 +03:00
28ba0250ba
fix: unhandled promise rejection in SearchableMultiSelect debounce
...
- Wrap onSearch call in .catch() to prevent Uncaught (in promise) errors
- Add console.warn to DashboardHubModel.loadDashboardSearchOptions catch
for debugging visibility
2026-06-17 17:33:44 +03:00
149c05bf1c
fix(frontend): full ADR compliance — Model-View concept, model decomposition, button migration
...
P0 — Model-first ADR compliance:
- Decompose DashboardHubModel (590→496 lines) into Dashboards.FiltersModel,
Dashboards.SelectionModel, Dashboards.GitActionsModel (DG split per plan)
- Decompose AgentChatModel (630→356 lines) into ConnectionManager,
StreamProcessor, LocalStorage, shared types
- Decompose MigrationModel (457→389 lines) into WizardModel, ExecutorModel
P0 — /ui atom compliance:
- Replace all raw <button> with <Button> from /ui in dashboards/+page.svelte
(~20 replacements) and 16 additional routes/ files (~70 replacements total)
P0 — Hierarchical region IDs (ATTN_2):
- Rename all 22 model #region/#endregion IDs from flat to Domain.Name format
- Update @ingroup from generic 'Models' to domain-specific (Dashboards, Git, etc.)
P1 — UX contract compliance:
- Add @UX_STATE declarations to agent/+page.svelte
- Extract Gradio Client.connect from page into AgentChatModel.retryConnection()
All new model files have proper GRACE anchors (#region/#endregion, @ingroup,
@BRIEF, @INVARIANT, @STATE, @ACTION, @RELATION).
Build: npm run build passes.
Tests: DashboardHubModel 112/112, MigrationModel 74/74 pass.
2026-06-17 14:02:17 +03:00
af923972b6
fix(agent): save conversations to DB, fix Test button hang, wire hasNext/search
...
## Root cause: _save_conversation() dead code + missing message persistence
### Backend: Conversation persistence (3 critical bugs)
- **app.py**: Replaced early with so _save_conversation() executes
after successful stream — was dead code on normal path
- **app.py**: Added _save_conversation call in HITL resume path (confirm/deny)
- **app.py**: Added broad that saves conversation (at least user
message) before re-raising on LLM errors (APIConnectionError etc.)
- **app.py**: _save_conversation now passes user_id from JWT (not hardcoded UUID)
and includes messages[] in payload
- **agent_conversations.py**: save_conversation endpoint now processes body.messages
and creates AgentMessage records (idempotent by msg id)
### Frontend: Agent chat sidebar wiring
- AgentChatModel.svelte.ts: added public derived getter
- AgentChatModel.svelte.ts: added method
- agent/+page.svelte: wired hasNext={model.conversationsHasNext} (was hardcoded false)
- agent/+page.svelte: wired onsearch to model.searchConversations (was no-op)
### Frontend: LLM Provider Test button hang fix
- ProviderConfig.svelte: resetForm/handleEdit now reset isTesting=false, isProbing=false
- ProviderConfig.svelte: Cancel button calls abortPendingRequests()
- ProviderConfig.svelte: Added AbortController lifecycle — cancels in-flight test/fetch
requests on modal close or provider switch, preventing stale disabled buttons
- provider_config.integration.test.ts: added 6 abort/reset invariant tests
2026-06-14 16:07:06 +03:00
85857e10e4
feat(ui): update frontend for direct DB insert — i18n, api client, components, models
...
- api.ts, api/translate.ts: add connection API methods (fetchConnections,
createConnection, testConnection, etc.)
- i18n (en/ru): add connection management and insert method translation keys
- TranslationJobModel.svelte.ts: add insert_method, connection_id fields
- ConfigTabForm.svelte, RunTabContent.svelte: integrate InsertMethodSelector
- TranslationPreview.svelte, TranslationRunResult.svelte: show insert method
badge and connection name in results
- TargetTabForm.svelte, TargetSchemaHint.svelte: insert method awareness
- routes.ts, routes-link-integrity: register connections settings tab
- test_translation_preview.svelte.js: update preview tests
- package.json: update deps as needed
2026-06-11 19:13:05 +03:00
2b303f92b3
test: bring frontend test coverage to 98% across core lib modules
...
## Summary
- Added 35+ new test files and expanded 22+ existing ones
- Coverage: statements 99.65%, lines 99.9%, functions 99.9%, branches 87.77%
- All thresholds enabled and enforced in vitest.config.js
## Details
### Stores (stores/__tests__/)
- test_health.ts, test_translationRun.ts, test_environmentContext.ts
- test_maintenance.ts, test_environmentContext.2.ts
- Expanded sidebar.test.ts, assistantChat.test.ts, taskDrawer.test.ts
- Expanded test_activity.ts, test_datasetReviewSession.ts
### Models (models/__tests__/)
- AgentChatModel.test.ts (77.7%→99.6%), AgentChatModel.2.test.ts
- BranchModel.test.ts, DashboardDetailModel.test.ts
- DashboardHubModel.test.ts (97.9%→100%)
- DatasetDetailModel.test.ts, DatasetReviewModel.test.ts
- DatasetsHubModel.test.ts, DictionaryDetailModel.test.ts
- GitConfigModel.test.ts, GitManagerModel.test.ts
- GitStatusModel.test.ts, HealthCenterModel.test.ts
- LLMReportModel.test.ts, MigrationModel.test.ts
- MigrationSettingsModel.test.ts, TranslateHistoryModel.test.ts
- TranslationJobModel.test.ts, ValidationRunDetailModel.test.ts
- ValidationTasksListModel.test.ts
### API (api/__tests__/, api/translate/__tests__/, api/dataset-review/__tests__/)
- api.test.ts (100% stmts), assistant.test.ts, datasetReview.test.ts
- maintenance.test.ts, corrections.test.ts, datasources.test.ts
- dictionaries.test.ts, jobs.test.ts, runs.test.ts, schedules.test.ts
- useReviewSession.test.ts + useReviewSession.2.test.ts
### Auth (auth/__tests__/)
- permissions.test.ts (95.2%→100%), store.test.ts
- store.browser-off.test.ts (covers !browser guards)
### UI (ui/__tests__/)
- EmptyState.test.ts, FeatureGate.test.ts, FeatureGate.2.test.ts
- HelpTooltip.test.ts, Icon.test.ts, Input.test.ts, Select.test.ts
- LanguageSwitcher.test.ts
### Top-level lib (lib/__tests__/)
- cot-logger.test.ts, routes.test.ts, stores.test.ts
- toasts.test.ts, utils.test.ts
### Helpers (helpers/__tests__/)
- review-workspace-helpers.test.ts
### Source changes (minimal, non-breaking)
- sidebar.svelte.ts: exported loadState() for testability
- HelpTooltip.svelte: removed default () destructuring
- vitest.config.js: coverage scope narrowed, thresholds enforced
- package.json: fixed @vitest/coverage-v8 version mismatch
2026-06-10 14:59:40 +03:00
f87ebf5d4b
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
a7fb06cd8e
tasks ready 1
2026-06-09 09:43:34 +03:00
8e8a3c3235
feat: attention-optimized semantic protocol v2.7
...
Core changes:
- Add @defgroup/@ingroup to 1791 C2+ contracts (555 files) for HCA 128× pre-training DSA grouping
- Add §0.1 Pre-Training Frequency matrix to semantics-core
- Add §VIII Attention Architecture rules (ATTN_1-4) with MLA/CSA/HCA/DSA mechanics
- Add @defgroup/@ingroup to canonical syntax (§II) and all contract examples
Agent prompts (5 files):
- Add ZERO-STATE RATIONALE with MLA/CSA/HCA/DSA compression mechanics
- Add pre-training note: @RATIONALE/@REJECTED are in-context learned tags
- svelte-coder: add missing #region contract, fix Svelte rule violations
- python-coder/fullstack-coder: honor function contracts from speckit plan
- qa-tester: add attention compliance audit (P3 ATTN_1-4 checks)
Skills (6 files):
- Translate all axiom_config descriptions to English
- Fix doc_dirs to index .opencode/ and .specify/
- Deduplicate 5× complexity_rules → single global_tags catalog
- Reduce semantics-svelte 591→485 lines (remove duplicate code blocks)
- Fix semantics-testing: 'Short IDs' → 'Short hierarchical IDs'
- Fix all examples: flat IDs → hierarchical Domain.Name format
- Fix Svelte examples: replace raw Tailwind + <button> with semantic tokens + /ui
Speckit workflow (commands + templates):
- speckit.plan: add Function-Level Contracts for C3+ with @PRE/@POST/@TEST_EDGE
- speckit.plan: add Attention Compliance Gate (ATTN_1-4 before contract generation)
- speckit.tasks: add function contract inlining format (constraints in task description)
- speckit.specify: load semantics-core for spec density rules
- spec-template: add #region contract, @SEMANTICS grouping, hierarchical IDs
- ux-reference-template: add #region wrapper
- plan-template: add attention gate, @defgroup/@ingroup guidance
- tasks-template: add attention audit + rebuild + orphan check tasks
- constitution.md: translate to English, add Principle VIII (attention-optimized contracts)
Reference modules rewritten (hierarchical IDs + full contracts):
- Auth.Jwt: 6 child contracts with @RATIONALE/@REJECTED/@TEST_EDGE
- Api.Auth: 5 endpoints with @TEST_EDGE + molecular CoT markers
- Migration.Model: @defgroup Migration with 18 @ACTION + 6 @INVARIANT
Scripts:
- add_defgroup_ingroup.py: zero-risk additive @ingroup migration (1791 insertions)
- migrate_hierarchical.py: flat→hierarchical ID dry-run analysis (792 contracts)
- merge_prompts.py: merge all prompts/skills/commands into one review file
Config:
- axiom_config.yaml: 749→395 lines (-47%), English, doc_dirs include prompts
- Fix test_datasets.py import collision (rename → test_datasets_routes.py)
- Fix test_preview.py: SupersetClient→get_superset_client, AsyncMock, logger f-string
2026-06-08 16:30:59 +03:00
41a3a41ec4
test(frontend): add model unit tests for Screen Models
...
Add L1 invariant tests for all Screen Models:
- DashboardDetailModel: test load, delete, pagination, column filter
- DashboardHubModel: test load, environment switching, selection, git actions
- DatasetDetailModel: test load, edit, delete
- DatasetsHubModel: test load, filter, pagination
- DictionaryDetailModel: test load entries, add, edit, delete, search
- LLMReportModel: test load, filter, report generation
- TranslateHistoryModel: test load runs, filter, pagination
- ValidationRunDetailModel: test load details, records
- ValidationTasksListModel: test load tasks, status transitions
Per semantics-testing protocol: L1 tests verify model invariants without
DOM rendering.
2026-06-04 16:17:59 +03:00
2f9058d888
feat(frontend): add admin/tools pages, i18n, UI improvements, route annotations
...
New pages:
- /admin: admin overview page with links to user/role/settings/LLM management
- /tools: tools overview page with links to mapper/debug/storage/backup tools
i18n:
- nav.json (en/ru): add description keys for admin and tools sub-items
- migration.json (en/ru): add help tooltips and step-by-step instructions
for the database mapping workflow
UI components:
- EnvSelector: add optional helpText with HelpTooltip
- MappingTable: add HelpTooltip for status column
- MultiSelect: add id for accessibility, fix label element structure
- Input: fix reactive id assignment with ()
- Select: fix reactive id assignment with ()
Routes:
- routes.ts: add admin.overview() and tools.overview() routes
- dashboards/+page.svelte: add @RELATION BINDS_TO annotation
- migration/mappings/+page.svelte: add HelpTooltip, Card imports, help texts
- translate pages: minor annotation updates
Other:
- .gitignore: add backend/:memory (SQLite test artifact)
2026-06-04 16:17:52 +03:00
26dfde81a5
refactor(frontend): migrate health center page to HealthCenterModel
...
Extract state management from inline health page into HealthCenterModel:
- HealthCenterModel.svelte.ts (new): hosts all state atoms (),
derived values (), and core actions (load, filter, delete)
- health page reduced from ~120 to ~27 lines of script — thin shell
delegating to model; only DOM/template concerns remain
- Integration test updated for model-based architecture
- HealthCenterModel.test.ts (new): model invariant tests
2026-06-04 16:17:03 +03:00
380fd4c2fa
refactor(frontend): migrate dataset review to DatasetReviewModel
...
Extract all state management from the inline page into a dedicated
DatasetReviewModel class following the Screen Model pattern:
- DatasetReviewModel.svelte.ts (new): hosts all state atoms (),
derived values (), and core actions (load, submit, export)
- review-workspace-helpers.ts moved from routes/ to /helpers/
- useReviewSession.ts moved from routes/ to /api/dataset-review/
- DatasetReviewModel.test.ts (new): model invariant tests
- [id]/+page.svelte: reduced from ~380 to ~190 lines — thin shell
delegating to model; only navigation/DOM concerns remain inline
- Old files deleted: routes/datasets/review/{review-workspace-helpers,useReviewSession}.ts
- Updated ux test for new model-based architecture
2026-06-04 16:16:51 +03:00
a1a855e670
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
371834cf43
chore: commit remaining maintenance and model changes
2026-06-03 23:26:20 +03:00
a819e1ec4d
fix: resolve 60 unresolved @RELATION targets and add @RATIONALE to models
...
- Batch-fixed [ApiModule.xxx] → [xxx] in 60 @RELATION targets across 26 API files
- Fixed [ToastsModule.addToast] → [addToast:Function] in notifyApiError contract
- Added #region contracts for getMaintenanceEventsWsUrl and getTranslateRunWsUrl
- Added @RATIONALE belief protocol to ValidationTasksListModel, DeploymentModel, MigrationModel
- Semantic audit: unresolved_relation dropped 104 → 43 (-59%)
2026-06-03 16:11:03 +03:00
5e4b03a662
fix: resolve all 221 eslint errors across frontend
...
- svelte/no-unused-svelte-ignore (7→0): removed stale a11y ignore comments
- svelte/no-unnecessary-state-wrap (5→0): removed () around SvelteSet
- svelte/prefer-writable-derived (3→0): suppressed with eslint-disable comments
- svelte/no-at-html-tags (2→0): added eslint-disable-next-line comments
- no-self-assign (1→0): replaced self-assign with map-based array update
- no-unsafe-optional-chaining (21→0): added ?? fallback defaults
- no-unused-vars (181→0): removed dead imports, vars, catch bindings
- parse error in health.svelte.ts: fixed malformed import statement
- Removed deprecated .eslintignore file (config moved to eslint.config.js)
- Updated test assertion that checked for removed dead code
Remaining warnings: 190 require-each-key + 67 navigation-without-resolve
(both intentionally set to warn level in eslint.config.js)
2026-06-03 15:51:31 +03:00
5ada8cf745
test(translate): add TranslationJobModel L1 tests for field mapping invariants
...
- 19 tests covering:
- disableReasoning load from API (true, false, omitted, null)
- disableReasoning save to API (POST new + PUT update)
- databaseDialect save to API (populated, empty, PUT)
- datasourceSearch name lookup on job page load
(found by ID, found by string ID, not found, no ID, API error)
- uxState transitions: loading→configured, idle on job fetch
failure, idle on Promise.all entry failure
Also changed datasourceSearch lookup from fire-and-forget .then()
to awaited try/catch — guarantees name is populated before
uxState transitions to 'configured'.
2026-06-03 12:04:18 +03:00
ebbbd51230
fix(translate): restore datasource display name on job page load
...
When opening a saved translation job, the datasource search input was empty
because datasourceSearch was never populated from the loaded job data.
The raw datasourceId was loaded correctly, but the display name
("table_name (database · dialect)") was missing.
Added fetchDatasources lookup in loadInitialData after environmentId is set:
finds the matching datasource by ID in the list and sets datasourceSearch
to the same format used in selectDatasource().
2026-06-03 11:52:38 +03:00
236dadb914
fix(translate): load/save disableReasoning and databaseDialect from/to API
...
- HIGH: disableReasoning was declared as and bound in UI but never
loaded from API (loadInitialData) nor sent in save payload. Checkbox was
decorative — value always defaulted to false and never persisted.
Backend fully supports disable_reasoning column + schema + runtime logic.
- MEDIUM: databaseDialect was loaded from API and displayed in UI but never
returned in save payload, causing unnecessary back-end re-detection on
every save.
- Documents includeSourceReference as known limitation (no backend column).
2026-06-03 11:44:14 +03:00
1729739624
fix(frontend): target column mapping fields not loaded from job
...
Three fields were never loaded from backend job data:
- targetLanguageColumn (job.target_language_column)
- targetSourceColumn (job.target_source_column)
- targetSourceLanguageColumn (job.target_source_language_column)
Caused empty inputs in Target Config tab after page load.
Also added missing target_source_language_column to save payload.
@RATIONALE The model's loadJob() method was incomplete — it only
loaded targetColumn but omitted the other three target mapping fields.
Save payload also omitted target_source_language_column.
Verification: browser reconfirmed — all 4 target columns pre-filled
with saved values after reload.
2026-06-03 11:38:38 +03:00
3b5b228f96
fix(frontend): replace with getT()?. in all .svelte.ts model files
...
Following the documented pattern from 27435e4 (bug report:
docs/bug-reports/2026-06-02-svelte5-proxy-store-t-undefined.md).
$t.x references in .svelte.ts files are fragile — Svelte 5 compiler
can fail to detect the Proxy-based t store as subscribable, causing
ReferenceError: $t is not defined at runtime.
Changed 3 model files:
- DashboardDetailModel.svelte.ts — 8 $t.dashboard?.x → getT()?.dashboard?.x
- TranslateHistoryModel.svelte.ts — 4 $t.translate?.run?.x → getT()?.translate?.run?.x
- ValidationTasksListModel.svelte.ts — 2 $t.validation?.x → getT()?.validation?.x
All imports changed from { t } to { getT } (or { _, getT } for
TranslateHistoryModel which already used _() for keyed lookups).
@RATIONALE getT() returns the plain translation object directly,
bypassing the Proxy store entirely — this avoids Svelte 5's fragile
static store-detection on Proxy objects.
Verification: npm run build clean, browser renders for all 4 affected
routes with zero console errors.
2026-06-03 10:59:22 +03:00
27435e4d92
fix(frontend): replace $t with _t pattern in translate components
...
Svelte 5 compiler fails to detect Proxy-based i18n store `t` as a store
in deeply nested/complex templates and in `.svelte.ts` model files,
generating `ReferenceError: $t is not defined` at runtime.
Fix: replace `$t.` references with:
- Template: `_t.` where `const _t = $derived(getT())`
- Script: `getT()?.` direct function call
Applied to:
- translate/[id]/+page.svelte (the failing page)
- TranslationJobModel.svelte.ts ($derived.by() in `tabs`)
- 12 translate components (ConfigTabForm, ScheduleConfig,
TranslationPreview, TargetTabForm, RunTabContent, BulkReplaceModal,
TranslationRunProgress, TranslationRunResult, TermCorrectionPopup,
BulkCorrectionSidebar, TranslationMetricsDashboard, CorrectionCell,
TranslationRunGlobalIndicator)
Verified all 5 tabs render correctly in browser:
Config, Preview, Target, Run, Schedule.
Build clean, 698/698 tests pass, 0 color violations.
2026-06-02 20:38:38 +03:00
fbb6a78d7d
refactor(frontend): add comprehensive TranslationJobModel for translate/[id] page
...
Model covers all 49 atoms: Config, Preview, Target, Run, Schedule tabs.
Environment switching, datasource loading, saveJob(), run lifecycle.
Page not yet bound — requires manual template migration due to
complex bind: short syntax and sub-component dependencies.
DictionaryDetail page: 822→166 (-80%) with DictionaryDetailModel.
3→2 oversized pages remaining (dashboards, migration).
2026-06-02 19:54:15 +03:00
09ee1143d5
refactor(frontend): extract TranslationJobModel for translate job config page
...
Translation job config: 835→131 lines (-84%).
Model: 5-step wizard (Config, Preview, Target, Run, Schedule),
form state management, saveJob() with method detection.
3→2 oversized pages remaining.
2026-06-02 18:40:23 +03:00