Commit Graph
16 Commits
Author SHA1 Message Date
Hao Zhe a809a0aaef feat(studio): show error details in request logs (#4172)
* feat(studio): show error details in request logs

* fix(observability): harden audit error details
2026-08-21 11:57:08 +08:00
Qin Haojie 31e01c58a2 feat(admin): 清理已删除用户数据 (#3924)
* feat(admin): 清理已删除用户数据

删除用户时立即撤销身份,并通过持久队列完成用户数据清理。

* fix(admin): 删除用户时清理任务记录

* fix(admin): 避免过早判定用户任务取消失败
2026-08-11 11:18:40 +08:00
Hao Zheandzhiheng.liu af914ca27b fix(core): harden privacy and background failure handling (#3548)
* fix(server): stop exporting raw query strings and buffering zip responses in observability

Sweep findings: B-03, B-13. Prevent query secrets from reaching traces and keep ZIP responses streaming.

(cherry picked from commit d8ac3dc33b)

* fix(session): tolerate missing/corrupt archive in Phase-2 replay

(NotFoundError / _ArchiveMessagesCorruptError) on a missing or corrupt
archive messages.jsonl instead of returning []. That PR added skip-on-
missing tolerance to the read path (_get_uncovered_archive_messages) and to
resume_queued_commit, but not to the Phase-2 commit replay path
(_prepare_phase2_archive_messages), which calls _read_archive_messages
unguarded while rolling earlier failed archives into the current commit.

Consequence: a terminally-failed earlier archive whose messages.jsonl is
missing/corrupt (legacy "no messages" terminal data, or produced by #3417's
own archive_read terminal path) makes every subsequent commit's Phase-2
extraction raise -> caught by _run_memory_extraction's except -> the current
archive is terminal-failed too. Because the poisoned archive is only removed
from replay once "covered" (which requires a later archive to complete), and
no later archive can ever complete, the session's memory extraction is
permanently poisoned. Raw messages are safe, but extraction is stuck.

Fix: wrap the replay-loop _read_archive_messages call in the same tolerance
_get_uncovered_archive_messages already uses -- skip + warn on not-found
(_is_storage_not_found) and on _ArchiveMessagesCorruptError, re-raise real
storage failures. The skipped archive stays in covered_failed so the current
archive's .done marks it covered, clearing the poison permanently.

Adds a regression test asserting the replay skips a failed archive with a
missing messages.jsonl (and marks it covered) instead of raising, and that a
real storage failure still propagates.

Follow-up to #3417.

(cherry picked from commit 5b8ec9e68a)

* fix(client): align client surfaces without leaking memory metadata

Reconstructs the client-parity work from upstream PR #3439 on current main and strips reserved memory metadata before line slicing in both embedded and HTTP reads.

Based-on: 48b411d58c

Co-authored-by: zhiheng.liu <zhiheng.liu@bytedance.com>

* fix(index): propagate semantic vectorization failures safely

Reconstructs upstream PR #3437 on current main, carries enqueue failures through SemanticDagExecutor, and drains the attempt's embedding tracker before retry-visible failure propagation.

Based-on: 02387deb09

Co-authored-by: zhiheng.liu <zhiheng.liu@bytedance.com>

* fix(core): close privacy and embedding failure gaps

* fix(memory): strip repeated metadata trailers

* fix(core): close public memory visibility gaps

* ci: skip embedding-dependent resource test without secrets

---------

Co-authored-by: zhiheng.liu <zhiheng.liu@bytedance.com>
2026-08-03 16:07:35 +08:00
Qin Haojie 8d087c0e39 feat(server): 增加 Request ID 日志关联 (#3572)
为 HTTP 请求提供可校验、可回传且贯穿服务端日志的关联标识。
2026-07-28 15:29:20 +08:00
Qin Haojie d47f2106ee refactor: remove unused and deprecated APIs (#3272)
Delete dead compatibility paths and test-only helpers so unsupported APIs do not remain as accidental contracts.
2026-07-16 10:49:56 +08:00
yufeng 65f80c46c8 feat: open studio metrics to users (#2882) 2026-06-29 15:08:36 +08:00
Qin Haojie ff258768c2 feat(memory): 引入 User/Peer 记忆隔离模型 (#2236)
* feat(memory): introduce user and peer memory isolation

Unify agent-scoped memory behavior into user-owned memory spaces, add peer_id compatibility for session and retrieval paths, and wire memory_policy through session commit flows.

* feat(memory): align session identity around peer IDs

* feat(search): pass peer id through retrieval

* refactor(memory): remove agent identity from integrations

* fix(memory): isolate peer identity from self extraction

* fix(tau2): provision benchmark user configs

* fix(auth): allow admin keys to access data APIs

* fix(openclaw): enable peer memory policy for peer roles

* fix(openclaw): resolve sender for peer recall

* refactor(session): simplify memory extraction routing

* refactor(ov-cli): reduce formatting-only diff

* refactor(message): remove unused message helpers

* refactor(retrieval): simplify peer target resolution

* refactor(namespace): remove deprecated agent namespace policy

* fix(agent): propagate peer id through integrations

* fix(auth): align integration clients with api-key mode
2026-06-05 10:55:48 +08:00
Evo 5fea075c09 docs(usage-audit): document timezone query param on Console BFF endpoints (v0.3.19) (#2209) 2026-05-25 11:26:00 +08:00
Zayn JarvisandClaude Opus 4.7 0d63f0e3c4 fix(observability): persist usage/audit in UTC and bucket per request tz (#2190)
* fix(observability): persist usage/audit in UTC and bucket per request tz

Dashboard, token-trend, and context-commit-heatmap previously bucketed by
server-process local timezone (`server/config.py` default `local`, which
on Railway / Docker without `TZ` is UTC). UTC+8 viewers saw "today" and
4h heatmap edges shifted relative to their wall clock.

Root cause: `projection.py` applied `astimezone(self._tz)` before writing
the rollup PKs, so date/hour columns were already locked to the
container's tz; a read-side `?timezone=` could not recover the buckets
because the raw UTC instants were no longer in storage.

Fix: persist all time-keyed columns (`date_utc`, `hour_utc`,
`created_at`) in UTC and accept `?timezone=` per request on
`/api/v1/console/{dashboard/summary,tokens,context-commits}`. The viewer
tz is resolved with `zoneinfo`, then the SQLite reads pull the spanning
UTC window and rebucket in Python to user-local days / 4h buckets. DST
is handled by `ZoneInfo` automatically.

Schema bump (v1 -> v2): `usage_token_daily` becomes `usage_token_hourly`
and `usage_retrieval_daily` becomes `usage_retrieval_hourly` (extra
`hour_utc` column in PK so cross-tz "today" slicing is precise). Other
tables keep their shape; `date` is renamed to `date_utc` to make the
semantic shift unambiguous. On boot, the store DROPs the legacy tables
once and recreates the new layout - acceptable because retention is 14
days and the product is pre-GA.

Frontend (`web-studio`) now passes
`Intl.DateTimeFormat().resolvedOptions().timeZone` on every console
fetch; `getLastDaysRange` derives the date range in the viewer's tz so
its boundaries match the backend interpretation. No visual / component
changes were needed.

Tests:
- Backend: existing 15 cases ported to the new keyword-only `tz=` API;
  three new cases exercise UTC+8 day-boundary, America/New_York day
  rebucketing across UTC midnight, and Asia/Shanghai 4h heatmap hour
  shift. All 20 observability tests pass.
- Frontend: typecheck + lint clean (no new errors).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix(observability): reset legacy usage audit sqlite schema

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 17:03:14 +08:00
Zayn Jarvis d6a024efa5 feat(docker)!: drop legacy console (keep BFF + Caddy), ship web-studio in pip, fix favicons (#2160)
The OpenViking docker image still launched the legacy `openviking/console`
standalone service on port 8020. Now that web-studio is bundled into the OV
server itself at /studio (see #2156), that process is redundant and the
port is just a confusing artefact.

This change retires the old console (python package + 8020 + console-frontend
favicons) but **keeps the in-compose Caddy as a stable single-ingress on
port 1934**, just simplified to one upstream now that there's no 8020. The
server-side BFF at `openviking/server/routers/console.py` (under
`/api/v1/console/*`) is also kept — web-studio uses the same endpoints.

**The OAuth authorize page (`openviking/server/oauth/router.py`) is
deliberately untouched in this PR** — the console-link button and Quick
authorize same-origin panel will be re-pointed at web-studio in a focused
follow-up.

BREAKING CHANGES:
- Port 8020 is gone from the docker image and docker-compose.yml; Caddy at
  1934 now forwards everything to 1933 (web-studio lives at /studio there).
  Anything bookmarked at `http://host:8020/...` must migrate to
  `http://host:1933/studio/`.
- `python -m openviking.console.bootstrap` no longer exists; the python
  package `openviking.console` has been removed.

Pip packaging:
- web-studio dist is now shipped inside the wheel under
  `openviking/web_studio/dist/` (mirroring the old `openviking/console/static/`
  layout). The dockerfile copies `--from=web-studio-builder /web-studio/dist`
  into the source tree before `uv sync`, so the wheel produced by the
  default docker build always carries the SPA. Building the wheel without
  running `npm run build` first leaves the directory empty, which gracefully
  degrades /studio to a 404 without breaking server startup.
- Favicon assets (`favicon.ico` / `favicon-32.png` / `apple-touch-icon.png`,
  ~11 KB total) are duplicated into `openviking/server/static/` and shipped
  via package-data so `/favicon.*` and `/mcp/favicon.*` routes are always
  registered, regardless of whether the web-studio dist is bundled.
- `pyproject.toml` and `setup.py` `package-data` drop `console/static/**`
  and add `server/static/**` + `web_studio/dist/**`.
- New favicons (the 16/32/180 set in both `openviking/server/static/` and
  `web-studio/public/`) are downscaled from the canonical
  `web-studio/public/openviking-icon.png`, so the small-icon family matches
  the SPA's high-res rel="icon" target — the studio tab icon now stays
  consistent whether the browser uses the HTML link tag or falls back to
  auto-fetching `/favicon.ico`.

Server:
- `openviking/server/app.py` now reads `/studio` from
  `Path(__file__).parent.parent / 'web_studio' / 'dist'` by default;
  `OPENVIKING_WEB_STUDIO_DIR` still wins for dev mode pointing at a
  repo-local build. Favicon routes are unconditionally registered and
  load from `openviking/server/static/`.
- `openviking/observability/usage_audit/projection.py` drops the legacy
  `/console/*` skip prefix (the BFF prefix `/api/v1/console/*` remains).

Docker:
- `web-studio-builder` stage moved earlier (Stage 2) so its dist can flow
  into `py-builder` before `uv sync` runs.
- Runtime stage no longer separately copies the dist or sets
  `OPENVIKING_WEB_STUDIO_DIR`; the in-package path is the default.
- Entrypoint renamed `openviking-console-entrypoint.sh` -> `openviking-entrypoint.sh`
  and stripped of the `python -m openviking.console.bootstrap` launch.
- `EXPOSE 1933 8020` -> `EXPOSE 1933`.
- `docker-compose.yml` drops the openviking service's 8020 port mapping;
  the caddy service stays but no longer needs port 8020 exposed.
- `Caddyfile` simplified to a single `:1934 { reverse_proxy openviking:1933 }`
  — the legacy `/console/*` route to :8020 is gone.

Docs:
- en/zh quickstart updated to drop the 8020 mapping and explain that the
  API server now also serves `/studio`.
- Other guides (`12-public-access.md`, `11-oauth.md`, `05-observability.md`,
  `04-setup-for-agent.md`, `03-deployment.md`) are intentionally left for a
  focused follow-up PR alongside the OAuth quick-authorize reintroduction.

Tests:
- Deleted `tests/misc/test_console_{proxy,static_assets}.py` (covered the
  removed console package). `tests/observability/test_console_router.py`
  stays — it covers the BFF, which remains.
2026-05-21 16:41:29 +08:00
Qin Haojie 1e484c9ca8 fix(observability): store usage audit sqlite under system data (#2149) 2026-05-20 21:20:20 +08:00
Kchenandchenpengfei cd72f9182e feat(observability): dump HTTP query, request body, and response body to trace spans (#2052)
Add an opt-in middleware that attaches the request and response bodies
(truncated, content-type filtered) onto the active OpenTelemetry root span,
and surface the URL query string as `url.query`. Off by default — bodies
may contain secrets and high-cardinality content; enable via
`server.observability.dump_body.enabled` and bound payload size with
`max_bytes`.

The dump middleware is registered before the HTTP observability middleware
so it nests inside the trace span (Starlette executes later-registered
middleware first). Streaming, multipart, and binary content types are
skipped, and any capture failure is swallowed so the request path is never
affected.

Co-authored-by: chenpengfei <chenpengfei@bytedance.com>
2026-05-14 21:18:43 +08:00
Qin Haojie 9d36b2fd83 feat(console): 增加 Usage/Audit Dashboard BFF (#2016)
* feat(console): add usage audit dashboard BFF

* feat(console): add usage audit retention config

* docs(console): remove local usage audit design doc
2026-05-14 18:19:42 +08:00
Jiahui Zhou 3bcefb298d fix: unify runtime loggers with openviking logger (#1981) 2026-05-12 11:26:30 +08:00
baojun-zhang d7fdb489ce feat(observability): support header param while OTLP export (#1805)
* feat(observability): support header param while OTLP export

* feat(observability): support header param while OTLP export
2026-04-29 20:14:31 +08:00
baojun-zhangandMaojiaSheng 17d2c5603e feat(observability): unify observability context && support otel && etc. (#1666)
* feat(observability): unify OTLP metrics export, log/trace context, and telemetry bridging
- - Add OTLP metrics http/grpc exporter that pushes MetricRegistry snapshots
- - Decouple telemetry response payload from telemetry collection; always finish() and bridge summary to metrics
- - Unify observability config under server.observability (metrics/traces/logs siblings); update ov.conf.example and docs (zh/en)
- - Improve log/trace correlation via structured context injection
- - Add/adjust tests for exporter lifecycle, config loader, metrics/telemetry runtime
- BREAKING CHANGE: remove legacy telemetry.* config path; use server.observability.*

* feat(observability): import Status/StatusCode for LogToSpanEventFilter

* feat(observability): fix check issue

* feat(observability): format code

---------

Co-authored-by: MaojiaSheng <shengmaojia@bytedance.com>
2026-04-24 21:32:25 +08:00