Commit Graph
14 Commits
Author SHA1 Message Date
t0saki a83b81715b feat(uri)!: remove uid-less current-user shorthand in favor of viking://~ (#4196)
* feat(uri)!: reject uid-less current-user shorthand in favor of viking://~

viking://user/<segment> (memories/resources/skills/peers/privacy/sessions
without a user id) was ambiguous with a user literally named after the
segment, and a user actually named e.g. "memories" was unreachable for
USER/ADMIN callers. Now that the viking://~ home alias (#4167) covers the
same need unambiguously, the shorthand fails closed at the request
boundary instead of expanding:

- resolve_current_user_uri raises NamespaceShapeError with a corrective
  hint naming both viking://~/<rest> and the explicit-uid form. Silently
  parsing the reserved segment as a peer user id would misdirect reads
  and writes, so rejection is the only safe removal.
- Bare viking://user falls through to the canonical parser and keeps
  container semantics (a user key listing it sees only its own space).
- The self-id escape stays: a caller whose user_id equals a reserved
  name keeps viking://user/<own-id> as their canonical root. ROOT-role
  literal parsing and the legacy viking://session alias are unchanged.
- AddTargetsConfig normalizes stored legacy config spellings
  (viking://user/resources|skills) to the viking://~ form at validation
  so existing ov.conf/user_config deployments keep working; the accepted
  per-user spelling is now viking://~/resources and viking://~/skills.
- usage_reporter keeps canonicalizing the historical shorthand found in
  old transcripts and additionally recognizes viking://~/memories/.

BREAKING CHANGE: requests using the uid-less viking://user/<segment>
spelling now fail with 400; use viking://~/<segment> or an explicit
viking://user/{user_id}/<segment> URI.

* refactor(clients): migrate first-party emitters to the viking://~ home alias

Every in-repo client that emitted the removed uid-less current-user
shorthand now sends viking://~/... instead: vikingbot fallbacks and
default sentinels, the LangChain store/tools defaults, the shared
recall-core.mjs (all synced plugin copies), the codex/claude-code/
openclaw/openwebui/dsh/zcode/pi plugin emitters, quick-app examples,
Go SDK example, tau2 benchmark targets, and the eval golden dataset.

Compat kept where legacy strings live in stored user configs: bot and
ov_dream sentinels accept both spellings while emitting only ~, and
recall-core still rewrites legacy viking://user/<reserved> config values
client-side. langchain_openviking._uri now classifies viking://~ with
the explicit-user shape so canonicalized server responses keep matching
a ~ root. Plugin READMEs note the server requirement for the alias.

* docs: replace current-user shorthand guidance with the viking://~ home alias

Rewrite every EN/ZH doc and model-facing prompt that advertised the
uid-less viking://user/<segment> spelling: URI concept catalogue,
context-types/storage/extraction/retrieval/session/privacy concepts,
configuration guide (with the legacy add_targets auto-normalization
note), resources/skills/sessions/retrieval/admin API references, FAQ,
capability reference, and the openviking-memory / ov-experience-memory /
openclaw / ov-resources skills. The stale MCP viking://user/<path>
dialect passage in the MCP guide is replaced by ~ guidance, and bare
viking://user is documented as the container of user spaces.

* test(api): migrate live API session-used tests off the removed shorthand

tests/api_test/sessions sent uid-less viking://user/skills/... URIs to
record_used, which the request boundary now rejects with 400 (caught by
the API & CLI Integration Tests CI job; these tests need a live server
and are not part of the local suites). The api_test client authenticates
as an admin-role user key, so the viking://~ home alias expands for it.
tests/api_test/common/test_edge_cases.py is left as is: it asserts a 400
for a non-resource add target, which still holds.
2026-08-21 19:00:19 +08:00
t0saki 458e7fae37 docs: add a cross-integration capability reference page (#4076)
* docs: fix integration docs and comments that contradict the code

- codex: credential resolution in the default `auto` mode is env-first — `credentials.mjs`
  only falls back to `ovcli.conf` when no credential env var is set, while the docs and the
  `config.mjs` header comment claimed `ovcli.conf` wins by default. Also document
  `OPENVIKING_CREDENTIAL_SOURCE=cli`, which was undocumented.
- codex: the four hook scripts send the key as `X-API-Key` in addition to
  `Authorization: Bearer`; the README documented Bearer only.
- claude-code: the OV session id is `cc-<cc_session_id>` verbatim (`deriveHarnessSessionId`
  does no hashing), not `cc-<sha256(cc_session_id)>`.
- claude-code: `hooks.json` registers 9 hooks, not 7 — the responsibilities table was
  missing the `PreToolUse` `viking://` guard and the `PostToolUse` skill-experience hook.
- claude-code: archival is triggered client-side (the `Stop` hook commits once
  server-reported pending tokens cross `commitTokenThreshold`, default 20000, plus
  unconditional commits from `PreCompact` / `SessionEnd` / `SubagentStop`). The README
  attributed it to a server-side `auto_commit_threshold`, but
  `memory.session_auto_commit.default_enabled` is false and no plugin sends a policy.
- trae / opencode: the MCP proxy transparently exposes the full server tool set (16 tools);
  the docs listed a 4-item sample or 11-13 tools and omitted `tree` / `write` / `edit`.
- trae-cli: the installer registers the MCP server as `openviking-memory`, but the verify
  step told users to look for `openviking`.
- pi: the manual install block omitted the `pi install <dest>` registration step that the
  one-click installer runs, so a hand-copied extension is never registered.
- install.sh: `--uninstall` handles cursor, trae, trae-cn, trae-cli and zcode; the `--help`
  text still said Cursor/TRAE only.
- mcp_endpoint.py: the module docstring enumerated 13 tools and omitted `recall`,
  `list_watches` and `cancel_watch`; replaced the stale enumeration with a pointer to the
  `@mcp.tool` registrations.

* docs: add a cross-integration capability reference page

The agent-integrations section had per-integration install guides but no place
to compare integrations against each other. This adds one bilingual page that
does that, and wires it into the existing pages in both directions.

- New page `docs/{en,zh}/agent-integrations/16-capability-reference.md`: a
  dimension-first comparison of every OpenViking integration — active tool
  surface, automatic hook surface, install/credential/config layering, recall
  and injection, session and commit lifecycle (including a shutdown-path x
  harness end-state matrix), compaction takeover, write/delete boundaries,
  degradation, and a per-harness profile card for each integration.
- Sidebar: `StructuredSidebarCopy` gains an optional `topItems` field so a
  section can list flat entries next to its overview; agent-integrations uses
  it to place the new page beside the overview. Other sections are unaffected.
- Links both ways: the overview and all 14 per-integration pages link to the
  reference, and the reference links back to each integration page from its
  profile card, from the non-coding integration table, and from the custom
  agent integration paths. Section cross-references (§x.x) are real in-page
  anchor links, generated from the built heading ids.
- trae-cli is documented as TraeCode CLI 2.0 only, installed through a codex
  plugin alias; 1.0 and its standalone plugin are called out as unsupported.
- The MCP tool surface is described as 15 tools throughout, matching the
  removal of the `recall` tool in favour of `search` with `mode="context"`.
  Pages outside this change that still mention an MCP `recall` tool
  (04-codex, 12-cursor, 15-agent-plugins, guides/06-mcp-integration) need a
  follow-up sweep once that removal lands.

* docs: 更新服务端 MCP 工具面描述,简化信息并明确更新方式
2026-08-18 20:38:06 +08:00
t0saki eb5aaf78e9 feat(mcp): consolidate recall into context search (#4075) 2026-08-18 12:45:45 +08:00
ValorandValor fdb4b571ca feat(opencode): add hook-only installation mode (#3734)
* feat(opencode): add hook-only installation mode

* test(opencode): cover hook-only plugin configuration

---------

Co-authored-by: Valor <210239105+zrh805@users.noreply.github.com>
2026-08-07 17:11:45 +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
zgy 49b182045b refactor(parser): Refactor code summaries to fixed skeleton-first routing (#3568)
* Refactor code summary skeleton routing

* Simplify code skeleton routing configuration

* Render C tag skeletons as signatures

* Revert "Render C tag skeletons as signatures"

This reverts commit 8e342055f8.

* Simplify fixed code skeleton summary route

* Inline process skeleton rendering

* Simplify code skeleton routing entrypoints

* Fix code summary review issues

* Address final code summary review feedback

* Route failed tags skeletons to LLM fallback

* Restore CUDA and TS extension routing

* Improve code skeleton query coverage

* Route semantic code detection through skeleton support

* Move process skeleton engine into ast package

* Admit skeleton-supported files during directory scan

* Align code summary docs after main merge

* Reduce code skeleton fallback log verbosity

* chore: require grep-ast 0.9.0
2026-07-31 11:38:57 +08:00
t0saki 2a81edc707 Add workspace peer mode for memory plugins (#3099) 2026-07-09 17:53:36 +08:00
t0saki b511d91ee5 feat(plugins): retrofit OpenCode and pi memory integrations (hybrid MCP, shared lib, 4-harness installer) (#3079)
* feat(plugins): align opencode and pi memory integrations

* fix(installer): tolerate missing optional harness CLIs

* fix(installer): install opencode file wrapper

* fix(opencode): import path for logger initialization

* fix(installer): register pi extension after copy

* feat(plugins): use MCP for opencode integration

* docs: move OpenCode and pi integrations to dedicated pages

Promote the OpenCode plugin and pi extension out of the community-plugins
page into their own numbered agent-integrations pages (10-opencode, 11-pi,
en + zh), update the overview routing table, and refresh the OpenCode image
cards to the hybrid MCP architecture (unified installer, openviking_* MCP
tools, ovcli.conf credentials).

* docs: bare TOS installer commands and reference more examples

Drop --harness from TOS-mirror install commands (image cards use the bare
installer URL, matching the claude-code/codex cards); add Open WebUI tool
server and an examples/ pointer to the community-plugins page (en + zh).

* docs: bare TOS installer commands across agent-integration pages

TOS-mirror install commands carry no flags anywhere; the installer wizard
asks for source, harnesses, language, and credentials.
2026-07-08 15:54:37 +08:00
Zayn Jarvis e43a4c5e6e ci(opencode-plugin): publish scoped npm package (#2807)
* fix(opencode-plugin): use js source install wrapper

* ci(opencode-plugin): publish scoped npm package
2026-06-24 21:21:57 +08:00
Zayn Jarvis 0829477d5d feat(opencode-plugin): memwrite & guard grep/glob on viking:// path (#2801)
* feat(opencode-plugin): improve project memory UX

* chore(opencode-plugin): defer project isolation
2026-06-24 13:43:48 +08:00
Zayn Jarvis 5e622ba6ea docs(plugin): keep one OpenCode plugin (#2540)
* docs(plugin): keep one OpenCode plugin

* docs(opencode): expand plugin install guide
2026-06-22 10:26:46 +08:00
Qin HaojieandMijamind719 8353976bc8 feat(plugins): use actor peer scope (#2595)
* feat(plugins): use actor peer scope

* docs(openclaw): clarify actor peer recall scope

---------

Co-authored-by: Mijamind719 <mijamind@163.com>
2026-06-14 10:15:27 +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
Jiahao Cao 31a31ff4d1 refactor(plugin):Merge OpenCode plugins (#1859)
* Merge opencode plugins

* update:readme&install docs

* Fix Opencode plugin packaging issues

Rename wrapper to .mjs, clean install docs, align README/INSTALL wording with the current directory layout, remove invalid README_ZH.md from package files, and pin @opencode-ai/plugin version.

* Address OpenCode plugin review feedback - Remove OpenViking server auto-start logic from the plugin runtime - Replace fixed-interval auto commits with lifecycle-boundary commits - Commit sessions on compaction, deletion, error, and plugin shutdown - Exclude source-install wrapper files from the npm package - Update docs to clarify wrapper usage and remove deprecated config fields

* fix(opencode-plugin): persist memory recall via chat.message synthetic parts

Replace experimental.chat.messages.transform recall injection with chat.message.

Inject recalled memories as hidden synthetic text parts persisted in session history.

Preserve idempotency with relevant-memories marker detection and update README wording.
2026-05-12 15:41:43 +08:00