Commit Graph
11 Commits
Author SHA1 Message Date
t0saki 674f5e6039 fix(retrieval): honor context tier ceilings and stop cooling unserved recalls (#3746)
* fix(retrieval): honor tier ceilings and stop cooling unserved recalls

Follow-up to #3534, from its post-merge review round.

- The abstract-to-overview substitute now applies only to categories whose
  stored abstract is the whole file body. A resource or skill whose abstract is
  missing (`processing_mode=vectors_only`) or over the per-entry cap read its
  body and returned an overview instead, which for a short file is the body
  almost verbatim — crossing the opt-in deepening boundary those categories are
  documented to have, and doing it even under an explicit `detail="abstract"`.
  They now degrade to a bare URI and their body is never read.
- A digest reporting `no_relevant` blanks `rendered`, so the client injects
  nothing, yet those URIs still entered the dedup ledger and were cooled for
  `dedup_turns` turns. That contradicted the ledger's own bare-URI grace rule
  and held memories back from the later turn they were relevant to.
- Flat retrieval reaches built-in memory types outside the four named ones
  (`cases`, `patterns`, `tools`, `trajectories`, skill-usage memories) and
  reported them as an undeclared `memories` category that no tier or penalty
  table covered, so other-peer hits skipped the score penalty and callers could
  not pin their tier. The catch-all is now a declared category with both; it
  stays out of `quotas`, whose buckets it would overlap. Skill-usage memories
  also stop being misread as the `skills` category.
- ZCode, OpenCode and pi own an OV session id but did not forward it, so their
  recalls silently ran without query expansion or cross-turn dedup.
- The context-request deadline covered only the server's 30s rewrite fuse, but
  the pipeline is serial: expansion, retrieval and budgeting all precede it.
  45s covers both fuses and the work between them.
- `plugin` config scope and the `/recall` successor example now match what the
  code actually does.

* fix(retrieval): make the context deadline and expansion opt-out reachable

Forwarding a session id turns on server-side query expansion, an LLM call with
its own 5s fuse, but neither the deadline that was supposed to cover it nor the
switch that turns it off reached the two harnesses this PR newly enabled it for.

- `contextRequestTimeoutMs()` now derives the deadline from the request body
  rather than from `cfg` plus a rewrite flag. The body is what states which
  server stages will run: a session takes the expansion fuse, `rewrite` takes
  the digest fuse, and a bare retrieval takes neither and keeps the caller's own
  budget. Reading `cfg` alone could not tell those apart.
- OpenCode pinned `timeoutMs: 5000` after spreading the helper's options and pi
  ignored them entirely, so the helper's deadline was dead code in both. Their
  own budgets are now defaults rather than ceilings. OpenCode's 5s in particular
  was shorter than the expansion fuse it had just enabled, so a legal request
  would have been aborted client-side and dropped back to the path with neither
  dedup nor expansion.
- OpenCode and pi read `OPENVIKING_RECALL_QUERY_EXPANSION` (and
  `recallQueryExpansion` in their own config files) and set the `configured`
  flag the shared body builder requires, so the documented opt-out exists where
  the cost was introduced.
- The integration overview no longer implies every harness reads the same
  environment knobs, and describes the deadline as per-stage rather than
  rewrite-only.
2026-08-05 23:52:15 +08:00
2cc96e393e feat(retrieval): assemble auto-recall context server-side via /search mode="context" (#3534)
* feat(retrieval): assemble auto-recall context server-side via /search mode="context"

Auto-recall assembly lived in every harness plugin: each one searched per
memory type, read hits back one by one, and stitched a context block with its
own budget and degradation rules. The implementations drifted, and the shared
weaknesses showed up in production injections — roughly half of the entries
degraded to a bare URI plus a score, character budgets distorted up to 6x on
CJK text, and adjacent turns re-injected the same memories.

This moves assembly into the server as one round trip. /find stays an unchanged
stateless primitive. /search gains mode="context" (mode="list" is the default
and byte-identical to before), and /recall becomes a thin preset over the same
kernel with its v1 field names folded onto the new contract.

New assembly kernel under openviking/retrieve/context_assembler/:

- Token budgeting with a CJK-aware estimate replaces the character budget.
- detail="auto" fills breadth-first then deepens: every candidate gets a
  readable floor, then overview, then full for high-scoring entries. An
  oversized tier falls back to the previous one instead of being truncated,
  bounded by max_tokens / candidates * 2 per entry.
- Overview extraction dispatches by source: memory files use their leading
  Summary section, code files reuse code_outline signatures, long documents use
  a heading tree plus first paragraph.
- Directory hits start at overview and read their .overview.md sidecar, since
  directories carry no stored abstract; their full tier stays capped at
  overview. v1 injected the sidecar as if it were a whole file.
- Quotas generalize beyond memory types to resources and skills, with purpose
  presets supplying ratios when quotas are absent.
- dedup_turns keeps a per-session ledger at {session_uri}/.recall_log.json so
  every harness inherits cross-turn dedup; exclude_uris remains as the
  stateless fallback.
- Rendering flattens to one <memory uri=... type=... score=... detail=...>
  element per entry. Every tier carries its URI, so the model can always drill
  down through the MCP read tool.
- Query expansion and digest rewriting are opt-in and fail closed: both have
  timeout fuses, and a failed rewrite still returns the unrewritten block.
  Retrieval failures are counted into stats rather than silently yielding an
  empty block.

Plugins now send one context request, falling back to /recall and then to raw
find on older deployments, and cache that outcome so only the first turn pays
for the probe. The tri-state recallRewrite knob chooses between local host-CLI
compression and the server digest, and client-side settings move to a plugin
section in ovcli.conf.

* refactor(retrieval): give context tiers a per-category default

The tier ladder assumed `abstract` is a cheap summary. For memory files it
is not: the memory writer stores the whole stripped body in that scalar
because it doubles as the embedding text, so `abstract` costs the same as
`full` and the ladder runs `uri < overview < abstract = full`. Two of the
model's properties fell out of that: exempting `abstract` from the per-entry
cap let a single entry eat several times the budget, and `detail` — which
only ever set a ceiling — collapsed to two distinguishable behaviours across
its four values, since `auto` already allowed `full` for memory.

Tiers now come from a per-category constant table that treats the storage
shape as a given: `events` starts at overview (the one memory type whose
`# Summary` extraction is a real compression) and may deepen to full on
leftover budget; every other category is served at `abstract`, which for
memory already is the complete file at zero read cost and for resources and
skills is the generated 256-char summary. The table carries the note to move
`events` back to `abstract` once the writer stores a separate summary scalar.

Falling out of that: prefetch now reads only the candidates whose planned
tier needs a body rather than every candidate, `detail` becomes a real pin
(start and ceiling) and additionally accepts a per-category map, and
`full_score_threshold` is gone — leftover budget is spent in score order
instead of behind an absolute threshold the observed score band cannot
support. `auto` is still accepted on the wire as a synonym for "unset".

Assembly fixes found alongside:

- Removing the abstract cap exemption would turn an oversized abstract into
  a bare URI, so it now falls back to overview first — for memory that is a
  cheaper substitute, not a step up.
- Rewrite timeouts were reported as failures on Python 3.10, where
  `asyncio.TimeoutError` is a separate class from the builtin.
- `stats.rewrite_usage` read `token_tracker` off `VLMConfig`, which has no
  such attribute; usage was structurally always null. It now reads the model
  instance's tracker and reports only when the call count moved by exactly
  one, since that tracker is shared.
- A single malformed ledger record made every deduped recall in that session
  fail, and the file was never rewritten, so it could not heal. Records are
  now coerced on read and dropped on the next write, along with records left
  ahead of the clock by an archive rotation.
- Entries served as a bare URI no longer enter the dedup cooldown: they lost
  to budget pressure, not to the reader having already seen them.
- The render envelope only neutralised a literal `</memory>`, so a body could
  forge a sibling entry with its own uri, type and score.
- Flat-mode gathering re-derived the category from the URI, reading
  `viking://resources/backup/memories/events/log.md` as an event.
- Cooled and excluded URIs are compensated with extra rows, so a fully cooled
  bucket falls through to the next-best hits instead of coming back empty.
- `/recall` quotas overlay the v1 bucket defaults again; `{"events": 5}` had
  started dropping the other three buckets.
- The MCP `recall` signature sent its own defaults as if the caller had, which
  resolved a different profile than `POST /recall`; an unknown `detail` value
  raised `KeyError` through the whole call instead of degrading.

* feat(codex): inject profile context on session start

Reuse the shared profile builder for startup, clear, and resume hooks while preserving archive injection and orphan-session status output.

Co-authored-by: TRAE CLI <noreply@bytedance.com>

* fix(retrieval): raise rewrite timeout default to 30s

* docs(agents): document low-latency recall settings

* fix(codex): prefer luna as recall compressor fallback

* refactor(plugins): unify recall compression setting

* feat(plugins): enable recall compression by default

* docs(agents): use absolute links in image docs

* fix(retrieval): address context assembly review feedback

Co-authored-by: TRAE CLI <noreply@bytedance.com>

* test: trim redundant context assembly coverage

* fix(retrieval): address second-round context assembly review

- Drop the backticked `/search` from the deprecated-recall row in both API
  overviews. The reference checker scans the whole row after the method cell
  for backticked paths, so it read the description as a route named
  `POST /search` and Build Docs failed on an unknown, undocumented route.
- Accept ovcli.conf's full field set in both Python readers. The file's schema
  belongs to the Rust CLI, which writes `root_api_key`, `output`,
  `echo_command`, `show_progress` and `verbose` and ignores unknown keys; the
  two Python readers had drifted into stricter subsets, so the shipped example
  already failed to load in both. Adding the new `plugin` section to a working
  ovcli.conf would have broken `ov doctor` and every SDK client the same way.
- Return 400 from `mode="context"` for a request `mode="list"` also rejects.
  Retrieval validates query and image_url before searching, and the gather
  fuse swallowed that rejection along with genuine scope failures, so a body
  of `{"mode":"context"}` came back 200 with an empty block instead of the
  documented parameter error. Runtime failures still degrade into
  `stats.retrieval_errors`.
- Let a context request that asks for a server-side digest outlast the
  server's rewrite fuse. The plugin's ordinary 15s request timeout is shorter
  than the 30s fuse, so a rewrite that finished inside its own budget was
  aborted client-side, discarding the whole response — including the
  uncompressed block the server returns when a rewrite fails — and falling
  back to `/recall`. The deadline is only extended when the body actually
  requests a rewrite, and `OPENVIKING_RECALL_CONTEXT_TIMEOUT_MS` /
  `plugin.recallContextTimeoutMs` pins it.

* chore(plugins): sync shared modules into the zcode snapshot

* fix(retrieval): align context quotas and plugin defaults

Restore cross-domain coding recall, reuse authoritative actor resource
scopes, and make bucket quotas the sole width control in purpose mode.
Keep plugin defaults server-owned while preserving explicit legacy limit
settings through quota conversion.

Co-authored-by: TRAE CLI <noreply@bytedance.com>

* fix(retrieval): preserve recall compatibility

Restore the deprecated recall threshold default, distinguish successful empty rewrites from compressor failures, and document legacy quota floors across coding-agent plugins.

Co-authored-by: TRAE CLI <noreply@bytedance.com>

---------

Co-authored-by: TRAE CLI <noreply@bytedance.com>
Co-authored-by: qin-ctx <qinhaojie.exe@bytedance.com>
2026-08-05 12:31:21 +08:00
DuTao cbfb387dc7 feat(bot): add unified VikingBot gateway routing and OpenViking auth (#3119)
* bot opt config\api check

* 优化vikingbot的启动链路

* 美化颜色

* docs: add VikingBot gateway routing diagram

* fix(bot): harden gateway auth and proxy routing
2026-07-10 17:45:41 +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
MaojiaShengandopenviking 85986a91bd fix: apikey security: API Key 管理重构与安全增强 (#1686)
* fix: apikey security

* fix: apikey security

* fix: apikey security

* fix: apikey security

---------

Co-authored-by: openviking <openviking@example.com>
2026-04-24 20:13:36 +08:00
MaojiaShengandopenviking 09ab814af5 fix: allow --sudo for ov admin commands (#1589)
* fix: allow --sudo for ov admin commands

* fix: allow --sudo for ov admin commands

* fix: allow --sudo for ov admin commands

* fix: allow --sudo for ov admin commands

---------

Co-authored-by: openviking <openviking@example.com>
2026-04-20 18:55:29 +08:00
Jiahui Zhou c5033b0bcd feat(cli): support tenant identity defaults and overrides (#1019) 2026-03-27 11:35:16 +08:00
MaojiaShengandopenviking 41f80495af chore: remove unsupported examples (#359)
* feat: update README.md

* chore: remove unsupported examples

---------

Co-authored-by: openviking <openviking@example.com>
2026-02-28 18:45:06 +08:00
Qin HaojieandClaude Opus 4.6 1a40839466 feat(client): support timeout config in ovcli.conf and fix Rust CLI alignment (#308)
- Python HTTP client reads `timeout` from ovcli.conf when using default value,
  with priority: SDK explicit param > ovcli.conf > default 60.0
- Rust CLI: replace unused `user` field with `agent_id`, send X-OpenViking-Agent
  header to align with Python client behavior
- Rust CLI: read `timeout` from ovcli.conf and pass to reqwest client
- Move timeout documentation from configuration guide to API overview
- Update examples and ovcli.conf.example with timeout field

Closes #306

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 17:25:42 +08:00
Qin Haojie b92f2c0fc7 feat: 多租户 Phase 1 - API 层多租户能力 (#260)
* doc: update design

* feat: multi_tenant

* feat: multi_tenant

* feat: multi tenant

* feat: multi tenant

* fix: tests

* fix: rust cli
2026-02-24 13:40:44 +08:00
qin-ctx 6d55bf4aa1 feat: 新增 Bash CLI 基础框架与完整命令实现 (T3 + T5) (#132)
* feat: 新增 Typer CLI 并统一配置加载机制

引入基于 Typer 的完整 CLI 模块 (openviking/cli),支持 resources、
sessions、search、filesystem、content、relations、pack、debug、
observer、system 等子命令。

新增统一配置加载器 (config_loader),采用三级解析链(显式路径 →
环境变量 → ~/.openviking/),同时服务于 server (ov.conf) 和
CLI (ovcli.conf)。

精简 AsyncOpenViking / SyncOpenViking 客户端,移除 service 模式
(vectordb_url / agfs_url) 和环境变量回退逻辑,仅保留 embedded
和 HTTP 两种模式。

同步更新中英文文档、示例和测试。

* fix: remove user  when create session

* fix: tests

* fix: tests
2026-02-11 15:53:10 +08:00