* feat(resource): add watch interval support for resource monitoring
implement resource watch functionality that allows automatic monitoring and re-processing of resources at specified intervals. key features include:
- add watch_interval parameter to resource APIs
- create watch scheduler service for task execution
- handle conflict detection for active watch tasks
- provide watch status query capability
- include comprehensive tests and examples
the watch feature enables periodic automatic updates of resources without manual intervention, improving data freshness for frequently changing content
* feat(resources): add watch status tracking and improve resource processing
- Implement get_watch_status API for tracking resource watch status
- Add immediate persistence for first-time resource additions
- Improve file change detection with size comparison
- Refactor watch scheduler with better concurrency control
- Add test coverage for watch status and resource processing
- Remove unused watch manager references and clean up code
* refactor: improve code style and fix minor issues
- Simplify logging by removing redundant data copying
- Fix syntax errors in docstrings and string literals
- Add new fields to EmbeddingMsg class
- Improve line wrapping and formatting
- Update watch task storage URIs to use hidden files
* refactor(embedding_msg): simplify EmbeddingMsg constructor by removing unused fields
Remove media_uri, media_mime_type and id parameters as they are not used in the implementation
* feat(watch): add backup task recovery and simplify permission check
Add test case for recovering tasks from backup storage when primary is missing
Remove require_owner parameter from _check_permission as it's redundant with the existing role-based checks
* feat(resources): add watch_interval support for resource updates
Add watch_interval parameter to enable periodic resource updates. When target is specified, watch_interval > 0 creates/updates a watch task, while <= 0 disables it. Also simplify resource moving logic in ResourceProcessor by using direct mv operation.
* refactor(watch): remove deprecated get_watch_status functionality
remove get_watch_status method and related tests, update examples to use direct task access
update watch manager to use ConflictError for URI conflicts and include original_role in tasks
add validation for watch_interval requiring target URI
* fix(resource_service): validate watch interval before processing resource
Move watch interval validation earlier in the flow to fail fast when 'to' parameter is missing
* refactor(resource_processor): remove redundant temp_uri assignment
* fix(mcp): add api_key support and configurable defaults to MCP query server
The MCP server at examples/mcp-query/server.py had three gaps:
1. No mechanism to pass API key for authenticated OpenViking deployments
2. No server-level default for search target_uri, requiring every client
to specify the scope on each search call
3. Example URLs used "localhost" which fails on Windows where it resolves
to ::1 while the server binds to 127.0.0.1
This adds --api-key/OV_API_KEY and --default-uri/OV_DEFAULT_URI CLI flags
with backward-compatible empty-string defaults, and fixes the epilog
examples to use 127.0.0.1.
Fixes#606
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(mcp): wire api_key to Recipe for LLM auth header
Override Recipe.api_key when --api-key / OV_API_KEY is provided,
so the Authorization header is sent on LLM requests.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(embedder): Gemini Embedding 2 multimodal support (text + image/video/audio/PDF)
Native text + multimodal (image, video, audio, PDF) embedding via `gemini-embedding-2-preview` (google-genai 1.67.0). Additive provider pattern — Volcengine remains the default; Gemini is opt-in via `provider: "gemini"` in `ov.conf`.
- **Model**: `gemini-embedding-2-preview`
- **Input**: text, image, video, audio, PDF (17 MIME types)
- **Output dimension**: 128–3072 (default: **3072**, recommended: 768 / 1536 / 3072)
- **Input token limit**: **8,192 tokens**
- **Supported MIME types**: `image/jpeg`, `image/png`, `image/gif`, `image/webp`, `audio/mpeg`, `audio/mp3`, `audio/wav`, `audio/ogg`, `audio/flac`, `video/mp4`, `video/mpeg`, `video/mov`, `video/avi`, `video/webm`, `video/wmv`, `video/3gpp`, `application/pdf`
- Gemini Embedding 2 Multimodal Support: Introduced a new GeminiDenseEmbedder to support native text and multimodal (image, video, audio, PDF) embedding using the gemini-embedding-2-preview model. This is an opt-in provider via configuration.
- Extended Queue Pipeline for Multimodal Content: The EmbeddingMsg now carries media_uri and media_mime_type to facilitate multimodal content processing. The TextEmbeddingHandler.on_dequeue() method was updated to read raw bytes from viking_fs and call embed_multimodal() when applicable.
- End-to-End Configuration and Security: The EmbeddingConfig now registers the 'gemini' provider with a task_type field. A critical security validation was added to ensure media_uri matches context_data['uri'] before file reads, preventing forged queue messages from accessing arbitrary files. If validation fails or multimodal embedding fails, it falls back to text embedding.
- Multimodal Content Representation: A new ModalContent dataclass was introduced to represent media references, including MIME type, URI, and optional raw data, enabling the Vectorize object to encapsulate both text and media for embedding
* feat: Add asynchronous batch embedding with concurrency control to Gemini embedder.
* Reduce scope to use GeminiDenseEmbedder as only text embed
The before_agent_start hook calls OpenViking's search API for auto-recall
before every agent run. The Promise.allSettled calls and subsequent
getClient() calls had no timeout protection - if the HTTP calls hang
(e.g. during initialization or after gateway restart), the entire agent
pipeline blocks indefinitely with no timeout, no error, and no fallback.
This wraps the auto-recall block with the existing withTimeout utility
using a 5-second timeout (AUTO_RECALL_TIMEOUT_MS). On timeout, a warning
is logged and the agent starts without memory context.
Fixes#673
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
OpenClaw loads the plugin in two separate contexts ([gateway] and [plugins]),
each calling register() and creating its own pending clientPromise. However,
start() only runs in one context, leaving the other context's promise permanently
pending — causing the before_agent_start hook to hang forever on await getClient().
Fix by introducing a module-level localClientPendingPromises map in client.ts.
All registrations share the same pending promise via this map. The first start()
call to run claims the entry (deletes it from the map) and spawns the process,
resolving the shared promise for all registrations. Subsequent start() calls fall
through to await getClient() which waits for the spawner to resolve. The stop()
service clears the map entry to prevent stale promises across hot-reloads.
Co-authored-by: Wiehan Boshoff <wiehanboshoff@Wiehans-Mac-mini.local>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Add POST /sessions/{session_id}/used API to record actually used
contexts and skills, enabling active_count tracking on commit.
Overhaul all plugin installation docs: simplify to npm global install,
add OpenClaw >= 2026.3.12 compatibility warning, expand troubleshooting
and configuration reference.
Co-Authored-By: Claude Opus 4.6
- Add 'ollama' as a supported embedding provider
- Ollama runs locally via OpenAI-compatible API, no API key required
- Allow OpenAI provider to work without api_key when api_base is set
(supports local OpenAI-compatible servers like vLLM, LocalAI)
- Add configuration example and tests for Ollama provider
This enables fully local embedding deployment without cloud API keys.
When OpenClaw gateway serves multiple agents, each agent's
before_agent_start and agent_end hooks now carry the agent's ID
in the second parameter (PluginHookAgentContext). The plugin
dynamically switches the client's agentId before each recall/capture
operation, ensuring memories are routed to the correct agent_space
(md5(user_id + agent_id)[:12]).
Changes:
- client.ts: Add setAgentId()/getAgentId() to allow dynamic agent
switching. Clears cached runtimeIdentity and resolvedSpaceByScope
when switching to ensure correct space derivation.
- index.ts: Extract agentId from hook ctx (2nd param) in both
before_agent_start and agent_end handlers.
This is backward compatible: if ctx.agentId is absent (single-agent
setup), the plugin falls back to the static config agentId as before.
Co-authored-by: Mac <mac@MacBookPro.lan>
agent_space_name() computed md5(user_id + agent_id) without a separator,
so different (user_id, agent_id) pairs could produce the same hash when
their concatenation matched (e.g. ("alice","bot") vs ("aliceb","ot")).
Add ":" separator between user_id and agent_id in the hash input. The ":"
character is safe because the validation regex [a-zA-Z0-9_-] prevents
either field from containing it.
Fix applied to all three implementations:
- openviking_cli/session/user_id.py (Python SDK)
- bot/vikingbot/openviking_mount/ov_server.py (bot server)
- examples/openclaw-memory-plugin/client.ts (TypeScript example)
Note: This is a breaking change for existing agent spaces. Existing data
directories were named using the old hash and will not be found with the
new hash. A migration script or fallback lookup may be needed.
Fixes#595
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Replace manual openclaw.json reading/writing with `openclaw plugins enable`
and `openclaw config set` commands across all three install scripts (sh, ps1, js).
This delegates config validation and merging to the CLI, reducing duplication
and avoiding potential conflicts with other plugins.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Add log section with WARNING level, file output, and 3-day rotation to the generated config across all install scripts (shell, PowerShell, and setup-helper CLI).
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Replace cli.js with install.js; update bin aliases and repo URL to volcengine/OpenViking
- Bump version to 0.2.7; improve venv error message with actionable fix steps for Ubuntu
- Update INSTALL.md and INSTALL-ZH.md: add npm global install as recommended method
Made-with: Cursor
Add tsconfig.json and new source files (client.ts, process-manager.ts,
memory-ranking.ts, text-utils.ts) to install scripts. Merge plugin load
paths and allow list instead of overwriting existing config. Adjust
default recallLimit to 6. Update uv.lock with resolved bot-full deps.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add log for embedder error
* fix: skills for add, search and operate server
* fix: skills for add, search and operate server
* fix: skills for add, search and operate server
* fix: skills for add, search and operate server
---------
Co-authored-by: openviking <openviking@example.com>
Replace fail-on-port-occupied with smart port preparation that kills stale
OpenViking processes or auto-finds free ports. Simplify agent ID to default
to "default" instead of random per-session generation. Change install scripts
to merge into existing allow lists and load paths instead of overwriting them.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: define a system path for future deployment
* feat: define a system path for future deployment
* fix: golang downgrade to 1.19
* fix: golang downgrade to 1.19, and change doc
* docs: change model recommendation
* fix: golang downgrade to 1.19, and change doc
* fix: mv test files
* fix: loguru
---------
Co-authored-by: openviking <openviking@example.com>
Session wrapper and OVClient example only accepted string content,
missing the parts parameter (TextPart, ContextPart, ToolPart) that
the underlying BaseClient already supports.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* tests(parsers): add unit tests for office extensions within add_resource directory
* feat: enhance add-resource functionality with new options
- Updated CLI commands to support additional parameters: --ignore-dirs, --include, --exclude, and --no-directly-upload-media.
- Modified resource processing to handle new parameters for directory scanning and file inclusion/exclusion.
- Improved README documentation for CLI usage and examples.
This update allows for more flexible resource management and better control over file uploads.
* feat(cli): enhance add-resource command with new options
- Added support for additional parameters: --no-strict, --ignore-dirs, --include, --exclude, and --no-directly-upload-media.
- Updated the handling of resource addition to accommodate new options for improved directory scanning and file management.
- Enhanced README documentation with examples for the new functionality.
This update provides users with greater flexibility in managing resources.
* chore(cli): remove unused cargo feature for edition 2024 in Cargo.toml
* chore(pyproject): update tag_regex in setuptools_scm configuration for version parsing