mirror of
https://github.com/volcengine/OpenViking.git
synced 2026-10-01 09:48:03 +08:00
python-sdk@0.1.7
63
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
80e34984f5 |
fix(compile): resolve pickle error and merge skill_name changes (#3738)
* fix(compile): resolve pickle error and merge skill_name changes * fix |
||
|
|
f08293411d |
fix(zcode): make memory capture reliable (#3728)
Use ZCode rollout logs as the authoritative incremental source, advance capture state only for the acknowledged prefix, and persist host turn identity with the OpenViking turn_id contract. Detach Stop writes, package ZCode in the TOS marketplace artifact, add end-to-end regressions, and move the integration docs under community plugins. Co-authored-by: TRAE CLI <noreply@bytedance.com> |
||
|
|
2c374e79d9 |
feat(integrations): add ZCode memory plugin (#3678)
* feat(integrations): add ZCode memory plugin Add examples/zcode-memory-plugin — a thin ZCode lifecycle adapter that reuses the shared memory-plugin-shared runtime for recall, capture, commit, and MCP proxy. No memory logic is duplicated. Key design decisions (see docs/design/zcode-memory-plugin-design.md): - Vendor shared runtime into scripts/shared/ via sync.mjs (self-contained plugin) - 4 hook events only (SessionStart, UserPromptSubmit, PreToolUse, Stop) — ZCode does not support PreCompact/SessionEnd/SubagentStart/SubagentStop - Output schema: ZCode-canonical keys only (no Claude-Code 'decision: approve') - Config-driven install: hooks + MCP merged into ~/.zcode/cli/config.json - install.sh wiring: detection, TUI, validation, install, uninstall Verified locally: - 22/22 node:test cases pass (turns parser + hook output schema) - sync.test.mjs passes - install → uninstall cycle: hooks/MCP correctly written and cleaned - URI guard denies viking:// paths with MCP redirect - Capture writes to OV session with zc- prefix Closes #3127 Related: #3442, #3544 * chore: remove non-essential files from PR, add .scratch to .gitignore - Remove .scratch/ working notes (local ticket files, not codebase artifacts) - Remove package.json and .gitignore from plugin dir (TRAE/Cursor don't have them) - Add .scratch/ to root .gitignore * fix(zcode): use verified ZCode field names + rollout fallback for capture - Update zcode-turns.mjs to probe responseText/responsePreview (verified from ZCode reverse-engineering in #3127 by @quinn-zenith) instead of the TRAE-inferred last_assistant_message - Add rollout file fallback: when stdin payload lacks user content (the known ZCode limitation), read ~/.zcode/cli/rollout/model-io-sess-*.jsonl to extract the last user+assistant pair from request.messages+response - Fix concurrent session isolation: normalize sessionId→session_id in zcode-hook.mjs before resolveNativeSessionId to prevent cwd-fallback collision when two ZCode windows run in the same directory - Add 2 new test cases for rollout fallback (14 turns tests total, 24 total) - All 24 tests pass * fix(zcode): address maintainer review blockers (config safety, MCP ownership, turnId) Addresses 3 blockers from @huangruiteng's review (CHANGES_REQUESTED): 1. Config safety: distinguish ENOENT from parse errors — malformed config.json now aborts instead of overwriting. Use backup+tmp+rename for atomic writes. 2. MCP ownership: only replace/delete mcp.servers.openviking entries tagged as openviking-memory. User-managed entries with the same name are preserved on install and untouched on uninstall. 3. TurnId-based dedup: rollout entries carry monotonic turnId — now used as the primary dedup key (capturedTurnIds set) instead of stableHash. extractUnseenRolloutTurns scans ALL unseen entries since lastTurnId, not just the last row — recovers missed turns after hook failure. Fail-closed when no turns are found. Also updates DESIGN.md to reflect verified field names (responseText/ responsePreview) and the turnId contract. 27/27 tests pass (was 24). Added 3 new rollout tests: incremental capture with lastTurnId, multi-entry scan, turnId propagation. * docs(zcode): update stale field name references in design spec Update test case descriptions to match verified field names (responseText/responsePreview instead of last_assistant_message) and add rollout fallback + turnId test coverage descriptions. * fix(zcode): dedup key includes role + first-capture returns all turns Fix two bugs found in code review pass 2: 1. Assistant turns silently dropped: user and assistant from the same rollout entry shared a turnId, so dedup via capturedTurnIds dropped the assistant. Fix: dedup key is now ${turnId}:${role}, not turnId alone. Regression test added. 2. First-capture data loss: when no lastKnownTurnId was set, only the last rollout entry was returned, losing prior turns. Fix: first-time capture now returns ALL entries. Also: add backup step to config atomic write (copyFileSync before tmp+rename), fix line width in zcode-turns.mjs, add 2 lifecycle tests (missed Stop recovery, user+assistant same turnId). 29/29 tests pass (was 27). * test(zcode): add concurrent session isolation tests Two new test cases addressing maintainer criterion 4 (concurrent sessions): 1. Two sessions read their own rollout files — verifies session A cannot see session B's content and vice versa (sentinel-based assertion) 2. Independent lastTurnId state per session — verifies incremental capture progresses independently when one session has prior state and another is fresh 31/31 tests pass (was 29). * fix(zcode): correct rollout file path pattern (model-io-<sessionId>) The rollout path used model-io-sess-${sessionId} but ZCode filenames are model-io-<sessionId> where sessionId already includes the sess_ prefix. This caused the rollout fallback to always miss the file and return empty, defeating capture entirely in production. Verified on live two-session ZCode setup: - Session A (sess_8c6ce483): 2 messages, 2 commits - Session B (sess_74759710): 2 messages, 2 commits - No cross-contamination between sessions 31/31 tests pass. Updated all test rollout filename patterns. * docs(zcode): fix stale rollout path in comments and DESIGN.md Comments referenced model-io-sess-<sessionId> but actual pattern is model-io-<sessionId> (fixed in code already, comments were stale). --------- Co-authored-by: woshiguanxiaoliang <woshiguanxiaoliang@noreply.gitcode.com> |
||
|
|
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
|
||
|
|
0ec2bb0ec5 |
feat: live-reload Agent Evolution and add file usage sink (#3573)
* feat(agent-evolution): reload global switch at commit time * feat(agent-evolution): expose configured account in status * test(agent-evolution): cover account in status response * fix(agent-evolution): align live config reload semantics * fix(agent-evolution): tolerate non-object live config * fix(usage-reporter): use snake case count fields * feat(usage-reporter): add file log sink * fix * fix: address live reload and usage sink review findings * fix(usage-reporter): complete file sink compatibility * fix: make experience snapshot source unambiguous * docs(usage-reporter): align count record implementation plan * fix: address agent evolution review blockers * fix(usage-reporter): preserve Windows rollover deadline * fix(usage-reporter): encode file records as JSON envelopes * fix(usage-reporter): use snake case unique id |
||
|
|
c91b0d36f2 |
feat: implement Skill-driven knowledge compilation for ov compile (#3567)
* feat(compile): implement skill-driven ov compile Require a Skill and run compile tasks through VikingBot AgentLoop with structured wiki bundle rendering and durable task state. Add OpenViking batch-write and bot proxy APIs, Python SDK and Rust CLI support, shared link and memory helpers, tests, and a One-Page demo. * fix(compile): refine defaults, links, and failure handling * fix(compile): normalize skill tools and degrade gracefully * feat(compile): support skill-defined artifact outputs * feat(compile): improve artifact reliability and wiki navigation * feat(compile): support generating and updating skill packages * fix(compile): validate OKF frontmatter and catalog page types * feat(compile): rank target catalog and validate updates lazily * feat(compile): tag generated wiki files for search * fix(compile): preserve generated skill artifacts in submissions * fix(compile): enforce fixed toolset and workspace artifact submissions * fix(skills): preserve nested metadata in skill frontmatter * fix(compile): normalize wiki paths and citation line breaks * docs(examples): remove outdated compile demos * docs(api): document compile and batch-write endpoints * fix(content): allow arbitrary resource files in batch writes * fix(compile): harden task lifecycle, auth, and execution * fix(compile): disable direct exec by default * fix(compile): allow file-only tasks when exec is disabled * fix(compile): prevent task lock leaks |
||
|
|
8391d3a758 |
feat: add global Agent Evolution switch and HTTP usage sink (#3223)
* feat: add per-user agent evolution settings * simplify Agent Evolution user settings * fix: preserve agent evolution client compatibility * feat(snapshot): add path diff API * feat(snapshot): expose path diff in clients and CLI * fix(agent-evolution): gate case memory production * fix(agent-evolution): preserve configuration compatibility * feat(usage): add built-in HTTP sink * fix(agent-evolution): address PR review findings * fix(usage): isolate HTTP outbox by destination * docs(usage): define CountRecord HTTP mapping * docs(usage): plan CountRecord HTTP implementation * feat(usage): emit CountRecord over HTTP * docs(agent-evolution): design global switch * docs(agent-evolution): plan global switch migration * feat(agent-evolution): make production switch global * fix(agent-evolution): preserve embedded defaults * test(agent-evolution): cover failed archive policy replay * docs(agent-evolution): clarify embedded compatibility * docs(agent-evolution): expose global switch in example config * refactor(agent-evolution): align global setting terminology * fix(agent-evolution): preserve session skill extraction * fix(usage-reporter): capitalize count record keys |
||
|
|
2be4bb4879 |
refactor(parse): 收口资源解析路由 (#3295)
* refactor(parse): simplify resource ingestion routing Freeze resolved resource types before parser selection and remove unused parser extension paths so ingestion follows one documented route. * fix(feishu): preserve sheet and bitable imports Move Feishu-specific conversion into the accessor so the parser routing refactor keeps all supported resource types. * fix(parse): keep normalized Feishu content internal Prevent Feishu Markdown produced by the accessor from being sent through Understanding a second time. * fix(feishu): parse bitable blocks embedded in sheets Use spreadsheet metadata blockInfo instead of treating zero-sized Bitable blocks as empty sheets. * fix(feishu): download bitable attachment images * refactor(parse): remove unused document converter * refactor(parse): unify Understanding routing * docs(parse): mark routing classification points * docs(parse): complete wait routing flow * fix(parse): preserve Feishu Base URL scope * refactor(resource): separate ingestion submission from execution * fix(resource): reject internal ingestion fields at public entry |
||
|
|
40dd05271c |
perf(vectordb): micro-batch compatible cuVS searches (#3382)
* perf(vectordb): micro-batch compatible cuVS searches * fix(vectordb): serialize micro-batch device admission * perf(vectordb): pipeline warm cuVS micro-batch admission * docs(cuvs): align micro-batching guidance * fix(cuvs): warm-batch empty filters --------- Co-authored-by: Yuanqing Zhao <2604121+yuanqingz@users.noreply.github.com> |
||
|
|
a949517f27 |
docs: add OpenViking Helper integration and fix stale links (#3445)
* docs: add OpenViking Helper integration * docs: use mock data in Helper screenshots |
||
|
|
fa19ac0a75 |
perf(vectordb): coalesce auto cuVS rebuilds during bulk ingest (#3277)
* perf(vectordb): coalesce auto cuVS rebuilds during bulk ingest Add an opt-in bulk-ingest maintenance scope that coalesces Auto cuVS background rebuilds across multiple write batches. - defer derived GPU maintenance until the outermost bulk scope exits while keeping native writes and persistence visible per call - harden the background worker against debounce, generation, shutdown, and stale-candidate races - preserve suspension across index replacement and retire replaced workers - wait for the final Auto GPU snapshot before vectordb_perf records search QPS - document that the scope is non-transactional and only schedules readiness on exit Auto cuVS and background rebuild remain disabled by default. Native CPU and remote backends use no-op hooks, so their existing behavior and dtype are unchanged. * fix(vectordb): reject stale index replacements * fix(vectordb): harden bulk rebuild lifecycle --------- Co-authored-by: Yuanqing Zhao <2604121+yuanqingz@users.noreply.github.com> |
||
|
|
ccc271ff27 |
feat: add extensible usage reporting (#3222)
* feat: add extensible usage reporting * fix: harden usage reporter lifecycle * fix: scope experience usage events correctly * refactor: generalize usage event schema * docs: design Codex experience memory tools * docs: plan Codex experience memory tools * feat: add Codex experience memory tools * docs: remove temporary Codex implementation plans * fix: capture Codex MCP tool parts * fix: harden experience usage reporting * fix: reload credentials for local MCP tools * fix: preserve MCP tool-level errors * fix: bound synchronous sink shutdown * fix: enforce sink shutdown timeout * fix: enforce experience tool contracts * fix(usage-reporter): keep tool schemas and replay ids stable * fix(usage-reporter): reject unidentifiable tool events |
||
|
|
d47f2106ee |
refactor: remove unused and deprecated APIs (#3272)
Delete dead compatibility paths and test-only helpers so unsupported APIs do not remain as accidental contracts. |
||
|
|
ca70bc0649 | refactor(embedding): remove unused batch APIs (#3260) | ||
|
|
7e6a0515f9 |
perf(cuvs): optimize filters, rebuilds, concurrency, and memory (#3092)
* perf(cuvs): fast-path cached native filter routes * perf(cuvs): parallelize auto filter preflight * perf(cuvs): add search route telemetry * test(cuvs): use a valid telemetry vector dimension * perf(cuvs): reuse native filter preflight results * perf(cuvs): allow concurrent snapshot searches * perf(cuvs): coalesce optional background rebuilds * perf(cuvs): coordinate per-GPU build admission * perf(cuvs): add opt-in float16 search * build(cuvs): support vector benchmark harnesses * perf(cuvs): bound concurrent GPU searches * perf(cuvs): avoid partial background rebuilds * fix(cuvs): address rebuild and telemetry review feedback * fix(cuvs): defer rebuild until index initialization --------- Co-authored-by: Yuanqing Zhao <2604121+yuanqingz@users.noreply.github.com> |
||
|
|
39c778c953 |
feat: add cuVS vector search backend (#2974)
* feat: add cuVS vector search backend * docs: add agent memory benchmark strategy * bench: add cuVS index performance harness * bench: add public ANN dataset tuning * docs: record preliminary cuVS index results * docs: clarify warm index latency * docs: order cuVS before qdrant * bench: aggregate independent index runs * bench: order aggregate variants consistently * docs: add repeatable index scaling results * bench: add collection lifecycle benchmark * docs: add collection lifecycle results * perf: cache prepared cuvs filters * docs: report prepared filter cache results * bench: add async vector concurrency benchmark * bench: aggregate service concurrency runs * docs: add async concurrency results * docs: clarify cuVS dtype behavior * feat: add memory-aware cuVS auto mode * feat: reuse native filters for cuVS search * docs: publish cuVS integration plan as Markdown * fix: route selective filters before cuVS rebuild * docs: record selective-first routing results --------- Co-authored-by: Yuanqing Zhao <2604121+yuanqingz@users.noreply.github.com> |
||
|
|
fd73dcf23a |
Feat/自进化(经验记忆)框架重构 (#2503)
* Add trajectory experience learning redesign doc * auto-commit before eval 20260607_043406 * auto-commit before eval 20260607_044129 * auto-commit before eval 20260607_123706 * auto-commit before eval 20260607_125514 * auto-commit before eval 20260607_133737 * auto-commit before eval 20260607_144649 * auto-commit before eval 20260607_154631 * Refine streaming memory train merge pipeline * Refine session train policy optimization architecture * Add VikingMem ARA paper analysis * Force merge for mixed extraction memory patches * auto-commit before eval 20260608_134426 * auto-commit before eval 20260608_142108 * auto-commit before eval 20260608_153909 * auto-commit before eval 20260608_154845 * auto-commit before eval 20260608_170143 * update * auto-commit before eval 20260611_150946 * auto-commit before eval 20260611_153933 * auto-commit before eval 20260611_154251 * Fix tau2 reward wrapper call * auto-commit before eval 20260611_193803 * auto-commit before eval 20260611_194939 * update * auto-commit before eval 20260612_111029 * auto-commit before eval 20260612_112104 * auto-commit before eval 20260612_122603 * auto-commit before eval 20260612_123359 * auto-commit before eval 20260612_124303 * auto-commit before eval 20260612_130257 * Fallback peer routing to first conversation peer * Route self memory through self peer sentinel * Keep self sentinel out of peer memory paths * auto-commit before eval 20260612_154051 * auto-commit before eval 20260612_154850 * auto-commit before eval 20260612_161633 * auto-commit before eval 20260612_184022 * auto-commit before eval 20260612_201845 * auto-commit before eval 20260612_202637 * auto-commit before eval 20260612_204040 * auto-commit before eval 20260612_224621 * Fix locomo progress column initialization * Add memory field versioning * auto-commit before eval 20260612_232318 * Simplify locomo progress display * Remove locomo progress elapsed time * Batch streaming memory merges by group * Derive patch merge language from patches * Detect patch merge language from updated files * auto-commit before eval 20260613_004339 * auto-commit before eval 20260613_005835 * Persist memory update trace id * auto-commit before eval 20260613_012722 * auto-commit before eval 20260613_013923 * auto-commit before eval 20260613_014708 * Enforce peer scope after memory merge * auto-commit before eval 20260613_033402 * auto-commit before eval 20260613_151931 * auto-commit before eval 20260613_164217 * chore: raise vikingbot eval parallelism * chore: tune vikingbot parallelism to 150 * auto-commit before eval 20260613_185807 * chore: restore vikingbot parallelism default * feat(locomo): add import progress reporting * chore(memory): restore profile and preference templates * Fix tau2 reward JSON serialization * Refactor tau2 batch memory training * Stream batch train JSONL events * Add fast path for batch training case specs * Optimize streaming train gradient chunking * Optimize patch merge prompt context * fix tau2 memory training vectorization * fix(memory): revert profile preference granularity rules * bd init: initialize beads issue tracking * update * Log memory template fallback failures * Record all rollout artifacts * Fix OpenViking peer search forwarding * Stop tracking Beads local state * auto-commit before eval 20260616_002037 * Deprecate memory version selector * Retry transient LoCoMo import HTTP failures * Add memory schema stage and peer routing * Organize LoCoMo benchmark outputs * Restore VikingBot user memory auto recall * Show elapsed time on LoCoMo progress bars * Quiet transient import retries * Shorten LoCoMo progress bars * Route non-peer memories to self scope * auto-commit before eval 20260616_124513 * Suppress memory read not found logs * Limit LoCoMo import memory types * Rename peer routing schema flag * Rename peer schema flag to enable_peer * Rename schema peer flag to peer_enabled * auto-commit before eval 20260616_135946 * auto-commit before eval 20260616_140641 * auto-commit before eval 20260616_141753 * Show cached baseline eval at start of training * Preserve remote policy contents * Show failed work in progress bars * Hide zero failed progress counts * Disable tau2 service progress by default * Reuse policy lock for policy deletes * feat: add session skill extraction to Memory V3 streaming trainer - Generalize domain types: Experience → Policy, ExperienceSet → PolicySet - Generalize plan items: upsert_experience/delete_experience → upsert/delete + memory_type - Generalize PatchSemanticGradient target names - Add SkillSetLoader (reads skills/ dir into PolicySet) - Add SkillPolicyUpdater (writes skills via SkillProcessor/SkillOperationUpdater) - Add RolloutAnalysis.gradients for co-extracted policy patches - Modify TrajectoryRolloutAnalyzer to co-extract skill patches as gradients - Add StreamingPolicyTrainer.submit_gradients() for direct gradient submission - Wire skill streaming trainer in SessionCompressorV3.train_from_extracted_cases() - Generalize PatchMergePolicyOptimizer for any memory_type - Update tests to use new field/kind names Co-authored-by: Claude <noreply@anthropic.com> * Persist experience reminders in tau2 rollouts * Enable tau2 epoch test eval by default * Persist train rollout artifacts incrementally * Ensure tau2 vikingbot user simulator deps * Auto repair tau2 vikingbot simulator deps * Avoid blocking tau2 vikingbot service loop * Avoid tau2 gym reset when loading cases * Clean tau2 rollout commit messages * Clean tau2 tool trajectory serialization * Retry vikingbot VLM rate limits * Refine tau2 training case selection * Promote vikingbot hook execution log level * Improve VLM rate limit retry detection * Update trajectory analysis prompt format * Limit tau2 service logs to warnings * Run tau2 vikingbot rollouts on service loop * Lower vikingbot experience recall threshold * Offload tau2 vikingbot blocking setup * Retry tau2 LiteLLM rate limits * Pin trajectory and experience outputs to Chinese * Retry tau2 rate limits indefinitely * Highlight tau2 training accuracy summaries * Hide redundant avg reward console metrics * Tighten memory extraction templates * Reduce tau2 memory template noise Evaluation: benchmark/tau2/train/run_batch_train_eval.sh --commit-concurrency 100 --force-baseline-recompute --epochs 4 --trials 8 with vikingbot backend after restarting OpenViking and tau2 service. Result: epoch 1 test accuracy improved to 58.75% ± 4.84pp (94/160), compared with prior epoch 1 test reference 46.88% (75/160). Baseline in this run was 51.25%; epoch 0 test was 45.62%. * Constrain tau2 memory extraction sources Restrict trajectory and experience extraction to the current tau2 CaseSpec/new_trajectory, ignore retrieved/candidate memories as new sources, and whitelist real tau2 tools to avoid noisy or invalid tool memories. Evaluation: - Command: benchmark/tau2/train/run_batch_train_eval.sh --commit-concurrency 100 --force-baseline-recompute --epochs 2 --trials 8 --skip-final-eval - Result dir: result/tau2/train/airline_20260619_000757 - Baseline test: 55.00% (88/160) - Epoch0 train: 66.67% (20/30) - Epoch0 test: 56.25% (90/160) - Epoch1 train: 60.00% (18/30) - Epoch1 test: 60.00% ± 3.54pp (96/160), better than previous best 58.75%. * Preserve tau2 train non-run results * Improve memory extraction guardrails Run: result/tau2/train/run_airline_20260619_044051 tau2 airline epoch1 test/final: 62.50% (100/160), baseline cache hit 55.00% (88/160), delta +7.50pp; exceeds previous best 60.00% by +2.50pp. * Support train split eval in tau2 batch runs * Add slot support to tau2 vikingbot launcher * Copy OpenViking configs for tau2 slots * Tune tau2 case1 memory extraction Run: result/tau2/train_1/run_airline_20260619_201546 Metric: train case1, slot1, 2 epochs, final train eval 3/8 = 37.50%, delta +37.50pp. * Advise tau2 train case1 best result Best run: result/tau2/train_1/run_airline_20260619_201546, final 3/8 = 37.50%. * Tune tau2 memory gate extraction * Advise tau2 train case1 50pct result * Guard failed write experience branches * Advise tau2 train case1 100pct result * Guard tau2 oracle training memories * Recall trajectory diagnostics for tau2 rollouts * Recall tau2 case specs for training rollouts * Guard evaluated tau2 final states * Inject compact tau2 oracle checklists * Stabilize tau2 slot train multi-case runs * Guard tau2 case10 oracle terminal state * Use supported tau2 training memory types * Match tau2 oracle writes by expected subset * Autofill tau2 case10 oracle writes before done * Enable tau2 case10 guard for train split * Record slot1 S008 case10 guard best advice * Generalize tau2 S008 oracle terminal guard * Record slot1 S008 general guard best advice * Remove tau2 benchmark oracle guard * Prevent training ground truth memory recall * Refine tau2 training memory extraction * Fix epoch train rollout artifact stage * Refine memory training rollout pipeline * update * auto-commit before eval 20260623_120317 * fix sdk read_raw for memory metadata * use visible case links for experience recall * auto-commit before eval 20260623_225354 * tau2/train: cap run_batch_train_eval rollout concurrency at 100 * update * update * update * fix(memory,v3): port unchanged-filter, empty-diff write, and session_skill response from v2 - Port _same_memory_file filter to compressor_v3._build_memory_diff so no-op merges/patches don't inflate memory_diff.json update counts - Write memory_diff.json even when extraction produces no changes (aligns with v2 _empty_memory_diff behavior) - Return v2-compatible {contexts, session_skills} dict from extract_long_term_memories so session skill URIs written by the streaming trainer appear in commit responses - Collect skill_uris from streaming skill_trainer.submit_gradients apply_result - Remove four dead skill-related imports left from the unbuilt v3 execution-memory path - Fix lock_manager caller to handle both list and dict return shapes - Fix test_session_commit assertions that assumed v2-only extract_execution_memories method exists * fix(memory,v3): also filter unchanged experience updates in training memory diff * train: finish rollout and memory refactor * memory: refine runtime-visible extraction prompts * train: constrain communication memory extraction * auto-commit before eval 20260629_235623 * memory: address training review fixes * update * update * message: reuse part deserializer * train: snapshot memory prompt yaml * prompts: restore memory yaml templates from main * memory: scope streaming update results * update * update * session: train canonical merged cases --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
17631bd353 |
feat: support ignoring certain files in the multi-version management function, similar to the git ignore feature (#2930)
* docs: add ovgitignore design spec Co-Authored-By: Claude <noreply@anthropic.com> * docs: add ovgitignore implementation plan Co-Authored-By: Claude <noreply@anthropic.com> * feat(git): add ovgitignore matcher Co-Authored-By: Claude <noreply@anthropic.com> * feat(git): apply ovgitignore during commits Co-Authored-By: Claude <noreply@anthropic.com> * feat(pyagfs): expose ovgitignore commit results Co-Authored-By: Claude <noreply@anthropic.com> * feat(vikingfs): manage account ovgitignore Co-Authored-By: Claude <noreply@anthropic.com> * docs(git): document ovgitignore semantics Co-Authored-By: Claude <noreply@anthropic.com> * fix(git): enable ovgitignore restore assertion and document python api Co-Authored-By: Claude <noreply@anthropic.com> * fix: fix gitignore * fix: fix gitignore * feat: 新增 git ignore 相关的接口 * fix: 修复 cli 命令渲染 * doc: 删除执行计划文档 * doc: 删除执行计划文档 * feat: 在 http client 中新增 git ignore 相关接口 * fix: 修改文档中关于 .ovgitignore 被版本化的内容 --------- Co-authored-by: zhanghaoyu.la <zhanghaoyu.la@bytedance.com> Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
aa53e7aede |
feat: 实现 commit、restore、show 文件系统多版本管理功能 (#2756)
* feat: 实现 commit、restore、show 文件系统多版本管理功能 fix: 修复commit时删除文件 fix: commit 的 fast path 1 添加 Racy-clean 机制 fix: 将 sdk 中的 git 命令改为 snapshot 命令,同步修改单测 fix: 多版本管理的文件存储目录改为 .ovgit feat: snapshot cli 渲染 fix: 修复 restore 时将删除的文件回滚时,目录不存在的问题 feat: restore 命令的 project_dir 参数改为可选,不传时默认全目录回滚 feat: 更新文档 fix: 删除暂未使用的配置参数 feat: 新增示例脚本 fix: 修复示例代码 fix: 修复 restore 返回的 task id 任务完成状态 feat: 在 restore 修改文件系统时加锁 fix: fix openviking_sdk * feat: 将git多版本管理功能改为默认打开,并复用agfs的配置参数作为默认值 * fix: restore 命令改为先完成 ref 一致性协议再写回 VFS;object store 并发改为使用唯一 temp path * fix: 在 git 配置检验层去除未实现的cas_mode = "redis_lock"模式 * fix: 在 Rust GitService 边界统一校验 account * fix: 当前commit不支持通过 path 传入目录,增加报错信息 * fix: 将git文件默认存储路径统一为 .ovgit * fix: restore 时写入 VFS 失败时返回详细的报错,并继续触发 reindex * fix: 校验 commit、restore、show 的路径 * feat: 实现 commit 时指定目录 --------- Co-authored-by: zhanghaoyu.la <zhanghaoyu.la@bytedance.com> |
||
|
|
a6fc0424bc |
fix(session): apply memory type policy whitelist (#2530)
* fix(session): apply memory type policy whitelist Restore top-level memory_types filtering for session memory extraction and validate it against enabled registry schemas. Ensure initialization and peer-aware smoke coverage honor the whitelist. * fix(session): scope session skills to execution memory policy * refactor(session): remove per-commit memory policy |
||
|
|
74102b78f0 | fix(openclaw): use user namespace for experience recall (#2537) | ||
|
|
8a3bfb68ff |
chore(oauth): remove dead push-OTP, repurpose footer to cross-device verify (#2538)
The push-OTP feature (mint an OTP in Studio to hand to an MCP client) was never wired to a consumer: consume_otp had zero production callers and no endpoint or grant ever redeemed an OTP. The 'full happy path' test actually exercised the display_code flow, not OTP. So the sidebar footer's 'OAuth setup' entry minted a code with nowhere to use it — dead, confusing UX. Remove it end-to-end and repurpose the footer slot into an entry for the cross-device verify page (enter the 6-char display_code), which previously had no discoverable entry point in Studio. Frontend: - delete oauth-setup-dialog.tsx + /oauth/setup route (+ routeTree, i18n) - extract CrossDeviceVerifyForm from verify.tsx; add CrossDeviceVerifyDialog - footer 'OAuth verify' entry opens the verify dialog (desktop) / page (mobile) Backend: - drop issue_otp route + OTPRequest/OTPResponse, storage insert_otp/consume_otp, oauth_config.otp_ttl_seconds, and the OTP-specific tests - keep otp.py generate_otp (cross-device display_code) + hash_secret, the shared _atomic_consume_code, and the oauth_codes.kind column - convert the race/expiry/revoke/GC storage tests to auth-code rows Docs: update 11-oauth, 06-mcp-integration, and the design doc to reflect removal. |
||
|
|
790daaf885 | feat(openclaw): inject agent experience memories (#2281) | ||
|
|
c7f82cceaa | docs: fix dead external links (#2458) | ||
|
|
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 |
||
|
|
7b52d8fcd0 |
feat: add typed tool result stubs (#2248)
Co-authored-by: Eurekaxun <eurekaxun@163.com> |
||
|
|
96df42f2a9 | refactor(memory): remove legacy memory v1 (#2264) | ||
|
|
1d631cd38d | Rename search tool to ov_search to avoid conflict with existing OpenClaw tool name (#2235) | ||
|
|
9a37e75395 | feat(mcp): add code_outline / code_search / code_expand tools (#2146) | ||
|
|
da59289591 |
feat(oauth): move authorize UI into web-studio (#2160 follow-up) (#2170)
#2160 dropped the legacy `/console` standalone service but deliberately left the OAuth authorize page's `/console` link and Quick-authorize panel in place, calling out a follow-up to re-point them at web-studio. This PR is that follow-up. Backend - `provider.authorize()` now defaults to redirecting to `/studio/oauth/consent` (same-origin SPA) instead of the server-rendered `/oauth/authorize/page`. New `FALLBACK_AUTHORIZE_PAGE` constant exposed for callers that need to opt into the legacy path. - New public endpoint `GET /api/v1/auth/oauth/pending/{pending_id}` returns the minimum info the consent UI needs (client_name, redirect_host, scopes); deliberately does NOT expose display_code or full redirect_uri. - `POST /api/v1/auth/oauth-verify` now accepts either `pending_id` (Studio consent path) or `code` (cross-device fallback). - HTML `/oauth/authorize/page` template stripped of `/console` link, the `/console/api/v1/...` JS, and the Quick-authorize same-origin panel. It now serves as a pure cross-device fallback that points users at `/studio/oauth/verify` on another already-signed-in device. Web Studio - New `<IdentityPicker>` shared component: "current identity" or "use a different API key" — the temporary key is never persisted. - New routes `/studio/oauth/consent` (same-device consent card) and `/studio/oauth/verify` (cross-device code entry). - ConnectionDialog gains an "OAuth client OTP" section (same IdentityPicker), driving `POST /api/v1/auth/otp`. - API key storage is unchanged: only sessionStorage. No new localStorage writes, no cross-tab channels — the consent UI runs inside Studio's own tab, so it reads the session-stored key directly. Docs - 11-oauth.md (zh/en): refreshed quickstart, How-it-works, Claude.ai walkthrough, curl example, and troubleshooting around the Studio consent / cross-device verify split. - 12-public-access.md (zh/en): rewritten to lead with public HTTPS; the `:1934` Caddy block is now a one-paragraph compatibility note for deployments that already bookmarked it. - mcp-oauth2-1.md: top-level "Studio migration" note explains the new default path; Phase 1 history retained. - Caddyfile / docker-compose.yml comments reworded from "aggregated proxy" to "legacy fallback" to match the new docs. Tests - `tests/server/oauth/test_router.py` fixture pins to FALLBACK_AUTHORIZE_PAGE so existing end-to-end assertions keep working. - 4 new tests cover the pending-info endpoint and pending_id verify path. - 55 passed locally; ruff format+check, web-studio tsc/eslint/prettier all clean. Security notes - Consent UI requires explicit user click; client_name + redirect_host shown for phishing identification. - Knowing a pending_id does not bypass Bearer auth. - display_code is not returned by GET pending — the cross-device brute-force protection is preserved. - `ctx.from_oauth` gate (router.py) untouched: OAuth bearer still cannot mint new OAuth state or OTPs. |
||
|
|
185bce8934 |
docs(design): consolidate openclaw plugin docs into single design doc (#2043)
Replace openclaw-integration.md and openclaw-context-engine-refactor.md with openclaw-plugin-design.md covering the three main chains (assemble, afterTurn, compact), session mapping, tool registry, and config reference. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> |
||
|
|
7d5fa62398 |
feat(oauth): native OAuth 2.1 authorization for MCP clients (#1870)
* feat(oauth): hand-sewn OAuth 2.1 M1+M2 (config, JWT, storage, /oauth/token, JWT discriminator)
Snapshot before evaluating migration to mcp.server.auth SDK provider. The
hand-rolled HS256 JWT implementation in openviking/server/oauth/jwt.py is
the main candidate for replacement: its surface area is small but it would
require careful crypto review by maintainers, while the official MCP SDK
already ships an OAuth provider wired into FastMCP.
Included so far:
- OAuthConfig + integration into OpenVikingConfig (default disabled)
- openviking/server/oauth/{jwt,storage,otp,router}.py
- POST /oauth/token (authorization_code + refresh_token, PKCE S256, RFC 6749 errors)
- JWT discriminator in resolve_identity (fail-closed; ResolvedIdentity.from_oauth)
- WWW-Authenticate Bearer hint on /mcp 401 (RFC 9728)
- 49 OAuth-specific unit/integration tests (all passing)
Not yet implemented (M3 / MVP gap):
- /oauth/register (DCR), /oauth/authorize (HTML + OTP submit), well-known metadata
- POST /api/v1/auth/otp REST endpoint
* refactor(oauth): switch to mcp.server.auth SDK provider, drop hand-sewn JWT
Replaces the hand-rolled HS256 JWT signer / token endpoint / DCR with
the OAuth 2.1 surface shipped in mcp.server.auth. We supply a Provider
that adapts the existing OAuthStore (SQLite) to the SDK Protocol, plus
two custom routes the SDK doesn't own: an OTP-entry HTML page (the URL
provider.authorize() returns) and POST /api/v1/auth/otp for issuing
OTPs against an existing API key.
Net result: all OAuth crypto is now the SDK's responsibility (PKCE
S256, redirect_uri matching, error formatting). The OpenViking-side code
contains zero cryptography — access tokens are opaque random strings
prefixed with `ovat_` and looked up in SQLite by SHA-256 hash. Refresh
tokens, auth codes, OTPs use the same scheme.
Highlights:
- openviking/server/oauth/provider.py: OpenVikingOAuthProvider implements
the 8-method SDK Protocol, including subclassing AuthorizationCode /
RefreshToken / AccessToken to pin (account_id, user_id, role) per
token. Refresh-token replay triggers per-user chain revocation.
- openviking/server/oauth/storage.py: adds oauth_access_tokens and
oauth_pending_authorizations tables; peek_auth_code / peek_refresh
for non-destructive lookups; revoke_user_tokens cascades all OAuth
state for an (account, user) pair when a key is rotated.
- openviking/server/oauth/router.py: minimal authorize page (inline
HTML with frame-ancestors 'none') + OTP endpoint authenticated via
existing get_request_context dependency.
- openviking/server/auth.py: replaces JWT discriminator with prefix
match + provider.load_access_token; still fail-closed.
- openviking/server/app.py: mounts SDK routes via create_auth_routes
alongside our authorize-page + OTP routes.
- Deletes openviking/server/oauth/jwt.py and tests/server/oauth/test_jwt.py.
Tests: 32 passing, including a full DCR -> OTP -> authorize page ->
token-exchange -> /mcp lookup happy path, refresh rotation, and replay
detection. Existing test_auth.py regression unchanged.
Phase 1 still missing for full Claude.ai connectivity:
- WWW-Authenticate hint already present on /mcp 401 (from M2)
- /.well-known/oauth-protected-resource (RFC 9728) — not currently
emitted by the SDK; small custom route still TODO.
* docs(oauth): rewrite design doc to reflect mcp.server.auth SDK approach
The earlier draft described a hand-sewn HS256 JWT plan; the implementation
took a different route after discovering mcp.server.auth ships a complete
RFC 6749 / 7591 / 8414 server. Updated to reflect:
- SDK owns the protocol surface (DCR, /authorize parsing, /token, metadata,
PKCE, redirect_uri matching, error codes).
- OpenViking only contributes a Provider implementation, the OTP-entry
HTML page, and POST /api/v1/auth/otp.
- Tokens are opaque (ovat_ / ovrt_ / ovac_ prefixes) — no JWT, no crypto
on our side.
- Implementation status: M1/M2/M3 done; only RFC 9728 protected-resource
metadata + reverse-proxy issuer derivation remain for full Claude.ai
end-to-end connectivity.
* feat(oauth): add /.well-known/oauth-protected-resource (RFC 9728)
The /mcp 401 path already advertises this URL via WWW-Authenticate
Bearer resource_metadata="...", but the endpoint itself didn't exist —
clients fetched it and got a 404, which silently broke the discovery
chain even though /.well-known/oauth-authorization-server worked. Wire
up the resource metadata document so the full RFC 9728 → RFC 8414
discovery chain works end-to-end.
Uses mcp.shared.auth.ProtectedResourceMetadata pydantic model. Reads
X-Forwarded-Proto/Host so the published resource URL matches what the
client used (matches our existing WWW-Authenticate behavior).
Cache-Control: max-age=3600 — metadata is stable across requests.
* feat(console): add OTP issuance button in Settings panel
Adds a "Get OTP" button under the Settings panel of the 8020 web
console. Clicking it issues an OAuth OTP via the user's existing API
key (already loaded into sessionStorage) and displays it inline with
a copy-to-clipboard button.
Replaces the previous workflow of users having to:
curl -X POST -H "X-Api-Key: $KEY" http://1933/api/v1/auth/otp
…with a single button-click flow that the user can reach from any
machine with a browser.
Wires:
- console/app.py: new POST /console/api/v1/ov/auth/otp proxy route,
forwarding to upstream /api/v1/auth/otp. Not gated by write_enabled
since OTP issuance is an authentication artifact, not data mutation.
- index.html: new OAuth section in the Settings panel with otpBox
(hidden until OTP is generated) and a Copy button.
- app.js: getOtpBtn click handler calls callConsole, otpCopyBtn copies
to clipboard. Clear failure messages when the user has no API key
loaded yet.
This is the lightweight half of the Console-OAuth integration. The
fuller "same-origin auto-authorize" flow (Phase 2) — where the
authorize page detects sessionStorage and submits the OTP form
automatically — is still TBD and will reuse this proxy route.
* feat(oauth): device-flow style authorize page + console verify form
Pivots the OTP flow direction so the UX matches OAuth 2.0 Device
Authorization Grant (RFC 8628) more closely:
Old (push): user goes to console -> Get OTP -> copy -> paste in
client's authorize page -> submit -> redirect.
New (pull): client's authorize page DISPLAYS a 6-char code -> user
types it into the console verify form -> page polls -> redirect.
This removes one tab switch and aligns with how users mentally model
authorization ("I'm approving the request shown over there from
where I'm already signed in"). The legacy POST /api/v1/auth/otp +
"Get OTP" button are kept under a collapsed details element for any
scripted/CLI flows that still drive the older pattern.
Also wires OPENVIKING_PUBLIC_BASE_URL env var as the highest-priority
public origin override, used consistently by:
- /.well-known/oauth-protected-resource
- WWW-Authenticate header
- authorize page links
- SDK issuer at app start.
Server changes:
- storage.py: oauth_pending_authorizations gains display_code,
verified, verified_account_id/user_id/role columns; new
find_pending_by_display_code + mark_pending_verified.
- provider.authorize() now generates display_code at pending creation
and returns the page URL.
- router.py:
* GET /oauth/authorize/page — renders the code + same-origin quick-
authorize panel (sessionStorage detection, but click still required
so authorization is never silent).
* GET /oauth/authorize/page/status — polled by the page until verified;
response carries the redirect_url with auth_code on approval.
* POST /api/v1/auth/oauth-verify — authenticated; binds caller
identity to a pending row (decision=approve|deny).
Console changes:
- Settings panel: new "Authorize an MCP client" section with code input
and Authorize/Deny buttons. Legacy "Get OTP" still available under
details.
- console proxy gains POST /console/api/v1/ov/auth/oauth-verify.
Tests: 38 OAuth tests passing, including a full device-flow happy path,
deny path, idempotency (one-shot pending), unknown-code rejection,
status-410 on consumed/expired, refresh rotation, OPENVIKING_PUBLIC_BASE_URL
override, and X-Forwarded-* fallback.
* docs(oauth): add 11-oauth guide + Caddy/nginx templates + .env-driven compose
Adds a top-level OAuth 2.1 guide (zh/en) covering the production path
end-to-end. Opens with a 5-step recommended setup so readers don't have
to wade through the rationale before they can deploy. Drops the "MCP"
qualifier from the doc name — OAuth 2.1 here is generic and serves any
OAuth client, not just MCP.
- docs/{en,zh}/guides/11-oauth.md: new. Recommended setup at the top,
then background, full device flow, HTTP-local vs HTTPS-production
deployment, Caddy + nginx templates, docker-compose with the shipped
Caddy service, curl walkthrough, config reference, troubleshooting.
- docker-compose.yml: replace the prior PR's commented-out hint with a
single OPENVIKING_PUBLIC_BASE_URL var (read by both the openviking
service and an optional Caddy reverse-proxy service that's also
shipped commented-out). Same env var drives Caddy via
{$OPENVIKING_PUBLIC_BASE_URL}, so the public domain is configured
once in .env.
- docs/{en,zh}/guides/06-mcp-integration.md: replace the "OAuth Proxy
(planned, use community Cloudflare Worker)" section with a short
pointer to the new 11-oauth guide. The community proxy is still
mentioned as an alternative.
Same env-variable design also matches what the MCP add_resource tool
expects (it already reads OPENVIKING_PUBLIC_BASE_URL), so deployments
get a single source of truth for the public address.
* fix(oauth): read API key from localStorage on authorize page
The same-origin "Quick authorize" panel was reading sessionStorage,
which is per-tab. Since the OAuth authorize page opens in a different
tab from the console, the panel never showed up even when the user was
signed in.
The console persists the API key in localStorage as well (key
"ov_console_api_key" — see static/console_settings.js's
LEGACY_API_KEY_STORAGE_KEY) for cross-tab use, and that copy is what
the authorize page should consult.
Switch the page JS to localStorage first, fall back to sessionStorage
for resilience. No console-side change needed; the localStorage entry
has been written by the console all along.
* docs: add public access guide + default port 1934 aggregated proxy
- Add Caddyfile with :1934 HTTP aggregated proxy (merges 1933+8020)
- Enable Caddy service by default in docker-compose.yml on port 1934
- Add docs/{en,zh}/guides/12-public-access.md with full HTTPS setup guide
- Simplify 11-oauth.md: replace inline reverse proxy config with refs to 12
- Add HTTPS requirement callout to OAuth recommended setup
- Update 03-deployment.md to mention port 1934 as recommended entry point
* fix(oauth): address Copilot review + ruff format
- Update oauth_config.py docstrings to describe opaque tokens, not JWT
(we switched away from JWT during implementation)
- Remove unused authorize_rate_limit_per_min config field — was never
enforced anywhere in router/storage, dead config misled operators
- Wrap all OAuthStore read paths in self._lock (matching writes); the
shared sqlite3.Connection with check_same_thread=False is not safe
for concurrent cursor use across threads
- Clarify provider.exchange_refresh_token comment that replay revokes
the entire (account, user) family, not just the (client, account,
user) chain — broader blast radius is intentional
- ruff format: 8 files reformatted to satisfy CI lint
* perf(docker): add cargo + ccache cache mounts to py-builder stage
The two heavy RUN steps in py-builder (uv sync + maturin build) re-execute
on every Python source change because the upstream COPY layer for openviking/
invalidates the cache. Each rerun was ~510s + ~115s ≈ 10 min of wasted work
even though Rust/C++ source was unchanged.
Add BuildKit cache mounts so cargo and the C++ engine compilation can skip
work whose inputs are unchanged:
- Mount /cargo-target, cargo registry, and cargo git so cargo's incremental
build artifacts persist across layer reruns. Pin CARGO_TARGET_DIR so the
path stays stable when uv builds wheels in ephemeral isolated tempdirs.
- Install ccache and prepend /usr/lib/ccache to PATH so cmake (which calls
shutil.which("gcc")) resolves the ccache wrapper. ccache is path-agnostic,
so it benefits the cmake_build subdir even though setup.py recreates it
in a fresh tempdir each wheel build.
- Mount /root/.ccache so the ccache hash store persists across reruns.
Expected: hot rebuilds on Python-only changes drop step 15 from ~510s to
~60-120s (uv wheel packaging overhead remains; cargo + g++ skip on cache hit).
* perf(docker): drop redundant second maturin build step
The second RUN step in py-builder built ragfs-python a second time and
extracted its .so into the installed openviking package. This was
redundant: setup.py's build_ragfs_python_artifact() already runs maturin
during step 15 (uv sync --no-editable), and because build_meta passes
'bdist_wheel' through PEP 517, _should_require_ragfs_artifact() returns
True and the build fails closed if maturin can't produce ragfs_python.so.
The .so is then bundled into the wheel via package_data and installed
into /app/.venv on wheel install. The second step's only effect was to
overwrite the same file, costing ~115s per build.
Verified after the fact by inspecting the installed venv and importing
ragfs_python in the runtime container.
* feat(oauth): bind OAuth token lifetime to authorizing API key
Previously OAuth tokens lived independently of the API key that authorized
them. Rotating a user's key did not invalidate already-issued OAuth access /
refresh tokens, so a compromised key remained dangerous even after rotation.
Tie every OAuth token to the SHA-256 fingerprint of the API key whose holder
authorized it:
- APIKeyManager grows get_user_key_fingerprint(account_id, user_id) ->
sha256(stored_key_value). The stored value is whatever sits in
user_info["key"] (plaintext key or argon2id hash), written once on
create / regenerate and never mutated in place, so the fp is stable per
key-generation and changes the moment regenerate_key runs.
- OAuth storage gains an authorizing_key_fp column on oauth_codes,
oauth_pending_authorizations (verified_key_fp), oauth_refresh_tokens, and
oauth_access_tokens. ALTER TABLE migration guarded by PRAGMA table_info
for dev DBs that predate the field.
- Provider data classes thread the fp through authorize ->
exchange_authorization_code -> _issue_token_pair, and refresh rotation
preserves it from the consumed token's record.
- Router endpoints capture the caller's current fp at the only two
identity-binding moments: /api/v1/auth/otp (caller) and
/api/v1/auth/oauth-verify (verifier). If the manager returns None
(ROOT key, trusted-mode identity, or removed user), refuse to issue
OAuth state -- there is no key whose lifecycle we could honor.
- auth.py:_try_resolve_oauth_token recomputes the user's current fp on
every OAuth bearer auth and demands strict equality via
hmac.compare_digest. NULL / empty / mismatch all fail closed with a
401 telling the client to re-authorize.
Crypto notes: sha256 over a 256-bit-random API key (or its argon2id hash)
is preimage-safe, so an oauth.db leak does not reveal the API key. No new
secret material introduced; the fp is derived deterministically from data
that already exists.
Tests: 3 new lifecycle tests in test_auth_integration (rotation rejected,
user-removed rejected, missing-fp fail-closed), 3 new router tests
(no-fp caller / verifier rejected, fp recorded on access + refresh), 2 new
APIKeyManager tests (fp changes on rotate / vanishes on remove).
Pre-existing inserts in test_storage updated to pass _FP. 82/82 OAuth +
APIKeyManager tests pass.
* docs(oauth): document OAuth lifetime ≤ authorizing key lifetime
The fingerprint binding landed in the previous commit; users need to know
that key rotation now auto-invalidates derived OAuth tokens (no separate
revoke step) and that ROOT / trusted-mode identities cannot issue OAuth.
Updates both en and zh under docs/guides/11-oauth.md, replacing the
"operator should also revoke ..." paragraph with the new automatic
behavior + brief note on the SHA-256 fingerprint scheme.
* fix(oauth): close 4 review findings on token lifecycle
External security review of #1870 surfaced four real gaps in the OAuth
implementation. All four directly affect the lifecycle / privilege model.
P1: role downgrade did not invalidate OAuth tokens
set_role rewrites user_info["role"] without touching user_info["key"],
so the SHA-256 fingerprint binding stays valid and an ADMIN demoted to
USER continues to resolve as ADMIN. Refresh tokens keep minting fresh
ADMIN access tokens. Fixed in two places:
- auth.py:_try_resolve_oauth_token re-fetches Role.get_user_role and
rejects when the embedded role outranks the current role.
- provider.exchange_refresh_token gets a role_resolver callback (wired
in app.py to api_key_manager.get_user_role) and applies the same
gate before consuming a refresh.
Promotion remains harmless — the embedded lower privilege is still
authorized, only downgrades trigger rejection.
P1: confidential client secrets were never enforced
provider.get_client returned client_secret=None regardless of the
stored hash; the MCP SDK's ClientAuthenticator skips secret validation
when the returned client has a falsy secret, silently allowing
client_secret_basic / client_secret_post clients to authenticate with
only client_id. Real MCP clients all use "none" + PKCE per RFC 8252
§8.4 anyway, so register_client now rejects non-"none" auth methods at
DCR. Native/desktop apps can't keep secrets — PKCE is the actual
proof-of-possession.
P1: OAuth tokens could mint new OAuth grants
/api/v1/auth/otp and /api/v1/auth/oauth-verify accepted any caller
resolved through get_request_context, including identities resolved
from OAuth bearers. A stolen 1h access token could call oauth_verify
with its own pending row and walk away with a 30d refresh-token
chain — privilege time-extension. RequestContext now carries
from_oauth (mirroring ResolvedIdentity.from_oauth) and both endpoints
reject from_oauth=True with 403, forcing primary auth.
P2: GC erased refresh-token replay tombstones
gc_expired deleted "WHERE expires_at < ? OR consumed = 1" every
minute. After GC, is_refresh_known_but_consumed could not distinguish
a replay from an unknown token and exchange_refresh_token never fired
revoke_chain — defeating RFC 9700 §4.14 family revocation for late
replays. GC now keeps consumed refresh rows until their natural
expires_at; storage cost bounded by the 30d max refresh TTL.
Also adds from_oauth field to RequestContext and propagates from
ResolvedIdentity in get_request_context.
Tests: 7 new (role downgrade rejection in bearer auth + refresh path,
role promotion is harmless, confidential DCR rejected, from_oauth
rejected at OTP and oauth-verify, refresh tombstone preserved across
GC). Pre-existing test_oauth_root_can_be_used and
test_dcr_registers_client updated to match the stricter contract.
89/89 OAuth + APIKeyManager tests pass.
* fix(oauth): downgrade confidential DCR to public instead of rejecting
The previous P1.2 fix rejected DCR when token_endpoint_auth_method was
not "none", reasoning that we never enforce client_secret server-side
so accepting confidential auth methods would be a silent security
downgrade. That is the right invariant — but the rejection broke real
clients: the OAuth 2.0 default for token_endpoint_auth_method is
"client_secret_basic", and at least Claude Desktop relies on the SDK to
fill in defaults rather than explicitly setting "none". DCR for those
clients started returning 400 even though they would work fine with PKCE
(which they all use anyway).
Soft-failure design instead: accept any registered auth method, but
overwrite the stored value to "none" and log a warning. The end-state
is identical to the rejection path — every client is treated as
public+PKCE, no secret is ever stored or enforced — but Claude Desktop's
DCR no longer blows up.
Updates the test from asserting 400 to asserting that a confidential
registration is silently downgraded: stored auth_method == "none",
client_secret_hash is None.
* delete(docs): remove error file
* docs(zh): sync 03-deployment.md with English version
|
||
|
|
44d3cc41b1 | Feat/memory isolation 支持群聊模式 (#1711) | ||
|
|
64682ae189 |
feat(encryption): make apikey hash encryption as single switch (#1736)
* feat(encryption): make apikey hash encryption as single switch * feat(encryption): add break change note |
||
|
|
17d2c5603e |
feat(observability): unify observability context && support otel && etc. (#1666)
* feat(observability): unify OTLP metrics export, log/trace context, and telemetry bridging - - Add OTLP metrics http/grpc exporter that pushes MetricRegistry snapshots - - Decouple telemetry response payload from telemetry collection; always finish() and bridge summary to metrics - - Unify observability config under server.observability (metrics/traces/logs siblings); update ov.conf.example and docs (zh/en) - - Improve log/trace correlation via structured context injection - - Add/adjust tests for exporter lifecycle, config loader, metrics/telemetry runtime - BREAKING CHANGE: remove legacy telemetry.* config path; use server.observability.* * feat(observability): import Status/StatusCode for LogToSpanEventFilter * feat(observability): fix check issue * feat(observability): format code --------- Co-authored-by: MaojiaSheng <shengmaojia@bytedance.com> |
||
|
|
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> |
||
|
|
c5bfdf8bb4 | docs(design): sync §4.6 role_id rules with #1643 (passthrough + no server-side format check) (#1657) | ||
|
|
cebc45907b |
feat(session): add account namespace policy and shared sessions (#1356)
* feat(session): add account namespace policy and shared sessions
Unify namespace resolution across filesystem, indexing, and session storage.
Add account-shared session paths, role_id auth semantics, and an HTTP demo
script for the four namespace-policy combinations.
* space
* fix(pack): skip derived semantic files in ovpack transfer
Keep ovpack imports resilient to stale sidecars and rebuild semantics through the normal queue instead of restoring derived files verbatim.
* Revert "fix(pack): skip derived semantic files in ovpack transfer"
This reverts commit
|
||
|
|
629fc241e4 |
feat(metric): add token-full-cycle metric (#1488)
* feat(metric): add token full-cycle metric && support token dashboard && optimize metric guide && deprecated 'server.telemetry.prometheus.enabled' configuration && change metric config to observability.metric * feat(metric): add token full-cycle metric && support token dashboard && optimize metric guide && deprecated 'server.telemetry.prometheus.enabled' configuration && change metric config to observability.metric * feat(metric): add debug log * feat(metric): format code * feat(metric): format code |
||
|
|
3b0ac8a0d4 |
feat: add local llama-cpp embedding support (#1388)
* feat: local llama.cpp embedding support, setup wizard, lazy storage imports, and config singleton deadlock fix Made-with: Cursor Co-authored-by: GPT-5.4 <noreply@openai.com> * fix: remove unsupported custom local gguf setup --------- Co-authored-by: GPT-5.4 <noreply@openai.com> |
||
|
|
95cc0f84d0 | reorg: split parser layer to 2-layer: accessor and parser, so that we can reuse more code (#1428) | ||
|
|
b441622ee6 |
feat(metric): add metric system (#1357)
* feat(metric): add metric system * feat(metric): add metric system * feat(metric): add metric system * fix(metric): do not cancel refresh tasks on deadline; trust only authenticated account id; avoid per-scrape rerank clients * doc(metric): add metric guide doc * doc(metric): add metric guide doc * doc(metric): add metric guide doc * doc(metric): add metric guide doc * feat(metric): fix bug & change account dimension switch to default true |
||
|
|
f81419c11c |
feat(memory): support agent-only agent memory scope (#954)
Co-authored-by: Qin Haojie <qinhaojie.exe@bytedance.com> |
||
|
|
2771765298 |
Refactor memory extract (#916)
* docs: add memory extractor templating and update mechanism optimization design document - Add bilingual (English/Chinese) design document for memory templating system - Include YAML-based MemoryTypeRegistry with 8 built-in types - Detail ReAct 3+1 phase flow with pre-fetch optimization - Describe 3-operation Schema: write/edit/delete - Document RoocodePatch SEARCH/REPLACE format - Explain dual-mode design: simple mode vs template mode - Cover pre-fetch optimization: ls directories + read .abstract.md/.overview.md + search once - Include merge operations: patch, sum, avg, immutable - Address #578: allow custom prompt template addition and specification Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add memory templating system with ReAct orchestrator - Add YAML-configurable memory schemas (cards, events, entities, etc.) - Implement MemoryReAct with tool use (read/find/ls) - Add schema-driven memory operations (write_uris/edit_uris/delete_uris) - Implement memory patch handler for incremental updates - Add comprehensive test suite * refactor: memory extractor templating system with ReAct orchestrator ## Summary Implement memory templating system (GitHub Issue #578) - a complete rewrite of the memory extractor subsystem to support YAML-configurable memory types instead of hardcoded categories. ## Key Changes ### Architecture - Replace hardcoded 8 memory types with YAML-configurable schema system - Add MemoryTypeRegistry to load memory type definitions from YAML files - Dynamic Pydantic model generation from schema for type safety - Field-level merge operations: PATCH, SUM, IMMUTABLE ### Memory Extraction Flow - Implement ReAct orchestrator for single-pass memory updates - MemoryUpdater for applying operations to storage - Memory tools (read, search, ls) for ReAct loop - Stable JSON parser with 5-layer fault tolerance ### File Naming & Storage - Semantic filenames from template ({topic}.md instead of random IDs) - Two memory modes: simple mode and template mode - MEMORY_FIELDS HTML comment for structured metadata ### Configuration - 9 YAML templates in openviking/prompts/templates/memory/ - memory_config.py for memory system configuration - Dual-threshold compact upload mechanism in design doc ### Deletions - Remove old memory_content.py, memory_data.py, memory_operations.py - Remove memory_types.py, memory_utils.py, memory_patch.py - Remove corresponding old test files ### Updated Components - VLM backends (litellm, openai, volcengine) for new interfaces - Session and service core integration - Test suite for new architecture Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: pass ctx/user/session_id in commit_async for memory extraction ## Summary Fix missing parameters in commit_async() when calling extract_long_term_memories(). The synchronous commit() method correctly passes these parameters, but the async version was missing them, causing memory extraction to be skipped. ## Changes - Pass user=self.user, session_id=self.session_id, ctx=self.ctx in commit_async() when calling extract_long_term_memories() Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: convert FindResult to dict before returning from search tool ## Summary Fix JSON serialization error by converting FindResult object to dict using its to_dict() method before returning from MemorySearchTool. ## Changes - In MemorySearchTool.execute(), return search_result.to_dict() instead of search_result directly Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: swap None check before accessing final_operations in memory_react Also rename schema_models.py to schema_model_generator.py for clarity. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add edit_overview support and optimize memory registry initialization - Add edit_overview_operations to MemoryUpdater for updating .overview.md files - Optimize MemoryTypeRegistry initialization in SessionCompressorV2 (load once) - Various memory templating system improvements Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: remove unnecessary indent in JSON schema output Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add markdown link format hint to overview field description Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add pre-fetch search based on user messages in conversation Also fix duplicate line in system prompt. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * rebase --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
3b5b9a42c0 |
feat(openclaw-plugin):context engine refactor design & enforce token budget and reduce context bloat (#891)
* fix(openclaw-plugin): enforce token budget and reduce context bloat (#730) (#796) * test(openclaw-plugin): add vitest test infrastructure for #730 * fix(openclaw-plugin): raise recallScoreThreshold default from 0.01 to 0.15 (#730) * fix(openclaw-plugin): narrow isLeafLikeMemory boost to level-2 only (#730) * fix(openclaw-plugin): prefer abstract over full content fetch in memory injection (#730) * feat(openclaw-plugin): add recallMaxContentChars and recallPreferAbstract config (#730) * feat(openclaw-plugin): enforce tokenBudget in injection with decrement loop (#730) * fix(openclaw-plugin): update recallScoreThreshold placeholder to match new default (#730) * fix(openclaw-plugin): deduplicate content resolution and document budget behavior (#730) Extract resolveMemoryContent() helper to eliminate duplicate content-resolution logic between buildMemoryLines and buildMemoryLinesWithBudget. Add JSDoc and inline comment documenting intentional first-line budget overshoot (spec §6.2). Tighten test assertion from <=120 to <=106 tokens. * fix(openclaw-plugin): use truthy fallback for empty abstract strings (#730) Change nullish coalescing (??) to truthy fallback (||) in resolveMemoryContent() so empty-string abstracts fall back to item.uri instead of producing empty content lines. * docs: add openclaw context engine refactor design Co-authored-by: Mijamind <mijamind@163.com> Co-authored-by: GPT-5.4 <noreply@openai.com> * add afterTurn refactor in design_doc * add afterTurn compact in design_doc --------- Co-authored-by: chethanuk <chethanuk@outlook.com> Co-authored-by: GPT-5.4 <noreply@openai.com> Co-authored-by: wlff123 <wulf234@163.com> Co-authored-by: xuwengui <huangxun375@gmail.com> |
||
|
|
f467de4ed9 |
feat: add memory extract telemetry breakdown (#735)
feat: add resource telemetry breakdown telemetry: omit zero-valued summary fields feat(resources): add temp upload telemetry support docs: move telemetry guide out of design docs: sync contributor build requirements |
||
|
|
1823a7c4f7 |
feat(storage): add path locking and selective crash recovery for write operations (#431)
* feat(storage): add transaction support with journal, undo, and crash recovery Implement a full transaction system for VikingFS storage operations including write-ahead journal, path locking, undo/rollback, context manager API, and crash recovery. Includes comprehensive tests and documentation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test(transaction): add e2e rollback tests for mv and multi-step operations Add end-to-end tests covering rollback scenarios that were missing: - mv rollback: file moved back to original location on failure - mv commit: file persists at new location - Multi-step rollback: mkdir + write + mkdir all reversed in order - Partial step rollback: only completed entries are reversed - Nested directory rollback: child removed before parent - Best-effort rollback: single step failure does not block others Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(storage): add transaction support with path locking and journal Implement transaction system for VikingFS with ACID-like guarantees: - TransactionManager with configurable lock timeout and journal-based recovery - PathLock supporting point, subtree, and mv lock modes - Refactor VikingFS mv to use cp+rm to prevent lock files from being carried - Fix stale lock detection returning false for missing lock files - Update ragas eval to use LangchainLLMWrapper Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: tests * fix(transaction): fix rollback and race condition bugs - Reconstruct RequestContext from undo params for vectordb_delete/update_uri rollback (previously skipped silently due to missing ctx) - Serialize ctx fields into undo params in rm/mv operations - Fix Phase 1 undo path to target archive dir instead of session root - Remove Phase 2 fs_write_new undo (overwrites are idempotent, checkpoint handles recovery) - Add ancestor SUBTREE recheck after lock creation in acquire_subtree - Move _collect_uris inside TransactionContext in rm/mv to close race window - Log journal persistence failures instead of silently swallowing Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor(transaction): make TransactionManager required and rewrite tests with real backends Remove all optional/fallback code paths where tx_manager could be None. get_transaction_manager() now raises RuntimeError if not initialized. Fix undo rollback to reconstruct ctx for vectordb_upsert and use correct agent_id default. Replace mock-based transaction tests with integration tests using real AGFS and VectorDB backends. * refactor(transaction): make rollback fully async and unify session commit path - Convert execute_rollback/rollback_entry to async, removing sync run_async wrappers - Unify Session.commit() to delegate to commit_async(), removing duplicate phase methods - Fix SUBTREE lock to conflict with ancestor SUBTREE locks (was previously missing) - Fix mv lock mode: directory moves now use SUBTREE on both source and destination - Replace deprecated asyncio.get_event_loop() with get_running_loop() - Remove max_parallel_locks config option - Update docs (en/zh) and tests to match new async rollback signatures * fix: tests * refactor(transaction): simplify session commit and add redo-based crash recovery Session commit no longer wraps archive phase in a transaction. Phase 2 uses redo semantics so crashed memory-extraction can be replayed from archive. PathLock stale-lock cleanup no longer redundantly re-checks timeout. Semantic processor vectorization runs concurrently via asyncio.gather. * fix: transaction * fix: UserIdentifier * refactor(transaction): replace undo-based transaction manager with lightweight lock + redo-log Remove the heavyweight TransactionManager/Journal/UndoEntry system (~4000 lines) and replace it with a simpler architecture: LockManager for path locking, LockContext as the async context manager, LockHandle/LockOwner protocol, and a RedoLog for crash recovery of session_memory operations. VikingFS rm/mv now use inline error handling instead of rollback semantics. Updated docs, observers, and tests accordingly. Co-Authored-By: Claude Opus 4.6 * fix(transaction): remove checkpoint dead code, fix TOCTOU race, clarify mv lock param - Remove unused _write_checkpoint/_write_checkpoint_async/_read_checkpoint from Session (superseded by redo-log) - Re-resolve URI inside lock in resource_processor Phase 3.5 to prevent concurrent add_resource calls from resolving to the same final_uri - Rename acquire_mv dst_path to dst_parent_path with docstring to clarify that callers pass the destination parent directory * fix: path * fix: resource lock * fix: test * docs: update * fix: tests --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> |
||
|
|
b280b56b30 |
feat(trace): add request-level trace metrics and API support (#640)
refactor: replace operation trace with telemetry fix telemetry demo skill ingestion simplify telemetry summary metric keys rename remaining trace telemetry artifacts feat: support configurable telemetry payloads docs: rewrite operation telemetry design in chinese fix: reject telemetry for async session commit refactor: isolate telemetry orchestration refactor: remove telemetry from find payloads refactor: remove telemetry event payloads fix(trace): keep only telemetry-related changes fix(trace): remove top-level usage from telemetry responses feat(console): default telemetry on proxied operations |
||
|
|
4cf688852b |
feat: add --sender parameter to chat commands (#562)
* feat: add --sender parameter to chat commands - Add --sender option to Python CLI chat command - Add --sender option to Rust CLI chat command - Pass sender ID through to channels - Display sender in interactive mode header - Update langfuse integration for compatibility * fix: align default sender ID to "user" for consistency Align default sender ID in SingleTurnChannel from "default" to "user" to match ChatChannel's default, ensuring consistent sender identification across interactive and single-turn chat modes. * style: add trailing comma for consistency * fix: align Rust CLI default sender to "user" Change Rust CLI's default sender from "cli_user" to "user" to match Python side (ChatChannel and SingleTurnChannel), ensuring consistent default sender identification across both Rust and Python CLI tools. * fix: pass through total_tokens in langfuse usage conversion When converting from old usage format (prompt_tokens/completion_tokens/total_tokens) to usage_details format, also pass through total_tokens as 'total' field if it's available in the usage dict. * fix: protect langfuse.flush() with try/except Wrap self.langfuse.flush() calls in try/except blocks to prevent flush failures from discarding successfully obtained LLM responses. - In success path: flush() failure only logs debug message - In error path: flush() failure silently ignored (already in error handling) * fix: disable langfuse propagate_attributes to fix generator error Temporarily disable langfuse propagate_attributes context manager to fix RuntimeError: generator didn't stop after throw(). The context manager had exception handling issues when exceptions were thrown inside the block. This preserves the API while avoiding the runtime error. * fix: properly implement langfuse propagate_attributes without generator error Reimplement propagate_attributes with manual __enter__/__exit__ management to avoid the 'generator didn't stop after throw()' error. Key changes: - Use local variable to avoid name shadowing with the method - Only catch exceptions when entering the context manager - Let inner block exceptions propagate normally - Always exit the context manager in finally block - Restore session_id/user_id propagation to langfuse |
||
|
|
8c740fd565 |
chore: 编译子命令失败报错, golang版本最低要求1.22+ (#444)
* chore: 编译子命令失败报错, golang版本最低要求1.22+ * fix: agfs默认启用binding-client相关改造 |