* refactor(storage): delete agfs http mode client
* refactor(storage): refactor protocol to support diff return type
* refactor(storage): refactor code format from lint
* fix(semantic): ensure memory processing always reports completion status
_process_memory_directory() had early return paths that could bypass
report_success()/report_error() in on_dequeue(), leaving the queue's
in_progress counter permanently stuck. This caused the semantic queue
to appear stalled with pending items never being processed.
All code paths now properly propagate to the completion callbacks.
Fixes#864.
* fix(semantic): classify filesystem errors as permanent to prevent infinite retry
Address review feedback: filesystem errors (FileNotFoundError,
PermissionError, IsADirectoryError, NotADirectoryError) are now
classified as permanent by classify_api_error(), so they hit
report_error() instead of being infinitely re-enqueued.
Tests updated to exercise real classifier behavior without mocking.
* test: fix set_callbacks signature for DequeueHandlerBase
DequeueHandlerBase.set_callbacks now takes (on_success, on_requeue, on_error);
the original PR #951 test harness called it with only (on_success, on_error).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(semantic): remove dead _mark_failed helper, add transient-error test
_mark_failed's two call sites were removed when _process_memory_directory
started raising on error. The closure itself was left behind. Delete it —
telemetry failure is now reported by on_dequeue's exception handler via
get_request_wait_tracker().mark_semantic_failed().
Add test_memory_ls_transient_error_requeues to cover the transient branch
of the memory path: a 500-class error from ls() must route through
_reenqueue_semantic_msg() and fire report_requeue() + report_success(),
not report_error(). The previous tests only exercised permanent errors.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: deepakdevp <deepakdevp@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
* lisence: change the main lisence from Apache-2.0 to AGPL-v3
* lisence: change the main lisence from Apache-2.0 to AGPL-v3
* lisence: change the main lisence from Apache-2.0 to AGPL-v3
---------
Co-authored-by: openviking <openviking@example.com>
* feat(utils): add CircuitBreaker and error classification for API protection
Adds a thread-safe CircuitBreaker with three states (CLOSED/OPEN/HALF_OPEN)
and classify_api_error() that distinguishes permanent (403/401) from transient
(429/5xx/timeout) errors. Permanent errors trip the breaker immediately.
Part of fix for #729.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(semantic): add circuit breaker to SemanticProcessor
on_dequeue() now checks a circuit breaker before processing. Permanent
API errors (403/401) trip the breaker immediately and drop the message.
Transient errors (429/5xx/timeout) re-enqueue the message for later
retry. When the breaker is open, messages are re-enqueued with a
throttled sleep to prevent re-enqueue storms.
Part of fix for #729.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(embedding): add circuit breaker to TextEmbeddingHandler
Replaces 429-only error check with classify_api_error() that handles
permanent (403/401), transient (429/5xx/timeout), and unknown errors.
Permanent errors trip the breaker and drop the message. Transient errors
re-enqueue for retry (extending existing 429 behavior to all transient
errors). Circuit breaker check before embedding prevents calling a
known-broken API.
Part of fix for #729.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: restore asyncio import and handle edge cases in circuit breaker integration
- Restore top-level `import asyncio` in collection_schemas.py (was
accidentally removed, breaking all embedding operations)
- Return error instead of falling through when breaker is open and no
queue manager is available
- Log warning when queue_manager is None in _reenqueue_semantic_msg
- Only call report_success() when msg was actually re-enqueued, not
when msg is None
Part of fix for #729.
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: windows zip path norm
* fix: account id in vector db
* fix: add some log
* fix: add some log, and fixed search
* fix: add some log, and fixed search
* fix: add some log, and fixed search
* fix: add some log, and fixed search
* fix: add some log, and fixed search
* fix: add some log, and fixed search
* fix: add some log, and fixed search
* fix: add some log, and fixed search
---------
Co-authored-by: openviking <openviking@example.com>
* refactor(sandbox): remove docker/aiosandbox backends, simplify SRT config
- Remove docker and aiosandbox from available backends
- Remove settings_path from SrtBackendConfig (now auto-generated in workspace)
- Update SRT settings path to workspace/sandboxes/{session}-srt-settings.json
- Update README examples to use srt backend and remove settingsPath
* refactor(sandbox): remove docker/aiosandbox backends, simplify SRT config
- Remove docker and aiosandbox from available backends
- Remove settings_path from SrtBackendConfig (now auto-generated in workspace)
- Update SRT settings path to workspace/sandboxes/{session}-srt-settings.json
- Update README examples to use srt backend and remove settingsPath
* fix: remove unused handle_chat_direct function and fix unused logs variable
* Fix UTF-8 issues in chat command
* Add tab indentation to Think, Calling, and Result lines in CLI output
* Add first release workflow
* Update release workflow with correct working directory
* 修改 SessionKey 构建逻辑:统一使用 type="cli",channel_id 默认 "default",chat_id 作为 session_id 使用
* Implement machine unique ID as default session ID for ov chat
* Remove unsupported --logs parameter from chat command
* 统一 Python 和 Rust CLI 的默认 session ID 生成逻辑
* 修改日志
* 去掉log依赖
* docs: add VikingBot quick start section to READMEs
* fix: use vikingbot chat instead of ov chat in READMEs
* Revert "fix: use vikingbot chat instead of ov chat in READMEs"
This reverts commit 59f4e87ba0.
* fix: use UUID v4 for machine ID generation in both Rust and Python
* refactor: move truncate_utf8 to utils, fix chat history path, and use BotProcess dataclass
* refactor: update machine ID generation and remove unused chat_v2
- Update Python to use py-machineid library
- Update Rust to use machine-uid crate
- Remove unused chat_v2.rs
- Move machine ID from file storage to system-provided IDs
- Add fallback to "default" if system ID is unavailable
* 优化格式
* ruff format .