Repository: volcengine/OpenViking Branch: main Commit: 33f1a8f42b40 Files: 1502 Total size: 11.0 MB Directory structure: gitextract_9tihp5kp/ ├── .clang-format ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.yml │ │ ├── config.yml │ │ ├── feature_request.yml │ │ └── question.yml │ ├── PULL_REQUEST_TEMPLATE.md │ ├── dependabot.yml │ └── workflows/ │ ├── _build.yml │ ├── _codeql.yml │ ├── _lint.yml │ ├── _publish.yml │ ├── _test_full.yml │ ├── _test_lite.yml │ ├── build-docker-image.yml │ ├── ci.yml │ ├── pr-review.yml │ ├── pr.yml │ ├── release-vikingbot-first.yml │ ├── release.yml │ ├── rust-cli.yml │ └── schedule.yml ├── .gitignore ├── .pr_agent.toml ├── .pre-commit-config.yaml ├── CONTRIBUTING.md ├── CONTRIBUTING_CN.md ├── CONTRIBUTING_JA.md ├── Cargo.toml ├── Dockerfile ├── LICENSE ├── MANIFEST.in ├── Makefile ├── README.md ├── README_CN.md ├── README_JA.md ├── bot/ │ ├── .coveragerc │ ├── .dockerignore │ ├── .github/ │ │ └── workflows/ │ │ ├── release.yml │ │ └── test.yml │ ├── .gitignore │ ├── README.md │ ├── README_CN.md │ ├── SECURITY.md │ ├── bridge/ │ │ ├── package.json │ │ ├── src/ │ │ │ ├── index.ts │ │ │ ├── server.ts │ │ │ ├── types.d.ts │ │ │ └── whatsapp.ts │ │ └── tsconfig.json │ ├── deploy/ │ │ ├── Dockerfile │ │ ├── docker/ │ │ │ ├── Dockerfile │ │ │ ├── README.md │ │ │ ├── build-image.sh │ │ │ ├── build-multiarch.sh │ │ │ ├── deploy.sh │ │ │ ├── deploy_langfuse.sh │ │ │ ├── docker-entrypoint.sh │ │ │ ├── image_upload.example.yaml │ │ │ ├── image_upload.sh │ │ │ ├── langfuse/ │ │ │ │ └── docker-compose.yml │ │ │ └── stop.sh │ │ ├── ecs/ │ │ │ └── README.md │ │ └── vke/ │ │ ├── README.md │ │ ├── deploy.sh │ │ ├── k8s/ │ │ │ ├── deployment.yaml │ │ │ ├── pvc-nas-example.yaml │ │ │ ├── pvc-tos-example.yaml │ │ │ └── pvc-tos.yaml │ │ └── vke_deploy.example.yaml │ ├── docs/ │ │ ├── CHANNEL.md │ │ ├── openclaw-plugin-analysis.md │ │ └── rfc-openviking-cli-ov-chat.md │ ├── eval/ │ │ ├── locomo/ │ │ │ ├── judge.py │ │ │ ├── run_eval.py │ │ │ └── stat_judge_result.py │ │ └── skillsbench/ │ │ └── skill_bench_eval.py │ ├── license/ │ │ └── LICENSE │ ├── package.json │ ├── scripts/ │ │ ├── clean_vikingbot.sh │ │ ├── restart_openviking_server.sh │ │ ├── start_vikingbot_in_ecs.sh │ │ └── test_all.sh │ ├── tests/ │ │ ├── conftest.py │ │ ├── example.py │ │ ├── experience_data_mini.json │ │ └── test_chat_functionality.py │ ├── vikingbot/ │ │ ├── __init__.py │ │ ├── __main__.py │ │ ├── agent/ │ │ │ ├── __init__.py │ │ │ ├── context.py │ │ │ ├── loop.py │ │ │ ├── memory.py │ │ │ ├── skills.py │ │ │ ├── subagent.py │ │ │ └── tools/ │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── cron.py │ │ │ ├── factory.py │ │ │ ├── filesystem.py │ │ │ ├── image.py │ │ │ ├── message.py │ │ │ ├── ov_file.py │ │ │ ├── registry.py │ │ │ ├── shell.py │ │ │ ├── spawn.py │ │ │ ├── web.py │ │ │ └── websearch/ │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── brave.py │ │ │ ├── ddgs.py │ │ │ ├── exa.py │ │ │ ├── registry.py │ │ │ └── tavily.py │ │ ├── bus/ │ │ │ ├── __init__.py │ │ │ ├── events.py │ │ │ └── queue.py │ │ ├── channels/ │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── chat.py │ │ │ ├── dingtalk.py │ │ │ ├── discord.py │ │ │ ├── email.py │ │ │ ├── feishu.py │ │ │ ├── manager.py │ │ │ ├── mochat.py │ │ │ ├── openapi.py │ │ │ ├── openapi_models.py │ │ │ ├── qq.py │ │ │ ├── single_turn.py │ │ │ ├── slack.py │ │ │ ├── telegram.py │ │ │ ├── utils.py │ │ │ └── whatsapp.py │ │ ├── cli/ │ │ │ ├── __init__.py │ │ │ └── commands.py │ │ ├── config/ │ │ │ ├── __init__.py │ │ │ ├── loader.py │ │ │ └── schema.py │ │ ├── console/ │ │ │ ├── README_GRADIO.md │ │ │ ├── __init__.py │ │ │ └── web_console.py │ │ ├── cron/ │ │ │ ├── __init__.py │ │ │ ├── service.py │ │ │ └── types.py │ │ ├── heartbeat/ │ │ │ ├── __init__.py │ │ │ └── service.py │ │ ├── hooks/ │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── builtins/ │ │ │ │ ├── __init__.py │ │ │ │ └── openviking_hooks.py │ │ │ └── manager.py │ │ ├── integrations/ │ │ │ ├── __init__.py │ │ │ └── langfuse.py │ │ ├── openviking_mount/ │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ ├── fuse_finder.py │ │ │ ├── fuse_proxy.py │ │ │ ├── fuse_simple.py │ │ │ ├── fuse_simple_debug.py │ │ │ ├── manager.py │ │ │ ├── mount.py │ │ │ ├── ov_server.py │ │ │ ├── session_integration.py │ │ │ ├── user_apikey_manager.py │ │ │ └── viking_fuse.py │ │ ├── providers/ │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── litellm_provider.py │ │ │ ├── registry.py │ │ │ └── transcription.py │ │ ├── sandbox/ │ │ │ ├── __init__.py │ │ │ ├── backends/ │ │ │ │ ├── __init__.py │ │ │ │ ├── aiosandbox.py │ │ │ │ ├── direct.py │ │ │ │ ├── opensandbox.py │ │ │ │ ├── srt-wrapper.mjs │ │ │ │ └── srt.py │ │ │ ├── base.py │ │ │ └── manager.py │ │ ├── session/ │ │ │ ├── __init__.py │ │ │ └── manager.py │ │ ├── tests/ │ │ │ ├── __init__.py │ │ │ ├── integration/ │ │ │ │ └── __init__.py │ │ │ └── unit/ │ │ │ ├── __init__.py │ │ │ ├── test_agent/ │ │ │ │ └── __init__.py │ │ │ ├── test_bus/ │ │ │ │ └── __init__.py │ │ │ ├── test_channels/ │ │ │ │ └── __init__.py │ │ │ └── test_config/ │ │ │ └── __init__.py │ │ └── utils/ │ │ ├── __init__.py │ │ ├── helpers.py │ │ └── tracing.py │ └── workspace/ │ ├── HEARTBEAT.md │ ├── SOUL.md │ ├── TOOLS.md │ ├── USER.md │ ├── memory/ │ │ └── MEMORY.md │ └── skills/ │ ├── README.md │ ├── cron/ │ │ └── SKILL.md │ ├── github/ │ │ └── SKILL.md │ ├── github-proxy/ │ │ ├── SKILL.md │ │ └── scripts/ │ │ └── convert_url.py │ ├── opencode/ │ │ ├── SKILL.md │ │ ├── list_sessions.py │ │ ├── opencode_utils.py │ │ └── status.json │ ├── skill-creator/ │ │ └── SKILL.md │ ├── summarize/ │ │ └── SKILL.md │ ├── tmux/ │ │ ├── SKILL.md │ │ └── scripts/ │ │ ├── find-sessions.sh │ │ └── wait-for-text.sh │ └── weather/ │ └── SKILL.md ├── build_support/ │ ├── __init__.py │ └── x86_profiles.py ├── crates/ │ └── ov_cli/ │ ├── Cargo.toml │ ├── README.md │ ├── install.sh │ ├── src/ │ │ ├── client.rs │ │ ├── commands/ │ │ │ ├── admin.rs │ │ │ ├── chat.rs │ │ │ ├── content.rs │ │ │ ├── filesystem.rs │ │ │ ├── mod.rs │ │ │ ├── observer.rs │ │ │ ├── pack.rs │ │ │ ├── relations.rs │ │ │ ├── resources.rs │ │ │ ├── search.rs │ │ │ ├── session.rs │ │ │ └── system.rs │ │ ├── config.rs │ │ ├── error.rs │ │ ├── main.rs │ │ ├── output.rs │ │ ├── tui/ │ │ │ ├── app.rs │ │ │ ├── event.rs │ │ │ ├── mod.rs │ │ │ ├── tree.rs │ │ │ └── ui.rs │ │ └── utils.rs │ └── test_ov.sh ├── deploy/ │ └── helm/ │ ├── README.md │ └── openviking/ │ ├── .helmignore │ ├── Chart.yaml │ ├── templates/ │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── configmap.yaml │ │ ├── deployment.yaml │ │ ├── ingress.yaml │ │ ├── pvc.yaml │ │ └── service.yaml │ └── values.yaml ├── docker-compose.yml ├── docs/ │ ├── design/ │ │ ├── multi-tenant-design.md │ │ └── openclaw-integration.md │ ├── en/ │ │ ├── about/ │ │ │ ├── 01-about-us.md │ │ │ ├── 02-changelog.md │ │ │ └── 03-roadmap.md │ │ ├── api/ │ │ │ ├── 01-overview.md │ │ │ ├── 02-resources.md │ │ │ ├── 03-filesystem.md │ │ │ ├── 04-skills.md │ │ │ ├── 05-sessions.md │ │ │ ├── 06-retrieval.md │ │ │ ├── 07-system.md │ │ │ └── 08-admin.md │ │ ├── concepts/ │ │ │ ├── 01-architecture.md │ │ │ ├── 02-context-types.md │ │ │ ├── 03-context-layers.md │ │ │ ├── 04-viking-uri.md │ │ │ ├── 05-storage.md │ │ │ ├── 06-extraction.md │ │ │ ├── 07-retrieval.md │ │ │ ├── 08-session.md │ │ │ └── 09-transaction.md │ │ ├── faq/ │ │ │ └── faq.md │ │ ├── getting-started/ │ │ │ ├── 01-introduction.md │ │ │ ├── 02-quickstart.md │ │ │ └── 03-quickstart-server.md │ │ └── guides/ │ │ ├── 01-configuration.md │ │ ├── 02-volcengine-purchase-guide.md │ │ ├── 03-deployment.md │ │ ├── 04-authentication.md │ │ ├── 05-monitoring.md │ │ ├── 06-mcp-integration.md │ │ └── 07-operation-telemetry.md │ └── zh/ │ ├── about/ │ │ ├── 01-about-us.md │ │ ├── 02-changelog.md │ │ └── 03-roadmap.md │ ├── api/ │ │ ├── 01-overview.md │ │ ├── 02-resources.md │ │ ├── 03-filesystem.md │ │ ├── 04-skills.md │ │ ├── 05-sessions.md │ │ ├── 06-retrieval.md │ │ ├── 07-system.md │ │ └── 08-admin.md │ ├── concepts/ │ │ ├── 01-architecture.md │ │ ├── 02-context-types.md │ │ ├── 03-context-layers.md │ │ ├── 04-viking-uri.md │ │ ├── 05-storage.md │ │ ├── 06-extraction.md │ │ ├── 07-retrieval.md │ │ ├── 08-session.md │ │ └── 09-transaction.md │ ├── faq/ │ │ └── faq.md │ ├── getting-started/ │ │ ├── 01-introduction.md │ │ ├── 02-quickstart.md │ │ └── 03-quickstart-server.md │ └── guides/ │ ├── 01-configuration.md │ ├── 02-volcengine-purchase-guide.md │ ├── 03-deployment.md │ ├── 04-authentication.md │ ├── 05-monitoring.md │ ├── 06-mcp-integration.md │ └── 07-operation-telemetry.md ├── examples/ │ ├── claude-memory-plugin/ │ │ ├── .claude-plugin/ │ │ │ └── plugin.json │ │ ├── README.md │ │ ├── hooks/ │ │ │ ├── common.sh │ │ │ ├── hooks.json │ │ │ ├── session-end.sh │ │ │ ├── session-start.sh │ │ │ ├── stop.sh │ │ │ └── user-prompt-submit.sh │ │ ├── scripts/ │ │ │ ├── ov_memory.py │ │ │ └── run_e2e_claude_session.sh │ │ └── skills/ │ │ └── memory-recall/ │ │ └── SKILL.md │ ├── cloud/ │ │ ├── .gitignore │ │ ├── GUIDE.md │ │ ├── alice.py │ │ ├── bob.py │ │ ├── ov.conf.example │ │ └── setup_users.py │ ├── common/ │ │ ├── __init__.py │ │ ├── boring_logging_config.py │ │ ├── recipe.py │ │ └── resource_manager.py │ ├── k8s-helm/ │ │ ├── .helmignore │ │ ├── Chart.yaml │ │ ├── README.md │ │ ├── templates/ │ │ │ ├── NOTES.txt │ │ │ ├── _helpers.tpl │ │ │ ├── deployment.yaml │ │ │ ├── secret.yaml │ │ │ └── service.yaml │ │ └── values.yaml │ ├── mcp-query/ │ │ ├── README.md │ │ ├── ov.conf.example │ │ ├── pyproject.toml │ │ └── server.py │ ├── misc/ │ │ └── memory_demo.py │ ├── multi_tenant/ │ │ ├── README.md │ │ ├── admin_workflow.py │ │ ├── admin_workflow.sh │ │ ├── ov.conf.example │ │ └── pyproject.toml │ ├── openclaw-plugin/ │ │ ├── .gitignore │ │ ├── INSTALL-AGENT.md │ │ ├── INSTALL-ZH.md │ │ ├── INSTALL.md │ │ ├── README.md │ │ ├── client.ts │ │ ├── config.ts │ │ ├── context-engine.ts │ │ ├── demo-memory-ajie.py │ │ ├── demo-memory-xiaomei.py │ │ ├── index.ts │ │ ├── install.ps1 │ │ ├── install.sh │ │ ├── memory-ranking.ts │ │ ├── openclaw.plugin.json │ │ ├── package.json │ │ ├── process-manager.ts │ │ ├── setup-helper/ │ │ │ ├── install.js │ │ │ └── package.json │ │ ├── skills/ │ │ │ └── install-openviking-memory/ │ │ │ └── SKILL.md │ │ ├── text-utils.ts │ │ └── tsconfig.json │ ├── opencode/ │ │ └── plugin/ │ │ ├── README.md │ │ ├── index.mjs │ │ ├── package.json │ │ └── skills/ │ │ └── openviking/ │ │ └── SKILL.md │ ├── opencode-memory-plugin/ │ │ ├── .gitignore │ │ ├── INSTALL-ZH.md │ │ ├── README.md │ │ ├── openviking-config.example.json │ │ └── openviking-memory.ts │ ├── ov.conf.example │ ├── ovcli.conf.example │ ├── quick_start.py │ ├── server_client/ │ │ ├── README.md │ │ ├── client_async.py │ │ ├── client_cli.sh │ │ ├── client_sync.py │ │ ├── ov.conf.example │ │ ├── ovcli.conf.example │ │ └── pyproject.toml │ ├── skills/ │ │ ├── ov-add-data/ │ │ │ └── SKILL.md │ │ ├── ov-search-context/ │ │ │ └── SKILL.md │ │ └── ov-server-operate/ │ │ └── SKILL.md │ └── watch_resource_example.py ├── openviking/ │ ├── __init__.py │ ├── agfs_manager.py │ ├── async_client.py │ ├── client/ │ │ ├── __init__.py │ │ ├── local.py │ │ └── session.py │ ├── client.py │ ├── console/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── app.py │ │ ├── bootstrap.py │ │ ├── config.py │ │ └── static/ │ │ ├── app.js │ │ ├── index.html │ │ └── styles.css │ ├── core/ │ │ ├── __init__.py │ │ ├── building_tree.py │ │ ├── context.py │ │ ├── directories.py │ │ ├── mcp_converter.py │ │ └── skill_loader.py │ ├── eval/ │ │ ├── README.md │ │ ├── __init__.py │ │ ├── datasets/ │ │ │ └── local_doc_example_glm5.jsonl │ │ ├── ragas/ │ │ │ ├── __init__.py │ │ │ ├── analyze_records.py │ │ │ ├── base.py │ │ │ ├── generator.py │ │ │ ├── pipeline.py │ │ │ ├── play_recorder.py │ │ │ ├── playback.py │ │ │ ├── rag_eval.py │ │ │ ├── record_analysis.py │ │ │ └── types.py │ │ └── recorder/ │ │ ├── __init__.py │ │ ├── async_writer.py │ │ ├── playback.py │ │ ├── recorder.py │ │ ├── recording_client.py │ │ ├── types.py │ │ └── wrapper.py │ ├── message/ │ │ ├── __init__.py │ │ ├── message.py │ │ └── part.py │ ├── models/ │ │ ├── __init__.py │ │ ├── embedder/ │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── gemini_embedders.py │ │ │ ├── jina_embedders.py │ │ │ ├── minimax_embedders.py │ │ │ ├── openai_embedders.py │ │ │ ├── vikingdb_embedders.py │ │ │ ├── volcengine_embedders.py │ │ │ └── voyage_embedders.py │ │ └── vlm/ │ │ ├── __init__.py │ │ ├── backends/ │ │ │ ├── litellm_vlm.py │ │ │ ├── openai_vlm.py │ │ │ └── volcengine_vlm.py │ │ ├── base.py │ │ ├── llm.py │ │ ├── registry.py │ │ └── token_usage.py │ ├── parse/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── converter.py │ │ ├── custom.py │ │ ├── directory_scan.py │ │ ├── ovpack/ │ │ │ └── __init__.py │ │ ├── parsers/ │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ ├── base_parser.py │ │ │ ├── code/ │ │ │ │ ├── README.md │ │ │ │ ├── __init__.py │ │ │ │ ├── ast/ │ │ │ │ │ ├── __init__.py │ │ │ │ │ ├── extractor.py │ │ │ │ │ ├── languages/ │ │ │ │ │ │ ├── __init__.py │ │ │ │ │ │ ├── base.py │ │ │ │ │ │ ├── cpp.py │ │ │ │ │ │ ├── csharp.py │ │ │ │ │ │ ├── go.py │ │ │ │ │ │ ├── java.py │ │ │ │ │ │ ├── js_ts.py │ │ │ │ │ │ ├── python.py │ │ │ │ │ │ └── rust.py │ │ │ │ │ └── skeleton.py │ │ │ │ └── code.py │ │ │ ├── constants.py │ │ │ ├── directory.py │ │ │ ├── epub.py │ │ │ ├── excel.py │ │ │ ├── html.py │ │ │ ├── legacy_doc.py │ │ │ ├── markdown.py │ │ │ ├── media/ │ │ │ │ ├── __init__.py │ │ │ │ ├── audio.py │ │ │ │ ├── constants.py │ │ │ │ ├── image.py │ │ │ │ ├── utils.py │ │ │ │ └── video.py │ │ │ ├── pdf.py │ │ │ ├── powerpoint.py │ │ │ ├── text.py │ │ │ ├── upload_utils.py │ │ │ ├── word.py │ │ │ └── zip_parser.py │ │ ├── registry.py │ │ ├── resource_detector/ │ │ │ ├── __init__.py │ │ │ ├── detect_info.py │ │ │ ├── recursive.py │ │ │ ├── size.py │ │ │ └── visit.py │ │ ├── tree_builder.py │ │ └── vlm.py │ ├── prompts/ │ │ ├── __init__.py │ │ ├── manager.py │ │ └── templates/ │ │ ├── compression/ │ │ │ ├── dedup_decision.yaml │ │ │ ├── field_compress.yaml │ │ │ ├── memory_extraction.yaml │ │ │ ├── memory_merge.yaml │ │ │ ├── memory_merge_bundle.yaml │ │ │ └── structured_summary.yaml │ │ ├── indexing/ │ │ │ └── relevance_scoring.yaml │ │ ├── parsing/ │ │ │ ├── chapter_analysis.yaml │ │ │ ├── context_generation.yaml │ │ │ ├── image_summary.yaml │ │ │ └── semantic_grouping.yaml │ │ ├── processing/ │ │ │ ├── interaction_learning.yaml │ │ │ ├── strategy_extraction.yaml │ │ │ └── tool_chain_analysis.yaml │ │ ├── retrieval/ │ │ │ └── intent_analysis.yaml │ │ ├── semantic/ │ │ │ ├── code_ast_summary.yaml │ │ │ ├── code_summary.yaml │ │ │ ├── document_summary.yaml │ │ │ ├── file_summary.yaml │ │ │ └── overview_generation.yaml │ │ ├── skill/ │ │ │ └── overview_generation.yaml │ │ ├── test/ │ │ │ └── skill_test_generation.yaml │ │ └── vision/ │ │ ├── batch_filtering.yaml │ │ ├── image_filtering.yaml │ │ ├── image_understanding.yaml │ │ ├── page_understanding.yaml │ │ ├── page_understanding_batch.yaml │ │ ├── table_understanding.yaml │ │ └── unified_analysis.yaml │ ├── pyagfs/ │ │ ├── __init__.py │ │ ├── binding_client.py │ │ ├── client.py │ │ ├── exceptions.py │ │ └── helpers.py │ ├── resource/ │ │ ├── __init__.py │ │ ├── watch_manager.py │ │ └── watch_scheduler.py │ ├── retrieve/ │ │ ├── __init__.py │ │ ├── hierarchical_retriever.py │ │ ├── intent_analyzer.py │ │ ├── memory_lifecycle.py │ │ └── retrieval_stats.py │ ├── server/ │ │ ├── __init__.py │ │ ├── api_keys.py │ │ ├── app.py │ │ ├── auth.py │ │ ├── bootstrap.py │ │ ├── config.py │ │ ├── dependencies.py │ │ ├── identity.py │ │ ├── models.py │ │ ├── routers/ │ │ │ ├── __init__.py │ │ │ ├── admin.py │ │ │ ├── bot.py │ │ │ ├── content.py │ │ │ ├── debug.py │ │ │ ├── filesystem.py │ │ │ ├── observer.py │ │ │ ├── pack.py │ │ │ ├── relations.py │ │ │ ├── resources.py │ │ │ ├── search.py │ │ │ ├── sessions.py │ │ │ ├── system.py │ │ │ └── tasks.py │ │ └── telemetry.py │ ├── service/ │ │ ├── __init__.py │ │ ├── core.py │ │ ├── debug_service.py │ │ ├── fs_service.py │ │ ├── pack_service.py │ │ ├── relation_service.py │ │ ├── resource_service.py │ │ ├── search_service.py │ │ ├── session_service.py │ │ └── task_tracker.py │ ├── session/ │ │ ├── __init__.py │ │ ├── compressor.py │ │ ├── memory_archiver.py │ │ ├── memory_deduplicator.py │ │ ├── memory_extractor.py │ │ ├── session.py │ │ └── tool_skill_utils.py │ ├── storage/ │ │ ├── __init__.py │ │ ├── collection_schemas.py │ │ ├── errors.py │ │ ├── expr.py │ │ ├── local_fs.py │ │ ├── observers/ │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ ├── base_observer.py │ │ │ ├── lock_observer.py │ │ │ ├── queue_observer.py │ │ │ ├── retrieval_observer.py │ │ │ ├── vikingdb_observer.py │ │ │ └── vlm_observer.py │ │ ├── queuefs/ │ │ │ ├── __init__.py │ │ │ ├── embedding_msg.py │ │ │ ├── embedding_msg_converter.py │ │ │ ├── embedding_queue.py │ │ │ ├── embedding_tracker.py │ │ │ ├── named_queue.py │ │ │ ├── queue_manager.py │ │ │ ├── semantic_dag.py │ │ │ ├── semantic_msg.py │ │ │ ├── semantic_processor.py │ │ │ └── semantic_queue.py │ │ ├── transaction/ │ │ │ ├── __init__.py │ │ │ ├── lock_context.py │ │ │ ├── lock_handle.py │ │ │ ├── lock_manager.py │ │ │ ├── path_lock.py │ │ │ └── redo_log.py │ │ ├── vectordb/ │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ ├── collection/ │ │ │ │ ├── __init__.py │ │ │ │ ├── collection.py │ │ │ │ ├── http_collection.py │ │ │ │ ├── local_collection.py │ │ │ │ ├── result.py │ │ │ │ ├── vikingdb_clients.py │ │ │ │ ├── vikingdb_collection.py │ │ │ │ ├── volcengine_clients.py │ │ │ │ └── volcengine_collection.py │ │ │ ├── engine/ │ │ │ │ └── __init__.py │ │ │ ├── index/ │ │ │ │ ├── __init__.py │ │ │ │ ├── index.py │ │ │ │ └── local_index.py │ │ │ ├── meta/ │ │ │ │ ├── __init__.py │ │ │ │ ├── collection_meta.py │ │ │ │ ├── dict.py │ │ │ │ ├── index_meta.py │ │ │ │ └── local_dict.py │ │ │ ├── project/ │ │ │ │ ├── __init__.py │ │ │ │ ├── http_project.py │ │ │ │ ├── local_project.py │ │ │ │ ├── project.py │ │ │ │ ├── project_group.py │ │ │ │ ├── vikingdb_project.py │ │ │ │ └── volcengine_project.py │ │ │ ├── service/ │ │ │ │ ├── README_FASTAPI.md │ │ │ │ ├── __init__.py │ │ │ │ ├── api_fastapi.py │ │ │ │ ├── app_models.py │ │ │ │ ├── code.py │ │ │ │ └── server_fastapi.py │ │ │ ├── store/ │ │ │ │ ├── __init__.py │ │ │ │ ├── bytes_row.py │ │ │ │ ├── data.py │ │ │ │ ├── file_store.py │ │ │ │ ├── local_store.py │ │ │ │ ├── serializable.py │ │ │ │ ├── store.py │ │ │ │ └── store_manager.py │ │ │ ├── utils/ │ │ │ │ ├── __init__.py │ │ │ │ ├── api_utils.py │ │ │ │ ├── config_utils.py │ │ │ │ ├── constants.py │ │ │ │ ├── data_processor.py │ │ │ │ ├── data_utils.py │ │ │ │ ├── dict_utils.py │ │ │ │ ├── file_utils.py │ │ │ │ ├── id_generator.py │ │ │ │ ├── logging_init.py │ │ │ │ ├── stale_lock.py │ │ │ │ ├── str_to_uint64.py │ │ │ │ └── validation.py │ │ │ └── vectorize/ │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── vectorizer.py │ │ │ ├── vectorizer_factory.py │ │ │ └── volcengine_vectorizer.py │ │ ├── vectordb_adapters/ │ │ │ ├── README.md │ │ │ ├── __init__.py │ │ │ ├── base.py │ │ │ ├── factory.py │ │ │ ├── http_adapter.py │ │ │ ├── local_adapter.py │ │ │ ├── vikingdb_private_adapter.py │ │ │ └── volcengine_adapter.py │ │ ├── viking_fs.py │ │ ├── viking_vector_index_backend.py │ │ └── vikingdb_manager.py │ ├── sync_client.py │ ├── telemetry/ │ │ ├── __init__.py │ │ ├── backends/ │ │ │ ├── __init__.py │ │ │ └── memory.py │ │ ├── context.py │ │ ├── execution.py │ │ ├── operation.py │ │ ├── registry.py │ │ ├── request.py │ │ ├── resource_summary.py │ │ ├── runtime.py │ │ └── snapshot.py │ └── utils/ │ ├── __init__.py │ ├── agfs_utils.py │ ├── code_hosting_utils.py │ ├── embedding_utils.py │ ├── media_processor.py │ ├── process_lock.py │ ├── resource_processor.py │ ├── skill_processor.py │ ├── summarizer.py │ └── time_utils.py ├── openviking_cli/ │ ├── __init__.py │ ├── client/ │ │ ├── __init__.py │ │ ├── base.py │ │ ├── http.py │ │ └── sync_http.py │ ├── exceptions.py │ ├── retrieve/ │ │ ├── __init__.py │ │ └── types.py │ ├── rust_cli.py │ ├── server_bootstrap.py │ ├── session/ │ │ ├── __init__.py │ │ └── user_id.py │ └── utils/ │ ├── __init__.py │ ├── async_utils.py │ ├── config/ │ │ ├── __init__.py │ │ ├── agfs_config.py │ │ ├── config_loader.py │ │ ├── consts.py │ │ ├── embedding_config.py │ │ ├── log_config.py │ │ ├── open_viking_config.py │ │ ├── parser_config.py │ │ ├── rerank_config.py │ │ ├── storage_config.py │ │ ├── transaction_config.py │ │ ├── vectordb_config.py │ │ └── vlm_config.py │ ├── downloader.py │ ├── extractor.py │ ├── llm.py │ ├── logger.py │ ├── rerank.py │ ├── rerank_openai.py │ ├── storage.py │ └── uri.py ├── pyproject.toml ├── setup.py ├── src/ │ ├── CMakeLists.txt │ ├── common/ │ │ ├── ann_utils.h │ │ ├── io_utils.h │ │ ├── json_utils.h │ │ ├── log_utils.cpp │ │ ├── log_utils.h │ │ ├── string_utils.h │ │ └── zip_sort.h │ ├── cpu_feature_probe.cpp │ ├── index/ │ │ ├── common_structs.h │ │ ├── detail/ │ │ │ ├── fields_dict.h │ │ │ ├── index_manager_impl.cpp │ │ │ ├── index_manager_impl.h │ │ │ ├── meta/ │ │ │ │ ├── bruteforce_meta.h │ │ │ │ ├── manager_meta.h │ │ │ │ ├── scalar_index_meta.cpp │ │ │ │ ├── scalar_index_meta.h │ │ │ │ ├── vector_index_meta.cpp │ │ │ │ └── vector_index_meta.h │ │ │ ├── scalar/ │ │ │ │ ├── bitmap_holder/ │ │ │ │ │ ├── bitmap.cpp │ │ │ │ │ ├── bitmap.h │ │ │ │ │ ├── bitmap_field_group.cpp │ │ │ │ │ ├── bitmap_field_group.h │ │ │ │ │ ├── bitmap_utils.h │ │ │ │ │ ├── dir_index.cpp │ │ │ │ │ ├── dir_index.h │ │ │ │ │ ├── ranged_map.cpp │ │ │ │ │ └── ranged_map.h │ │ │ │ ├── filter/ │ │ │ │ │ ├── filter_ops.cpp │ │ │ │ │ ├── filter_ops.h │ │ │ │ │ ├── op_base.cpp │ │ │ │ │ ├── op_base.h │ │ │ │ │ ├── sort_ops.cpp │ │ │ │ │ └── sort_ops.h │ │ │ │ ├── scalar_index.cpp │ │ │ │ └── scalar_index.h │ │ │ ├── search_context.h │ │ │ └── vector/ │ │ │ ├── common/ │ │ │ │ ├── bruteforce.h │ │ │ │ ├── quantization_int8.h │ │ │ │ ├── quantizer.h │ │ │ │ ├── space_int8.h │ │ │ │ ├── space_ip.h │ │ │ │ ├── space_l2.h │ │ │ │ └── vector_base.h │ │ │ ├── sparse_retrieval/ │ │ │ │ ├── common.h │ │ │ │ ├── sparse_data_holder.h │ │ │ │ ├── sparse_datapoint.cpp │ │ │ │ ├── sparse_datapoint.h │ │ │ │ ├── sparse_dataset.h │ │ │ │ ├── sparse_distance_measure.h │ │ │ │ ├── sparse_row_index.cpp │ │ │ │ └── sparse_row_index.h │ │ │ ├── vector_index_adapter.h │ │ │ └── vector_recall.h │ │ ├── index_engine.cpp │ │ ├── index_engine.h │ │ └── index_manager.h │ ├── py_accessors.h │ ├── pybind11_interface.cpp │ └── store/ │ ├── bytes_row.cpp │ ├── bytes_row.h │ ├── common_structs.h │ ├── kv_store.h │ ├── persist_store.cpp │ ├── persist_store.h │ ├── volatile_store.cpp │ └── volatile_store.h ├── tests/ │ ├── README.md │ ├── __init__.py │ ├── agfs/ │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── test_fs_binding.py │ │ ├── test_fs_binding_s3.py │ │ ├── test_fs_local.py │ │ └── test_fs_s3.py │ ├── cli/ │ │ ├── conftest.py │ │ └── test_user_identifier.py │ ├── client/ │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── test_chat_integration.py │ │ ├── test_file_operations.py │ │ ├── test_filesystem.py │ │ ├── test_import_export.py │ │ ├── test_lifecycle.py │ │ ├── test_relations.py │ │ ├── test_resource_management.py │ │ ├── test_search.py │ │ ├── test_skill_management.py │ │ └── test_windows_path_handling.py │ ├── conftest.py │ ├── engine/ │ │ ├── CMakeLists.txt │ │ ├── test_common.cpp │ │ └── test_index_engine.cpp │ ├── eval/ │ │ ├── test_ragas_basic.py │ │ ├── test_ragas_eval.py │ │ └── test_ragas_validation.py │ ├── integration/ │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── test_add_resource_index.py │ │ ├── test_full_workflow.py │ │ ├── test_gemini_e2e.py │ │ ├── test_gemini_embedding_it.py │ │ ├── test_gemini_openviking_it.py │ │ ├── test_http_integration.py │ │ ├── test_quick_start_lite.py │ │ └── test_watch_e2e.py │ ├── misc/ │ │ ├── test_code_parser.py │ │ ├── test_config_validation.py │ │ ├── test_debug_service.py │ │ ├── test_embedding_input_type.py │ │ ├── test_extract_zip.py │ │ ├── test_mkdir.py │ │ ├── test_port_check.py │ │ ├── test_process_lock.py │ │ ├── test_rerank_openai.py │ │ ├── test_resource_processor_mv.py │ │ ├── test_semantic_config.py │ │ ├── test_tree_builder_dedup.py │ │ ├── test_vectordb_engine_loader.py │ │ ├── test_vikingdb_observer.py │ │ ├── test_vikingfs_find_without_rerank.py │ │ ├── test_vikingfs_uri_guard.py │ │ └── test_x86_profiles.py │ ├── models/ │ │ ├── test_embedding_telemetry_usage.py │ │ └── test_vlm_strip_think_tags.py │ ├── parse/ │ │ ├── __init__.py │ │ ├── test_add_directory.py │ │ ├── test_ast_extractor.py │ │ ├── test_directory_parser_routing.py │ │ ├── test_directory_scan.py │ │ ├── test_filename_safety.py │ │ ├── test_html_parser_utils.py │ │ ├── test_pdf_bookmark_extraction.py │ │ └── test_url_filename_preservation.py │ ├── resource/ │ │ ├── __init__.py │ │ ├── test_watch_manager.py │ │ └── test_watch_scheduler.py │ ├── retrieve/ │ │ ├── test_hierarchical_retriever_rerank.py │ │ └── test_hierarchical_retriever_target_dirs.py │ ├── server/ │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── test_admin_api.py │ │ ├── test_api_content.py │ │ ├── test_api_filesystem.py │ │ ├── test_api_key_manager.py │ │ ├── test_api_observer.py │ │ ├── test_api_relations.py │ │ ├── test_api_resources.py │ │ ├── test_api_search.py │ │ ├── test_api_sessions.py │ │ ├── test_auth.py │ │ ├── test_error_scenarios.py │ │ ├── test_http_client_sdk.py │ │ ├── test_identity.py │ │ └── test_server_health.py │ ├── service/ │ │ ├── test_resource_service_watch.py │ │ └── test_watch_recovery.py │ ├── session/ │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── test_memory_dedup_actions.py │ │ ├── test_memory_extractor_language.py │ │ ├── test_memory_extractor_response_types.py │ │ ├── test_session_commit.py │ │ ├── test_session_compressor_vikingdb.py │ │ ├── test_session_context.py │ │ ├── test_session_lifecycle.py │ │ ├── test_session_messages.py │ │ └── test_session_usage.py │ ├── storage/ │ │ ├── mock_backend.py │ │ ├── test_collection_schemas.py │ │ ├── test_embedding_msg_converter_tenant.py │ │ ├── test_semantic_dag_skip_files.py │ │ ├── test_semantic_dag_stats.py │ │ ├── test_semantic_processor_mv_vector_store.py │ │ ├── test_stale_lock.py │ │ ├── test_vectordb_adaptor.py │ │ └── test_vectordb_collection_loading.py │ ├── telemetry/ │ │ ├── test_execution.py │ │ ├── test_layering_rules.py │ │ └── test_resource_summary.py │ ├── test_code_hosting_utils.py │ ├── test_config_loader.py │ ├── test_edge_cases.py │ ├── test_edge_cases_simple.py │ ├── test_memory_lifecycle.py │ ├── test_session_async_commit.py │ ├── test_session_task_tracking.py │ ├── test_task_tracker.py │ ├── test_telemetry_runtime.py │ ├── test_upload_utils.py │ ├── transaction/ │ │ ├── __init__.py │ │ ├── conftest.py │ │ ├── test_concurrent_lock.py │ │ ├── test_e2e.py │ │ ├── test_lock_context.py │ │ ├── test_lock_manager.py │ │ ├── test_path_lock.py │ │ └── test_redo_log.py │ ├── unit/ │ │ ├── __init__.py │ │ ├── retrieve/ │ │ │ └── test_retrieval_stats.py │ │ ├── session/ │ │ │ ├── test_deduplicator_uri.py │ │ │ └── test_memory_archiver.py │ │ ├── test_embedding_config_gemini.py │ │ ├── test_embedding_config_voyage.py │ │ ├── test_extra_headers_embedding.py │ │ ├── test_extra_headers_vlm.py │ │ ├── test_gemini_embedder.py │ │ ├── test_jina_embedder.py │ │ ├── test_minimax_embedder_simple.py │ │ ├── test_ollama_embedding_factory.py │ │ ├── test_openai_embedder.py │ │ ├── test_skill_processor_none.py │ │ ├── test_stream_config_vlm.py │ │ ├── test_time_utils.py │ │ ├── test_uri_short_format.py │ │ ├── test_vlm_response_formats.py │ │ ├── test_voyage_embedder.py │ │ └── tool_skill/ │ │ ├── test_tool_skill_calibration.py │ │ ├── test_tool_skill_memory_guardrails.py │ │ └── test_tool_skill_utils.py │ ├── utils/ │ │ ├── __init__.py │ │ ├── mock_agfs.py │ │ └── mock_context.py │ └── vectordb/ │ ├── benchmark_stress.py │ ├── test_bytes_row.py │ ├── test_collection_large_scale.py │ ├── test_crash_recovery.py │ ├── test_data_processor.py │ ├── test_filter_ops.py │ ├── test_openviking_vectordb.py │ ├── test_project_group.py │ ├── test_pydantic_validation.py │ ├── test_recall.py │ └── test_vikingdb_project.py └── third_party/ ├── agfs/ │ ├── .github/ │ │ └── workflows/ │ │ └── daily-build.yml │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── agfs-fuse/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── README.md │ │ ├── cmd/ │ │ │ └── agfs-fuse/ │ │ │ └── main.go │ │ ├── go.mod │ │ ├── go.sum │ │ └── pkg/ │ │ ├── cache/ │ │ │ ├── cache.go │ │ │ └── cache_test.go │ │ ├── fusefs/ │ │ │ ├── file.go │ │ │ ├── fs.go │ │ │ ├── handles.go │ │ │ ├── handles_test.go │ │ │ └── node.go │ │ └── version/ │ │ └── version.go │ ├── agfs-mcp/ │ │ ├── .gitignore │ │ ├── .mcp.json │ │ ├── README.md │ │ ├── demos/ │ │ │ ├── hackernews_research.py │ │ │ ├── parallel_research.py │ │ │ ├── start_agents.sh │ │ │ ├── start_agents_tmux.sh │ │ │ ├── stop_agents.sh │ │ │ ├── stop_agents_tmux.sh │ │ │ └── task_loop.py │ │ ├── pyproject.toml │ │ └── src/ │ │ └── agfs_mcp/ │ │ ├── __init__.py │ │ └── server.py │ ├── agfs-sdk/ │ │ ├── go/ │ │ │ ├── README.md │ │ │ ├── client.go │ │ │ ├── client_test.go │ │ │ ├── go.mod │ │ │ └── types.go │ │ └── python/ │ │ ├── README.md │ │ ├── examples/ │ │ │ ├── advanced_usage.py │ │ │ ├── basic_usage.py │ │ │ └── helpers_usage.py │ │ ├── pyagfs/ │ │ │ ├── __init__.py │ │ │ ├── binding_client.py │ │ │ ├── client.py │ │ │ ├── exceptions.py │ │ │ └── helpers.py │ │ └── pyproject.toml │ ├── agfs-shell/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── README.md │ │ ├── agfs_shell/ │ │ │ ├── __init__.py │ │ │ ├── arg_parser.py │ │ │ ├── ast_nodes.py │ │ │ ├── builtins.py │ │ │ ├── cli.py │ │ │ ├── command_decorators.py │ │ │ ├── commands/ │ │ │ │ ├── __init__.py │ │ │ │ ├── base.py │ │ │ │ ├── basename.py │ │ │ │ ├── break_cmd.py │ │ │ │ ├── cat.py │ │ │ │ ├── cd.py │ │ │ │ ├── continue_cmd.py │ │ │ │ ├── cp.py │ │ │ │ ├── cut.py │ │ │ │ ├── date.py │ │ │ │ ├── dirname.py │ │ │ │ ├── download.py │ │ │ │ ├── echo.py │ │ │ │ ├── env.py │ │ │ │ ├── exit.py │ │ │ │ ├── export.py │ │ │ │ ├── false.py │ │ │ │ ├── grep.py │ │ │ │ ├── head.py │ │ │ │ ├── help.py │ │ │ │ ├── jq.py │ │ │ │ ├── llm.py │ │ │ │ ├── local.py │ │ │ │ ├── ls.py │ │ │ │ ├── mkdir.py │ │ │ │ ├── mount.py │ │ │ │ ├── mv.py │ │ │ │ ├── plugins.py │ │ │ │ ├── pwd.py │ │ │ │ ├── return_cmd.py │ │ │ │ ├── rev.py │ │ │ │ ├── rm.py │ │ │ │ ├── sleep.py │ │ │ │ ├── sort.py │ │ │ │ ├── stat.py │ │ │ │ ├── tail.py │ │ │ │ ├── tee.py │ │ │ │ ├── test.py │ │ │ │ ├── touch.py │ │ │ │ ├── tr.py │ │ │ │ ├── tree.py │ │ │ │ ├── true.py │ │ │ │ ├── uniq.py │ │ │ │ ├── unset.py │ │ │ │ ├── upload.py │ │ │ │ └── wc.py │ │ │ ├── completer.py │ │ │ ├── config.py │ │ │ ├── control_flow.py │ │ │ ├── control_parser.py │ │ │ ├── executor.py │ │ │ ├── exit_codes.py │ │ │ ├── expression.py │ │ │ ├── filesystem.py │ │ │ ├── lexer.py │ │ │ ├── parser.py │ │ │ ├── pipeline.py │ │ │ ├── process.py │ │ │ ├── shell.py │ │ │ ├── streams.py │ │ │ ├── utils/ │ │ │ │ ├── __init__.py │ │ │ │ └── formatters.py │ │ │ └── webapp_server.py │ │ ├── build.py │ │ ├── examples/ │ │ │ ├── enqueue_task.as │ │ │ └── task_queue_worker.as │ │ ├── pyproject.toml │ │ ├── scripts/ │ │ │ └── test_functions.as │ │ ├── tests/ │ │ │ ├── test_builtins.py │ │ │ ├── test_parser.py │ │ │ └── test_pipeline.py │ │ └── webapp/ │ │ ├── .gitignore │ │ ├── index.html │ │ ├── package.json │ │ ├── setup.sh │ │ ├── src/ │ │ │ ├── App.css │ │ │ ├── App.jsx │ │ │ ├── components/ │ │ │ │ ├── ContextMenu.jsx │ │ │ │ ├── Editor.jsx │ │ │ │ ├── FileTree.jsx │ │ │ │ ├── MenuBar.jsx │ │ │ │ └── Terminal.jsx │ │ │ └── main.jsx │ │ └── vite.config.js │ └── install.sh ├── croaring/ │ ├── LICENSE │ ├── roaring.c │ ├── roaring.h │ └── roaring.hh ├── krl/ │ ├── CMakeLists.txt │ ├── include/ │ │ ├── krl.h │ │ ├── krl_internal.h │ │ ├── platform_macros.h │ │ └── safe_memory.h │ └── src/ │ ├── IPdistance_simd.cpp │ └── L2distance_simd.cpp ├── leveldb-1.23/ │ ├── .appveyor.yml │ ├── .clang-format │ ├── .gitignore │ ├── .gitmodules │ ├── .travis.yml │ ├── AUTHORS │ ├── CMakeLists.txt │ ├── CONTRIBUTING.md │ ├── LICENSE │ ├── NEWS │ ├── README.md │ ├── TODO │ ├── benchmarks/ │ │ ├── db_bench.cc │ │ ├── db_bench_sqlite3.cc │ │ └── db_bench_tree_db.cc │ ├── cmake/ │ │ └── leveldbConfig.cmake.in │ ├── db/ │ │ ├── autocompact_test.cc │ │ ├── builder.cc │ │ ├── builder.h │ │ ├── c.cc │ │ ├── c_test.c │ │ ├── corruption_test.cc │ │ ├── db_impl.cc │ │ ├── db_impl.h │ │ ├── db_iter.cc │ │ ├── db_iter.h │ │ ├── db_test.cc │ │ ├── dbformat.cc │ │ ├── dbformat.h │ │ ├── dbformat_test.cc │ │ ├── dumpfile.cc │ │ ├── fault_injection_test.cc │ │ ├── filename.cc │ │ ├── filename.h │ │ ├── filename_test.cc │ │ ├── leveldbutil.cc │ │ ├── log_format.h │ │ ├── log_reader.cc │ │ ├── log_reader.h │ │ ├── log_test.cc │ │ ├── log_writer.cc │ │ ├── log_writer.h │ │ ├── memtable.cc │ │ ├── memtable.h │ │ ├── recovery_test.cc │ │ ├── repair.cc │ │ ├── skiplist.h │ │ ├── skiplist_test.cc │ │ ├── snapshot.h │ │ ├── table_cache.cc │ │ ├── table_cache.h │ │ ├── version_edit.cc │ │ ├── version_edit.h │ │ ├── version_edit_test.cc │ │ ├── version_set.cc │ │ ├── version_set.h │ │ ├── version_set_test.cc │ │ ├── write_batch.cc │ │ ├── write_batch_internal.h │ │ └── write_batch_test.cc │ ├── doc/ │ │ ├── benchmark.html │ │ ├── impl.md │ │ ├── index.md │ │ ├── log_format.md │ │ └── table_format.md │ ├── helpers/ │ │ └── memenv/ │ │ ├── memenv.cc │ │ ├── memenv.h │ │ └── memenv_test.cc │ ├── include/ │ │ ├── leveldb/ │ │ │ ├── c.h │ │ │ ├── cache.h │ │ │ ├── comparator.h │ │ │ ├── db.h │ │ │ ├── dumpfile.h │ │ │ ├── env.h │ │ │ ├── export.h │ │ │ ├── filter_policy.h │ │ │ ├── iterator.h │ │ │ ├── options.h │ │ │ ├── slice.h │ │ │ ├── status.h │ │ │ ├── table.h │ │ │ ├── table_builder.h │ │ │ └── write_batch.h │ │ └── port/ │ │ └── port_config.h │ ├── issues/ │ │ ├── issue178_test.cc │ │ ├── issue200_test.cc │ │ └── issue320_test.cc │ ├── port/ │ │ ├── README.md │ │ ├── port.h │ │ ├── port_config.h.in │ │ ├── port_example.h │ │ ├── port_stdcxx.h │ │ └── thread_annotations.h │ ├── table/ │ │ ├── block.cc │ │ ├── block.h │ │ ├── block_builder.cc │ │ ├── block_builder.h │ │ ├── filter_block.cc │ │ ├── filter_block.h │ │ ├── filter_block_test.cc │ │ ├── format.cc │ │ ├── format.h │ │ ├── iterator.cc │ │ ├── iterator_wrapper.h │ │ ├── merger.cc │ │ ├── merger.h │ │ ├── table.cc │ │ ├── table_builder.cc │ │ ├── table_test.cc │ │ ├── two_level_iterator.cc │ │ └── two_level_iterator.h │ └── util/ │ ├── arena.cc │ ├── arena.h │ ├── arena_test.cc │ ├── bloom.cc │ ├── bloom_test.cc │ ├── cache.cc │ ├── cache_test.cc │ ├── coding.cc │ ├── coding.h │ ├── coding_test.cc │ ├── comparator.cc │ ├── crc32c.cc │ ├── crc32c.h │ ├── crc32c_test.cc │ ├── env.cc │ ├── env_posix.cc │ ├── env_posix_test.cc │ ├── env_posix_test_helper.h │ ├── env_test.cc │ ├── env_windows.cc │ ├── env_windows_test.cc │ ├── env_windows_test_helper.h │ ├── filter_policy.cc │ ├── hash.cc │ ├── hash.h │ ├── hash_test.cc │ ├── histogram.cc │ ├── histogram.h │ ├── logging.cc │ ├── logging.h │ ├── logging_test.cc │ ├── mutexlock.h │ ├── no_destructor.h │ ├── no_destructor_test.cc │ ├── options.cc │ ├── posix_logger.h │ ├── random.h │ ├── status.cc │ ├── status_test.cc │ ├── testutil.cc │ ├── testutil.h │ └── windows_logger.h ├── rapidjson/ │ ├── LICENSE │ ├── allocators.h │ ├── document.h │ ├── encodedstream.h │ ├── encodings.h │ ├── error/ │ │ ├── en.h │ │ └── error.h │ ├── filereadstream.h │ ├── filewritestream.h │ ├── fwd.h │ ├── internal/ │ │ ├── biginteger.h │ │ ├── diyfp.h │ │ ├── dtoa.h │ │ ├── ieee754.h │ │ ├── itoa.h │ │ ├── meta.h │ │ ├── pow10.h │ │ ├── regex.h │ │ ├── stack.h │ │ ├── strfunc.h │ │ ├── strtod.h │ │ └── swap.h │ ├── istreamwrapper.h │ ├── memorybuffer.h │ ├── memorystream.h │ ├── msinttypes/ │ │ ├── inttypes.h │ │ └── stdint.h │ ├── ostreamwrapper.h │ ├── pointer.h │ ├── prettywriter.h │ ├── rapidjson.h │ ├── reader.h │ ├── schema.h │ ├── stream.h │ ├── stringbuffer.h │ └── writer.h └── spdlog-1.14.1/ ├── .clang-format ├── .clang-tidy ├── .git-blame-ignore-revs ├── .gitattributes ├── .github/ │ └── workflows/ │ └── ci.yml ├── .gitignore ├── CMakeLists.txt ├── INSTALL ├── LICENSE ├── README.md ├── appveyor.yml ├── bench/ │ ├── CMakeLists.txt │ ├── async_bench.cpp │ ├── bench.cpp │ ├── formatter-bench.cpp │ ├── latency.cpp │ └── utils.h ├── cmake/ │ ├── ide.cmake │ ├── pch.h.in │ ├── spdlog.pc.in │ ├── spdlogCPack.cmake │ ├── spdlogConfig.cmake.in │ ├── utils.cmake │ └── version.rc.in ├── example/ │ ├── CMakeLists.txt │ └── example.cpp ├── include/ │ └── spdlog/ │ ├── async.h │ ├── async_logger-inl.h │ ├── async_logger.h │ ├── cfg/ │ │ ├── argv.h │ │ ├── env.h │ │ ├── helpers-inl.h │ │ └── helpers.h │ ├── common-inl.h │ ├── common.h │ ├── details/ │ │ ├── backtracer-inl.h │ │ ├── backtracer.h │ │ ├── circular_q.h │ │ ├── console_globals.h │ │ ├── file_helper-inl.h │ │ ├── file_helper.h │ │ ├── fmt_helper.h │ │ ├── log_msg-inl.h │ │ ├── log_msg.h │ │ ├── log_msg_buffer-inl.h │ │ ├── log_msg_buffer.h │ │ ├── mpmc_blocking_q.h │ │ ├── null_mutex.h │ │ ├── os-inl.h │ │ ├── os.h │ │ ├── periodic_worker-inl.h │ │ ├── periodic_worker.h │ │ ├── registry-inl.h │ │ ├── registry.h │ │ ├── synchronous_factory.h │ │ ├── tcp_client-windows.h │ │ ├── tcp_client.h │ │ ├── thread_pool-inl.h │ │ ├── thread_pool.h │ │ ├── udp_client-windows.h │ │ ├── udp_client.h │ │ └── windows_include.h │ ├── fmt/ │ │ ├── bin_to_hex.h │ │ ├── bundled/ │ │ │ ├── args.h │ │ │ ├── chrono.h │ │ │ ├── color.h │ │ │ ├── compile.h │ │ │ ├── core.h │ │ │ ├── fmt.license.rst │ │ │ ├── format-inl.h │ │ │ ├── format.h │ │ │ ├── locale.h │ │ │ ├── os.h │ │ │ ├── ostream.h │ │ │ ├── printf.h │ │ │ ├── ranges.h │ │ │ ├── std.h │ │ │ └── xchar.h │ │ ├── chrono.h │ │ ├── compile.h │ │ ├── fmt.h │ │ ├── ostr.h │ │ ├── ranges.h │ │ ├── std.h │ │ └── xchar.h │ ├── formatter.h │ ├── fwd.h │ ├── logger-inl.h │ ├── logger.h │ ├── mdc.h │ ├── pattern_formatter-inl.h │ ├── pattern_formatter.h │ ├── sinks/ │ │ ├── android_sink.h │ │ ├── ansicolor_sink-inl.h │ │ ├── ansicolor_sink.h │ │ ├── base_sink-inl.h │ │ ├── base_sink.h │ │ ├── basic_file_sink-inl.h │ │ ├── basic_file_sink.h │ │ ├── callback_sink.h │ │ ├── daily_file_sink.h │ │ ├── dist_sink.h │ │ ├── dup_filter_sink.h │ │ ├── hourly_file_sink.h │ │ ├── kafka_sink.h │ │ ├── mongo_sink.h │ │ ├── msvc_sink.h │ │ ├── null_sink.h │ │ ├── ostream_sink.h │ │ ├── qt_sinks.h │ │ ├── ringbuffer_sink.h │ │ ├── rotating_file_sink-inl.h │ │ ├── rotating_file_sink.h │ │ ├── sink-inl.h │ │ ├── sink.h │ │ ├── stdout_color_sinks-inl.h │ │ ├── stdout_color_sinks.h │ │ ├── stdout_sinks-inl.h │ │ ├── stdout_sinks.h │ │ ├── syslog_sink.h │ │ ├── systemd_sink.h │ │ ├── tcp_sink.h │ │ ├── udp_sink.h │ │ ├── win_eventlog_sink.h │ │ ├── wincolor_sink-inl.h │ │ └── wincolor_sink.h │ ├── spdlog-inl.h │ ├── spdlog.h │ ├── stopwatch.h │ ├── tweakme.h │ └── version.h ├── scripts/ │ ├── ci_setup_clang.sh │ ├── extract_version.py │ └── format.sh ├── src/ │ ├── async.cpp │ ├── bundled_fmtlib_format.cpp │ ├── cfg.cpp │ ├── color_sinks.cpp │ ├── file_sinks.cpp │ ├── spdlog.cpp │ └── stdout_sinks.cpp └── tests/ ├── CMakeLists.txt ├── includes.h ├── main.cpp ├── test_async.cpp ├── test_backtrace.cpp ├── test_bin_to_hex.cpp ├── test_cfg.cpp ├── test_circular_q.cpp ├── test_create_dir.cpp ├── test_custom_callbacks.cpp ├── test_daily_logger.cpp ├── test_dup_filter.cpp ├── test_errors.cpp ├── test_eventlog.cpp ├── test_file_helper.cpp ├── test_file_logging.cpp ├── test_fmt_helper.cpp ├── test_macros.cpp ├── test_misc.cpp ├── test_mpmc_q.cpp ├── test_pattern_formatter.cpp ├── test_registry.cpp ├── test_sink.h ├── test_stdout_api.cpp ├── test_stopwatch.cpp ├── test_systemd.cpp ├── test_time_point.cpp ├── utils.cpp └── utils.h ================================================ FILE CONTENTS ================================================ ================================================ FILE: .clang-format ================================================ IndentWidth: 2 TabWidth: 2 Language: Cpp Standard: Cpp11 BasedOnStyle: Google # indent AccessModifierOffset: -1 ContinuationIndentWidth: 4 # align BreakBeforeTernaryOperators: true BreakBeforeBinaryOperators: false ColumnLimit: 80 # constructor BreakConstructorInitializersBeforeComma: false ConstructorInitializerIndentWidth: 4 ConstructorInitializerAllOnOneLineOrOnePerLine: true # blocks AllowShortBlocksOnASingleLine: false AllowShortFunctionsOnASingleLine: false AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false Cpp11BracedListStyle: true # other AlwaysBreakTemplateDeclarations: true DerivePointerAlignment: false PointerAlignment: Left # clang 3.9+ BreakStringLiterals: false SortIncludes: false ReflowComments: true ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.yml ================================================ name: Bug Report description: Report a bug or unexpected behavior title: "[Bug]: " labels: ["bug"] body: - type: markdown attributes: value: | Thanks for taking the time to report a bug! Please fill out the form below. - type: textarea id: description attributes: label: Bug Description description: A clear and concise description of what the bug is. placeholder: Describe the bug... validations: required: true - type: textarea id: reproduce attributes: label: Steps to Reproduce description: Steps to reproduce the behavior. placeholder: | 1. Initialize client with '...' 2. Call method '...' 3. See error validations: required: true - type: textarea id: expected attributes: label: Expected Behavior description: What did you expect to happen? validations: required: true - type: textarea id: actual attributes: label: Actual Behavior description: What actually happened? validations: required: true - type: textarea id: code attributes: label: Minimal Reproducible Example description: If applicable, provide a minimal code example that reproduces the issue. render: python - type: textarea id: logs attributes: label: Error Logs description: If applicable, paste any error messages or stack traces. render: shell - type: input id: version attributes: label: OpenViking Version description: What version of OpenViking are you using? placeholder: e.g., 0.1.0 validations: required: true - type: input id: python-version attributes: label: Python Version description: What version of Python are you using? placeholder: e.g., 3.10.0 validations: required: true - type: dropdown id: os attributes: label: Operating System options: - Linux - macOS - Windows - Other validations: required: true - type: dropdown id: backend attributes: label: Model Backend description: Which model backend are you using? options: - Volcengine (Doubao) - OpenAI - Other - type: textarea id: additional attributes: label: Additional Context description: Add any other context about the problem here. ================================================ FILE: .github/ISSUE_TEMPLATE/config.yml ================================================ blank_issues_enabled: false contact_links: - name: Documentation url: https://www.openviking.ai/docs about: Check the documentation for guides and API reference - name: Lark Community url: https://applink.larkoffice.com/client/chat/chatter/add_by_link?link_token=dd9l9590-7e6e-49f5-bf41-18aef1ma06v3 about: Join our Lark group for discussions and support - name: Questions & Discussions url: https://github.com/volcengine/OpenViking/discussions about: Ask questions and share ideas in GitHub Discussions ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.yml ================================================ name: Feature Request description: Suggest a new feature or enhancement title: "[Feature]: " labels: ["enhancement"] body: - type: markdown attributes: value: | Thanks for suggesting a feature! Please fill out the form below. - type: textarea id: problem attributes: label: Problem Statement description: Is your feature request related to a problem? Please describe. placeholder: A clear description of what the problem is. Ex. I'm always frustrated when... validations: required: true - type: textarea id: solution attributes: label: Proposed Solution description: Describe the solution you'd like. placeholder: A clear description of what you want to happen. validations: required: true - type: textarea id: alternatives attributes: label: Alternatives Considered description: Describe any alternative solutions or features you've considered. - type: dropdown id: area attributes: label: Feature Area description: Which area of OpenViking does this feature relate to? options: - Core (Client/Engine) - Filesystem Operations - Retrieval/Search - Session Management - Model Integration - Storage/VectorDB - CLI Tools - Documentation - Other validations: required: true - type: textarea id: use-case attributes: label: Use Case description: Describe the use case for this feature. placeholder: How would you use this feature in your project? validations: required: true - type: textarea id: code-example attributes: label: Example API (Optional) description: If applicable, provide an example of how the API might look. render: python - type: textarea id: additional attributes: label: Additional Context description: Add any other context, screenshots, or references about the feature request. - type: checkboxes id: contribution attributes: label: Contribution options: - label: I am willing to contribute to implementing this feature ================================================ FILE: .github/ISSUE_TEMPLATE/question.yml ================================================ name: Question description: Ask a question about OpenViking usage title: "[Question]: " labels: ["question"] body: - type: markdown attributes: value: | Have a question about OpenViking? We're here to help! - type: textarea id: question attributes: label: Your Question description: What would you like to know? placeholder: Describe your question clearly... validations: required: true - type: textarea id: context attributes: label: Context description: Provide any relevant context or background. placeholder: | - What are you trying to achieve? - What have you tried so far? - type: textarea id: code attributes: label: Code Example (Optional) description: If applicable, share relevant code. render: python - type: dropdown id: area attributes: label: Related Area options: - Installation / Setup - Configuration - API Usage - Retrieval / Search - Session Management - Performance - Other - type: checkboxes id: checked-docs attributes: label: Before Asking options: - label: I have checked the [documentation](https://www.openviking.ai/docs) required: true ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ ## Description ## Related Issue ## Type of Change - [ ] Bug fix (non-breaking change that fixes an issue) - [ ] New feature (non-breaking change that adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Documentation update - [ ] Refactoring (no functional changes) - [ ] Performance improvement - [ ] Test update ## Changes Made - - - ## Testing - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] I have tested this on the following platforms: - [ ] Linux - [ ] macOS - [ ] Windows ## Checklist - [ ] My code follows the project's coding style - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] Any dependent changes have been merged and published ## Screenshots (if applicable) ## Additional Notes ================================================ FILE: .github/dependabot.yml ================================================ version: 2 updates: # GitHub Actions 依赖更新 - package-ecosystem: "github-actions" directory: "/" schedule: interval: "weekly" labels: - "dependencies" - "github-actions" # Python 依赖更新 - package-ecosystem: "pip" directory: "/" schedule: interval: "weekly" labels: - "dependencies" - "python" # 忽略主要版本更新,避免破坏性变更 ignore: - dependency-name: "*" update-types: ["version-update:semver-major"] ================================================ FILE: .github/workflows/_build.yml ================================================ name: 15. _Build Distribution on: workflow_call: inputs: os_json: description: 'JSON string of runner labels to build on (ubuntu-24.04=x86_64, ubuntu-24.04-arm=aarch64, macos-14=arm64, macos-15-intel=x86_64, windows-latest=x86_64)' required: false type: string default: '["ubuntu-24.04", "ubuntu-24.04-arm", "macos-14", "macos-15-intel", "windows-latest"]' python_json: description: 'JSON string of Python versions' required: false type: string default: '["3.10", "3.11", "3.12", "3.13", "3.14"]' build_sdist: description: 'Whether to build source distribution' required: false type: boolean default: true build_wheels: description: 'Whether to build wheel distribution' required: false type: boolean default: true workflow_dispatch: inputs: build_sdist: description: 'Whether to build source distribution' required: false type: boolean default: true build_wheels: description: 'Whether to build wheel distribution' required: false type: boolean default: true os_json: description: 'JSON string of runner labels to build on (ubuntu-24.04=x86_64, ubuntu-24.04-arm=aarch64, macos-14=arm64, macos-15-intel=x86_64, windows-latest=x86_64)' required: false default: '["ubuntu-24.04", "ubuntu-24.04-arm", "macos-14", "macos-15-intel", "windows-latest"]' python_json: description: 'JSON string of Python versions' required: false default: '["3.10", "3.11", "3.12", "3.13", "3.14"]' jobs: build-sdist: name: Build source distribution py3.12 if: inputs.build_sdist runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 with: submodules: recursive fetch-depth: 0 # Required for setuptools_scm to detect version from git tags - name: Fetch all tags run: git fetch --force --tags - name: Set up Python uses: actions/setup-python@v6 with: python-version: '3.12' - name: Install uv uses: astral-sh/setup-uv@v7 with: enable-cache: true - name: Create venv run: uv venv - name: Install build dependencies run: uv pip install build setuptools_scm - name: Clean workspace (force ignore dirty) shell: bash run: | git reset --hard HEAD git clean -fd # For sdist, ensure local runtime binaries are not packaged even if present rm -rf openviking/bin openviking/lib third_party/agfs/bin || true rm -f openviking/storage/vectordb/*.so openviking/storage/vectordb/*.dylib openviking/storage/vectordb/*.dll openviking/storage/vectordb/*.exe || true rm -rf openviking/_version.py openviking.egg-info # Ignore uv.lock changes to avoid dirty state in setuptools_scm git update-index --assume-unchanged uv.lock || true - name: Debug Git and SCM shell: bash run: | echo "=== Git Describe ===" git describe --tags --long --dirty --always echo "=== Setuptools SCM Version ===" uv run --frozen python -m setuptools_scm echo "=== Git Status (Ignored included) ===" git status --ignored echo "=== Check openviking/_version.py ===" if [ -f openviking/_version.py ]; then cat openviking/_version.py; else echo "Not found"; fi - name: Build sdist run: uv run --frozen python -m build --sdist - name: Store the distribution packages uses: actions/upload-artifact@v7 with: name: python-package-distributions-sdist path: dist/*.tar.gz - name: Display built sdist version continue-on-error: true run: | VERSION=$(ls dist/*.tar.gz | head -n 1 | xargs basename | sed -E 's/^[^-]+-(.+)\.tar\.gz$/\1/') echo "Build Version: $VERSION" echo "::notice::Build sdist Version: $VERSION" build-linux: name: Build distribution on Linux ${{ matrix.arch }} (glibc 2.31) py${{ matrix.python-version }} # Run if Linux runners are requested (explicit labels or generic 'linux') if: >- inputs.build_wheels && ( contains(inputs.os_json, 'linux') || contains(inputs.os_json, '"ubuntu-24.04"') || contains(inputs.os_json, 'ubuntu-24.04-arm') ) runs-on: ${{ matrix.arch == 'aarch64' && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} container: ubuntu:20.04 env: DEBIAN_FRONTEND: noninteractive TZ: Etc/UTC strategy: fail-fast: false matrix: python-version: ${{ fromJson(inputs.python_json) }} arch: ${{ contains(inputs.os_json, 'linux') && fromJson('["x86_64","aarch64"]') || (contains(inputs.os_json, '"ubuntu-24.04"') && contains(inputs.os_json, 'ubuntu-24.04-arm')) && fromJson('["x86_64","aarch64"]') || contains(inputs.os_json, 'ubuntu-24.04-arm') && fromJson('["aarch64"]') || fromJson('["x86_64"]') }} steps: - name: Install system dependencies (Linux) run: | # Replace archive.ubuntu.com with azure.archive.ubuntu.com for better stability in GH Actions sed -i 's/http:\/\/archive.ubuntu.com\/ubuntu\//http:\/\/azure.archive.ubuntu.com\/ubuntu\//g' /etc/apt/sources.list # Retry apt-get update for i in 1 2 3 4 5; do apt-get update && break || sleep 5; done apt-get install -y \ git ca-certificates cmake build-essential tzdata curl \ libssl-dev zlib1g-dev libbz2-dev libreadline-dev libsqlite3-dev \ libffi-dev liblzma-dev libgdbm-dev libnss3-dev libncurses5-dev \ libncursesw5-dev tk-dev uuid-dev libexpat1-dev ln -fs /usr/share/zoneinfo/Etc/UTC /etc/localtime dpkg-reconfigure -f noninteractive tzdata - uses: actions/checkout@v6 with: submodules: recursive fetch-depth: 0 # Required for setuptools_scm to detect version from git tags - name: Fetch all tags run: | git config --global --add safe.directory "$GITHUB_WORKSPACE" git fetch --force --tags - name: Build CPython (Dynamic Selection) run: | # Map short version to full version for our specific build environment PYTHON_VERSION="${{ matrix.python-version }}" case "$PYTHON_VERSION" in "3.9") PYTHON_FULL="3.9.18" ;; "3.10") PYTHON_FULL="3.10.13" ;; "3.11") PYTHON_FULL="3.11.8" ;; "3.12") PYTHON_FULL="3.12.2" ;; "3.13") PYTHON_FULL="3.13.2" ;; "3.14") PYTHON_FULL="3.14.3" ;; *) echo "Error: Unknown python version $PYTHON_VERSION" exit 1 ;; esac PYTHON_PREFIX="/opt/python/${PYTHON_FULL}" PYTHON_BIN="${PYTHON_PREFIX}/bin/python${{ matrix.python-version }}" if [ ! -x "$PYTHON_BIN" ]; then curl -fsSL -o /tmp/Python-${PYTHON_FULL}.tgz \ https://www.python.org/ftp/python/${PYTHON_FULL}/Python-${PYTHON_FULL}.tgz tar -xzf /tmp/Python-${PYTHON_FULL}.tgz -C /tmp cd /tmp/Python-${PYTHON_FULL} CFLAGS="-fPIC" \ ./configure --prefix="${PYTHON_PREFIX}" --with-ensurepip=install --enable-shared make -j"$(nproc)" make install fi echo "PYTHON_BIN=${PYTHON_BIN}" >> "$GITHUB_ENV" echo "LD_LIBRARY_PATH=${PYTHON_PREFIX}/lib:${LD_LIBRARY_PATH}" >> "$GITHUB_ENV" export LD_LIBRARY_PATH="${PYTHON_PREFIX}/lib:${LD_LIBRARY_PATH}" "$PYTHON_BIN" -V - name: Set up Go uses: actions/setup-go@v6 with: go-version: '1.25.1' - name: Set up Rust uses: dtolnay/rust-toolchain@v1 with: toolchain: stable targets: ${{ matrix.arch == 'aarch64' && 'aarch64-unknown-linux-gnu' || 'x86_64-unknown-linux-gnu' }} - name: Install uv uses: astral-sh/setup-uv@v7 with: enable-cache: true - name: Create venv (Linux) run: uv venv --python "$PYTHON_BIN" - name: Seed pip (Linux) run: uv run python -m ensurepip --upgrade - name: Install dependencies run: uv sync --frozen - name: Install build dependencies run: uv pip install setuptools setuptools_scm pybind11 cmake wheel build - name: Build Rust CLI (Linux) run: cargo build --release --target ${{ matrix.arch == 'aarch64' && 'aarch64-unknown-linux-gnu' || 'x86_64-unknown-linux-gnu' }} -p ov_cli - name: Copy Rust CLI binary (Linux) run: | mkdir -p openviking/bin cp target/${{ matrix.arch == 'aarch64' && 'aarch64-unknown-linux-gnu' || 'x86_64-unknown-linux-gnu' }}/release/ov openviking/bin/ chmod +x openviking/bin/ov - name: Clean workspace (force ignore dirty) shell: bash run: | git reset --hard HEAD git clean -fd rm -rf openviking/_version.py openviking.egg-info # Ignore uv.lock changes to avoid dirty state in setuptools_scm git update-index --assume-unchanged uv.lock || true - name: Debug Git and SCM shell: bash run: | echo "=== Git Describe ===" git describe --tags --long --dirty --always echo "=== Setuptools SCM Version ===" uv run --frozen python -m setuptools_scm echo "=== Git Status (Ignored included) ===" git status --ignored echo "=== Check openviking/_version.py ===" if [ -f openviking/_version.py ]; then cat openviking/_version.py; else echo "Not found"; fi - name: Build package (Wheel Only) run: uv run --frozen python -m build --wheel - name: Install patchelf (Linux) run: | PATCHELF_VERSION=0.18.0 curl -fsSL -o /tmp/patchelf-${PATCHELF_VERSION}.tar.gz \ https://github.com/NixOS/patchelf/releases/download/${PATCHELF_VERSION}/patchelf-${PATCHELF_VERSION}.tar.gz tar -xzf /tmp/patchelf-${PATCHELF_VERSION}.tar.gz -C /tmp cd /tmp/patchelf-${PATCHELF_VERSION} ./configure make -j"$(nproc)" make install patchelf --version - name: Repair wheels (Linux) run: | uv pip install auditwheel # Repair wheels and output to a temporary directory uv run auditwheel repair dist/*.whl -w dist_fixed # Remove original non-compliant wheels rm dist/*.whl # Move repaired wheels back to dist mv dist_fixed/*.whl dist/ rmdir dist_fixed - name: Store the distribution packages uses: actions/upload-artifact@v7 with: name: python-package-distributions-linux-${{ matrix.arch }}-${{ matrix.python-version }} path: dist/ - name: Display built wheel version continue-on-error: true run: | VERSION=$(ls dist/*.whl | head -n 1 | xargs basename | cut -d- -f2) echo "Build Version: $VERSION" echo "::notice::Build Wheel Version (Linux ${{ matrix.arch }} glibc 2.31 py${{ matrix.python-version }}): $VERSION" build-other: name: Build non-Linux distributions # Run only when non-Linux runners are explicitly requested if: inputs.build_wheels && (contains(inputs.os_json, 'macos') || contains(inputs.os_json, 'windows')) runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: ${{ fromJson(inputs.os_json) }} python-version: ${{ fromJson(inputs.python_json) }} # Exclude ubuntu-24.04 from this matrix if it was passed in inputs exclude: - os: linux - os: ubuntu-24.04 - os: ubuntu-24.04-arm steps: - uses: actions/checkout@v6 with: submodules: recursive fetch-depth: 0 # Required for setuptools_scm to detect version from git tags - name: Fetch all tags run: git fetch --force --tags - name: Set up Python uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Configure macOS wheel architecture tag if: runner.os == 'macOS' shell: bash run: | if [[ "${{ matrix.os }}" == "macos-14" ]]; then TARGET_ARCH="arm64" MACOS_VERSION="14.0" elif [[ "${{ matrix.os }}" == "macos-15-intel" ]]; then TARGET_ARCH="x86_64" MACOS_VERSION="15.0" else echo "Unsupported macOS runner for release wheels: ${{ matrix.os }}" exit 1 fi echo "ARCHFLAGS=-arch ${TARGET_ARCH}" >> "$GITHUB_ENV" echo "CMAKE_OSX_ARCHITECTURES=${TARGET_ARCH}" >> "$GITHUB_ENV" echo "_PYTHON_HOST_PLATFORM=macosx-${MACOS_VERSION}-${TARGET_ARCH}" >> "$GITHUB_ENV" echo "Configured macOS wheel platform: macosx-${MACOS_VERSION}-${TARGET_ARCH}" - name: Set up Go uses: actions/setup-go@v6 with: go-version: '1.25.1' - name: Set up Rust uses: dtolnay/rust-toolchain@v1 with: toolchain: stable - name: Install uv uses: astral-sh/setup-uv@v7 with: enable-cache: true - name: Install system dependencies (macOS) if: runner.os == 'macOS' run: brew install cmake - name: Install system dependencies (Windows) if: runner.os == 'Windows' run: | choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' choco install mingw - name: Install dependencies run: uv sync --frozen - name: Install build dependencies run: uv pip install setuptools setuptools_scm pybind11 cmake wheel build - name: Build Rust CLI (macOS/Windows) shell: bash run: | if [[ "${{ matrix.os }}" == "windows-latest" ]]; then cargo build --release --target x86_64-pc-windows-msvc -p ov_cli else cargo build --release -p ov_cli fi - name: Copy Rust CLI binary (macOS/Windows) shell: bash run: | mkdir -p openviking/bin if [[ "${{ matrix.os }}" == "windows-latest" ]]; then cp target/x86_64-pc-windows-msvc/release/ov.exe openviking/bin/ else cp target/release/ov openviking/bin/ chmod +x openviking/bin/ov fi - name: Clean workspace (force ignore dirty) shell: bash run: | git reset --hard HEAD git clean -fd rm -rf openviking/_version.py openviking.egg-info # Ignore uv.lock changes to avoid dirty state in setuptools_scm git update-index --assume-unchanged uv.lock || true - name: Debug Git and SCM shell: bash run: | echo "=== Git Describe ===" git describe --tags --long --dirty --always echo "=== Setuptools SCM Version ===" uv run --frozen python -m setuptools_scm echo "=== Git Status (Ignored included) ===" git status --ignored echo "=== Check openviking/_version.py ===" if [ -f openviking/_version.py ]; then cat openviking/_version.py; else echo "Not found"; fi - name: Build package (Wheel Only) run: uv run --frozen python -m build --wheel - name: Store the distribution packages uses: actions/upload-artifact@v7 with: name: python-package-distributions-${{ matrix.os == 'macos-14' && 'macos-arm64' || matrix.os == 'macos-15-intel' && 'macos-x86_64' || matrix.os == 'windows-latest' && 'windows-x86_64' || matrix.os }}-${{ matrix.python-version }} path: dist/ - name: Display built wheel version shell: bash continue-on-error: true run: | VERSION=$(ls dist/*.whl | head -n 1 | xargs basename | cut -d- -f2) echo "Build Version: $VERSION" echo "::notice::Build Wheel Version (${{ matrix.os == 'macos-14' && 'macOS arm64 (macos-14)' || matrix.os == 'macos-15-intel' && 'macOS x86_64 (macos-15-intel)' || matrix.os == 'windows-latest' && 'Windows x86_64 (windows-latest)' || matrix.os }} py${{ matrix.python-version }}): $VERSION" verify-macos-14-wheel-on-macos-15: name: Verify macOS 14 arm64 wheel installs on macOS 15 needs: [build-other] if: >- inputs.build_wheels && contains(inputs.os_json, 'macos-14') && contains(inputs.python_json, '3.12') runs-on: macos-15 steps: - name: Set up Python 3.12 uses: actions/setup-python@v6 with: python-version: '3.12' - name: Download macOS arm64 wheel artifact uses: actions/download-artifact@v8 with: name: python-package-distributions-macos-arm64-3.12 path: dist/ - name: Install built wheel shell: bash run: | python -m pip install --upgrade pip python -m pip install dist/*.whl - name: Smoke test native extension loading shell: bash run: | python - <<'PY' import importlib import importlib.util import openviking.storage.vectordb.engine as engine native_spec = importlib.util.find_spec("openviking.storage.vectordb.engine._native") if native_spec is None or native_spec.origin is None: raise SystemExit("openviking storage native backend extension was not installed") native_module = importlib.import_module("openviking.storage.vectordb.engine._native") if engine.ENGINE_VARIANT != "native": raise SystemExit( f"expected native engine variant on macOS arm64 wheel, got {engine.ENGINE_VARIANT}" ) print(f"Loaded runtime engine variant {engine.ENGINE_VARIANT}") print(f"Loaded native extension from {native_spec.origin}") print(f"Imported backend module {native_module.__name__}") PY ================================================ FILE: .github/workflows/_codeql.yml ================================================ name: 14. _CodeQL Scan on: workflow_call: workflow_dispatch: jobs: analyze: name: Analyze runs-on: ubuntu-24.04 permissions: actions: read contents: read security-events: write strategy: fail-fast: false matrix: language: [ 'python', 'cpp' ] steps: - name: Checkout repository uses: actions/checkout@v6 with: submodules: recursive - name: Set up Python uses: actions/setup-python@v6 with: python-version: '3.11' - name: Set up Go uses: actions/setup-go@v6 with: go-version: 'stable' - name: Install uv uses: astral-sh/setup-uv@v7 with: enable-cache: true - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y cmake build-essential - name: Install dependencies run: | uv sync --frozen uv pip install setuptools pybind11 cmake wheel - name: Initialize CodeQL uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} queries: security-and-quality - name: Build extensions if: matrix.language == 'cpp' run: uv run python setup.py build_ext --inplace - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v4 with: category: "/language:${{ matrix.language }}" ================================================ FILE: .github/workflows/_lint.yml ================================================ name: 11. _Lint Checks on: workflow_call: workflow_dispatch: jobs: lint: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 with: fetch-depth: 0 # Required to calculate the git diff - name: Set up Python uses: actions/setup-python@v6 with: python-version: '3.11' - name: Set up Go uses: actions/setup-go@v6 with: go-version: 'stable' - name: Install uv uses: astral-sh/setup-uv@v7 with: enable-cache: true - name: Install dependencies run: uv sync --frozen --extra dev # --- NEW STEP: Get the list of changed files --- - name: Get changed files id: files run: | # Compare the PR head to the base branch echo "changed_files=$(git diff --name-only --diff-filter=d origin/${{ github.base_ref }} HEAD | grep '\.py$' | xargs)" >> $GITHUB_OUTPUT # --- UPDATED STEPS: Use the file list --- - name: List files run: echo "The changed files are ${{ steps.files.outputs.changed_files }}" - name: Format with ruff (Changed files only) if: steps.files.outputs.changed_files != '' run: uv run ruff format --check ${{ steps.files.outputs.changed_files }} - name: Lint with ruff (Changed files only) if: steps.files.outputs.changed_files != '' run: uv run ruff check ${{ steps.files.outputs.changed_files }} - name: Type check with mypy (Changed files only) if: steps.files.outputs.changed_files != '' # Note: Running mypy on specific files may miss cross-file type errors run: uv run mypy ${{ steps.files.outputs.changed_files }} continue-on-error: true ================================================ FILE: .github/workflows/_publish.yml ================================================ name: 16. _Publish Distribution on: workflow_call: inputs: target: description: 'Publish Target' required: false type: string default: 'pypi' # Callers (like release.yml) typically want PyPI build_run_id: description: 'Build Workflow Run ID (Optional, defaults to current run)' required: false type: string default: '' workflow_dispatch: inputs: target: description: 'Select where to publish' required: true type: choice default: 'testpypi' options: - testpypi - pypi - both build_run_id: description: 'Build Workflow Run ID (Required for manual dispatch, find it in the Build run URL)' required: true type: string jobs: permission-check: name: Check write permission runs-on: ubuntu-24.04 permissions: contents: read outputs: allowed: ${{ steps.check.outputs.allowed }} steps: - name: Verify actor permission id: check uses: actions/github-script@v8 with: script: | // Only check permission for manual dispatch if (context.eventName !== 'workflow_dispatch') { core.setOutput('allowed', 'true'); return; } const { owner, repo } = context.repo; const actor = context.actor; const { data } = await github.rest.repos.getCollaboratorPermissionLevel({ owner, repo, username: actor, }); const perm = data.permission; core.info(`Actor ${actor} permission: ${perm}`); const allowed = ['admin', 'maintain', 'write'].includes(perm); core.setOutput('allowed', allowed ? 'true' : 'false'); if (!allowed) { core.setFailed(`User ${actor} does not have write permission`); } publish-testpypi: name: Publish to TestPyPI needs: [permission-check] if: >- needs.permission-check.outputs.allowed == 'true' && (inputs.target == 'testpypi' || inputs.target == 'both') runs-on: ubuntu-24.04 environment: name: testpypi url: https://test.pypi.org/p/openviking permissions: id-token: write actions: read # Required for downloading artifacts from other runs steps: - name: Download all the dists (Same Run) if: inputs.build_run_id == '' uses: actions/download-artifact@v8 with: pattern: python-package-distributions-* path: dist/ merge-multiple: true - name: Download all the dists (Cross Run) if: inputs.build_run_id != '' uses: actions/download-artifact@v8 with: run-id: ${{ inputs.build_run_id }} github-token: ${{ secrets.GITHUB_TOKEN }} pattern: python-package-distributions-* path: dist/ merge-multiple: true - name: Publish distribution to TestPyPI uses: pypa/gh-action-pypi-publish@release/v1 with: repository-url: https://test.pypi.org/legacy/ skip-existing: true verbose: true - name: Display published version run: | # Get version from the first wheel file found VERSION=$(ls dist/*.whl | head -n 1 | xargs basename | cut -d- -f2) echo "Published to TestPyPI (or already existed) with version: $VERSION" echo "::notice::Published to TestPyPI (or already existed) with version: $VERSION" publish-pypi: name: Publish to PyPI needs: [permission-check] if: >- needs.permission-check.outputs.allowed == 'true' && (inputs.target == 'pypi' || inputs.target == 'both') runs-on: ubuntu-24.04 environment: name: pypi url: https://pypi.org/p/openviking permissions: id-token: write actions: read # Required for downloading artifacts from other runs steps: - name: Download all the dists (Same Run) if: inputs.build_run_id == '' uses: actions/download-artifact@v8 with: pattern: python-package-distributions-* path: dist/ merge-multiple: true - name: Download all the dists (Cross Run) if: inputs.build_run_id != '' uses: actions/download-artifact@v8 with: run-id: ${{ inputs.build_run_id }} github-token: ${{ secrets.GITHUB_TOKEN }} pattern: python-package-distributions-* path: dist/ merge-multiple: true - name: Publish distribution to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: skip-existing: true verbose: true - name: Display published version run: | # Get version from the first wheel file found VERSION=$(ls dist/*.whl | head -n 1 | xargs basename | cut -d- -f2) echo "Published to PyPI (or already existed) with version: $VERSION" echo "::notice::Published to PyPI (or already existed) with version: $VERSION" ================================================ FILE: .github/workflows/_test_full.yml ================================================ name: 13. _Test Suite (Full) on: workflow_call: inputs: os_json: description: 'JSON string of OS to run on' required: false type: string default: '["ubuntu-24.04", "macos-14", "windows-latest"]' python_json: description: 'JSON string of Python versions' required: false type: string default: '["3.10", "3.11", "3.12", "3.13"]' workflow_dispatch: inputs: os_json: description: 'JSON string of OS to run on' required: false default: '["ubuntu-24.04", "macos-14", "windows-latest"]' python_json: description: 'JSON string of Python versions' required: false default: '["3.10", "3.11", "3.12", "3.13"]' jobs: test: name: Full Test (${{ matrix.os }}, ${{ matrix.python-version }}) runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: ${{ fromJson(inputs.os_json || '["ubuntu-24.04", "macos-14", "windows-latest"]') }} python-version: ${{ fromJson(inputs.python_json || '["3.10", "3.11", "3.12", "3.13"]') }} steps: - uses: actions/checkout@v6 with: submodules: recursive - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Set up Go uses: actions/setup-go@v6 with: go-version: '1.25.1' - name: Install uv uses: astral-sh/setup-uv@v7 with: enable-cache: true - name: Install system dependencies (Ubuntu) if: runner.os == 'Linux' run: | sudo apt-get update sudo apt-get install -y cmake build-essential - name: Install system dependencies (macOS) if: runner.os == 'macOS' run: brew install cmake - name: Install system dependencies (Windows) if: runner.os == 'Windows' run: | choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' choco install mingw - name: Add MinGW to PATH (Windows) if: runner.os == 'Windows' run: echo "C:\mingw64\bin" >> $env:GITHUB_PATH - name: Install Python dependencies run: uv sync --frozen --extra test - name: Install build dependencies run: uv pip install setuptools pybind11 cmake wheel - name: Build C++ extensions run: uv run python setup.py build_ext --inplace # TODO: Once unit tests are fixed, switch this back to running the full test suite # run: uv run pytest tests/ -v --cov=openviking --cov-report=term - name: Run Lite Integration Test (Temporary Replacement) shell: bash run: | export PYTHONPATH=$PYTHONPATH:$(pwd) uv run python tests/integration/test_quick_start_lite.py ================================================ FILE: .github/workflows/_test_lite.yml ================================================ name: 12. _Test Suite (Lite) on: workflow_call: inputs: os_json: description: 'JSON string of OS to run on' required: false type: string default: '["ubuntu-24.04"]' python_json: description: 'JSON string of Python versions' required: false type: string default: '["3.10"]' workflow_dispatch: inputs: os_json: description: 'JSON string of OS to run on' required: false default: '["ubuntu-24.04"]' python_json: description: 'JSON string of Python versions' required: false default: '["3.10"]' jobs: test-lite: name: Lite Test (${{ matrix.os }}, ${{ matrix.python-version }}) runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: ${{ fromJson(inputs.os_json) }} python-version: ${{ fromJson(inputs.python_json) }} steps: - uses: actions/checkout@v6 with: submodules: recursive - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} - name: Set up Go uses: actions/setup-go@v6 with: go-version: '1.25.1' - name: Install uv uses: astral-sh/setup-uv@v7 with: enable-cache: true - name: Install system dependencies (Ubuntu) if: runner.os == 'Linux' run: | sudo apt-get update sudo apt-get install -y cmake build-essential - name: Install system dependencies (macOS) if: runner.os == 'macOS' run: brew install cmake - name: Install system dependencies (Windows) if: runner.os == 'Windows' run: | choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' choco install mingw - name: Add MinGW to PATH (Windows) if: runner.os == 'Windows' run: echo "C:\mingw64\bin" >> $env:GITHUB_PATH - name: Install Python dependencies run: uv sync --frozen --extra test - name: Install build dependencies run: uv pip install setuptools pybind11 cmake wheel - name: Build C++ extensions run: uv run python setup.py build_ext --inplace - name: Run Lite Integration Test (Quick Start) shell: bash run: | export PYTHONPATH=$PYTHONPATH:$(pwd) # Using bash shell ensures this works across platforms (including Windows via Git Bash) uv run python tests/integration/test_quick_start_lite.py ================================================ FILE: .github/workflows/build-docker-image.yml ================================================ name: Build and Push Docker Image on: workflow_dispatch: inputs: version: description: "application version for OpenViking" required: true type: string push: tags: [ "v*.*.*" ] env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} jobs: build-and-push-image: runs-on: ubuntu-24.04 permissions: contents: read packages: write attestations: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v6 with: submodules: recursive - name: Log in to the Container registry uses: docker/login-action@v4 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v6 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} - name: Set up QEMU uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Build and push Docker image id: push uses: docker/build-push-action@v7 with: context: . platforms: linux/amd64,linux/arm64 push: ${{ github.ref_type == 'tag' || github.event_name == 'workflow_dispatch' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-args: | # fallback to 0.0.0 if no version is provided OPENVIKING_VERSION=${{ (github.event_name == 'workflow_dispatch' && github.event.inputs.version) || (github.ref_type == 'tag' && github.ref_name) || '0.0.0' }} ================================================ FILE: .github/workflows/ci.yml ================================================ name: 02. Main Branch Checks on: workflow_dispatch: push: branches: [ main ] paths-ignore: - 'docs/**' - '**.md' - 'LICENSE' - 'CONTRIBUTING.md' - '**.png' - '**.jpg' - '**.jpeg' - '**.gif' - '**.svg' - '.gitignore' - '.editorconfig' permissions: actions: read contents: read security-events: write jobs: test-full: uses: ./.github/workflows/_test_full.yml security-scan: uses: ./.github/workflows/_codeql.yml ================================================ FILE: .github/workflows/pr-review.yml ================================================ name: PR Review (Qodo) on: pull_request_target: types: [opened, synchronize, reopened, ready_for_review] issue_comment: jobs: pr_review: if: ${{ github.event.sender.type != 'Bot' }} runs-on: ubuntu-24.04 permissions: issues: write pull-requests: write contents: write steps: # Checkout required so PR-Agent reads .pr_agent.toml from repo root. # All review rules, custom labels, ignore patterns, and tool configs # live in .pr_agent.toml — no inline extra_instructions needed here. - name: Checkout uses: actions/checkout@v4 - name: PR Agent uses: qodo-ai/pr-agent@main env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} OPENAI_KEY: ${{ secrets.DOUBAO_API_KEY }} OPENAI.API_BASE: "https://ark.cn-beijing.volces.com/api/coding/v3" config.model: "ark-code-latest" github_action_config.auto_review: "true" github_action_config.auto_describe: "true" github_action_config.auto_improve: "true" ================================================ FILE: .github/workflows/pr.yml ================================================ name: 01. Pull Request Checks on: workflow_dispatch: pull_request: branches: [ main, develop ] paths-ignore: - 'docs/**' - '**.md' - 'LICENSE' - 'CONTRIBUTING.md' - '**.png' - '**.jpg' - '**.jpeg' - '**.gif' - '**.svg' - '.gitignore' - '.editorconfig' jobs: lint: uses: ./.github/workflows/_lint.yml test-lite: uses: ./.github/workflows/_test_lite.yml with: os_json: '["ubuntu-24.04"]' python_json: '["3.10"]' check-deps: runs-on: ubuntu-24.04 outputs: deps_changed: ${{ steps.check.outputs.deps_changed }} steps: - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Check for dependency changes id: check run: | git fetch origin ${{ github.base_ref }} # Define grep pattern for dependency files PATTERN="pyproject\.toml|setup\.py|uv\.lock|src/CMakeLists\.txt|third_party/|\.github/workflows/_build\.yml" # Check for changes CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }} HEAD | grep -E "$PATTERN" || true) if [ -n "$CHANGED_FILES" ]; then echo "Dependency changes detected:" echo "$CHANGED_FILES" echo "deps_changed=true" >> $GITHUB_OUTPUT else echo "No dependency changes detected." echo "deps_changed=false" >> $GITHUB_OUTPUT fi build: needs: check-deps if: ${{ needs.check-deps.outputs.deps_changed == 'true' }} uses: ./.github/workflows/_build.yml ================================================ FILE: .github/workflows/release-vikingbot-first.yml ================================================ name: First Release to PyPI on: workflow_dispatch: # 手动触发 jobs: release: runs-on: ubuntu-24.04 defaults: run: working-directory: bot steps: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: python-version: '3.11' - name: Install build dependencies run: pip install build - name: Build package run: python -m build - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: password: ${{ secrets.VIKINGBOT_PYPI_API_TOKEN }} packages-dir: bot/dist/ ================================================ FILE: .github/workflows/release.yml ================================================ name: 03. Release on: release: types: [published] workflow_dispatch: inputs: target: description: 'Select where to publish' required: true type: choice default: 'testpypi' options: - none - testpypi - pypi - both build_sdist: description: 'Whether to build source distribution' required: false type: boolean default: true build_wheels: description: 'Whether to build wheel distribution' required: false type: boolean default: true os_json: description: 'JSON string of runner labels to build on (Manual only; ubuntu-24.04=x86_64, ubuntu-24.04-arm=aarch64, macos-14=arm64, macos-15-intel=x86_64, windows-latest=x86_64)' required: false type: string default: '["ubuntu-24.04", "ubuntu-24.04-arm", "macos-14", "macos-15-intel", "windows-latest"]' python_json: description: 'JSON string of Python versions (Manual only)' required: false type: string default: '["3.10", "3.11", "3.12", "3.13", "3.14"]' permissions: contents: write id-token: write actions: read jobs: build: # Skip this workflow for CLI releases (tags starting with cli-) if: "!startsWith(github.event.release.tag_name, 'cli-')" uses: ./.github/workflows/_build.yml with: os_json: ${{ inputs.os_json || '["ubuntu-24.04", "ubuntu-24.04-arm", "macos-14", "macos-15-intel", "windows-latest"]' }} python_json: ${{ inputs.python_json || '["3.10", "3.11", "3.12", "3.13", "3.14"]' }} build_sdist: ${{ github.event_name == 'release' || inputs.build_sdist != false }} build_wheels: ${{ github.event_name == 'release' || inputs.build_wheels != false }} permission-check: name: Check write permission needs: [build] runs-on: ubuntu-24.04 permissions: contents: read outputs: allowed: ${{ steps.check.outputs.allowed }} steps: - name: Verify actor permission id: check uses: actions/github-script@v8 with: script: | // Only check permission for manual dispatch if (context.eventName !== 'workflow_dispatch') { core.setOutput('allowed', 'true'); return; } const { owner, repo } = context.repo; const actor = context.actor; const { data } = await github.rest.repos.getCollaboratorPermissionLevel({ owner, repo, username: actor, }); const perm = data.permission; core.info(`Actor ${actor} permission: ${perm}`); const allowed = ['admin', 'maintain', 'write'].includes(perm); core.setOutput('allowed', allowed ? 'true' : 'false'); if (!allowed) { core.setFailed(`User ${actor} does not have write permission`); } publish-testpypi: name: Publish to TestPyPI needs: [build, permission-check] if: >- needs.permission-check.outputs.allowed == 'true' && (inputs.target == 'testpypi' || inputs.target == 'both') runs-on: ubuntu-24.04 environment: name: testpypi url: https://test.pypi.org/p/openviking permissions: id-token: write actions: read steps: - name: Download all the dists (Same Run) uses: actions/download-artifact@v8 with: pattern: python-package-distributions-* path: dist/ merge-multiple: true - name: Publish distribution to TestPyPI uses: pypa/gh-action-pypi-publish@release/v1 with: repository-url: https://test.pypi.org/legacy/ skip-existing: true verbose: true - name: Display published version run: | # Get version from the first wheel file found VERSION=$(ls dist/*.whl | head -n 1 | xargs basename | cut -d- -f2) echo "Published to TestPyPI (or already existed) with version: $VERSION" echo "::notice::Published to TestPyPI (or already existed) with version: $VERSION" publish-pypi: name: Publish to PyPI needs: [build, permission-check] if: >- needs.permission-check.outputs.allowed == 'true' && (github.event_name == 'release' || inputs.target == 'pypi' || inputs.target == 'both') runs-on: ubuntu-24.04 environment: name: pypi url: https://pypi.org/p/openviking permissions: id-token: write actions: read steps: - name: Download all the dists (Same Run) uses: actions/download-artifact@v8 with: pattern: python-package-distributions-* path: dist/ merge-multiple: true - name: Publish distribution to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: skip-existing: true verbose: true - name: Display published version run: | # Get version from the first wheel file found VERSION=$(ls dist/*.whl | head -n 1 | xargs basename | cut -d- -f2) echo "Published to PyPI (or already existed) with version: $VERSION" echo "::notice::Published to PyPI (or already existed) with version: $VERSION" docker: name: Build and Push Docker Image needs: [build, permission-check] if: >- needs.permission-check.outputs.allowed == 'true' && github.event_name == 'release' runs-on: ubuntu-24.04 permissions: contents: read packages: write attestations: write id-token: write steps: - name: Checkout repository uses: actions/checkout@v6 with: submodules: recursive - name: Log in to the Container registry uses: docker/login-action@v4 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata (tags, labels) for Docker id: meta uses: docker/metadata-action@v6 with: images: ghcr.io/${{ github.repository }} - name: Set up QEMU uses: docker/setup-qemu-action@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v4 - name: Build and push Docker image uses: docker/build-push-action@v7 with: context: . platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} build-args: | OPENVIKING_VERSION=${{ github.event.release.tag_name }} ================================================ FILE: .github/workflows/rust-cli.yml ================================================ name: Rust CLI Build on: workflow_call: push: branches: [ main, feat/rust-cli ] paths: - 'crates/**' - 'Cargo.toml' - '.github/workflows/rust-cli.yml' tags: - 'cli@*' # Trigger release on tags starting with cli@ pull_request: branches: [ main ] paths: - 'crates/**' - 'Cargo.toml' - '.github/workflows/rust-cli.yml' jobs: build: name: Build ${{ matrix.target }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: include: - os: ubuntu-24.04 target: x86_64-unknown-linux-gnu artifact_name: ov-linux-x86_64 - os: ubuntu-24.04 target: aarch64-unknown-linux-gnu artifact_name: ov-linux-aarch64 - os: macos-15-intel target: x86_64-apple-darwin artifact_name: ov-macos-x86_64 - os: macos-14 target: aarch64-apple-darwin artifact_name: ov-macos-aarch64 - os: windows-latest target: x86_64-pc-windows-msvc artifact_name: ov-windows-x86_64.exe steps: - uses: actions/checkout@v6 - name: Install Rust uses: dtolnay/rust-toolchain@v1 with: toolchain: stable targets: ${{ matrix.target }} - name: Install system dependencies (Linux) if: runner.os == 'Linux' run: | sudo apt-get update sudo apt-get install -y pkg-config libssl-dev - name: Install cross-compilation tools (Linux ARM64) if: matrix.target == 'aarch64-unknown-linux-gnu' run: | sudo apt-get install -y gcc-aarch64-linux-gnu g++-aarch64-linux-gnu echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> $GITHUB_ENV echo "CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc" >> $GITHUB_ENV echo "CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++" >> $GITHUB_ENV - name: Cache Cargo registry and index uses: actions/cache@v5 with: path: | ~/.cargo/registry/index ~/.cargo/registry/cache ~/.cargo/git/db key: ${{ runner.os }}-cargo-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} restore-keys: | ${{ runner.os }}-cargo-${{ matrix.target }}- ${{ runner.os }}-cargo- - name: Cache build artifacts uses: actions/cache@v5 with: path: target key: ${{ runner.os }}-target-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}-${{ hashFiles('crates/**/*.rs') }} restore-keys: | ${{ runner.os }}-target-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }}- ${{ runner.os }}-target-${{ matrix.target }}- - name: Build CLI run: cargo build --release --target ${{ matrix.target }} -p ov_cli - name: Create compressed artifacts shell: bash run: | mkdir -p artifacts cd target/${{ matrix.target }}/release if [[ "${{ matrix.os }}" == "windows-latest" ]]; then # Windows: create zip 7z a ../../../artifacts/${{ matrix.artifact_name }}.zip ov.exe cd ../../../artifacts # Use PowerShell to get hash in correct format powershell -Command "(Get-FileHash -Algorithm SHA256 '${{ matrix.artifact_name }}.zip').Hash.ToLower() + ' ${{ matrix.artifact_name }}.zip'" > ${{ matrix.artifact_name }}.zip.sha256 else # Unix: create tar.gz tar czf ../../../artifacts/${{ matrix.artifact_name }}.tar.gz ov cd ../../../artifacts # shasum format: shasum -a 256 ${{ matrix.artifact_name }}.tar.gz > ${{ matrix.artifact_name }}.tar.gz.sha256 fi - name: Verify checksum format shell: bash run: | echo "Contents of checksum file:" cat artifacts/*.sha256 echo "" echo "Verifying checksum locally:" cd artifacts if [[ "${{ matrix.os }}" == "windows-latest" ]]; then sha256sum -c *.sha256 || shasum -a 256 -c *.sha256 || echo "Checksum verification skipped on Windows" else shasum -a 256 -c *.sha256 fi - name: Upload artifacts uses: actions/upload-artifact@v7 with: name: ${{ matrix.artifact_name }} path: artifacts/* release: name: Create GitHub Release runs-on: ubuntu-24.04 needs: build if: startsWith(github.ref, 'refs/tags/cli@') permissions: contents: write steps: - name: Checkout code uses: actions/checkout@v6 - name: Get version from tag id: get_version run: echo "version=${GITHUB_REF#refs/tags/cli@}" >> $GITHUB_OUTPUT - name: Download all artifacts uses: actions/download-artifact@v8 with: path: artifacts - name: Display artifact structure run: ls -R artifacts/ - name: Create GitHub Release uses: softprops/action-gh-release@v2 with: name: CLI v${{ steps.get_version.outputs.version }} body: | # OpenViking CLI v${{ steps.get_version.outputs.version }} ## Installation ### Quick Install (macOS/Linux) ```bash curl -fsSL https://raw.githubusercontent.com/${{ github.repository }}/refs/tags/cli@${{ steps.get_version.outputs.version }}/crates/ov_cli/install.sh | bash ``` ### Manual Installation Download the appropriate binary for your platform below, extract it, and add it to your PATH. The CLI command is simply `ov`: ```bash # After extraction chmod +x ov # Unix only mv ov /usr/local/bin/ # or any directory in your PATH # Verify installation ov --version ``` ### Checksums SHA256 checksums are provided for each binary for verification. ## Changes See the [commit history](https://github.com/${{ github.repository }}/commits/cli@${{ steps.get_version.outputs.version }}) for details. files: | artifacts/**/*.tar.gz artifacts/**/*.zip artifacts/**/*.sha256 draft: false prerelease: ${{ contains(steps.get_version.outputs.version, 'alpha') || contains(steps.get_version.outputs.version, 'beta') || contains(steps.get_version.outputs.version, 'rc') }} env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ================================================ FILE: .github/workflows/schedule.yml ================================================ name: 04. Weekly Security Scan on: schedule: - cron: '0 0 * * 0' # Run at 00:00 on Sunday permissions: actions: read contents: read security-events: write jobs: security-scan: uses: ./.github/workflows/_codeql.yml ================================================ FILE: .gitignore ================================================ # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ share/python-wheels/ *.egg-info/ .installed.cfg *.egg MANIFEST openviking.egg-info/ data/ # Rust target/ **/*.rs.bk *.pdb # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Unit test / coverage reports htmlcov/ .tox/ .nox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover *.py,cover .hypothesis/ .pytest_cache/ .ruff_cache/ cover/ test_data/ test_data_sync/ # Virtual environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # IDE .vscode/ .idea/ *.swp *.swo *~ # macOS .DS_Store .AppleDouble .LSOverride # Thumbnails ._* # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd .Spotlight-V100 .TemporaryItems .Trashes .VolumeIcon.icns .com.apple.timemachine.donotpresent # Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk # OpenViking specific /data/* /demo_data/* /benchmark_data/* .claude .openviking *.code-workspace # AI Coding CLAUDE.md *.so AGENTS.md # Git worktrees .worktrees/ # Logs *.log logs/ # Temporary files *.tmp *.temp .tmp/ ov.conf # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Environments .env.local .env.development.local .env.test.local .env.production.local # mkdocs documentation /site docs/superpowers/ # mypy .mypy_cache/ .dmypy.json dmypy.json # Pyre type checker .pyre/ # pytype static type analyzer .pytype/ # Cython debug symbols cython_debug/ openviking/bin/ third_party/agfs/bin/ test_scripts/ examples/data/ openviking/_version.py specs/ .trae/ ================================================ FILE: .pr_agent.toml ================================================ # ============================================================================= # Qodo PR-Agent Configuration for OpenViking # ============================================================================= # OpenViking: polyglot (Python/TypeScript/Rust) context database for AI agents. # By ByteDance/Volcengine — Apache-2.0 licensed. # # Rules derived from: real bug history (PRs #505, #728, #749, #740/#745), # codebase conventions, CI pipeline (ruff, mypy, pytest), and Qodo best # practices (Rule System blog, 2.2 PR History, raw configuration.toml). # # Principle: edit only what you need (Qodo Tip #1). Every override here has # a documented reason tied to OpenViking's specific patterns. # ============================================================================= # --------------------------------------------------------------------------- # Global Config # --------------------------------------------------------------------------- [config] output_relevant_configurations = false # Use high reasoning for this complex polyglot codebase with subtle async/ # concurrency bugs. Worth the extra latency for quality. reasoning_effort = "high" # More context around hunks helps the model understand memory pipeline flows # that often span multiple functions. patch_extra_lines_before = 8 patch_extra_lines_after = 3 allow_dynamic_context = true # Auto-detect language from PR content (Chinese contributors are common) response_language = "en-US" # Custom labels for OpenViking-specific PR categorization enable_custom_labels = true # --------------------------------------------------------------------------- # Ignore: skip generated/vendored/lock files from analysis # Reduces noise and token waste on files humans don't review. # --------------------------------------------------------------------------- [ignore] glob = [ # Lock files (auto-generated, not human-authored) 'uv.lock', '*.lock', 'package-lock.json', # Third-party vendored code (not our responsibility) 'third_party/**', # Rust build artifacts 'target/**', # Test data fixtures (binary/large JSON blobs) 'db_test_*/**', 'test_data/**', 'test_data_sync/**', # Worktree scratch spaces '.worktrees/**', # Build support (C++ profiles, not core logic) 'build_support/**', ] # --------------------------------------------------------------------------- # Auto-triggers on PR open # --------------------------------------------------------------------------- [github_app] pr_commands = [ "/describe", "/review", "/improve --pr_code_suggestions.commitable_code_suggestions=false", ] # --------------------------------------------------------------------------- # Custom Labels: OpenViking-specific PR categorization # Each description is a conditional statement (Qodo best practice) so the # model knows exactly when to apply it. # --------------------------------------------------------------------------- [custom_labels."memory-pipeline"] description = "Apply when the PR modifies memory extraction, deduplication, archival, or any code in openviking/session/ that touches MemoryCategory, SessionCompressor, MemoryDeduplicator, or MemoryExtractor." [custom_labels."async-change"] description = "Apply when the PR modifies async/await patterns, changes commit() to commit_async(), adds asyncio.gather/TaskGroup usage, or modifies any coroutine in the session or storage layer." [custom_labels."embedding-vectorization"] description = "Apply when the PR modifies embedding models, vectorization logic, chunked vectorization, or VLM provider integrations in openviking/embedding/ or openviking/vlm/." [custom_labels."plugin-bot"] description = "Apply when the PR modifies TypeScript code in bot/ or examples/openclaw-plugin/, including hook handlers, process management, or client initialization." [custom_labels."api-breaking"] description = "Apply when the PR removes, renames, or changes the type of any public API parameter, REST endpoint, SDK method, or configuration key that external consumers depend on." [custom_labels."multi-tenant"] description = "Apply when the PR modifies authentication, authorization, account/user routing, root key handling, or RequestContext identity resolution." [custom_labels."retrieval"] description = "Apply when the PR modifies the retrieval pipeline: find, rerank, semantic search, or context level (L0/L1/L2) scoring logic." [custom_labels."rust-cli"] description = "Apply when the PR modifies Rust source files (src/*.rs) or Cargo.toml for the CLI tool." # --------------------------------------------------------------------------- # Review Tool # --------------------------------------------------------------------------- [pr_reviewer] persistent_comment = true final_update_message = true # Increased from default 3 → 8 because OpenViking PRs often span multiple # subsystems (Python core + TypeScript bot + config) with cross-cutting concerns. num_max_findings = 8 enable_intro_text = true enable_help_text = false publish_output_no_suggestions = true # --- Feature toggles (overrides from defaults) --- require_score_review = true # Score each PR 1-100 (disabled by default, useful for quality tracking) require_tests_review = true # Check if tests are present (default: true) require_estimate_effort_to_review = true # Effort estimate label (default: true) require_can_be_split_review = true # Flag large PRs that should be split (default: false → enabled) require_security_review = true # Dedicated security audit section (default: true) require_todo_scan = true # Surface TODO/FIXME/HACK in changed code (default: false → enabled) require_ticket_analysis_review = true # Check ticket compliance if linked # --- Labels --- enable_review_labels_security = true enable_review_labels_effort = true extra_instructions = """\ You are reviewing OpenViking — an agent-native context database. Stack: Python 3.10+ core (FastAPI, pydantic, httpx, loguru), TypeScript bot (Vikingbot/OpenClaw plugin), Rust CLI, C++ extensions (AGFS). ## Severity Classification (exactly ONE per finding) [Critical] — Blocks release. Security vulnerability, data loss/corruption, crash in production path, resource leak without cleanup, auth bypass. [Bug] — Must fix before merge. Logic error, behavioral regression, API contract violation, race condition, missing await on coroutine, silent exception swallowing. [Perf] — Performance regression. O(n²)+ algorithmic complexity, unbounded collection growth, N+1 queries against VikingDB, redundant embedding/VLM API calls, unnecessary large object copies in hot paths. [Suggestion] — Recommended improvement. Missing tests, dead code, naming inconsistency, poor observability (missing telemetry/logging), unclear intent, unrelated changes in PR. ## Rules (structured as: WHEN condition → THEN check → BECAUSE rationale) ### PYTHON CORE (openviking/, openviking_cli/) R1. ASYNC DISCIPLINE WHEN code is inside an async function or coroutine THEN verify all I/O calls use async variants (commit_async not commit, httpx.AsyncClient not requests, async for on streams) BECAUSE blocking calls in async context starve the event loop. Real bug: PR #728 replaced blocking commit() with commit_async(). Also check: missing `await` on coroutine calls (silent bug — returns coroutine object instead of result). R2. MEMORY PIPELINE COMPLETENESS WHEN code touches MemoryCategory, MemoryExtractor, MemoryDeduplicator, SessionCompressor, or MemoryArchiver THEN verify all 6 categories are handled: PREFERENCES, ENTITIES, PATTERNS, EVENTS, TOOLS, SKILLS. Check that match/if-elif chains on DedupDecision (KEEP/MERGE/DELETE/SKIP) are exhaustive. BECAUSE partial handling silently drops memories. The 6-category model is a core invariant of the extraction pipeline. R3. QUADRATIC REPROCESSING GUARD WHEN code enqueues items (SemanticMsg, embedding tasks) inside a loop that also processes the queue, or when a callback re-enqueues work THEN flag as [Perf] or [Bug] — this pattern causes O(n²) reprocessing. BECAUSE PR #505 fixed exactly this: misdirected SemanticMsg enqueue inside a processing loop caused quadratic growth. R4. VLM/EMBEDDING API RESILIENCE WHEN code calls VLM providers (OpenAI, Doubao/Ark, Gemini) or embedding APIs THEN verify: (a) timeout is set (ai_timeout or explicit), (b) retry/fallback exists for transient failures, (c) streaming responses handle partial failure gracefully, (d) JSON output uses json-repair not raw json.loads. BECAUSE PR #740 was reverted (#745) due to streaming response issues, then re-landed in #756 with proper handling. This is a repeat-risk area. R5. TYPE SAFETY WHEN new Python code is added or modified THEN check: no bare `type: ignore` (must have explanation comment), consistent Optional[X] vs X|None style within each file, proper use of TYPE_CHECKING imports for circular dependency avoidance. BECAUSE CI enforces ruff + mypy on changed files. Suppressions without rationale hide real type errors. R6. LICENSE HEADERS WHEN a new .py file is created in openviking/ or openviking_cli/ THEN it MUST contain at the top: # Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. # SPDX-License-Identifier: Apache-2.0 BECAUSE Apache-2.0 compliance requires headers on all source files. Every existing file in these directories follows this convention. R7. ERROR HANDLING WHEN code uses try/except THEN verify: no bare `except:` or `except Exception:` without logging (loguru) or re-raising. Narrow exceptions to specific types where possible. BECAUSE PR #148f6e3 fixed overly broad `except Exception` to specific (ImportError, ModuleNotFoundError, AttributeError). Broad catches hide real bugs. ### TYPESCRIPT / BOT (bot/, examples/openclaw-plugin/) R8. PLUGIN HOOK TIMEOUT WHEN code registers or modifies a hook handler (before_prompt_build, after_prompt_build, etc.) or calls getClient() THEN verify the call has timeout protection (Promise.race with timeout, AbortController, or equivalent). BECAUSE PR #749 added timeout protection to getClient() after discovering hooks could hang indefinitely, blocking the entire bot. R9. PROCESS LIFECYCLE WHEN code spawns child processes or manages bot lifecycle THEN verify: SIGTERM/SIGINT handlers exist, stdio streams are properly closed, and cleanup runs in all exit paths (including uncaught exceptions). BECAUSE the bot uses process-manager.ts for lifecycle; leaked processes or file descriptors degrade the host system. ### CROSS-CUTTING R10. API BACKWARD COMPATIBILITY WHEN a PR modifies public interfaces (FastAPI endpoints, SDK client params, RequestContext fields, config keys in ov.conf) THEN verify: existing params are not removed or renamed (only deprecated), new params have defaults, multi-tenant changes preserve single-tenant behavior as the default path. BECAUSE PR #767 added account/user params — these must be optional to avoid breaking existing single-tenant deployments. R11. CONCURRENCY SAFETY WHEN code modifies shared mutable state (dicts, lists, sets) in async functions, or uses _pending_semantic_changes or similar shared structures THEN verify proper synchronization (asyncio.Lock, thread-safe collections) and that no produce-and-consume-in-same-loop pattern exists. BECAUSE the SessionCompressor._pending_semantic_changes dict is accessed from multiple async paths; unsynchronized access causes data races. R12. RETRIEVAL PIPELINE INTEGRITY WHEN code modifies find/rerank/search logic or ContextLevel scoring (L0/L1/L2) THEN verify: rerank is optional (PR #754 fixed find-without-rerank), level-2 scores are preserved through the pipeline, and search results maintain their ranking order. BECAUSE PR #754 fixed a bug where find() required rerank and level-2 scores were silently dropped. R13. TESTING REQUIREMENTS WHEN a PR fixes a bug → it MUST include a regression test or explicitly explain in the PR description why one is impractical. WHEN a PR adds a feature → it SHOULD include unit tests for the happy path and at least one error/edge case. WHEN a PR modifies embedding/VLM integration → verify test isolation (no hardcoded API keys — construct test keys dynamically as in PR #148f6e3). BECAUSE the repo uses pytest; test patterns should use fixtures, not globals. R14. DOCUMENTATION CONSISTENCY WHEN a PR modifies docs/ (en/ and zh/cn/ and ja/) or README files THEN verify all language versions are updated consistently. Flag if only one language is updated when the content change is substantive. BECAUSE the repo maintains en/zh/ja translations (PR #755 added Japanese docs). R15. TELEMETRY & OBSERVABILITY WHEN code adds or modifies operations that call external services (VLM, embedding, VikingDB) or processes memories THEN verify telemetry integration exists (get_current_telemetry pattern) and that timing/count metrics are recorded for the operation. BECAUSE PR #735 added memory extract telemetry breakdown — new operations should follow this pattern for production observability. ## Output Format Be specific: reference exact variable names, function calls, line numbers. When suggesting a fix, include a minimal code block. Match PR language (Chinese PR → Chinese review, English PR → English review). """ # --------------------------------------------------------------------------- # Improve Tool (code suggestions) # --------------------------------------------------------------------------- [pr_code_suggestions] commitable_code_suggestions = false persistent_comment = true focus_only_on_problems = true # Filter low-confidence suggestions. 0 = show all, 7+ = high quality only. # Set to 5 to balance signal-to-noise for this codebase. suggestions_score_threshold = 5 # Extended mode for thorough analysis of large PRs auto_extended_mode = true num_code_suggestions_per_chunk = 4 max_number_of_calls = 3 parallel_calls = true extra_instructions = """\ Focus suggestions on these OpenViking-specific anti-patterns: 1. BLOCKING IN ASYNC: Replace `commit()`, `requests.get()`, `time.sleep()` with `commit_async()`, `httpx.AsyncClient`, `asyncio.sleep()` inside async functions. 2. QUADRATIC LOOPS: Simplify nested loops over memory categories or semantic queues. If an inner loop re-processes items already in the outer loop, suggest flattening or using a set-based approach. 3. PROMPT CONSTRUCTION: Extract repeated LLM prompt strings into Jinja2 templates (the dependency exists in pyproject.toml). Inline f-string prompts over 5 lines should be templated. 4. LOGGING: Replace `print()` with `logger = get_logger(__name__)` (loguru pattern used throughout the codebase). Include structured context in log messages. 5. VALIDATION: Prefer pydantic models for API request/response validation over raw dicts. The codebase already depends on pydantic>=2.0.0. 6. API RESILIENCE: Flag any VLM/embedding API call missing timeout or retry logic. Suggest wrapping with httpx timeout config or litellm retry patterns. 7. RESOURCE CLEANUP: Ensure context managers (async with) are used for DB connections, HTTP clients, and file handles. Flag bare open() without context manager. """ # --------------------------------------------------------------------------- # Describe Tool # --------------------------------------------------------------------------- [pr_description] generate_ai_title = false use_bullet_points = true add_original_user_description = true enable_pr_type = true enable_pr_diagram = true enable_semantic_files_types = true collapsible_file_list = 'adaptive' collapsible_file_list_threshold = 8 enable_large_pr_handling = true include_generated_by_header = true publish_labels = true final_update_message = true extra_instructions = """\ For OpenViking PRs, structure the description to include: - **Layer affected**: core (Python), bot (TypeScript), CLI (Rust), AGFS (C++/Go), or docs. - **Backward compatibility**: state whether existing APIs, config keys, or SDK params are affected. - **Memory pipeline impact**: if session/ is touched, list which of the 6 memory categories (PREFERENCES, ENTITIES, PATTERNS, EVENTS, TOOLS, SKILLS) are affected. - **Multi-tenant impact**: if auth/identity is touched, note whether single-tenant default is preserved. """ ================================================ FILE: .pre-commit-config.yaml ================================================ repos: - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.14.14 hooks: - id: ruff args: [ --fix ] - id: ruff-format ================================================ FILE: CONTRIBUTING.md ================================================ # Contributing Guide Thank you for your interest in OpenViking! We welcome contributions of all kinds: - Bug reports - Feature requests - Documentation improvements - Code contributions --- ## Development Setup ### Prerequisites - **Python**: 3.10+ - **Go**: 1.22+ (Required for building AGFS components from source) - **Rust**: 1.88+ (Required for source builds because the bundled `ov` CLI is built during packaging) - **C++ Compiler**: GCC 9+ or Clang 11+ (Required for building core extensions, must support C++17) - **CMake**: 3.12+ #### Platform-Specific Native Build Tools - **Linux**: Install `build-essential`; some environments may also require `pkg-config` - **macOS**: Install Xcode Command Line Tools (`xcode-select --install`) - **Windows**: Install CMake and MinGW for local native builds #### Supported Platforms (Pre-compiled Wheels) OpenViking provides pre-compiled **Wheel** packages for the following environments: - **Windows**: x86_64 - **macOS**: x86_64, arm64 (Apple Silicon) - **Linux**: x86_64, arm64 (manylinux) For other platforms (e.g., FreeBSD), the package will be automatically compiled from source during installation via `pip`. Ensure you have the [Prerequisites](#prerequisites) installed. ### 1. Fork and Clone ```bash git clone https://github.com/YOUR_USERNAME/openviking.git cd openviking ``` ### 2. Install Dependencies We recommend using `uv` for Python environment management: ```bash # Install uv (if not installed) curl -LsSf https://astral.sh/uv/install.sh | sh # Sync dependencies and create virtual environment uv sync --all-extras source .venv/bin/activate # Linux/macOS # or .venv\Scripts\activate # Windows ``` #### Local Development & Native Rebuilds OpenViking defaults to `binding-client` mode for AGFS, which requires pre-built native artifacts. If you modify the **AGFS (Go)** code, the bundled **Rust CLI**, or the **C++ extensions**, or if the pre-built artifacts are not found, you need to re-compile and re-install them. Run the following command in the project root: ```bash uv pip install -e . --force-reinstall ``` This command ensures that `setup.py` is re-executed, triggering rebuilds for AGFS, the bundled `ov` CLI, and the C++ components. ### 3. Configure Environment Create a configuration file `~/.openviking/ov.conf`: ```json { "embedding": { "dense": { "provider": "volcengine", "api_key": "your-api-key", "model": "doubao-embedding-vision-250615", "api_base": "https://ark.cn-beijing.volces.com/api/v3", "dimension": 1024, "input": "multimodal" } }, "vlm": { "api_key": "your-api-key", "model": "doubao-seed-2-0-pro-260215", "api_base": "https://ark.cn-beijing.volces.com/api/v3" } } ``` Set the environment variable: ```bash export OPENVIKING_CONFIG_FILE=~/.openviking/ov.conf ``` ### 4. Verify Installation ```python import asyncio import openviking as ov async def main(): client = ov.AsyncOpenViking(path="./test_data") await client.initialize() print("OpenViking initialized successfully!") await client.close() asyncio.run(main()) ``` ### 5. Build Rust CLI (Optional) The Rust CLI (`ov`) provides a high-performance command-line client for interacting with OpenViking Server. Even if you do not plan to use `ov` directly, the Rust toolchain is still required when building OpenViking from source because packaging also builds the bundled CLI binary. ```bash # Build and install from source cargo install --path crates/ov_cli # Or use the quick install script (downloads pre-built binary) curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/crates/ov_cli/install.sh | bash ``` After installation, run `ov --help` to see all available commands. CLI connection config goes in `~/.openviking/ovcli.conf`. --- ## Project Structure ``` openviking/ ├── pyproject.toml # Project configuration ├── Cargo.toml # Rust workspace configuration ├── third_party/ # Third-party dependencies │ └── agfs/ # AGFS filesystem │ ├── openviking/ # Python SDK │ ├── async_client.py # AsyncOpenViking client │ ├── sync_client.py # SyncOpenViking client │ ├── client/ # Local and HTTP client implementations │ ├── console/ # Standalone console UI and proxy service │ ├── core/ # Core data models and directory abstractions │ ├── message/ # Session message and part models │ ├── models/ # Embedding and VLM backends │ ├── parse/ # Resource parsers and detectors │ ├── resource/ # Resource processing and watch management │ ├── retrieve/ # Retrieval system │ ├── server/ # HTTP server │ ├── service/ # Shared service layer │ ├── session/ # Session management and compression │ ├── storage/ # Storage layer │ ├── telemetry/ # Operation telemetry │ ├── trace/ # Trace and runtime tracing helpers │ ├── utils/ # Utilities and configuration helpers │ └── prompts/ # Prompt templates │ ├── crates/ # Rust components │ └── ov_cli/ # Rust CLI client │ ├── src/ # CLI source code │ └── install.sh # Quick install script │ ├── src/ # C++ extensions (pybind11) │ ├── tests/ # Test suite │ ├── client/ # Client tests │ ├── console/ # Console tests │ ├── core/ # Core logic tests │ ├── parse/ # Parser tests │ ├── resource/ # Resource processing tests │ ├── retrieve/ # Retrieval tests │ ├── server/ # Server tests │ ├── service/ # Service layer tests │ ├── session/ # Session tests │ ├── storage/ # Storage tests │ ├── telemetry/ # Telemetry tests │ ├── vectordb/ # Vector database tests │ └── integration/ # End-to-end tests │ └── docs/ # Documentation ├── en/ # English docs └── zh/ # Chinese docs ``` --- ## Code Style We use the following tools to maintain code consistency: | Tool | Purpose | Config | |------|---------|--------| | **Ruff** | Linting, Formatting, Import sorting | `pyproject.toml` | | **mypy** | Type checking | `pyproject.toml` | ### Automated Checks (Recommended) We use [pre-commit](https://pre-commit.com/) to automatically run these checks before every commit. This ensures your code always meets the standards without manual effort. 1. **Install pre-commit**: ```bash pip install pre-commit ``` 2. **Install the git hooks**: ```bash pre-commit install ``` Now, `ruff` (check & format) will run automatically when you run `git commit`. If any check fails, it may automatically fix the file. You just need to add the changes and commit again. ### Running Checks ```bash # Format code ruff format openviking/ # Lint ruff check openviking/ # Type check mypy openviking/ ``` ### Style Guidelines 1. **Line width**: 100 characters 2. **Indentation**: 4 spaces 3. **Strings**: Prefer double quotes 4. **Type hints**: Encouraged but not required 5. **Docstrings**: Required for public APIs (1-2 lines max) --- ## Testing ### Running Tests ```bash # Run all tests pytest # Run specific test module pytest tests/client/ -v pytest tests/server/ -v pytest tests/parse/ -v # Run specific test file pytest tests/client/test_lifecycle.py # Run specific test pytest tests/client/test_lifecycle.py::TestClientInitialization::test_initialize_success # Run by keyword pytest -k "search" -v # Run with coverage pytest --cov=openviking --cov-report=term-missing ``` ### Writing Tests Tests are organized in subdirectories under `tests/`. The project uses `asyncio_mode = "auto"`, so async tests do **not** need the `@pytest.mark.asyncio` decorator: ```python # tests/client/test_example.py from openviking import AsyncOpenViking class TestAsyncOpenViking: async def test_initialize(self, uninitialized_client: AsyncOpenViking): await uninitialized_client.initialize() assert uninitialized_client._service is not None await uninitialized_client.close() async def test_add_resource(self, client: AsyncOpenViking, sample_markdown_file): result = await client.add_resource( path=str(sample_markdown_file), reason="test document" ) assert "root_uri" in result assert result["root_uri"].startswith("viking://") ``` Common fixtures are defined in `tests/conftest.py`, including `client` (initialized `AsyncOpenViking`), `uninitialized_client`, `temp_dir`, `sample_markdown_file`, and more. --- ## Contribution Workflow ### 1. Create a Branch ```bash git checkout main git pull origin main git checkout -b feature/your-feature-name ``` Branch naming conventions: - `feature/xxx` - New features - `fix/xxx` - Bug fixes - `docs/xxx` - Documentation updates - `refactor/xxx` - Code refactoring ### 2. Make Changes - Follow code style guidelines - Add tests for new functionality - Update documentation as needed ### 3. Commit Changes ```bash git add . git commit -m "feat: add new parser for xlsx files" ``` ### 4. Push and Create PR ```bash git push origin feature/your-feature-name ``` Then create a Pull Request on GitHub. --- ## Commit Convention We follow [Conventional Commits](https://www.conventionalcommits.org/): ``` ():