1586c31d9b
chore: причесать .env.example — удалить дубликаты и мёртвые vars
...
- backend/.env.enterprise-clean.example — удалён (точная копия root)
- .env.enterprise-clean.example — очищен от мёртвых OPENAI_API_KEY,
ANTHROPIC_API_KEY, добавлен пример Fernet-ключа
- docker/.env.agent.example — переписан под новую архитектуру:
убраны LLM_*, JWT_SECRET (больше не читаются агентом),
добавлен AUTH_SECRET_KEY
2026-07-06 08:55:11 +03:00
57b7ee05e0
test(git): align route mocks with async services
2026-07-06 01:23:20 +03:00
1e56416c9f
test(backend): update legacy agent and auth expectations
2026-07-06 01:23:09 +03:00
28cd141e76
feat(reports): add task status settings and tests
2026-07-06 01:22:39 +03:00
99bbdb4398
docs(agent-chat): update 035 verification traceability
2026-07-06 01:22:07 +03:00
082d6af3ab
test(agent-chat): audit guardrail and error handling
2026-07-06 01:20:12 +03:00
49e4ac0fe2
refactor(frontend): integrate compact filters into reports page
...
- Rename page title "Отчеты задач" → "Центр статусов"
- Remove standalone quick-status filter block (moved to FilterBar)
- Remove inline filter/sort/time-range HTML (replaced by FilterBar)
- Replace statusTotal() with quickStatusCounts
- Pass quickStatusCounts and onQuickStatusToggle to FilterBar
- Error recovery button text "Повторить" → "Повторить загрузку"
2026-07-05 15:50:51 +03:00
86ac209615
feat(frontend): compact FilterBar with disclosure toggle and quick pills
...
- Quick status pills (Упавшие/В работе/Успешные) always visible
- Search input with flex spacer in same row
- Explicit "Фильтры" disclosure button with filter icon, badge count, chevron
- aria-expanded / aria-controls for accessibility
- Expandable panel: type, status, time range, sort controls
- Remove bottom status bar ("Показано X из Y", "Активно фильтров")
- Update tests for expanded state and quick pill interactions
2026-07-05 15:50:46 +03:00
95308273b3
refactor(frontend): replace raw buttons with /ui/Button in SummaryPanel
...
- Replace raw <button> with <Button variant="ghost">
- Dim zero-count badges with opacity-50
- Add transition-colors duration-300 to count numbers
- Replace inline reconnect link with themed <Button>
2026-07-05 15:50:41 +03:00
c75017f1e4
fix(frontend): prevent TaskList horizontal overflow
...
- Add min-w-0 overflow-hidden to TaskList shell container
- Add filtered_empty UX state to contract
- Update layout contract test to verify TaskList source directly
- Add transition-colors to status badges
2026-07-05 15:50:36 +03:00
147d711657
feat(agent-chat): complete context guardrail event coverage
2026-07-05 14:14:42 +03:00
45e781fb74
chore: commit remaining working changes
...
Backend:
- agent: confirmation, persistence, app, langgraph_setup updates
- routes: agent_superset_explore, environments, git helpers/operations
- services: git sync refactoring
- tests: git_status_route expanded
Frontend:
- Navbar: minor cleanup
- Profile: i18n (en/ru), page enhancements, integration tests
- New: _llm_params.py
2026-07-05 09:24:45 +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
a91023d83e
fix(frontend): fix Svelte prop shorthand in TranslationRunResult
...
{model.targetLanguages} is invalid shorthand — Svelte only supports
bare identifiers, not property access. Changed to explicit
targetLanguages={model.targetLanguages}
2026-07-05 09:17:33 +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
deed06fada
refactor(frontend): remove @PURPOSE duplicates, merge into @BRIEF (INV_4)
...
- ProviderConfig: remove duplicate @LAYER/@PURPOSE/@UX_STATE block
- SemanticLayerReview: generic @BRIEF → detailed @PURPOSE text,
remove duplicate @LAYER/@SEMANTICS
- ExecutionMappingReview: same — generic @BRIEF → @PURPOSE detail
- TaskRunner: remove duplicate @SEMANTICS/@PURPOSE/@LAYER block
- ValidationFindingsPanel: generic @BRIEF → @PURPOSE detail,
remove duplicate @LAYER/@SEMANTICS
All: INV_4 compliance — single source of truth for contract metadata
in #region HTML comment, no scattered duplicates
2026-07-05 08:54:38 +03:00
008a8a92a5
refactor(frontend): clean metadata on AssistantChatPanel + TaskDrawer
...
- AssistantChatPanel: C:3→C:4 (33 side-effecting functions), remove JSDoc
duplicates (INV_4), add @PRE/@POST/@SIDE_EFFECT/@DATA_CONTRACT/@RATIONALE/@REJECTED
- TaskDrawer: remove JSDoc duplicates (INV_4), replace 4x @PURPOSE
JSDoc blocks with @BRIEF/@PRE/@POST in function contracts (INV_4),
add @RATIONALE/@REJECTED
- Both: consolidate all metadata in HTML comment #region, remove
scattered JSDoc in <script>
2026-07-05 08:53:17 +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
4c5fde8b5c
chore(kilo): sync OpenCode config into Kilo format
2026-07-04 22:43:17 +03:00
1f502c9785
docs(readme): add SSL/TLS configuration section with passphrase and PKCS#12 options
2026-07-04 17:10:04 +03:00
1c6b3d6e8a
feat(ssl): add passphrase-protected key and PKCS#12 support in nginx entrypoint
...
- docker/frontend.entrypoint.sh: add 3 new functions:
- extract_p12_if_needed — openssl pkcs12 extraction to .crt+.key
- resolve_ssl_passphrase — read SSL_KEY_PASSPHRASE env var
- decrypt_key_if_needed — openssl rsa decryption before nginx start
- Pipeline: install CA -> extract p12 -> get passphrase -> select config -> decrypt key -> start nginx
- Crash-early: encrypted key without SSL_KEY_PASSPHRASE exits entrypoint
- docker-compose.enterprise-clean.yml: add SSL_KEY_PASSPHRASE to frontend env
- .env.enterprise-clean.example: document SSL_KEY_PASSPHRASE usage
- build.sh: add SSL_KEY_PASSPHRASE to generated deploy compose
2026-07-04 17:05:51 +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
0237e2f7e8
chore: добавить пример Fernet-ключа в .env.example
...
- Сгенерированный пример ENCRYPTION_KEY с командой для генерации
- Пометка 'сгенерируйте свой для прода'
2026-07-04 15:01:23 +03:00
b78493aeb7
chore: добавить примеры значений в .env.example
...
- backend/.env.example — пример DATABASE_URL с комментарием
- root/.env.example — заполнены примеры для всех переменных
(AUTH_SECRET_KEY, DATABASE_URL, INITIAL_ADMIN_PASSWORD, POSTGRES_PASSWORD)
2026-07-04 14:59:39 +03:00
ec9bc76a37
cleanup: убрать мёртвые env-переменные, консолидировать чтение в agent/_config.py
...
Удалены из кода:
- JWT_SECRET — мёртвая (decode_token использует AUTH_SECRET_KEY)
- SESSION_SECRET_KEY — заменён на прямой AUTH_SECRET_KEY
- POSTGRES_URL — deprecated fallback, удалён из database.py и reencrypt.py
Консолидировано чтение env-переменных agent-модуля:
- Создан agent/_config.py — единый модуль для FASTAPI_URL,
SERVICE_JWT, GRADIO_*, STORAGE_ROOT, AGENT_* (9 констант)
- Все agent/*.py импортируют из _config вместо разрозненных os.getenv
Удалены or-дефолты (безопасность):
- agent/langgraph_setup.py — удалён hardcoded DB URL postgres:postgres
- agent/langgraph_setup.py — удалены fallback API URL и model name
- scripts/reencrypt.py — удалён hardcoded DB URL postgres:postgres
- plugins/llm_analysis/service.py — удалены or-дефолты URL/app name
.env.example — минимализация:
- backend/.env.example: только 4 обязательные переменные
- root/.env.example: обязательные + docker + SSO/админ
Обновлены тесты (139 passed)
2026-07-04 14:58:43 +03:00
a99c1d6d01
Improve agent UX and spec sync
2026-07-03 16:47:10 +03:00
500491c281
test(tls): add encrypted (passphrase-protected) private key integration tests
...
- ca_chain fixture: add server_key_encrypted (BestAvailableEncryption) +
server_key_passphrase to returned dict; existing fields unchanged
- TestEncryptedPrivateKey: 6 new tests covering
- ssl.SSLContext.load_cert_chain() with correct/wrong/missing passphrase
- asyncio SSL server end-to-end with encrypted key + full chain trust
- openssl rsa -check with wrong/missing passphrase (CLI validation)
- All 6 tests pass; 14/14 in test_superset_tls_custom_ca.py
2026-07-03 16:46:12 +03:00
89b340c64f
fix(agent): debug panel copyDebugInfo — full state snapshot (was 9 fields, now all model atoms)
...
Previously copyDebugInfo() only exported 9 hand-picked fields
(conversation_id, thread_id, connection/streaming state, user, env,
message count, truncated tool calls, error). The debug panel was
missing LLM health (status, retry, banner), confirmation/HITL state
(pending_tool, args, risk), queue position, message previews, full
tool call objects, and UI flags (sidebar, debug panel, cancelled).
Now:
- Full model snapshot with all fields
- active_tool_calls_full — complete ToolCall objects
- last_message_preview — first 200 chars of last message
- LLM status, banner dismiss, retry countdown
- HITL confirmation state (pending_tool_name, args, risk, level)
- Conversations count, queue position, user_cancelled flag
- Visual debug panel grid: 5-column layout with new rows for
LLM health, confirmation, queue, sidebar, convs_count
2026-07-03 15:35:22 +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
1e24452b1a
chore(opencode): remove closure-gate agent; swarm-master emits summary itself
...
Eliminates closure-gate as a separate subagent. Swarm-master now
performs the closure audit and emits the user-facing summary
directly per a new SELF-CLOSURE CONTRACT (§VIIa):
- audit_contracts to verify no broken contracts post-implementation
- audit_belief_protocol to verify C5 contracts have @RATIONALE/@REJECTED
- read_events to check for runtime errors
- Noise reduction (raw dumps, browser transcripts suppressed)
- One closure summary: Applied | Verified | Remaining | Decision
Memory | Next Action
Also fixes pre-existing anchor corruption in swarm-master.md
(duplicate #endregion at file tail) per semantics-contracts §VIII.
Files changed:
- Deleted: .opencode/agents/closure-gate.md
- Deleted: .agents/agents/closure-gate.md
- Modified: .opencode/agents/swarm-master.md
- Modified: .agents/agents/swarm-master.md
2026-07-01 12:37:28 +03:00
e174c11d4a
tasks 033 updated
2026-06-30 19:05:17 +03:00
f1810090b6
feat(opencode): add security-auditor agent + /security.audit command
...
Read-only security audit tooling aligned with GRACE-Poly v2.6 and
axiom MCP scan capabilities. Combines code+secrets (S1–S3),
supply-chain (S4), and runtime/config (S5–S7) projections into a
single severity-ranked report with OWASP/CWE references.
Agent: .opencode/agents/security-auditor.md
- mode: all, edit: deny (hard read-only contract)
- 7 orthogonal projections with pattern catalogs for secrets, Python
SAST, Svelte/TS SAST, dependency audit, config/runtime, contract
coverage, and logging hygiene
- Maps findings to CVSS v3.1 severity bands, CWE, and OWASP Top 10
- Mirrors qa-tester P1–P7 anti-loop protocol for [ATTEMPT: N] ladder
- Anti-corruption §VIII: tooling absence is reported as Info finding,
never silently dropped
Command: .opencode/command/security.audit.md
- Dispatches security-auditor subagent via axiom MCP scan
- Supports --floor, --profile, --ci (exit code 0/1/2 for CI gates)
- PCAM worker packet contract; severity floor + suppression footer
Mirrored to .agents/agents/ and .agents/commands/ per repo convention.
2026-06-30 18:44:52 +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
60674c8639
fix(logging): defensive trace_id seed + falsy error/payload in CotJsonFormatter
...
log_requests middleware (BaseHTTPMiddleware) showed no-trace
because anyio.create_task_group() in Starlette 0.50.0 does not
always propagate ContextVar from raw ASGI TraceContextMiddleware.
Fix 1: defensive get_trace_id() check at log_requests entry —
if empty, seed_trace_id() to ensure every request has one.
Fix 2: CotJsonFormatter used 'if error:' and 'if payload:' which
silently drop empty strings (str(e)='') and empty dicts.
Changed to 'is not None' checks — preserves all data.
Root cause: 12 EXPLORE-without-error entries from belief_scope's
exception handler where Exception() has empty message.
2026-06-30 17:41:13 +03:00
2f238dee13
fix(agent): seed trace_id for agent process lifecycle
...
Agent logs had trace_id='no-trace' because the Gradio process
never called seed_trace_id(). The CotJsonFormatter reads trace_id
from ContextVar — without seeding, it defaults to empty string
displayed as 'no-trace'.
Fix:
- app.py: seed_trace_id() on every agent_handler invocation
- run.py: seed_trace_id() on agent startup (for LLM config fetch)
Each Gradio submit gets a fresh trace_id, making agent logs
correlatable with downstream FastAPI calls.
2026-06-30 17:33:21 +03:00
79d0f8f678
feat(agent-superset): extend SupersetClient with agent-critical methods + DDL/DML guard + tests (126 passed)
...
Ported from mcp-superset research module, integrated into existing async SupersetClient:
New mixins (4 files):
- safety.py: DDL/DML guard (13 keywords), comment/string stripping, viz_type validation
- _sql_lab.py: execute_sql, format_sql, results, estimate, CSV export, query history
- _saved_queries.py: saved queries CRUD (5 methods)
- _audit.py: permissions audit matrix (user × dashboard × dataset × RLS)
Extended mixins (4 files):
- _dashboards_write.py: +create, +update (general), +copy, +publish, +unpublish
- _dashboards_crud.py: +standalone get_dashboard_charts/datasets, +get_dashboard
- _datasets.py: +create, +delete, +duplicate, +refresh_schema, +get_or_create, +export/import
- _databases.py: +update, +test_connection, +schemas/tables/catalogs, +validate_sql, +select_star, +table_metadata
FastAPI proxy (2 files):
- agent_superset.py (284L): SQL Lab + Dashboards/Datasets write endpoints
- agent_superset_explore.py (240L): DB explore + Audit + Saved Queries endpoints
Agent tools (2 files):
- tools.py: +7 LangChain @tools (24 total), intent-routing keywords
- _tool_resolver.py: updated SAFE/GUARDED/FAST_CONFIRM classification sets
Tests (3 files, 126 tests):
- test_superset_safety.py (51): DDL/DML bypass/legitimate/safe scenarios
- test_superset_extended.py (42): all mixin methods with mock AsyncAPIClient
- test_superset_tools.py (33): agent tool registration, intent matching, @tool .ainvoke()
2026-06-30 17:26:51 +03:00
a0619ca049
fix(agent): unify logging API + add molecular-cot coverage to agent module
...
Phase 1 — API unification:
- Replace direct log() from cot_logger with canonical logger.reason/reflect/explore
across _confirmation.py, _persistence.py, _tool_resolver.py, app.py
Phase 2 — Gap filling:
- tools.py: add REASON/REFLECT/EXPLORE to 17 C3 tool functions (was 0 logs)
- app.py agent_handler (C4): add lifecycle REASON on entry, REFLECT on exit,
EXPLORE on OutputParserException + general exception
- langgraph_setup.py create_agent (C4): add REASON with model/config_source,
EXPLORE on env-var/InMemorySaver fallback, REFLECT on graph compilation
- _tool_resolver.py infer_tool_from_text (C3, 13 branches): REASON on inference
- _persistence.py: REFLECT on save_conversation success, EXPLORE on prefetch
Phase 3 — Plain log migration:
- middleware.py: plain logger.info() -> logger.reason()
- run.py: 7 plain logger.info/warning/error -> molecular REASON/EXPLORE
Phase 4 — Cleanup:
- cot_logger.py: deprecate MarkerLogger (@DEPRECATED + @REPLACED_BY)
- molecular-cot-logging SKILL.md: remove cot_span Section IV (never implemented),
renumber sections V-VII -> IV-VI, add cot_span rejection rationale
Verification: pytest 27/27, axiom rebuild 5844/2993/0 warnings
2026-06-30 15:48:46 +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
7090ec979f
fix(run.sh): correct PID capture with process substitution, add SIGTERM trap, 3-phase cleanup
...
Problem: pipeline cmd | awk & captured awks PID instead of Python PID.
When cleanup killed AGENT_PID, awk died but Gradio kept port 7860 occupied.
Fix:
- Replace | awk & with > >(awk) 2>&1 & (process substitution) so 0 gives real PID
- Trap SIGTERM + SIGHUP in addition to SIGINT
- Three-phase cleanup: SIGTERM -> wait 1s -> SIGKILL -> fuser port fallback
2026-06-29 17:43:42 +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