Skip to content

fix(session): persist usage across requests - #3721

Draft
ehz0ah wants to merge 1 commit into
volcengine:mainfrom
ehz0ah:fix/session-used-durability
Draft

fix(session): persist usage across requests#3721
ehz0ah wants to merge 1 commit into
volcengine:mainfrom
ehz0ah:fix/session-used-durability

Conversation

@ehz0ah

@ehz0ah ehz0ah commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Description

Persist session /used records across request and process boundaries so a later session commit can update relations and vector active_count values reliably.

Before this change, the HTTP used route only mutated the in-memory Session instance created for that request. A separate commit request loaded a fresh instance, so its Phase 2 worker received no usage records. In an isolated baseline server, /used returned contexts_used: 1, but the subsequent completed commit reported active_count_updated: 0 and created no usage relation.

This change stores pending usage events in a hidden per-session .usage.jsonl sidecar under the existing Session Phase 1 tree lock. Commit snapshots exact event IDs, carries full usage records through the durable queue payload, consumes only the committed snapshot, and restores it if Phase 1 fails.

Human Involvement

  • A human participated in the implementation or review loop
  • This PR was generated entirely by AI agents without human participation in the loop

Related Issue

No open issue was found for this exact cross-request usage-loss path.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test update

Changes Made

  • Make the HTTP used route await lock-protected durable usage persistence.
  • Serialize every Usage field, including skill contribution, input, output, success, and timestamp.
  • Snapshot and consume stable usage event IDs during Session Phase 1 so concurrent later appends remain for the next commit.
  • Carry full usage records in SessionCommitMsg while preserving replay compatibility with legacy usage_uris payloads.
  • Deduplicate active-count URIs and skip empty relation targets without changing in-process Session.used() compatibility.

Testing

  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have tested this on the following platforms:
    • Linux
    • macOS
    • Windows

Commands:

.venv/bin/pytest -q \
  tests/session/test_session_usage.py \
  tests/unit/session/test_session_commit_resume.py \
  tests/server/test_api_sessions.py::test_used_then_separate_commit_updates_active_count_and_relation \
  tests/session/test_session_usage_reporter.py
# 18 passed

.venv/bin/ruff check \
  openviking/server/routers/sessions.py \
  openviking/session/session.py \
  openviking/storage/queuefs/session_commit_msg.py \
  tests/server/test_api_sessions.py \
  tests/session/test_session_usage.py \
  tests/unit/session/test_session_commit_resume.py
# passed

git diff --check upstream/main...HEAD
# passed

Live isolated HTTP validation used a fresh server/workspace and the supported temporary-upload pipeline:

baseline upstream/main: active_count_updated = 0
this branch:             active_count_updated = 1

The fixed-server run also verified all of the following:

  • two pending records survived the /used -> separate /commit reload boundary;
  • rich skill fields survived unchanged;
  • both resource and skill relations were created;
  • the resource active count was incremented once;
  • the exact snapshotted sidecar events were consumed after commit;
  • the background commit completed successfully.

Runtime artifact: /tmp/openviking-memory-research-fixed/usage-smoke-result.json in the local validation environment.

Checklist

  • My code follows the project's coding style
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

Screenshots (if applicable)

Not applicable.

Additional Notes

  • Direct synchronous Session.used() remains process-local until that same instance commits; HTTP uses the durable async path.
  • The sidecar is rewritten under the existing session lock, so write cost is linear in the number of uncommitted usage events.
  • Malformed sidecar data fails explicitly instead of silently dropping usage.
  • Open PRs touch some Session files for unrelated changes, but no open PR found in the current 400-PR scan implements this cross-request durability behavior.

Store usage events durably under the session lock so a later commit can preserve relations, rich skill metadata, and active-count updates across process and request boundaries.
@ehz0ah
ehz0ah force-pushed the fix/session-used-durability branch from a8097cf to 047521b Compare August 4, 2026 02:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant