* fix(studio): group agent session messages and improve chat readability
* feat(studio): refine sidebar icon system
* fix(studio): align session images with server format and localize errors
* fix(studio): unify active sidebar icon color
* fix(web-studio): honor task API status instead of inventing pending
Pass status to GET /api/v1/tasks so filters apply before the limit, and stop reclassifying surplus running tasks as pending in Studio.
Fixes#4821
* chore: retrigger CI after unrelated fs_cp 409 flake
* feat(web-studio): add Agent Experience page with impact analysis
Add a new workspace page that surfaces experience memories distilled
from committed sessions and their application impact, powered by the
Agent Evolution HTTP API:
- List view (`/agent-experience`): experience files under
`viking://user/<id>/memories/experiences` via `GET /api/v1/fs/ls`
with keyword search, refresh, empty/loading/error states (a missing
directory is treated as an empty list).
- Detail view (`/agent-experience/$experienceUri`): experience content
rendered from `GET /api/v1/content/read`, plus an impact panel that
queries `GET /api/v1/agent-evolution/experiences/outcomes` (stacked
outcome distribution over the five fixed buckets) and
`GET /api/v1/agent-evolution/experiences/trajectories` (paginated
applied-trajectory list with load-more and a markdown preview sheet).
- Time-range presets (all / 7d / 30d) share UTC date bounds across the
outcome and trajectory queries.
- Sidebar navigation entry, zh-CN/en translations, and unit tests for
URI building, payload normalization, time ranges, and the router
param round-trip.
* feat(web-studio): complete Agent Experience page features
Close the main gaps against the reference experience console and the
available OSS server APIs:
- Evolution settings: admin/root-only popover toggling the deployment
Agent Evolution switch (GET/PUT /api/v1/admin/agent-evolution) with
status hints, toasts, and hot-reload via query cache updates.
- Source trace tab on the detail page: outgoing experience relations
(GET /api/v1/relations) listing the trajectories that generated and
evolved the experience.
- List preview drawer: clicking a row (or its name) opens a quick
markdown preview with a jump-to-impact action; the Impact button in
the actions column navigates to the detail page.
- Per-row applied count: lazy trajectory totals (limit=1) shown in a
new "Applied" column with a stable 60s cache.
- Updated badges: pre-visit snapshot via localStorage last-seen map so
rows updated since the previous visit are highlighted.
- Custom time range: preset buttons plus a UTC date-range popover with
inline validation (format + ordering), shared by the outcome and
trajectory queries.
- Search keyword highlighting in the list, and an empty-state
checklist (agent connected / new sessions / committed).
- Sessions cross-link: experience rows in the MemoryImpact sheet now
link to the Agent Experience impact page.
- zh-CN/en translations for all new copy; unit tests for relation
normalization, custom ranges, and last-seen tracking (207 total).
* fix(web-studio): align experience source trace API
* fix(web-studio): align Agent Experience APIs and previews
* feat(web-studio): paginate experiences and refine page layout
* feat(web-studio): switch users inline in identity menu
* fix(web-studio): guard evolution account scope and pagination loading
* feat(web-studio): search modes, panel collapse, and structured JSONL rendering
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C65Cb79Dvr5zLD6ib1T9Ew
* fix(web-studio): keep the palette one width across search and dir browsing
`/` and `//` put the palette into directory browsing, which was still using
the narrow layout, so the dialog resized whenever the query switched between
searching and browsing. Only the empty idle prompt stays narrow now.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C65Cb79Dvr5zLD6ib1T9Ew
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
* chore(web-studio): remove dead code (unreachable files and unused exports)
Static sweep of web-studio/src for code no module reaches from the
main.tsx / routeTree.gen.ts entry graph, plus exported symbols nothing
references anywhere (including their own file and tests).
Deleted files:
- src/router.tsx — superseded by the inline createRouter in main.tsx
- src/lib/sessions/generate-title.ts — never called
- src/lib/sessions/types/session.ts — re-export barrel nobody imports
- src/components/ui/{breadcrumb,combobox,context-menu,input-group,progress}.tsx
— shadcn primitives never added to any screen; re-addable via `shadcn add`
Removed unused exports (and the imports/constants they were the last
consumer of):
- lib/admin-options.ts: sortedAccounts
- lib/sessions/types/chat.ts: ChatState
- lib/sessions/types/message.ts: getTextContent, getToolParts, getContextParts
- routes/home/-lib/format.ts: formatDateKey, formatTimestamp
- routes/playground/-lib/types.ts: VikingEntryHandler
- routes/playground/-lib/utils.ts: buildBreadcrumbs
- routes/resources/-hooks/viking-fm.ts: usePrefetchVikingFsList, useVikingFind
- routes/resources/-lib/normalize.ts: sameUri, normalizeUriForDisplay
- routes/resources/-lib/upload.ts: getExtensionFromName
No behaviour change. `vite build` succeeds, `tsc --noEmit` output is
byte-identical to main, and `vitest run` shows the same pre-existing
19 failed files / 56 failed tests as main.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* chore(web-studio): drop the unused pnpm lockfile
Nothing in the repo installs web-studio with pnpm: `make build-studio`
runs `npm ci && npm run build`, and both setup-node steps in
`.github/workflows/_build.yml` cache on `web-studio/package-lock.json`.
No workflow reads `pnpm-lock.yaml`.
The file had also drifted out of sync with package.json — 24 specifiers
missing — so `pnpm install --frozen-lockfile` failed outright, which only
ever hurt someone reaching for pnpm locally.
Also drops the `pnpm.onlyBuiltDependencies` field: pnpm 11 no longer
reads it and warns when it is present.
package-lock.json stays as the single source of truth.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
- Add rehype-raw and rehype-sanitize so raw HTML in Markdown renders while stripping scripts and other dangerous tags
- Give table cells full borders, center content both axes, and pass through colSpan / rowSpan
- Add file-preview-html tests covering raw HTML rendering, table attribute passthrough, and script stripping
Route internal viking:// Markdown targets through the existing resource navigator instead of the attachment download endpoint. Preserve download fallback behavior for previews without a navigation callback and add a click regression test.
Test: NODE_OPTIONS='--localstorage-file=/tmp/openviking-vitest-localstorage' pnpm test\nTest: pnpm build
* feat: support oidc and ldap auth
* feat: support oidc and ldap auth
* fix: remove heima partner, clean up auth docs, add web-studio unsupported auth banner
- Remove heima from partner list in README (en/zh/ja)
- Remove unsupported env var references (OPENVIKING_AUTH_MODE, OPENVIKING_USERNAME,
OPENVIKING_PASSWORD) from LDAP auth docs
- Remove temporary switch bash snippets from auth docs
- Fix ldap_password description
- Add web-studio unsupported-auth-mode banner for oidc/ldap servers
* fix: address OIDC/LDAP review comments on auth plugin design
Key changes driven by PR review:
- **Role mapping**: OIDC and LDAP external identities always resolve to
USER role. Removed map_role() calls and group_membership-based role
mapping. Admin access is gated by the root API key mechanism only.
- **LDAP credential extraction**: Removed query-parameter-based username/
password extraction (security concern — passwords in URLs can leak via
shell history, proxy logs, and monitoring). Clients must use Basic Auth
header or form data.
- **OIDC identifier sanitization**: Auth0 and other providers may include
characters like "|" in the `sub` claim. These are now replaced with "_"
to produce valid OpenViking user identifiers.
- **Dead code removal**: Removed _extract_groups, memberof_attribute,
require_root_api_key_for_admin, _initialize_api_key_manager, and
get_request_context_checks from both plugins since they are no longer
needed.
- **Docs**: Removed query-parameter curl example, memberof_attribute and
require_root_api_key_for_admin config references.
Co-authored-by: TRAE CLI <noreply@bytedance.com>
* feat: support oidc and ldap auth
* feat: support oidc and ldap auth
* fix(auth): bind lazy OIDC imports at module scope
---------
Co-authored-by: TRAE CLI <noreply@bytedance.com>
Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>
* fix(feishu): surface permission errors clearly and keep users on page
Map Feishu/Lark API failures to typed OpenViking errors with actionable hints, and keep Web Studio from treating HTTP 403 permission denials as session logout.
* fix(feishu): simplify API error mapping
* refactor(feishu): inline API error mapping
---------
Co-authored-by: wugj <wugj@g-bits.com>
Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>
In trusted mode, /health identity resolution requires X-OpenViking-Account
and X-OpenViking-User headers alongside X-API-Key. Without them, the
trusted auth plugin raises InvalidArgumentError, the exception is swallowed
by the health handler, and the response omits role/account_id/user_id —
so the studio falls back to connectionRole='unknown' and gates the admin
UI behind 'Usage/Audit 未初始化'.
Sending the headers is always safe: in api_key mode the server strips
them from the request scope; in trusted mode they are required.
Closes#2977 for the web-studio side.