Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
4b47d89
docs(backlog): reconcile v0.4.0 completions and add v0.5 entries
fvadicamo Apr 18, 2026
c6db57f
docs(plans): add v0.5.0 implementation plan
fvadicamo Apr 18, 2026
41eea9c
feat(admin): add PATCH /api/v1/namespaces/{id}/config for instructor …
fvadicamo Apr 21, 2026
192b62c
feat(core): add document_name to source citations (WI-2, FEAT-012)
fvadicamo Apr 21, 2026
4675445
feat(learn): add JWT-scoped GET /conversations/{id}/turns (WI-1, FEAT…
fvadicamo Apr 21, 2026
5e12eb1
feat(widget): white-label data-attrs for course customization (WI-4, …
fvadicamo Apr 21, 2026
baf77b1
feat(widget): conversation persistence + New chat button (WI-5, FEAT-…
fvadicamo Apr 21, 2026
bcbde1a
docs(v0.5.0): update BACKLOG and CHANGELOG for widget + prof config
fvadicamo Apr 21, 2026
45437c8
fix(core): populate document_name in AdvancedQueryPipeline.execute_st…
fvadicamo Apr 21, 2026
e787cc4
fix(v0.5.0): archived marker, learn audit log, namespace PATCH route
fvadicamo Apr 21, 2026
bda675b
fix(v0.5.0): powered-by customization, restore race, fetch timeout, t…
fvadicamo Apr 21, 2026
dfe6be5
fix(learn): always emit turns-read audit even without request_id (CR-…
fvadicamo Apr 21, 2026
c8e72f8
fix(widget): preserve --vektra-primary on hover (CR-3120130903, Gemin…
fvadicamo Apr 21, 2026
18af4f3
fix(core): normalize document_name lookup keys to str (CR-3120130886)
fvadicamo Apr 21, 2026
86e5330
style(v0.5.0): address minor review comments (CR + Gemini)
fvadicamo Apr 21, 2026
c57e5f5
docs(backlog): track deferred items from PR #66 review
fvadicamo Apr 21, 2026
f4dbecd
fix(widget): lock input while restoring conversation history (CR new …
fvadicamo Apr 21, 2026
6ff6d0d
feat(core): record document_names step in QueryTrace (CR new round)
fvadicamo Apr 21, 2026
5433a0d
chore: bump version to 0.5.0-dev across all submodules
fvadicamo Apr 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 117 additions & 7 deletions .s2s/BACKLOG.md

Large diffs are not rendered by default.

306 changes: 306 additions & 0 deletions .s2s/plans/20260418-v050-widget-and-prof-config.md

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased] — v0.5.0 "Widget production-ready + instructor configuration"

### Added

- **vektra-admin**: `PATCH /api/v1/admin/namespaces/{id}/config` endpoint for instructor configuration. Admin-scoped, whitelisted (v0.5.0 accepts `grounding_mode` only), partial updates, null removes a key. Backs the Moodle block form that lets teachers toggle strict/hybrid RAG per course without admin intervention.
- **vektra-learn**: `GET /api/v1/learn/conversations/{id}/turns` JWT-scoped endpoint so the widget can restore a conversation after a page reload. Returns decrypted question/answer + created_at; admin-only metadata is not exposed. 403 on namespace mismatch, 404 on missing.
- **vektra-core**: `document_name` field on every source citation, joined from `source_documents.filename` so the widget renders `[1] lecture-07.pdf` instead of chunk UUIDs. Propagates through both `SimpleQueryPipeline` and `AdvancedQueryPipeline`, JSON and SSE paths. Soft-deleted source documents (REQ-057) keep their citation with an `(archived)` suffix so answers stay traceable.
- **vektra-learn**: content-access audit entry (`learn_conversation_turns_read`) written on every successful turns fetch via the shared `vektra_shared.audit` interface (NFR-007).
- **widget**: white-label `data-*` attributes — `data-title`, `data-primary-color`, `data-icon` (emoji or URL), `data-welcome-message`, `data-powered-by`. All rendered via `textContent` / safe color whitelist to avoid XSS.
- **widget**: tab-scoped conversation persistence via `sessionStorage` keyed by `course_id` (24h cutoff); history replay on load via the new turns endpoint; explicit "New chat" button in the header.
- **errors**: new codes `ERR-ADMIN-005/006/007` (namespace config) and `ERR-LEARN-005/006` (conversation turns).

### Changed

- **widget styles**: button and accent colors now use `var(--vektra-primary, …)` so `data-primary-color` takes effect without rebuilding the bundle. Hover states use `filter: brightness()` so custom colors still feel interactive.

## [0.3.0] - 2026-03-21

E-learning vertical refinements, widget UX improvements, and Phase 2 stabilization.
Expand Down
42 changes: 41 additions & 1 deletion docs/reference/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,45 @@ curl -s -X DELETE \

Returns HTTP 204 (no body).

## Namespaces

### PATCH /api/v1/admin/namespaces/{namespace_id}/config

Partially update a namespace's behavioral config (JSONB). Requires `admin` scope.

**Scopes**: `admin`

Used by upstream plugins (e.g. the Moodle block) to toggle per-course settings such as the grounding mode without touching environment variables. The read path is `resolve_grounding_mode()` in `vektra-shared/src/vektra_shared/namespace.py`.

```bash
curl -s -X PATCH \
-H "Authorization: Bearer $VEKTRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"grounding_mode":"hybrid"}' \
http://localhost:8000/api/v1/admin/namespaces/default/config | python3 -m json.tool
```

Request body (flat dict, one entry per config key):

| Field | Type | Allowed values | Description |
|-------|------|----------------|-------------|
| `grounding_mode` | string or null | `"strict"`, `"hybrid"`, `null` | RAG grounding policy. `null` removes the key and falls back to `VEKTRA_PROMPT_GROUNDING_MODE`. |

Behavior:
- **Partial update**: keys not present in the body are preserved.
- **Unknown keys rejected** with `400 ERR-ADMIN-006` (not silently ignored — surfaces typos early).
- **Invalid values rejected** with `400 ERR-ADMIN-007`.
- **Missing namespace** returns `404 ERR-ADMIN-005`.

Response (HTTP 200):

```json
{
"namespace_id": "default",
"config": {"grounding_mode": "hybrid"}
}
```

## Ingest

### POST /api/v1/ingest
Expand Down Expand Up @@ -254,7 +293,8 @@ Response:
"score": 0.912,
"snippet": "...",
"citation_id": "d4e5f6-...",
"document_version": 1
"document_version": 1,
"document_name": "lecture-07.pdf"
}
],
"conversation_id": null,
Expand Down
6 changes: 6 additions & 0 deletions docs/reference/error-codes.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,17 @@ These codes are used by specific components and are not part of the REQ-011 regi
| ERR-ADMIN-001 | vektra-admin | 422 | Invalid scopes in API key creation request |
| ERR-ADMIN-002 | vektra-admin | 404 | API key not found |
| ERR-ADMIN-003 | vektra-admin | 409 | API key already revoked |
| ERR-ADMIN-004 | vektra-admin | 422 | API key `expires_at` must be in the future |
| ERR-ADMIN-005 | vektra-admin | 404 | Namespace not found (config PATCH) |
| ERR-ADMIN-006 | vektra-admin | 400 | Unknown config key in namespace PATCH body |
| ERR-ADMIN-007 | vektra-admin | 400 | Invalid value for namespace config key |
| ERR-SAFEGUARD-001 | vektra-core | 400 | Query blocked by safeguard pre-check |
| ERR-LEARN-001 | vektra-learn | 503 | Learn service unavailable or pipeline not configured |
| ERR-LEARN-002 | vektra-learn | 404 | No enrollment found for student in course |
| ERR-LEARN-003 | vektra-learn | 401 | Dashboard token missing required course_id claim |
| ERR-LEARN-004 | vektra-learn | 422 | Invalid learn request (missing fields, bad format) |
| ERR-LEARN-005 | vektra-learn | 404 | Conversation not found (GET conversations/turns) |
| ERR-LEARN-006 | vektra-learn | 403 | Conversation belongs to a different course/namespace |

## Adding new error codes

Expand Down
Loading
Loading