From 6d34883b35f64d1f1ed2643253d39611f41218b4 Mon Sep 17 00:00:00 2001 From: Hao Zhe Date: Tue, 13 Oct 2026 21:09:24 +0800 Subject: [PATCH 1/8] refactor(integrations): organize framework packages Move framework packages, tests, and examples into integrations/frameworks. Remove the legacy LangChain forwarding namespace and document canonical imports. Add an SDK-based adapter guide and update CI and release paths. Signed-off-by: Hao Zhe --- .github/workflows/pr.yml | 38 ++-- .github/workflows/python-agent-framework.yml | 6 +- .../workflows/python-langchain-release.yml | 10 +- CONTRIBUTING.md | 2 +- README.md | 3 + .../07-langchain-langgraph.md | 20 +- docs/en/guides/working-memory-default-off.md | 2 +- docs/repository/CONTRIBUTING_CN.md | 2 +- docs/repository/CONTRIBUTING_JA.md | 2 +- .../07-langchain-langgraph.md | 18 +- docs/zh/guides/working-memory-default-off.md | 2 +- integrations/frameworks/README.md | 110 ++++++++++ .../frameworks}/langchain/README.md | 28 ++- .../frameworks}/langchain/README_CN.md | 23 +- .../frameworks/langchain/examples/LICENSE | 201 ++++++++++++++++++ .../langchain/context-backend/quick_app.py | 0 .../langchain/message-history/quick_app.py | 0 .../examples}/langchain/rag/quick_app.py | 0 .../examples}/langgraph/agent/live_app.py | 0 .../examples}/langgraph/agent/quick_app.py | 0 .../langgraph/middleware/native_history.py | 0 .../langgraph/middleware/quick_app.py | 0 .../middleware/requirements-native.txt | 0 .../frameworks}/langchain/pyproject.toml | 2 +- .../src/langchain_openviking/__init__.py | 0 .../_async_client_cache.py | 0 .../langchain_openviking/_testing_utils.py | 0 .../src/langchain_openviking/_uri.py | 0 .../src/langchain_openviking/actor_peer.py | 0 .../src/langchain_openviking/client.py | 0 .../src/langchain_openviking/context.py | 0 .../src/langchain_openviking/history.py | 0 .../src/langchain_openviking/messages.py | 0 .../src/langchain_openviking/middleware.py | 0 .../src/langchain_openviking/py.typed | 0 .../src/langchain_openviking/recording.py | 0 .../src/langchain_openviking/retrievers.py | 0 .../src/langchain_openviking/store.py | 0 .../src/langchain_openviking/testing.py | 0 .../src/langchain_openviking/tools.py | 0 .../langchain/tests/installed_base_smoke.py | 0 .../langchain/tests/installed_smoke.py | 0 .../langchain/tests/integration}/conftest.py | 0 .../langchain/tests/integration}/live_e2e.py | 9 +- .../integration}/test_async_recording.py | 1 + .../integration}/test_context_lifecycle.py | 1 + .../tests/integration}/test_recording.py | 1 + .../integration}/test_runtime_actor_peer.py | 0 .../tests/integration}/test_smoke.py | 12 +- .../frameworks}/langchain/tests/test_store.py | 0 .../unit/test_langchain_async_integration.py | 1 + .../unit/test_langchain_host_history.py | 1 + .../tests}/unit/test_langchain_integration.py | 7 +- .../test_langchain_lifecycle_resources.py | 0 .../tests}/unit/test_langchain_recording.py | 3 +- .../unit/test_langchain_runtime_actor_peer.py | 0 .../microsoft-agent-framework}/README.md | 11 +- .../examples/LICENSE | 201 ++++++++++++++++++ .../examples}/example.py | 0 .../microsoft-agent-framework}/pyproject.toml | 2 +- .../openviking_agent_framework/__init__.py | 0 .../openviking_agent_framework/provider.py | 0 .../src/openviking_agent_framework/py.typed | 0 .../tests/test_provider.py | 0 openviking/integrations/__init__.py | 3 - openviking/integrations/langchain/__init__.py | 75 ------- .../integrations/langchain/actor_peer.py | 7 - openviking/integrations/langchain/client.py | 7 - openviking/integrations/langchain/context.py | 7 - openviking/integrations/langchain/history.py | 7 - openviking/integrations/langchain/messages.py | 7 - .../integrations/langchain/middleware.py | 7 - .../integrations/langchain/recording.py | 7 - .../integrations/langchain/retrievers.py | 7 - openviking/integrations/langchain/store.py | 7 - openviking/integrations/langchain/testing.py | 7 - openviking/integrations/langchain/tools.py | 7 - tests/unit/test_langchain_package_boundary.py | 108 +--------- 78 files changed, 643 insertions(+), 339 deletions(-) create mode 100644 integrations/frameworks/README.md rename {examples => integrations/frameworks}/langchain/README.md (63%) rename {examples => integrations/frameworks}/langchain/README_CN.md (61%) create mode 100644 integrations/frameworks/langchain/examples/LICENSE rename {examples/langchain-langgraph => integrations/frameworks/langchain/examples}/langchain/context-backend/quick_app.py (100%) rename {examples/langchain-langgraph => integrations/frameworks/langchain/examples}/langchain/message-history/quick_app.py (100%) rename {examples/langchain-langgraph => integrations/frameworks/langchain/examples}/langchain/rag/quick_app.py (100%) rename {examples/langchain-langgraph => integrations/frameworks/langchain/examples}/langgraph/agent/live_app.py (100%) rename {examples/langchain-langgraph => integrations/frameworks/langchain/examples}/langgraph/agent/quick_app.py (100%) rename {examples/langchain-langgraph => integrations/frameworks/langchain/examples}/langgraph/middleware/native_history.py (100%) rename {examples/langchain-langgraph => integrations/frameworks/langchain/examples}/langgraph/middleware/quick_app.py (100%) rename {examples/langchain-langgraph => integrations/frameworks/langchain/examples}/langgraph/middleware/requirements-native.txt (100%) rename {examples => integrations/frameworks}/langchain/pyproject.toml (99%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/__init__.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/_async_client_cache.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/_testing_utils.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/_uri.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/actor_peer.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/client.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/context.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/history.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/messages.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/middleware.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/py.typed (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/recording.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/retrievers.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/store.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/testing.py (100%) rename {examples => integrations/frameworks}/langchain/src/langchain_openviking/tools.py (100%) rename {examples => integrations/frameworks}/langchain/tests/installed_base_smoke.py (100%) rename {examples => integrations/frameworks}/langchain/tests/installed_smoke.py (100%) rename {tests/integration/langchain_langgraph => integrations/frameworks/langchain/tests/integration}/conftest.py (100%) rename {tests/integration/langchain_langgraph => integrations/frameworks/langchain/tests/integration}/live_e2e.py (99%) rename {tests/integration/langchain_langgraph => integrations/frameworks/langchain/tests/integration}/test_async_recording.py (99%) rename {tests/integration/langchain_langgraph => integrations/frameworks/langchain/tests/integration}/test_context_lifecycle.py (99%) rename {tests/integration/langchain_langgraph => integrations/frameworks/langchain/tests/integration}/test_recording.py (99%) rename {tests/integration/langchain_langgraph => integrations/frameworks/langchain/tests/integration}/test_runtime_actor_peer.py (100%) rename {tests/integration/langchain_langgraph => integrations/frameworks/langchain/tests/integration}/test_smoke.py (73%) rename {examples => integrations/frameworks}/langchain/tests/test_store.py (100%) rename {tests => integrations/frameworks/langchain/tests}/unit/test_langchain_async_integration.py (99%) rename {tests => integrations/frameworks/langchain/tests}/unit/test_langchain_host_history.py (99%) rename {tests => integrations/frameworks/langchain/tests}/unit/test_langchain_integration.py (99%) rename {tests => integrations/frameworks/langchain/tests}/unit/test_langchain_lifecycle_resources.py (100%) rename {tests => integrations/frameworks/langchain/tests}/unit/test_langchain_recording.py (99%) rename {tests => integrations/frameworks/langchain/tests}/unit/test_langchain_runtime_actor_peer.py (100%) rename {examples/agent-framework => integrations/frameworks/microsoft-agent-framework}/README.md (89%) create mode 100644 integrations/frameworks/microsoft-agent-framework/examples/LICENSE rename {examples/agent-framework => integrations/frameworks/microsoft-agent-framework/examples}/example.py (100%) rename {examples/agent-framework => integrations/frameworks/microsoft-agent-framework}/pyproject.toml (95%) rename {examples/agent-framework => integrations/frameworks/microsoft-agent-framework}/src/openviking_agent_framework/__init__.py (100%) rename {examples/agent-framework => integrations/frameworks/microsoft-agent-framework}/src/openviking_agent_framework/provider.py (100%) rename {examples/agent-framework => integrations/frameworks/microsoft-agent-framework}/src/openviking_agent_framework/py.typed (100%) rename {examples/agent-framework => integrations/frameworks/microsoft-agent-framework}/tests/test_provider.py (100%) delete mode 100644 openviking/integrations/__init__.py delete mode 100644 openviking/integrations/langchain/__init__.py delete mode 100644 openviking/integrations/langchain/actor_peer.py delete mode 100644 openviking/integrations/langchain/client.py delete mode 100644 openviking/integrations/langchain/context.py delete mode 100644 openviking/integrations/langchain/history.py delete mode 100644 openviking/integrations/langchain/messages.py delete mode 100644 openviking/integrations/langchain/middleware.py delete mode 100644 openviking/integrations/langchain/recording.py delete mode 100644 openviking/integrations/langchain/retrievers.py delete mode 100644 openviking/integrations/langchain/store.py delete mode 100644 openviking/integrations/langchain/testing.py delete mode 100644 openviking/integrations/langchain/tools.py diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index f27e544c0c..bc0a94a573 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -181,7 +181,7 @@ jobs: echo "cuvs_changed=false" >> $GITHUB_OUTPUT fi - LANGCHAIN_PATTERN="examples/langchain/|openviking/integrations/langchain/|tests/(unit/test_langchain|integration/langchain_langgraph/)|examples/langchain-langgraph/|^pyproject\.toml$|^uv\.lock$|\.github/workflows/(pr|python-langchain-release)\.yml" + LANGCHAIN_PATTERN="integrations/frameworks/langchain/|tests/unit/test_langchain_package_boundary\.py$|^pyproject\.toml$|^uv\.lock$|\.github/workflows/(pr|python-langchain-release)\.yml" LANGCHAIN_CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }} HEAD | grep -E "$LANGCHAIN_PATTERN" || true) if [ -n "$LANGCHAIN_CHANGED_FILES" ]; then @@ -292,44 +292,40 @@ jobs: - name: Install standalone integration run: | uv pip install --system -e sdk/python - uv pip install --system -e "examples/langchain[langgraph,test,dev]" + uv pip install --system -e "integrations/frameworks/langchain[langgraph,test,dev]" - name: Check package formatting and lint run: | ruff format --check \ - examples/langchain/src \ - examples/langchain/tests \ - openviking/integrations/langchain \ - tests/integration/langchain_langgraph \ - tests/unit/test_langchain*.py + integrations/frameworks/langchain/src \ + integrations/frameworks/langchain/tests \ + tests/unit/test_langchain_package_boundary.py ruff check \ - examples/langchain/src \ - examples/langchain/tests \ - openviking/integrations/langchain \ - tests/integration/langchain_langgraph \ - tests/unit/test_langchain*.py + integrations/frameworks/langchain/src \ + integrations/frameworks/langchain/tests \ + tests/unit/test_langchain_package_boundary.py - name: Type-check package run: >- mypy - --config-file examples/langchain/pyproject.toml - examples/langchain/src/langchain_openviking + --config-file integrations/frameworks/langchain/pyproject.toml + integrations/frameworks/langchain/src/langchain_openviking - name: Run LangChain and LangGraph tests run: | python -m pytest -q --noconftest -o addopts='' \ - tests/unit/test_langchain*.py \ - tests/integration/langchain_langgraph + integrations/frameworks/langchain/tests \ + tests/unit/test_langchain_package_boundary.py - name: Build and inspect distributions run: | - python -m build examples/langchain - python -m twine check examples/langchain/dist/* + python -m build integrations/frameworks/langchain + python -m twine check integrations/frameworks/langchain/dist/* - name: Verify the installed wheel if: matrix.python-version == '3.12' run: | - WHEEL_PATH="${GITHUB_WORKSPACE}/$(find examples/langchain/dist -name '*.whl' -print -quit)" + WHEEL_PATH="${GITHUB_WORKSPACE}/$(find integrations/frameworks/langchain/dist -name '*.whl' -print -quit)" uv venv .langchain-wheel-venv --python "${{ matrix.python-version }}" uv pip install \ --python .langchain-wheel-venv/bin/python \ @@ -337,10 +333,10 @@ jobs: "${WHEEL_PATH}" cd /tmp "${GITHUB_WORKSPACE}/.langchain-wheel-venv/bin/python" \ - "${GITHUB_WORKSPACE}/examples/langchain/tests/installed_base_smoke.py" + "${GITHUB_WORKSPACE}/integrations/frameworks/langchain/tests/installed_base_smoke.py" uv pip install \ --python "${GITHUB_WORKSPACE}/.langchain-wheel-venv/bin/python" \ "${WHEEL_PATH}[langgraph]" "${GITHUB_WORKSPACE}/.langchain-wheel-venv/bin/python" \ - "${GITHUB_WORKSPACE}/examples/langchain/tests/installed_smoke.py" + "${GITHUB_WORKSPACE}/integrations/frameworks/langchain/tests/installed_smoke.py" uv pip check --python "${GITHUB_WORKSPACE}/.langchain-wheel-venv/bin/python" diff --git a/.github/workflows/python-agent-framework.yml b/.github/workflows/python-agent-framework.yml index a69bc63336..08c59565ac 100644 --- a/.github/workflows/python-agent-framework.yml +++ b/.github/workflows/python-agent-framework.yml @@ -3,12 +3,12 @@ name: Microsoft Agent Framework Integration on: pull_request: paths: - - 'examples/agent-framework/**' + - 'integrations/frameworks/microsoft-agent-framework/**' - '.github/workflows/python-agent-framework.yml' push: branches: [main] paths: - - 'examples/agent-framework/**' + - 'integrations/frameworks/microsoft-agent-framework/**' - '.github/workflows/python-agent-framework.yml' permissions: @@ -26,7 +26,7 @@ jobs: sdk: 'openviking-sdk>=0.1.13,<0.2' defaults: run: - working-directory: examples/agent-framework + working-directory: integrations/frameworks/microsoft-agent-framework steps: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 diff --git a/.github/workflows/python-langchain-release.yml b/.github/workflows/python-langchain-release.yml index e4f94cb391..29754f8d95 100644 --- a/.github/workflows/python-langchain-release.yml +++ b/.github/workflows/python-langchain-release.yml @@ -50,12 +50,12 @@ jobs: python-version: "3.12" - name: Install build dependencies - working-directory: examples/langchain + working-directory: integrations/frameworks/langchain run: python -m pip install build setuptools setuptools-scm twine wheel - name: Resolve package version id: version - working-directory: examples/langchain + working-directory: integrations/frameworks/langchain run: | PACKAGE_VERSION=$(python -m setuptools_scm) echo "package_version=$PACKAGE_VERSION" >> "$GITHUB_OUTPUT" @@ -74,18 +74,18 @@ jobs: fi - name: Build distributions - working-directory: examples/langchain + working-directory: integrations/frameworks/langchain run: python -m build - name: Validate distributions - working-directory: examples/langchain + working-directory: integrations/frameworks/langchain run: python -m twine check dist/* - name: Upload distributions uses: actions/upload-artifact@v7 with: name: langchain-openviking-distributions - path: examples/langchain/dist/* + path: integrations/frameworks/langchain/dist/* publish-testpypi: name: Publish to TestPyPI diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 51e598b561..466f204cc1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -91,7 +91,7 @@ only the contacts relevant to the change. | Storage | RAGFS, PathLock, QueueFS, and encryption | `openviking/storage`, `openviking/pyagfs`, `openviking/crypto`, `crates/ragfs*` | `@baojun-zhang` | | Integration | Agent plugins and MCP | `agent-plugins`, memory plugin examples, server MCP | `@t0saki`, `@ZaynJarvis` | | Integration | VikingBot and agent compilation | `bot`, `ov compile` | `@yeshion23333`, `@fujiajie666` | -| Client | SDKs, CLI, and LangChain | `sdk`, `crates/ov_cli`, `examples/langchain` | `@zhoujh01`, `@t0saki`, `@ehz0ah` | +| Client | SDKs, CLI, and LangChain | `sdk`, `crates/ov_cli`, `integrations/frameworks/langchain` | `@zhoujh01`, `@t0saki`, `@ehz0ah` | | Product | Web Studio | `web-studio` | `@yufeng201`, `@ZaynJarvis` | | Project | Documentation, CI, and plugin releases | `docs`, `.github/workflows` | `@yufeng201`, `@ZaynJarvis` | diff --git a/README.md b/README.md index 89cc3a7c51..066c0d931b 100644 --- a/README.md +++ b/README.md @@ -316,6 +316,8 @@ Setup guides for each integration: For setup instructions and integration details, see [Integrations](https://openviking.ai/integrations). +For framework applications, see the [LangChain/LangGraph and Microsoft Agent Framework packages](integrations/frameworks/README.md), with a guide to adding other adapters. + ## Desktop App (Beta) The desktop app is a console for macOS and Windows x64 (beta). It configures supported local agent integrations, inspects recall and capture events in sessions, and syncs local memories and skills to OpenViking. @@ -424,6 +426,7 @@ The OpenViking project uses different licenses for different components: - **Main Project**: AGPLv3 - see the [LICENSE](./LICENSE) file for details - **crates/ov\_cli**: Apache 2.0 - see the [LICENSE](./crates/LICENSE) for details - **examples**: Apache 2.0 - see the [LICENSE](./examples/LICENSE) for details. The Hermes plugin in `examples/hermes-plugin` retains its [MIT license](./examples/hermes-plugin/LICENSE). +- **integrations/frameworks**: adapters use AGPLv3; their runnable examples retain Apache 2.0, with licenses in each package's `examples/` directory. - **third\_party**: Respective original licenses of third-party projects Please also note: any wholesale rewriting and subsequent re-open-sourcing of this project is prohibited; any request to translate all or a substantial portion of the project code into another coding language requires prior written authorization from Volcano Engine. For permission requests, please contact the Volcano Engine team — see [Community & Contributing](#community--contributing) for contact channels. diff --git a/docs/en/agent-integrations/07-langchain-langgraph.md b/docs/en/agent-integrations/07-langchain-langgraph.md index 0c22d8cfec..2713995476 100644 --- a/docs/en/agent-integrations/07-langchain-langgraph.md +++ b/docs/en/agent-integrations/07-langchain-langgraph.md @@ -11,9 +11,9 @@ pip install langchain-openviking # LangChain adapters pip install "langchain-openviking[langgraph]" # LangGraph middleware support ``` -The integration is released independently from the OpenViking server. The full -package keeps forwarding the legacy `openviking.integrations.langchain` import -path to `langchain-openviking` for existing applications. +The integration is released independently from the OpenViking server. The legacy +`openviking.integrations.langchain` namespace has been removed; install the +standalone package and import from `langchain_openviking` instead. ## Connection @@ -311,17 +311,17 @@ finish an async lifecycle with `recorder.close()`. The repository includes runnable examples that work without model credentials using an in-memory test client: ```bash -uv run --project examples/langchain --extra langgraph python examples/langchain-langgraph/langchain/rag/quick_app.py -uv run --project examples/langchain --extra langgraph python examples/langchain-langgraph/langchain/context-backend/quick_app.py -uv run --project examples/langchain --extra langgraph python examples/langchain-langgraph/langchain/message-history/quick_app.py -uv run --project examples/langchain --extra langgraph python examples/langchain-langgraph/langgraph/agent/quick_app.py -uv run --project examples/langchain --extra langgraph python examples/langchain-langgraph/langgraph/middleware/quick_app.py +uv run --project integrations/frameworks/langchain --extra langgraph python integrations/frameworks/langchain/examples/langchain/rag/quick_app.py +uv run --project integrations/frameworks/langchain --extra langgraph python integrations/frameworks/langchain/examples/langchain/context-backend/quick_app.py +uv run --project integrations/frameworks/langchain --extra langgraph python integrations/frameworks/langchain/examples/langchain/message-history/quick_app.py +uv run --project integrations/frameworks/langchain --extra langgraph python integrations/frameworks/langchain/examples/langgraph/agent/quick_app.py +uv run --project integrations/frameworks/langchain --extra langgraph python integrations/frameworks/langchain/examples/langgraph/middleware/quick_app.py ``` -For a real OpenViking server and OpenAI-compatible model flow, see the [live LangGraph app](https://github.com/volcengine/OpenViking/blob/main/examples/langchain-langgraph/langgraph/agent/live_app.py). +For a real OpenViking server and OpenAI-compatible model flow, see the [live LangGraph app](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/langchain/examples/langgraph/agent/live_app.py). ## See also - [Capability Reference](./16-capability-reference.md) -- [examples/langchain-langgraph/](https://github.com/volcengine/OpenViking/tree/main/examples/langchain-langgraph) — full source for all examples above +- [integrations/frameworks/langchain/examples/](https://github.com/volcengine/OpenViking/tree/main/integrations/frameworks/langchain/examples) — full source for all examples above - [MCP Clients](./06-mcp-clients.md) — for non-SDK MCP integration diff --git a/docs/en/guides/working-memory-default-off.md b/docs/en/guides/working-memory-default-off.md index 7500de4432..0769a152b8 100644 --- a/docs/en/guides/working-memory-default-off.md +++ b/docs/en/guides/working-memory-default-off.md @@ -86,7 +86,7 @@ that it depends on OV history. Middleware defaults to `include_session_context=False`. Put it before native summarization middleware so raw messages are captured before the framework replaces them. Message capture watermarks are persisted in graph state. See the runnable -[native history example](https://github.com/volcengine/OpenViking/blob/main/examples/langchain-langgraph/langgraph/middleware/native_history.py) +[native history example](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/langchain/examples/langgraph/middleware/native_history.py) and its pinned requirements for LangChain summarization with a SQLite checkpointer. VikingBot is an exception to the host-history default: it still uses OV Working diff --git a/docs/repository/CONTRIBUTING_CN.md b/docs/repository/CONTRIBUTING_CN.md index 01d0124f48..987f9586e3 100644 --- a/docs/repository/CONTRIBUTING_CN.md +++ b/docs/repository/CONTRIBUTING_CN.md @@ -77,7 +77,7 @@ OpenViking 重视聚焦且经过充分理解的改动。无论是否使用 AI | Storage | RAGFS、PathLock、QueueFS 与加密 | `openviking/storage`、`openviking/pyagfs`、`openviking/crypto`、`crates/ragfs*` | `@baojun-zhang` | | Integration | Agent Plugin 与 MCP | `agent-plugins`、记忆插件示例、Server MCP | `@t0saki`、`@ZaynJarvis` | | Integration | VikingBot 与 Agent 编译 | `bot`、`ov compile` | `@yeshion23333`、`@fujiajie666` | -| Client | SDK、CLI 与 LangChain | `sdk`、`crates/ov_cli`、`examples/langchain` | `@zhoujh01`、`@t0saki`、`@ehz0ah` | +| Client | SDK、CLI 与 LangChain | `sdk`、`crates/ov_cli`、`integrations/frameworks/langchain` | `@zhoujh01`、`@t0saki`、`@ehz0ah` | | Product | Web Studio | `web-studio` | `@yufeng201`、`@ZaynJarvis` | | Project | 文档、CI 与 Plugin 发布 | `docs`、`.github/workflows` | `@yufeng201`、`@ZaynJarvis` | diff --git a/docs/repository/CONTRIBUTING_JA.md b/docs/repository/CONTRIBUTING_JA.md index 3e4ab7f2dc..abd79edd0d 100644 --- a/docs/repository/CONTRIBUTING_JA.md +++ b/docs/repository/CONTRIBUTING_JA.md @@ -83,7 +83,7 @@ OpenVikingでは、焦点が絞られ、十分に理解された変更を重視 | Storage | RAGFS、PathLock、QueueFS、暗号化 | `openviking/storage`、`openviking/pyagfs`、`openviking/crypto`、`crates/ragfs*` | `@baojun-zhang` | | Integration | Agent PluginとMCP | `agent-plugins`、メモリPluginの例、Server MCP | `@t0saki`、`@ZaynJarvis` | | Integration | VikingBotとAgentコンパイル | `bot`、`ov compile` | `@yeshion23333`、`@fujiajie666` | -| Client | SDK、CLI、LangChain | `sdk`、`crates/ov_cli`、`examples/langchain` | `@zhoujh01`、`@t0saki`、`@ehz0ah` | +| Client | SDK、CLI、LangChain | `sdk`、`crates/ov_cli`、`integrations/frameworks/langchain` | `@zhoujh01`、`@t0saki`、`@ehz0ah` | | Product | Web Studio | `web-studio` | `@yufeng201`、`@ZaynJarvis` | | Project | ドキュメント、CI、Pluginリリース | `docs`、`.github/workflows` | `@yufeng201`、`@ZaynJarvis` | diff --git a/docs/zh/agent-integrations/07-langchain-langgraph.md b/docs/zh/agent-integrations/07-langchain-langgraph.md index f02172f245..b21c70b3aa 100644 --- a/docs/zh/agent-integrations/07-langchain-langgraph.md +++ b/docs/zh/agent-integrations/07-langchain-langgraph.md @@ -11,8 +11,8 @@ pip install langchain-openviking # LangChain 适配器 pip install "langchain-openviking[langgraph]" # LangGraph middleware ``` -该集成独立于 OpenViking server 发布。为兼容现有应用,完整包仍会把旧的 -`openviking.integrations.langchain` 导入路径转发到 `langchain-openviking`。 +该集成独立于 OpenViking server 发布。旧的 `openviking.integrations.langchain` +命名空间已移除;请安装独立包,并改用 `langchain_openviking` 导入。 ## 连接 @@ -295,17 +295,17 @@ commit 策略。如果后续批次或写入后的 commit 失败,`OpenVikingPar 仓库内提供了可直接运行的最小示例,使用内存测试客户端,无需模型凭证: ```bash -uv run --project examples/langchain --extra langgraph python examples/langchain-langgraph/langchain/rag/quick_app.py -uv run --project examples/langchain --extra langgraph python examples/langchain-langgraph/langchain/context-backend/quick_app.py -uv run --project examples/langchain --extra langgraph python examples/langchain-langgraph/langchain/message-history/quick_app.py -uv run --project examples/langchain --extra langgraph python examples/langchain-langgraph/langgraph/agent/quick_app.py -uv run --project examples/langchain --extra langgraph python examples/langchain-langgraph/langgraph/middleware/quick_app.py +uv run --project integrations/frameworks/langchain --extra langgraph python integrations/frameworks/langchain/examples/langchain/rag/quick_app.py +uv run --project integrations/frameworks/langchain --extra langgraph python integrations/frameworks/langchain/examples/langchain/context-backend/quick_app.py +uv run --project integrations/frameworks/langchain --extra langgraph python integrations/frameworks/langchain/examples/langchain/message-history/quick_app.py +uv run --project integrations/frameworks/langchain --extra langgraph python integrations/frameworks/langchain/examples/langgraph/agent/quick_app.py +uv run --project integrations/frameworks/langchain --extra langgraph python integrations/frameworks/langchain/examples/langgraph/middleware/quick_app.py ``` -连接真实 OpenViking 服务和 OpenAI 兼容模型的示例见 [live LangGraph app](https://github.com/volcengine/OpenViking/blob/main/examples/langchain-langgraph/langgraph/agent/live_app.py)。 +连接真实 OpenViking 服务和 OpenAI 兼容模型的示例见 [live LangGraph app](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/langchain/examples/langgraph/agent/live_app.py)。 ## 参见 - [集成能力参考](./16-capability-reference.md) -- [examples/langchain-langgraph/](https://github.com/volcengine/OpenViking/tree/main/examples/langchain-langgraph) — 上面所有示例的完整源码 +- [integrations/frameworks/langchain/examples/](https://github.com/volcengine/OpenViking/tree/main/integrations/frameworks/langchain/examples) — 上面所有示例的完整源码 - [MCP 客户端](./06-mcp-clients.md) — 非 SDK 方式的 MCP 集成 diff --git a/docs/zh/guides/working-memory-default-off.md b/docs/zh/guides/working-memory-default-off.md index a05be0d88c..8e25a1e66e 100644 --- a/docs/zh/guides/working-memory-default-off.md +++ b/docs/zh/guides/working-memory-default-off.md @@ -42,7 +42,7 @@ Pi 的实验性上下文管理扩展不在本次 WM 关闭适配范围内,请 ## 应用与旧会话 -LangChain 请使用 `with_openviking_memory(..., history_factory=...)` 并配合宿主的历史提供者。未提供 provider 的旧版 `with_openviking_context` 会警告它依赖 OV 历史。中间件默认 `include_session_context=False`。请把它放在原生 summarization 中间件之前,使原始消息在框架替换它们之前被捕获。消息捕获水位线保存在 graph state 中。可运行的[原生历史示例](https://github.com/volcengine/OpenViking/blob/main/examples/langchain-langgraph/langgraph/middleware/native_history.py)及其固定版本的依赖,演示了 LangChain summarization 配合 SQLite checkpointer 的用法。 +LangChain 请使用 `with_openviking_memory(..., history_factory=...)` 并配合宿主的历史提供者。未提供 provider 的旧版 `with_openviking_context` 会警告它依赖 OV 历史。中间件默认 `include_session_context=False`。请把它放在原生 summarization 中间件之前,使原始消息在框架替换它们之前被捕获。消息捕获水位线保存在 graph state 中。可运行的[原生历史示例](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/langchain/examples/langgraph/middleware/native_history.py)及其固定版本的依赖,演示了 LangChain summarization 配合 SQLite checkpointer 的用法。 VikingBot 是“默认使用宿主历史”的例外:它仍然使用 OV Working Memory 管理上下文和压缩。它的会话上下文 commit 会显式发送 `enable_working_memory: true`,包括已保存策略关闭了 WM 的既有会话。它保持现有的 commit-and-clear 流程;之后的上下文读取使用 OV 的 overview/checkpoint 和保留的消息,生成仍在进行时则使用待处理归档中的消息。如果服务端未确认 WM 生成,该 commit 会被视为失败,本地历史保留以便重试。此变更不会替换 VikingBot 的本地压缩。 diff --git a/integrations/frameworks/README.md b/integrations/frameworks/README.md new file mode 100644 index 0000000000..16ff068bf3 --- /dev/null +++ b/integrations/frameworks/README.md @@ -0,0 +1,110 @@ +# Agent framework integrations + +These packages connect OpenViking to agent applications through each framework's +public extension points and the official OpenViking SDK. Install only the adapter +your application needs; each package owns its dependencies, tests, and release. + +## Available adapters + +| Framework | Package | Entry points | Installation | +| --- | --- | --- | --- | +| [LangChain / LangGraph](langchain/) | `langchain-openviking` | Retriever, context middleware, history, store, and tools | `pip install "langchain-openviking[langgraph]"` (omit the extra for base LangChain adapters) | +| [Microsoft Agent Framework](microsoft-agent-framework/) | `openviking-agent-framework` | `OpenVikingContextProvider` | From a checkout: `pip install ./integrations/frameworks/microsoft-agent-framework`; PyPI publication is pending | + +LangChain and LangGraph share one package. Repository directory names do not +change the Python imports: use `langchain_openviking` or +`openviking_agent_framework`. + +## Common lifecycle + +1. **Recall:** retrieve relevant context before agent execution and attach it as + attributed reference data using the framework's context or middleware API. +2. **Execute:** the framework owns model calls, tools, chat history, and streaming. +3. **Capture:** convert completed messages and tool evidence into OpenViking + session messages. Track acknowledged progress in persistent framework state. +4. **Extract:** request a commit at an application-selected boundary or according + to the adapter's documented commit policy. Commit acceptance starts a task; + wait for that task when the application needs extracted memory immediately. + +Native chat history and OpenViking memory capture have different responsibilities. +An adapter that implements a history/store interface must document and test that +interface separately. For example, MAF owns its chat history; the LangChain package +also provides explicit history and LangGraph store components. + +## SDK operations to reuse + +Use a supported SDK version that exposes the operations your adapter needs. +The existing adapters describe their minimum versions in their package manifests. + +| Purpose | Python SDK | TypeScript SDK | +| --- | --- | --- | +| Recall assembled context | `search_context` | `searchContext` | +| Ensure/read session state | `get_session` | `getSession` | +| Append structured messages | `batch_add_messages` | `batchAddMessages` | +| Request extraction | `commit_session` | `commitSession` | +| Check extraction completion | `get_task` | `getTask` | + +See the [Python SDK](../../sdk/python/) and [TypeScript SDK](../../sdk/typescript/). +The server owns retrieval, authorization, storage, and extraction. The application +binds an authenticated client, owns its lifetime, and persists framework state. +The adapter maps framework hooks, messages, and conversation IDs to SDK calls. +MCP can expose model-callable OpenViking tools alongside the lifecycle adapter. + +## Add an adapter + +Create one package under `integrations/frameworks//` containing its +manifest, `src/`, `tests/`, README, and runnable `examples/`. Use the two existing +adapters as references for the OpenViking contract and inspect the target +framework's current public APIs before choosing its hooks. + +- **Identity and state:** use the application's authenticated OV client and keep + a stable mapping from framework conversations to OV sessions. Preserve delivery + IDs and unresolved capture through supported session restoration. +- **Messages:** preserve visible text and linked tool calls/results. Exclude + system instructions, hidden reasoning, and injected recall from automatic + conversation capture. Document any media support and sensitive tool data. +- **Completion:** capture completed invocations. Check streaming exhaustion and + multi-step/tool-loop behavior; document which boundary counts as completed. +- **Policies:** expose capture controls and extraction timing. Apply automatic + commit policies only after all captured messages are acknowledged. Use the + server's pending-token count for a token-based threshold. +- **Failures:** report recall/capture/commit failures according to a documented + policy. Keep confirmed progress when a later batch or commit fails. OV append + is not idempotent: a lost acknowledgement requires reconciliation before retry. +- **Packaging:** keep framework dependencies in the adapter. The server's root + environment and Docker build must not require adapter directories. Preserve + the framework's own extension APIs; ship a runnable example and contract tests. + +### Test checklist + +Exercise the real framework lifecycle with deterministic model responses and a +controlled SDK boundary. Cover ordinary and streamed runs, tool calls/results, +multi-step loops, interrupted streams, session restoration, separate users and +sessions, partial/lost acknowledgements, and extraction-policy failures. + +Build a wheel and sdist, install outside the checkout, and test the supported +minimum and current dependency versions. Verify remote SDK usage does not import +the OV server. A documented live smoke should demonstrate capture, extraction, +and recall in a new conversation when credentials and a server are available. + +### Coding-agent prompt + +> Implement an OpenViking adapter for **[framework and supported versions]** using +> the official **[Python/TypeScript] SDK**. Inspect the framework's current public +> lifecycle and message APIs first. Follow this guide and the MAF/LangChain +> implementations for identity, recall, completed-message capture, and extraction +> policy. Adapt their hooks and state to this framework. Preserve tool evidence; +> exclude injected recall, system instructions, and hidden reasoning. Test full +> and interrupted streams, tool loops, restored sessions, partial writes, and lost +> acknowledgements. Provide a focused package, README, runnable example, and +> offline contract tests. Keep runtime dependencies local to the adapter package. + +This prompt is a development aid. Review generated code and pass the contract +tests before listing the framework as supported. + +## Future candidates + +Google ADK, OpenAI Agents SDK, Vercel AI SDK, CrewAI, LlamaIndex, Mastra, Pydantic AI, +AutoGen/AG2, Strands, and Agno are candidates for additional adapters. Their adapters +are not implemented here. Start with the SDK-based recipe above and add each +integration when its lifecycle, message mapping, and tests are verified. diff --git a/examples/langchain/README.md b/integrations/frameworks/langchain/README.md similarity index 63% rename from examples/langchain/README.md rename to integrations/frameworks/langchain/README.md index fe3fe4de99..ad618001da 100644 --- a/examples/langchain/README.md +++ b/integrations/frameworks/langchain/README.md @@ -1,6 +1,6 @@ # langchain-openviking -> **Working memory is now opt-in.** Update installed plugins separately from the OV server, then restart the host. Existing explicit settings still take precedence. See the [default-off upgrade guide](../../docs/en/guides/working-memory-default-off.md) for native history, re-enabling WM, and old-conversation handoffs. +> **Working memory is now opt-in.** Update installed plugins separately from the OV server, then restart the host. Existing explicit settings still take precedence. See the [default-off upgrade guide](https://github.com/volcengine/OpenViking/blob/main/docs/en/guides/working-memory-default-off.md) for native history, re-enabling WM, and old-conversation handoffs. `langchain-openviking` is the official OpenViking integration package for LangChain and LangGraph applications. It keeps framework-specific adapters @@ -59,8 +59,26 @@ The package also provides `OpenVikingSessionRecorder`, - Clients created from `url=` are managed by the adapter and can be closed with `close()` or `aclose()` as documented by each adapter. -The previous `openviking.integrations.langchain` import path remains available -from the full `openviking` distribution as a compatibility shim. +## Import migration -See the [OpenViking documentation](https://openviking.ai) and the repository's -`examples/langchain-langgraph` directory for complete examples. +The server distribution no longer provides `openviking.integrations.langchain`. +Install this standalone package and change imports to `langchain_openviking`: + +```python +from langchain_openviking import OpenVikingRetriever +``` + +See the [OpenViking documentation](https://openviking.ai), [examples](https://github.com/volcengine/OpenViking/tree/main/integrations/frameworks/langchain/examples), +and the [framework adapter guide](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/README.md). + +## Validate + +From the repository root: + +```bash +pip install -e 'integrations/frameworks/langchain[langgraph,test,dev]' +python -m pytest -q --noconftest -o addopts='' \ + integrations/frameworks/langchain/tests tests/unit/test_langchain_package_boundary.py +``` + +The adapter is AGPL-3.0; the runnable [examples](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/langchain/examples/LICENSE) retain Apache-2.0. diff --git a/examples/langchain/README_CN.md b/integrations/frameworks/langchain/README_CN.md similarity index 61% rename from examples/langchain/README_CN.md rename to integrations/frameworks/langchain/README_CN.md index 58f12bf09a..16d35eb453 100644 --- a/examples/langchain/README_CN.md +++ b/integrations/frameworks/langchain/README_CN.md @@ -44,5 +44,24 @@ finally: 外部传入的 client 仍由调用方管理。通过 `url=` 创建的 client 由适配器管理。 -完整 `openviking` 包会继续保留原有的 -`openviking.integrations.langchain` 导入路径,并转发到本包,方便现有应用平滑迁移。 +## 导入迁移 + +服务端包不再提供 `openviking.integrations.langchain`。请安装独立包,并将导入改为: + +```python +from langchain_openviking import OpenVikingRetriever +``` + +参见[示例](https://github.com/volcengine/OpenViking/tree/main/integrations/frameworks/langchain/examples)和[框架适配指南](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/README.md)。 + +## 验证 + +在仓库根目录运行: + +```bash +pip install -e 'integrations/frameworks/langchain[langgraph,test,dev]' +python -m pytest -q --noconftest -o addopts='' \ + integrations/frameworks/langchain/tests tests/unit/test_langchain_package_boundary.py +``` + +适配器使用 AGPL-3.0;可运行[示例](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/langchain/examples/LICENSE)保留 Apache-2.0 许可。 diff --git a/integrations/frameworks/langchain/examples/LICENSE b/integrations/frameworks/langchain/examples/LICENSE new file mode 100644 index 0000000000..b65287786d --- /dev/null +++ b/integrations/frameworks/langchain/examples/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited + to communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including but negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor + be liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Der Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if you agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/examples/langchain-langgraph/langchain/context-backend/quick_app.py b/integrations/frameworks/langchain/examples/langchain/context-backend/quick_app.py similarity index 100% rename from examples/langchain-langgraph/langchain/context-backend/quick_app.py rename to integrations/frameworks/langchain/examples/langchain/context-backend/quick_app.py diff --git a/examples/langchain-langgraph/langchain/message-history/quick_app.py b/integrations/frameworks/langchain/examples/langchain/message-history/quick_app.py similarity index 100% rename from examples/langchain-langgraph/langchain/message-history/quick_app.py rename to integrations/frameworks/langchain/examples/langchain/message-history/quick_app.py diff --git a/examples/langchain-langgraph/langchain/rag/quick_app.py b/integrations/frameworks/langchain/examples/langchain/rag/quick_app.py similarity index 100% rename from examples/langchain-langgraph/langchain/rag/quick_app.py rename to integrations/frameworks/langchain/examples/langchain/rag/quick_app.py diff --git a/examples/langchain-langgraph/langgraph/agent/live_app.py b/integrations/frameworks/langchain/examples/langgraph/agent/live_app.py similarity index 100% rename from examples/langchain-langgraph/langgraph/agent/live_app.py rename to integrations/frameworks/langchain/examples/langgraph/agent/live_app.py diff --git a/examples/langchain-langgraph/langgraph/agent/quick_app.py b/integrations/frameworks/langchain/examples/langgraph/agent/quick_app.py similarity index 100% rename from examples/langchain-langgraph/langgraph/agent/quick_app.py rename to integrations/frameworks/langchain/examples/langgraph/agent/quick_app.py diff --git a/examples/langchain-langgraph/langgraph/middleware/native_history.py b/integrations/frameworks/langchain/examples/langgraph/middleware/native_history.py similarity index 100% rename from examples/langchain-langgraph/langgraph/middleware/native_history.py rename to integrations/frameworks/langchain/examples/langgraph/middleware/native_history.py diff --git a/examples/langchain-langgraph/langgraph/middleware/quick_app.py b/integrations/frameworks/langchain/examples/langgraph/middleware/quick_app.py similarity index 100% rename from examples/langchain-langgraph/langgraph/middleware/quick_app.py rename to integrations/frameworks/langchain/examples/langgraph/middleware/quick_app.py diff --git a/examples/langchain-langgraph/langgraph/middleware/requirements-native.txt b/integrations/frameworks/langchain/examples/langgraph/middleware/requirements-native.txt similarity index 100% rename from examples/langchain-langgraph/langgraph/middleware/requirements-native.txt rename to integrations/frameworks/langchain/examples/langgraph/middleware/requirements-native.txt diff --git a/examples/langchain/pyproject.toml b/integrations/frameworks/langchain/pyproject.toml similarity index 99% rename from examples/langchain/pyproject.toml rename to integrations/frameworks/langchain/pyproject.toml index c32842ccae..b44c5814e2 100644 --- a/examples/langchain/pyproject.toml +++ b/integrations/frameworks/langchain/pyproject.toml @@ -62,7 +62,7 @@ include = ["langchain_openviking*"] langchain_openviking = ["py.typed"] [tool.setuptools_scm] -root = "../.." +root = "../../.." local_scheme = "no-local-version" tag_regex = "^langchain-openviking@(?P[0-9]+(?:\\.[0-9]+)*)$" git_describe_command = "git describe --dirty --tags --long --match langchain-openviking@*" diff --git a/examples/langchain/src/langchain_openviking/__init__.py b/integrations/frameworks/langchain/src/langchain_openviking/__init__.py similarity index 100% rename from examples/langchain/src/langchain_openviking/__init__.py rename to integrations/frameworks/langchain/src/langchain_openviking/__init__.py diff --git a/examples/langchain/src/langchain_openviking/_async_client_cache.py b/integrations/frameworks/langchain/src/langchain_openviking/_async_client_cache.py similarity index 100% rename from examples/langchain/src/langchain_openviking/_async_client_cache.py rename to integrations/frameworks/langchain/src/langchain_openviking/_async_client_cache.py diff --git a/examples/langchain/src/langchain_openviking/_testing_utils.py b/integrations/frameworks/langchain/src/langchain_openviking/_testing_utils.py similarity index 100% rename from examples/langchain/src/langchain_openviking/_testing_utils.py rename to integrations/frameworks/langchain/src/langchain_openviking/_testing_utils.py diff --git a/examples/langchain/src/langchain_openviking/_uri.py b/integrations/frameworks/langchain/src/langchain_openviking/_uri.py similarity index 100% rename from examples/langchain/src/langchain_openviking/_uri.py rename to integrations/frameworks/langchain/src/langchain_openviking/_uri.py diff --git a/examples/langchain/src/langchain_openviking/actor_peer.py b/integrations/frameworks/langchain/src/langchain_openviking/actor_peer.py similarity index 100% rename from examples/langchain/src/langchain_openviking/actor_peer.py rename to integrations/frameworks/langchain/src/langchain_openviking/actor_peer.py diff --git a/examples/langchain/src/langchain_openviking/client.py b/integrations/frameworks/langchain/src/langchain_openviking/client.py similarity index 100% rename from examples/langchain/src/langchain_openviking/client.py rename to integrations/frameworks/langchain/src/langchain_openviking/client.py diff --git a/examples/langchain/src/langchain_openviking/context.py b/integrations/frameworks/langchain/src/langchain_openviking/context.py similarity index 100% rename from examples/langchain/src/langchain_openviking/context.py rename to integrations/frameworks/langchain/src/langchain_openviking/context.py diff --git a/examples/langchain/src/langchain_openviking/history.py b/integrations/frameworks/langchain/src/langchain_openviking/history.py similarity index 100% rename from examples/langchain/src/langchain_openviking/history.py rename to integrations/frameworks/langchain/src/langchain_openviking/history.py diff --git a/examples/langchain/src/langchain_openviking/messages.py b/integrations/frameworks/langchain/src/langchain_openviking/messages.py similarity index 100% rename from examples/langchain/src/langchain_openviking/messages.py rename to integrations/frameworks/langchain/src/langchain_openviking/messages.py diff --git a/examples/langchain/src/langchain_openviking/middleware.py b/integrations/frameworks/langchain/src/langchain_openviking/middleware.py similarity index 100% rename from examples/langchain/src/langchain_openviking/middleware.py rename to integrations/frameworks/langchain/src/langchain_openviking/middleware.py diff --git a/examples/langchain/src/langchain_openviking/py.typed b/integrations/frameworks/langchain/src/langchain_openviking/py.typed similarity index 100% rename from examples/langchain/src/langchain_openviking/py.typed rename to integrations/frameworks/langchain/src/langchain_openviking/py.typed diff --git a/examples/langchain/src/langchain_openviking/recording.py b/integrations/frameworks/langchain/src/langchain_openviking/recording.py similarity index 100% rename from examples/langchain/src/langchain_openviking/recording.py rename to integrations/frameworks/langchain/src/langchain_openviking/recording.py diff --git a/examples/langchain/src/langchain_openviking/retrievers.py b/integrations/frameworks/langchain/src/langchain_openviking/retrievers.py similarity index 100% rename from examples/langchain/src/langchain_openviking/retrievers.py rename to integrations/frameworks/langchain/src/langchain_openviking/retrievers.py diff --git a/examples/langchain/src/langchain_openviking/store.py b/integrations/frameworks/langchain/src/langchain_openviking/store.py similarity index 100% rename from examples/langchain/src/langchain_openviking/store.py rename to integrations/frameworks/langchain/src/langchain_openviking/store.py diff --git a/examples/langchain/src/langchain_openviking/testing.py b/integrations/frameworks/langchain/src/langchain_openviking/testing.py similarity index 100% rename from examples/langchain/src/langchain_openviking/testing.py rename to integrations/frameworks/langchain/src/langchain_openviking/testing.py diff --git a/examples/langchain/src/langchain_openviking/tools.py b/integrations/frameworks/langchain/src/langchain_openviking/tools.py similarity index 100% rename from examples/langchain/src/langchain_openviking/tools.py rename to integrations/frameworks/langchain/src/langchain_openviking/tools.py diff --git a/examples/langchain/tests/installed_base_smoke.py b/integrations/frameworks/langchain/tests/installed_base_smoke.py similarity index 100% rename from examples/langchain/tests/installed_base_smoke.py rename to integrations/frameworks/langchain/tests/installed_base_smoke.py diff --git a/examples/langchain/tests/installed_smoke.py b/integrations/frameworks/langchain/tests/installed_smoke.py similarity index 100% rename from examples/langchain/tests/installed_smoke.py rename to integrations/frameworks/langchain/tests/installed_smoke.py diff --git a/tests/integration/langchain_langgraph/conftest.py b/integrations/frameworks/langchain/tests/integration/conftest.py similarity index 100% rename from tests/integration/langchain_langgraph/conftest.py rename to integrations/frameworks/langchain/tests/integration/conftest.py diff --git a/tests/integration/langchain_langgraph/live_e2e.py b/integrations/frameworks/langchain/tests/integration/live_e2e.py similarity index 99% rename from tests/integration/langchain_langgraph/live_e2e.py rename to integrations/frameworks/langchain/tests/integration/live_e2e.py index c5bc2366ac..0b8a5a6611 100644 --- a/tests/integration/langchain_langgraph/live_e2e.py +++ b/integrations/frameworks/langchain/tests/integration/live_e2e.py @@ -17,6 +17,11 @@ from langchain_core.messages import AIMessage, BaseMessage, HumanMessage, SystemMessage from langchain_core.runnables import RunnableLambda from langchain_core.runnables.history import RunnableWithMessageHistory +from langgraph.graph import END, START, StateGraph +from langgraph.graph.message import add_messages +from openai import OpenAI +from typing_extensions import Annotated, TypedDict + from langchain_openviking import ( OpenVikingChatMessageHistory, OpenVikingContextMiddleware, @@ -26,10 +31,6 @@ with_openviking_context, ) from langchain_openviking.client import extract_message_text -from langgraph.graph import END, START, StateGraph -from langgraph.graph.message import add_messages -from openai import OpenAI -from typing_extensions import Annotated, TypedDict def test_true_live_langchain_context_backend_e2e(): diff --git a/tests/integration/langchain_langgraph/test_async_recording.py b/integrations/frameworks/langchain/tests/integration/test_async_recording.py similarity index 99% rename from tests/integration/langchain_langgraph/test_async_recording.py rename to integrations/frameworks/langchain/tests/integration/test_async_recording.py index 05cbd44d32..fa84a12465 100644 --- a/tests/integration/langchain_langgraph/test_async_recording.py +++ b/integrations/frameworks/langchain/tests/integration/test_async_recording.py @@ -15,6 +15,7 @@ from langchain_core.messages import AIMessage, BaseMessage, HumanMessage from langchain_core.runnables import RunnableLambda from langchain_core.runnables.history import RunnableWithMessageHistory + from langchain_openviking import ( InMemoryOpenVikingClient, OpenVikingChatMessageHistory, diff --git a/tests/integration/langchain_langgraph/test_context_lifecycle.py b/integrations/frameworks/langchain/tests/integration/test_context_lifecycle.py similarity index 99% rename from tests/integration/langchain_langgraph/test_context_lifecycle.py rename to integrations/frameworks/langchain/tests/integration/test_context_lifecycle.py index 931a7ce5d5..5a9205dcef 100644 --- a/tests/integration/langchain_langgraph/test_context_lifecycle.py +++ b/integrations/frameworks/langchain/tests/integration/test_context_lifecycle.py @@ -13,6 +13,7 @@ from langchain_core.messages import AIMessage, BaseMessage, HumanMessage from langchain_core.runnables import RunnableLambda from langchain_core.runnables.history import RunnableWithMessageHistory + from langchain_openviking import ( OpenVikingCommitPolicy, OpenVikingContextRunnable, diff --git a/tests/integration/langchain_langgraph/test_recording.py b/integrations/frameworks/langchain/tests/integration/test_recording.py similarity index 99% rename from tests/integration/langchain_langgraph/test_recording.py rename to integrations/frameworks/langchain/tests/integration/test_recording.py index fab2213006..983e8125c5 100644 --- a/tests/integration/langchain_langgraph/test_recording.py +++ b/integrations/frameworks/langchain/tests/integration/test_recording.py @@ -12,6 +12,7 @@ from langchain_core.messages import AIMessage, BaseMessage, HumanMessage from langchain_core.runnables import RunnableLambda from langchain_core.runnables.history import RunnableWithMessageHistory + from langchain_openviking import ( InMemoryOpenVikingClient, OpenVikingChatMessageHistory, diff --git a/tests/integration/langchain_langgraph/test_runtime_actor_peer.py b/integrations/frameworks/langchain/tests/integration/test_runtime_actor_peer.py similarity index 100% rename from tests/integration/langchain_langgraph/test_runtime_actor_peer.py rename to integrations/frameworks/langchain/tests/integration/test_runtime_actor_peer.py diff --git a/tests/integration/langchain_langgraph/test_smoke.py b/integrations/frameworks/langchain/tests/integration/test_smoke.py similarity index 73% rename from tests/integration/langchain_langgraph/test_smoke.py rename to integrations/frameworks/langchain/tests/integration/test_smoke.py index a519a78086..cf0bc04f6e 100644 --- a/tests/integration/langchain_langgraph/test_smoke.py +++ b/integrations/frameworks/langchain/tests/integration/test_smoke.py @@ -9,12 +9,12 @@ pytest.importorskip("langgraph") pytest.importorskip("langchain_openviking") -PROJECT_ROOT = Path(__file__).resolve().parents[3] +EXAMPLES_ROOT = Path(__file__).resolve().parents[2] / "examples" def test_langchain_quick_app_runs(): namespace = runpy.run_path( - str(PROJECT_ROOT / "examples/langchain-langgraph/langchain/rag/quick_app.py"), + str(EXAMPLES_ROOT / "langchain/rag/quick_app.py"), run_name="openviking_langchain_quick", ) @@ -24,7 +24,7 @@ def test_langchain_quick_app_runs(): def test_langchain_context_backend_quick_app_runs(): namespace = runpy.run_path( - str(PROJECT_ROOT / "examples/langchain-langgraph/langchain/context-backend/quick_app.py"), + str(EXAMPLES_ROOT / "langchain/context-backend/quick_app.py"), run_name="openviking_langchain_context_backend_quick", ) @@ -35,7 +35,7 @@ def test_langchain_context_backend_quick_app_runs(): def test_langchain_message_history_quick_app_runs(): namespace = runpy.run_path( - str(PROJECT_ROOT / "examples/langchain-langgraph/langchain/message-history/quick_app.py"), + str(EXAMPLES_ROOT / "langchain/message-history/quick_app.py"), run_name="openviking_langchain_message_history_quick", ) @@ -46,7 +46,7 @@ def test_langchain_message_history_quick_app_runs(): def test_langgraph_quick_app_runs(): namespace = runpy.run_path( - str(PROJECT_ROOT / "examples/langchain-langgraph/langgraph/agent/quick_app.py"), + str(EXAMPLES_ROOT / "langgraph/agent/quick_app.py"), run_name="openviking_langgraph_quick", ) @@ -57,7 +57,7 @@ def test_langgraph_quick_app_runs(): def test_langgraph_middleware_quick_app_runs(): namespace = runpy.run_path( - str(PROJECT_ROOT / "examples/langchain-langgraph/langgraph/middleware/quick_app.py"), + str(EXAMPLES_ROOT / "langgraph/middleware/quick_app.py"), run_name="openviking_langgraph_middleware_quick", ) diff --git a/examples/langchain/tests/test_store.py b/integrations/frameworks/langchain/tests/test_store.py similarity index 100% rename from examples/langchain/tests/test_store.py rename to integrations/frameworks/langchain/tests/test_store.py diff --git a/tests/unit/test_langchain_async_integration.py b/integrations/frameworks/langchain/tests/unit/test_langchain_async_integration.py similarity index 99% rename from tests/unit/test_langchain_async_integration.py rename to integrations/frameworks/langchain/tests/unit/test_langchain_async_integration.py index 41dccedc73..98698da3b6 100644 --- a/tests/unit/test_langchain_async_integration.py +++ b/integrations/frameworks/langchain/tests/unit/test_langchain_async_integration.py @@ -13,6 +13,7 @@ pytest.importorskip("langchain_openviking") from langchain_core.messages import AIMessage, HumanMessage + from langchain_openviking import ( InMemoryOpenVikingClient, OpenVikingCancellationProgress, diff --git a/tests/unit/test_langchain_host_history.py b/integrations/frameworks/langchain/tests/unit/test_langchain_host_history.py similarity index 99% rename from tests/unit/test_langchain_host_history.py rename to integrations/frameworks/langchain/tests/unit/test_langchain_host_history.py index 3fc5cc0568..bc2c49f897 100644 --- a/tests/unit/test_langchain_host_history.py +++ b/integrations/frameworks/langchain/tests/unit/test_langchain_host_history.py @@ -11,6 +11,7 @@ from langchain_core.chat_history import InMemoryChatMessageHistory from langchain_core.messages import AIMessage, HumanMessage from langchain_core.runnables import RunnableLambda + from langchain_openviking import ( InMemoryOpenVikingClient, OpenVikingCommitPolicy, diff --git a/tests/unit/test_langchain_integration.py b/integrations/frameworks/langchain/tests/unit/test_langchain_integration.py similarity index 99% rename from tests/unit/test_langchain_integration.py rename to integrations/frameworks/langchain/tests/unit/test_langchain_integration.py index e9321a1611..d0affed064 100644 --- a/tests/unit/test_langchain_integration.py +++ b/integrations/frameworks/langchain/tests/unit/test_langchain_integration.py @@ -10,9 +10,12 @@ pytest.importorskip("langgraph") pytest.importorskip("langchain_openviking") -import langchain_openviking.client as client_helpers from langchain_core.messages import AIMessage, HumanMessage, SystemMessage, ToolMessage from langchain_core.runnables import RunnableLambda +from langgraph.store.base import PutOp +from openviking_sdk.errors import InvalidArgumentError + +import langchain_openviking.client as client_helpers from langchain_openviking import ( InMemoryOpenVikingClient, OpenVikingChatMessageHistory, @@ -36,8 +39,6 @@ ) from langchain_openviking.middleware import _message_signature from langchain_openviking.tools import _archive_grep_pattern, _resolve_resource_source -from langgraph.store.base import PutOp -from openviking_sdk.errors import InvalidArgumentError def test_langchain_client_exposes_apply_commit_policy_without_legacy_alias(): diff --git a/tests/unit/test_langchain_lifecycle_resources.py b/integrations/frameworks/langchain/tests/unit/test_langchain_lifecycle_resources.py similarity index 100% rename from tests/unit/test_langchain_lifecycle_resources.py rename to integrations/frameworks/langchain/tests/unit/test_langchain_lifecycle_resources.py diff --git a/tests/unit/test_langchain_recording.py b/integrations/frameworks/langchain/tests/unit/test_langchain_recording.py similarity index 99% rename from tests/unit/test_langchain_recording.py rename to integrations/frameworks/langchain/tests/unit/test_langchain_recording.py index cc44df8624..5177e8d74e 100644 --- a/tests/unit/test_langchain_recording.py +++ b/integrations/frameworks/langchain/tests/unit/test_langchain_recording.py @@ -7,7 +7,6 @@ pytest.importorskip("langchain_core") pytest.importorskip("langchain_openviking") -import langchain_openviking.recording as recording_module from langchain_core.messages import ( AIMessage, BaseMessage, @@ -15,6 +14,8 @@ SystemMessage, ToolMessage, ) + +import langchain_openviking.recording as recording_module from langchain_openviking import ( InMemoryOpenVikingClient, OpenVikingChatMessageHistory, diff --git a/tests/unit/test_langchain_runtime_actor_peer.py b/integrations/frameworks/langchain/tests/unit/test_langchain_runtime_actor_peer.py similarity index 100% rename from tests/unit/test_langchain_runtime_actor_peer.py rename to integrations/frameworks/langchain/tests/unit/test_langchain_runtime_actor_peer.py diff --git a/examples/agent-framework/README.md b/integrations/frameworks/microsoft-agent-framework/README.md similarity index 89% rename from examples/agent-framework/README.md rename to integrations/frameworks/microsoft-agent-framework/README.md index e113ce3f2e..b51e4f5609 100644 --- a/examples/agent-framework/README.md +++ b/integrations/frameworks/microsoft-agent-framework/README.md @@ -10,14 +10,14 @@ Requires Python 3.10+, MAF core 1.20–1.x, OpenViking SDK 0.1.13–0.1.x, and a running OpenViking 0.4.23+ server. Install from an OpenViking checkout: ```bash -pip install './examples/agent-framework[example]' +pip install './integrations/frameworks/microsoft-agent-framework[example]' ``` Set `OPENVIKING_URL`, `OPENVIKING_API_KEY` (a normal user key), `OPENAI_API_KEY`, `OPENAI_BASE_URL`, and `OPENAI_MODEL`, then run: ```bash -python examples/agent-framework/example.py +python integrations/frameworks/microsoft-agent-framework/examples/example.py ``` The example records a preference, waits for extraction, and asks about it in a new @@ -104,8 +104,8 @@ execution and chat history. No framework modifications or MCP tools are required ## Validate ```bash -pip install -e './examples/agent-framework[test,dev]' -cd examples/agent-framework +pip install -e './integrations/frameworks/microsoft-agent-framework[test,dev]' +cd integrations/frameworks/microsoft-agent-framework pytest -q --confcutdir=tests tests ruff check . ruff format --check . @@ -116,3 +116,6 @@ python -m build Offline tests use the real MAF agent lifecycle with deterministic model and SDK boundaries. They require no server, credentials, or model calls. Support belongs in [OpenViking issues](https://github.com/volcengine/OpenViking/issues/new/choose). + +See the [framework adapter guide](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/README.md) for adding other integrations. +The adapter is AGPL-3.0; the runnable [example](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/microsoft-agent-framework/examples/LICENSE) retains Apache-2.0. diff --git a/integrations/frameworks/microsoft-agent-framework/examples/LICENSE b/integrations/frameworks/microsoft-agent-framework/examples/LICENSE new file mode 100644 index 0000000000..b65287786d --- /dev/null +++ b/integrations/frameworks/microsoft-agent-framework/examples/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited + to communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including but negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor + be liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Der Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if you agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/examples/agent-framework/example.py b/integrations/frameworks/microsoft-agent-framework/examples/example.py similarity index 100% rename from examples/agent-framework/example.py rename to integrations/frameworks/microsoft-agent-framework/examples/example.py diff --git a/examples/agent-framework/pyproject.toml b/integrations/frameworks/microsoft-agent-framework/pyproject.toml similarity index 95% rename from examples/agent-framework/pyproject.toml rename to integrations/frameworks/microsoft-agent-framework/pyproject.toml index 4818dc7f88..05ec56524b 100644 --- a/examples/agent-framework/pyproject.toml +++ b/integrations/frameworks/microsoft-agent-framework/pyproject.toml @@ -18,7 +18,7 @@ dev = ["ruff", "mypy", "build", "twine"] [project.urls] Repository = "https://github.com/volcengine/OpenViking" -Documentation = "https://github.com/volcengine/OpenViking/tree/main/examples/agent-framework" +Documentation = "https://github.com/volcengine/OpenViking/tree/main/integrations/frameworks/microsoft-agent-framework" Issues = "https://github.com/volcengine/OpenViking/issues/new/choose" [tool.setuptools.packages.find] diff --git a/examples/agent-framework/src/openviking_agent_framework/__init__.py b/integrations/frameworks/microsoft-agent-framework/src/openviking_agent_framework/__init__.py similarity index 100% rename from examples/agent-framework/src/openviking_agent_framework/__init__.py rename to integrations/frameworks/microsoft-agent-framework/src/openviking_agent_framework/__init__.py diff --git a/examples/agent-framework/src/openviking_agent_framework/provider.py b/integrations/frameworks/microsoft-agent-framework/src/openviking_agent_framework/provider.py similarity index 100% rename from examples/agent-framework/src/openviking_agent_framework/provider.py rename to integrations/frameworks/microsoft-agent-framework/src/openviking_agent_framework/provider.py diff --git a/examples/agent-framework/src/openviking_agent_framework/py.typed b/integrations/frameworks/microsoft-agent-framework/src/openviking_agent_framework/py.typed similarity index 100% rename from examples/agent-framework/src/openviking_agent_framework/py.typed rename to integrations/frameworks/microsoft-agent-framework/src/openviking_agent_framework/py.typed diff --git a/examples/agent-framework/tests/test_provider.py b/integrations/frameworks/microsoft-agent-framework/tests/test_provider.py similarity index 100% rename from examples/agent-framework/tests/test_provider.py rename to integrations/frameworks/microsoft-agent-framework/tests/test_provider.py diff --git a/openviking/integrations/__init__.py b/openviking/integrations/__init__.py deleted file mode 100644 index 857da4c89b..0000000000 --- a/openviking/integrations/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: AGPL-3.0 -"""Optional framework integrations for OpenViking.""" diff --git a/openviking/integrations/langchain/__init__.py b/openviking/integrations/langchain/__init__.py deleted file mode 100644 index 40e2fc0348..0000000000 --- a/openviking/integrations/langchain/__init__.py +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: AGPL-3.0 -"""Compatibility imports for the standalone ``langchain-openviking`` package.""" - -from __future__ import annotations - -from importlib import import_module -from typing import Any - -_LEGACY_EXPORTS = [ - "InMemoryOpenVikingClient", - "OpenVikingChatMessageHistory", - "OpenVikingCancellationProgress", - "OpenVikingCommitPolicy", - "OpenVikingContextRunnable", - "OpenVikingContextMiddleware", - "OpenVikingPartialWriteError", - "OpenVikingRecordResult", - "OpenVikingRetriever", - "OpenVikingSessionContextAssembler", - "OpenVikingSessionRecorder", - "OpenVikingStore", - "create_openviking_tools", - "get_openviking_cancellation_progress", - "has_request_actor_peer_support", - "with_openviking_context", -] - - -def _missing_standalone_error() -> ImportError: - return ImportError( - "The legacy OpenViking LangChain integration requires the standalone " - "langchain-openviking package. Install it with " - "`pip install langchain-openviking` (or " - '`pip install "langchain-openviking[langgraph]"` for LangGraph support).' - ) - - -def _forward_legacy_module(module_name: str, namespace: dict[str, Any]) -> None: - """Populate a legacy submodule with the canonical package's public names.""" - - try: - canonical = import_module(f"langchain_openviking.{module_name}") - except ModuleNotFoundError as exc: - if exc.name != "langchain_openviking": - raise - raise _missing_standalone_error() from exc - - public_names = getattr(canonical, "__all__", None) - if public_names is None: - public_names = (name for name in vars(canonical) if not name.startswith("_")) - namespace.update({name: getattr(canonical, name) for name in public_names}) - - -try: - from langchain_openviking import __all__, __getattr__, has_request_actor_peer_support -except ModuleNotFoundError as exc: - if exc.name != "langchain_openviking": - raise - - __all__ = _LEGACY_EXPORTS - - def has_request_actor_peer_support() -> bool: - """Return whether the installed SDK supports request-scoped actor peers.""" - - openviking_sdk = import_module("openviking_sdk") - return ( - getattr(openviking_sdk, "get_actor_peer_id", None) is not None - and getattr(openviking_sdk, "use_actor_peer", None) is not None - ) - - def __getattr__(name: str) -> Any: - if name in __all__: - raise _missing_standalone_error() - raise AttributeError(name) diff --git a/openviking/integrations/langchain/actor_peer.py b/openviking/integrations/langchain/actor_peer.py deleted file mode 100644 index 2c263911e5..0000000000 --- a/openviking/integrations/langchain/actor_peer.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: AGPL-3.0 -"""Compatibility wrapper for :mod:`langchain_openviking.actor_peer`.""" - -from openviking.integrations.langchain import _forward_legacy_module - -_forward_legacy_module("actor_peer", globals()) diff --git a/openviking/integrations/langchain/client.py b/openviking/integrations/langchain/client.py deleted file mode 100644 index 8f21bfc819..0000000000 --- a/openviking/integrations/langchain/client.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: AGPL-3.0 -"""Compatibility wrapper for :mod:`langchain_openviking.client`.""" - -from openviking.integrations.langchain import _forward_legacy_module - -_forward_legacy_module("client", globals()) diff --git a/openviking/integrations/langchain/context.py b/openviking/integrations/langchain/context.py deleted file mode 100644 index 9b80429bf2..0000000000 --- a/openviking/integrations/langchain/context.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: AGPL-3.0 -"""Compatibility wrapper for :mod:`langchain_openviking.context`.""" - -from openviking.integrations.langchain import _forward_legacy_module - -_forward_legacy_module("context", globals()) diff --git a/openviking/integrations/langchain/history.py b/openviking/integrations/langchain/history.py deleted file mode 100644 index 74a079669f..0000000000 --- a/openviking/integrations/langchain/history.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: AGPL-3.0 -"""Compatibility wrapper for :mod:`langchain_openviking.history`.""" - -from openviking.integrations.langchain import _forward_legacy_module - -_forward_legacy_module("history", globals()) diff --git a/openviking/integrations/langchain/messages.py b/openviking/integrations/langchain/messages.py deleted file mode 100644 index 006cd29c11..0000000000 --- a/openviking/integrations/langchain/messages.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: AGPL-3.0 -"""Compatibility wrapper for :mod:`langchain_openviking.messages`.""" - -from openviking.integrations.langchain import _forward_legacy_module - -_forward_legacy_module("messages", globals()) diff --git a/openviking/integrations/langchain/middleware.py b/openviking/integrations/langchain/middleware.py deleted file mode 100644 index ed5ddfa49d..0000000000 --- a/openviking/integrations/langchain/middleware.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: AGPL-3.0 -"""Compatibility wrapper for :mod:`langchain_openviking.middleware`.""" - -from openviking.integrations.langchain import _forward_legacy_module - -_forward_legacy_module("middleware", globals()) diff --git a/openviking/integrations/langchain/recording.py b/openviking/integrations/langchain/recording.py deleted file mode 100644 index 6167d07182..0000000000 --- a/openviking/integrations/langchain/recording.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: AGPL-3.0 -"""Compatibility wrapper for :mod:`langchain_openviking.recording`.""" - -from openviking.integrations.langchain import _forward_legacy_module - -_forward_legacy_module("recording", globals()) diff --git a/openviking/integrations/langchain/retrievers.py b/openviking/integrations/langchain/retrievers.py deleted file mode 100644 index 6edea13418..0000000000 --- a/openviking/integrations/langchain/retrievers.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: AGPL-3.0 -"""Compatibility wrapper for :mod:`langchain_openviking.retrievers`.""" - -from openviking.integrations.langchain import _forward_legacy_module - -_forward_legacy_module("retrievers", globals()) diff --git a/openviking/integrations/langchain/store.py b/openviking/integrations/langchain/store.py deleted file mode 100644 index 7383185096..0000000000 --- a/openviking/integrations/langchain/store.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: AGPL-3.0 -"""Compatibility wrapper for :mod:`langchain_openviking.store`.""" - -from openviking.integrations.langchain import _forward_legacy_module - -_forward_legacy_module("store", globals()) diff --git a/openviking/integrations/langchain/testing.py b/openviking/integrations/langchain/testing.py deleted file mode 100644 index 7360e8e099..0000000000 --- a/openviking/integrations/langchain/testing.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: AGPL-3.0 -"""Compatibility wrapper for :mod:`langchain_openviking.testing`.""" - -from openviking.integrations.langchain import _forward_legacy_module - -_forward_legacy_module("testing", globals()) diff --git a/openviking/integrations/langchain/tools.py b/openviking/integrations/langchain/tools.py deleted file mode 100644 index 6d87fdbb88..0000000000 --- a/openviking/integrations/langchain/tools.py +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2026 Beijing Volcano Engine Technology Co., Ltd. -# SPDX-License-Identifier: AGPL-3.0 -"""Compatibility wrapper for :mod:`langchain_openviking.tools`.""" - -from openviking.integrations.langchain import _forward_legacy_module - -_forward_legacy_module("tools", globals()) diff --git a/tests/unit/test_langchain_package_boundary.py b/tests/unit/test_langchain_package_boundary.py index cd33f5119a..6db557b70a 100644 --- a/tests/unit/test_langchain_package_boundary.py +++ b/tests/unit/test_langchain_package_boundary.py @@ -4,13 +4,12 @@ import os import subprocess import sys -from importlib import import_module from pathlib import Path import pytest PROJECT_ROOT = Path(__file__).resolve().parents[2] -PACKAGE_ROOT = PROJECT_ROOT / "examples" / "langchain" +PACKAGE_ROOT = PROJECT_ROOT / "integrations" / "frameworks" / "langchain" SOURCE_ROOT = PACKAGE_ROOT / "src" SDK_ROOT = PROJECT_ROOT / "sdk" / "python" @@ -25,7 +24,9 @@ def test_server_distribution_does_not_depend_on_standalone_integration(): def test_standalone_package_has_no_server_imports_at_module_scope(): violations: list[str] = [] - for source_file in sorted((SOURCE_ROOT / "langchain_openviking").glob("*.py")): + source_files = sorted((SOURCE_ROOT / "langchain_openviking").glob("*.py")) + assert source_files, "Standalone package source must be available for the boundary check" + for source_file in source_files: tree = ast.parse(source_file.read_text(encoding="utf-8"), filename=str(source_file)) for node in tree.body: if isinstance(node, ast.ImportFrom): @@ -113,107 +114,6 @@ def test_base_star_import_omits_optional_middleware(tmp_path): ) -def test_legacy_namespace_remains_importable_without_standalone_package(tmp_path): - env = os.environ.copy() - env["PYTHONPATH"] = os.pathsep.join((str(PROJECT_ROOT), str(SDK_ROOT))) - probe = """ -import importlib.abc -import importlib -import sys - - -class BlockStandalonePackage(importlib.abc.MetaPathFinder): - def find_spec(self, fullname, path=None, target=None): - if fullname == "langchain_openviking" or fullname.startswith("langchain_openviking."): - raise ModuleNotFoundError( - "No module named 'langchain_openviking'", - name="langchain_openviking", - ) - return None - - -sys.meta_path.insert(0, BlockStandalonePackage()) - -import openviking.integrations.langchain as legacy - -assert "OpenVikingRetriever" in legacy.__all__ -assert isinstance(legacy.has_request_actor_peer_support(), bool) - -try: - legacy.OpenVikingRetriever -except ImportError as exc: - message = str(exc) - assert "langchain-openviking" in message - assert "openviking[langchain]" not in message -else: - raise AssertionError("missing standalone package should produce an installation error") - -for submodule in ( - "actor_peer", - "client", - "context", - "history", - "messages", - "middleware", - "recording", - "retrievers", - "store", - "testing", - "tools", -): - try: - importlib.import_module(f"openviking.integrations.langchain.{submodule}") - except ImportError as exc: - assert not isinstance(exc, ModuleNotFoundError) - message = str(exc) - assert "langchain-openviking" in message - assert "openviking[langchain]" not in message - else: - raise AssertionError(f"legacy {submodule} import should produce an installation error") -""" - - subprocess.run( - [sys.executable, "-c", probe], - cwd=tmp_path, - env=env, - check=True, - capture_output=True, - text=True, - ) - - -def test_legacy_imports_resolve_to_canonical_objects(): - pytest.importorskip("langchain_core") - pytest.importorskip("langchain_openviking") - canonical = import_module("langchain_openviking") - legacy = import_module("openviking.integrations.langchain") - - for name in canonical.__all__: - assert getattr(legacy, name) is getattr(canonical, name) - - for submodule in ( - "actor_peer", - "client", - "context", - "history", - "messages", - "middleware", - "recording", - "retrievers", - "store", - "testing", - "tools", - ): - legacy_module = import_module(f"openviking.integrations.langchain.{submodule}") - canonical_module = import_module(f"langchain_openviking.{submodule}") - legacy_public = {name for name in vars(legacy_module) if not name.startswith("_")} - canonical_public = {name for name in vars(canonical_module) if not name.startswith("_")} - - assert legacy_public == canonical_public - for name in sorted(canonical_public): - assert getattr(legacy_module, name) is getattr(canonical_module, name) - - @pytest.mark.parametrize( ("uri", "expected_parts", "expected_scope", "expected_content_index"), [ From 7965bf2de884c63958db21f21297d981d7f4e432 Mon Sep 17 00:00:00 2001 From: Hao Zhe Date: Wed, 14 Oct 2026 01:00:44 +0800 Subject: [PATCH 2/8] fix(integrations): document migration and include licenses Signed-off-by: Hao Zhe --- .github/workflows/_build.yml | 9 + README.md | 2 +- docs/en/about/02-changelog.md | 9 + docs/repository/README_CN.md | 1 + docs/repository/README_JA.md | 1 + docs/zh/about/02-changelog.md | 9 + integrations/frameworks/langchain/LICENSE | 662 ++++++++++++++++++ integrations/frameworks/langchain/README.md | 3 +- .../frameworks/langchain/README_CN.md | 3 +- .../frameworks/langchain/pyproject.toml | 3 +- .../microsoft-agent-framework/LICENSE | 662 ++++++++++++++++++ .../microsoft-agent-framework/README.md | 3 +- .../microsoft-agent-framework/pyproject.toml | 1 + tests/unit/test_langchain_package_boundary.py | 4 + 14 files changed, 1367 insertions(+), 5 deletions(-) create mode 100644 integrations/frameworks/langchain/LICENSE create mode 100644 integrations/frameworks/microsoft-agent-framework/LICENSE diff --git a/.github/workflows/_build.yml b/.github/workflows/_build.yml index f673a3a0b6..6a7a03d650 100644 --- a/.github/workflows/_build.yml +++ b/.github/workflows/_build.yml @@ -320,6 +320,9 @@ jobs: from openviking.pyagfs import get_binding_client import openviking.storage.vectordb.engine as engine + if importlib.util.find_spec("openviking.integrations") is not None: + raise SystemExit("Server wheel must not ship the removed framework namespace") + binding_client, _ = get_binding_client() if binding_client is None: raise SystemExit("ragfs binding client was not installed") @@ -555,6 +558,9 @@ jobs: from openviking.pyagfs import get_binding_client import openviking.storage.vectordb.engine as engine + if importlib.util.find_spec("openviking.integrations") is not None: + raise SystemExit("Server wheel must not ship the removed framework namespace") + binding_client, _ = get_binding_client() if binding_client is None: raise SystemExit("ragfs binding client was not installed") @@ -591,6 +597,9 @@ jobs: import openviking.storage.vectordb.engine as engine + if importlib.util.find_spec("openviking.integrations") is not None: + raise SystemExit("Server wheel must not ship the removed framework namespace") + print(f"Loaded runtime engine variant {engine.ENGINE_VARIANT}") print(f"Available engine variants {engine.AVAILABLE_ENGINE_VARIANTS}") diff --git a/README.md b/README.md index 066c0d931b..d380ca5070 100644 --- a/README.md +++ b/README.md @@ -426,7 +426,7 @@ The OpenViking project uses different licenses for different components: - **Main Project**: AGPLv3 - see the [LICENSE](./LICENSE) file for details - **crates/ov\_cli**: Apache 2.0 - see the [LICENSE](./crates/LICENSE) for details - **examples**: Apache 2.0 - see the [LICENSE](./examples/LICENSE) for details. The Hermes plugin in `examples/hermes-plugin` retains its [MIT license](./examples/hermes-plugin/LICENSE). -- **integrations/frameworks**: adapters use AGPLv3; their runnable examples retain Apache 2.0, with licenses in each package's `examples/` directory. +- **integrations/frameworks**: adapters declare AGPLv3 in their package metadata and source headers; see each package's `LICENSE`. Their runnable examples retain Apache 2.0; see each package's `examples/LICENSE`. - **third\_party**: Respective original licenses of third-party projects Please also note: any wholesale rewriting and subsequent re-open-sourcing of this project is prohibited; any request to translate all or a substantial portion of the project code into another coding language requires prior written authorization from Volcano Engine. For permission requests, please contact the Volcano Engine team — see [Community & Contributing](#community--contributing) for contact channels. diff --git a/docs/en/about/02-changelog.md b/docs/en/about/02-changelog.md index 7a0fdae959..eee9c12ff1 100644 --- a/docs/en/about/02-changelog.md +++ b/docs/en/about/02-changelog.md @@ -7,6 +7,15 @@ This changelog is automatically generated from [GitHub Releases](https://github. ## Unreleased +- **LangChain import migration (breaking change)**: The server no longer ships + `openviking.integrations.langchain` or its forwarding modules. Old imports fail + immediately; there is no deprecation period or compatibility stub. Install + `langchain-openviking` (or `pip install "langchain-openviking[langgraph]"` for + LangGraph) and replace the `openviking.integrations.langchain` prefix with + `langchain_openviking`, including submodule imports. For example, use + `from langchain_openviking import OpenVikingRetriever`. The maintained packages + and examples now live under `integrations/frameworks/`; package names and + canonical imports are unchanged. See the [migration guide](../agent-integrations/07-langchain-langgraph.md). - **Working Memory defaults off (behavior change)**: Commits continue to archive raw messages and extract long-term memories, but generate no WM/checkpoint summaries by default. Update installed agent plugins separately: automatic archive injection and takeover now diff --git a/docs/repository/README_CN.md b/docs/repository/README_CN.md index e9b82bb279..1866b679d1 100644 --- a/docs/repository/README_CN.md +++ b/docs/repository/README_CN.md @@ -417,4 +417,5 @@ OpenViking 各组件采用不同的许可证: - **主项目**:AGPLv3——详见 [LICENSE](../../LICENSE) - **crates/ov\_cli**:Apache 2.0——详见 [LICENSE](../../crates/LICENSE) - **examples**:Apache 2.0——详见 [LICENSE](../../examples/LICENSE)。`examples/hermes-plugin` 中的 Hermes 插件保留其 [MIT 许可证](../../examples/hermes-plugin/LICENSE)。 +- **integrations/frameworks**:适配器的包元数据和源码声明 AGPLv3,详见各包的 `LICENSE`;可运行示例保留 Apache 2.0,详见各包的 `examples/LICENSE`。 - **third\_party**:各三方项目保留其原有协议 diff --git a/docs/repository/README_JA.md b/docs/repository/README_JA.md index 8f10ea8d9e..17107844c1 100644 --- a/docs/repository/README_JA.md +++ b/docs/repository/README_JA.md @@ -424,4 +424,5 @@ OpenViking プロジェクトは、コンポーネントごとに異なるライ - **メインプロジェクト**: AGPLv3 - 詳細は [LICENSE](../../LICENSE) ファイルを参照してください - **crates/ov\_cli**: Apache 2.0 - 詳細は [LICENSE](../../crates/LICENSE) を参照してください - **examples**: Apache 2.0 - 詳細は [LICENSE](../../examples/LICENSE) を参照してください。`examples/hermes-plugin` の Hermes プラグインは元の [MIT ライセンス](../../examples/hermes-plugin/LICENSE) を保持します。 +- **integrations/frameworks**: アダプターのパッケージメタデータとソースヘッダーは AGPLv3 を宣言しています。各パッケージの `LICENSE` を参照してください。実行可能なサンプルは Apache 2.0 を維持し、各パッケージの `examples/LICENSE` に記載されています。 - **third\_party**: 各サードパーティプロジェクトの元のライセンス diff --git a/docs/zh/about/02-changelog.md b/docs/zh/about/02-changelog.md index b637e623e4..4b3c44461c 100644 --- a/docs/zh/about/02-changelog.md +++ b/docs/zh/about/02-changelog.md @@ -7,6 +7,15 @@ OpenViking 的所有重要变更都将记录在此文件中。 ## 未发布 +- **LangChain 导入迁移(不兼容变更)**:服务端不再提供 + `openviking.integrations.langchain` 及其转发模块,旧导入会立即失败, + 不提供弃用过渡期或兼容占位模块。请安装 `langchain-openviking` + (LangGraph 使用 `pip install "langchain-openviking[langgraph]"`), + 将导入前缀 `openviking.integrations.langchain` 改为 `langchain_openviking`, + 子模块导入也需同步修改。例如使用 + `from langchain_openviking import OpenVikingRetriever`。维护中的包和示例迁至 + `integrations/frameworks/`,包名和标准导入路径保持不变。 + 详见[迁移指南](../agent-integrations/07-langchain-langgraph.md)。 - **Working Memory 默认关闭(行为变更)**:commit 仍保存原文并抽取长期记忆,默认不生成 WM 或 checkpoint 摘要。用户需要单独升级已安装的 agent 插件;新版默认关闭自动归档 摘要注入和上下文接管,由宿主管理历史与压缩。VikingBot 仍默认使用 OV 管理上下文与压缩, diff --git a/integrations/frameworks/langchain/LICENSE b/integrations/frameworks/langchain/LICENSE new file mode 100644 index 0000000000..27268c8e4a --- /dev/null +++ b/integrations/frameworks/langchain/LICENSE @@ -0,0 +1,662 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do not +control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes the unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of +the rights granted or affirmed under this License. For example, you +may not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the parties +who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work for use in or with those products, unless +you entered into that arrangement, or that patent license was granted, +prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero +General Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you to +choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAM), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information about this, and how to apply and follow the GNU AGPL, see +. \ No newline at end of file diff --git a/integrations/frameworks/langchain/README.md b/integrations/frameworks/langchain/README.md index ad618001da..9b4ed9eac4 100644 --- a/integrations/frameworks/langchain/README.md +++ b/integrations/frameworks/langchain/README.md @@ -81,4 +81,5 @@ python -m pytest -q --noconftest -o addopts='' \ integrations/frameworks/langchain/tests tests/unit/test_langchain_package_boundary.py ``` -The adapter is AGPL-3.0; the runnable [examples](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/langchain/examples/LICENSE) retain Apache-2.0. +Package metadata and source headers declare AGPL-3.0; see [LICENSE](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/langchain/LICENSE). +The runnable [examples](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/langchain/examples/LICENSE) retain Apache-2.0. diff --git a/integrations/frameworks/langchain/README_CN.md b/integrations/frameworks/langchain/README_CN.md index 16d35eb453..4698942a7c 100644 --- a/integrations/frameworks/langchain/README_CN.md +++ b/integrations/frameworks/langchain/README_CN.md @@ -64,4 +64,5 @@ python -m pytest -q --noconftest -o addopts='' \ integrations/frameworks/langchain/tests tests/unit/test_langchain_package_boundary.py ``` -适配器使用 AGPL-3.0;可运行[示例](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/langchain/examples/LICENSE)保留 Apache-2.0 许可。 +包元数据和源码声明 AGPL-3.0,详见 [LICENSE](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/langchain/LICENSE)。 +可运行[示例](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/langchain/examples/LICENSE)保留 Apache-2.0 许可。 diff --git a/integrations/frameworks/langchain/pyproject.toml b/integrations/frameworks/langchain/pyproject.toml index b44c5814e2..99d90d1bc6 100644 --- a/integrations/frameworks/langchain/pyproject.toml +++ b/integrations/frameworks/langchain/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=61.0", "setuptools-scm>=8.0", "wheel"] +requires = ["setuptools>=77.0", "setuptools-scm>=8.0", "wheel"] build-backend = "setuptools.build_meta" [project] @@ -12,6 +12,7 @@ authors = [ {name = "ByteDance", email = "noreply@bytedance.com"}, ] license = "AGPL-3.0" +license-files = ["LICENSE", "examples/LICENSE"] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", diff --git a/integrations/frameworks/microsoft-agent-framework/LICENSE b/integrations/frameworks/microsoft-agent-framework/LICENSE new file mode 100644 index 0000000000..27268c8e4a --- /dev/null +++ b/integrations/frameworks/microsoft-agent-framework/LICENSE @@ -0,0 +1,662 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do not +control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes the unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of +the rights granted or affirmed under this License. For example, you +may not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the parties +who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work for use in or with those products, unless +you entered into that arrangement, or that patent license was granted, +prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero +General Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you to +choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAM), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information about this, and how to apply and follow the GNU AGPL, see +. \ No newline at end of file diff --git a/integrations/frameworks/microsoft-agent-framework/README.md b/integrations/frameworks/microsoft-agent-framework/README.md index b51e4f5609..16c17bcc46 100644 --- a/integrations/frameworks/microsoft-agent-framework/README.md +++ b/integrations/frameworks/microsoft-agent-framework/README.md @@ -118,4 +118,5 @@ boundaries. They require no server, credentials, or model calls. Support belongs in [OpenViking issues](https://github.com/volcengine/OpenViking/issues/new/choose). See the [framework adapter guide](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/README.md) for adding other integrations. -The adapter is AGPL-3.0; the runnable [example](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/microsoft-agent-framework/examples/LICENSE) retains Apache-2.0. +Package metadata and source headers declare AGPL-3.0; see [LICENSE](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/microsoft-agent-framework/LICENSE). +The runnable [example](https://github.com/volcengine/OpenViking/blob/main/integrations/frameworks/microsoft-agent-framework/examples/LICENSE) retains Apache-2.0. diff --git a/integrations/frameworks/microsoft-agent-framework/pyproject.toml b/integrations/frameworks/microsoft-agent-framework/pyproject.toml index 05ec56524b..76853d6e80 100644 --- a/integrations/frameworks/microsoft-agent-framework/pyproject.toml +++ b/integrations/frameworks/microsoft-agent-framework/pyproject.toml @@ -9,6 +9,7 @@ description = "OpenViking context provider for Microsoft Agent Framework" readme = "README.md" requires-python = ">=3.10" license = "AGPL-3.0" +license-files = ["LICENSE", "examples/LICENSE"] dependencies = ["agent-framework-core>=1.20,<2", "openviking-sdk>=0.1.13,<0.2"] [project.optional-dependencies] diff --git a/tests/unit/test_langchain_package_boundary.py b/tests/unit/test_langchain_package_boundary.py index 6db557b70a..cac75ef804 100644 --- a/tests/unit/test_langchain_package_boundary.py +++ b/tests/unit/test_langchain_package_boundary.py @@ -22,6 +22,10 @@ def test_server_distribution_does_not_depend_on_standalone_integration(): assert 'name = "langchain-openviking"' not in root_lock +def test_server_source_excludes_removed_framework_namespace(): + assert not (PROJECT_ROOT / "openviking" / "integrations").exists() + + def test_standalone_package_has_no_server_imports_at_module_scope(): violations: list[str] = [] source_files = sorted((SOURCE_ROOT / "langchain_openviking").glob("*.py")) From 4040316a8c3a13c22fb2c92aad127cecedf13cdb Mon Sep 17 00:00:00 2001 From: Hao Zhe Date: Wed, 14 Oct 2026 01:29:41 +0800 Subject: [PATCH 3/8] fix(ci): check restored legacy integration paths Signed-off-by: Hao Zhe --- .github/workflows/pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index bc0a94a573..d11a1a8af0 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -181,7 +181,7 @@ jobs: echo "cuvs_changed=false" >> $GITHUB_OUTPUT fi - LANGCHAIN_PATTERN="integrations/frameworks/langchain/|tests/unit/test_langchain_package_boundary\.py$|^pyproject\.toml$|^uv\.lock$|\.github/workflows/(pr|python-langchain-release)\.yml" + LANGCHAIN_PATTERN="integrations/frameworks/langchain/|^openviking/integrations/|tests/unit/test_langchain_package_boundary\.py$|^pyproject\.toml$|^uv\.lock$|\.github/workflows/(pr|python-langchain-release)\.yml" LANGCHAIN_CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }} HEAD | grep -E "$LANGCHAIN_PATTERN" || true) if [ -n "$LANGCHAIN_CHANGED_FILES" ]; then From 04becf553a34ad54b84a1b88d195213b0f67b994 Mon Sep 17 00:00:00 2001 From: Hao Zhe Date: Wed, 14 Oct 2026 03:32:29 +0800 Subject: [PATCH 4/8] fix(ci): reject retired framework source and test paths Signed-off-by: Hao Zhe --- .github/workflows/pr.yml | 2 +- .../07-langchain-langgraph.md | 8 ++++--- docs/repository/README_CN.md | 2 ++ docs/repository/README_JA.md | 2 ++ .../07-langchain-langgraph.md | 6 ++++-- tests/unit/test_langchain_package_boundary.py | 21 ++++++++++++++++++- 6 files changed, 34 insertions(+), 7 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index d11a1a8af0..c3d19c69b5 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -181,7 +181,7 @@ jobs: echo "cuvs_changed=false" >> $GITHUB_OUTPUT fi - LANGCHAIN_PATTERN="integrations/frameworks/langchain/|^openviking/integrations/|tests/unit/test_langchain_package_boundary\.py$|^pyproject\.toml$|^uv\.lock$|\.github/workflows/(pr|python-langchain-release)\.yml" + LANGCHAIN_PATTERN="integrations/frameworks/langchain/|^openviking/integrations/|^tests/unit/test_langchain_[^/]*\.py$|^tests/integration/langchain_langgraph/|^examples/(langchain[^/]*|agent-framework)/|^pyproject\.toml$|^uv\.lock$|\.github/workflows/(pr|python-langchain-release)\.yml" LANGCHAIN_CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }} HEAD | grep -E "$LANGCHAIN_PATTERN" || true) if [ -n "$LANGCHAIN_CHANGED_FILES" ]; then diff --git a/docs/en/agent-integrations/07-langchain-langgraph.md b/docs/en/agent-integrations/07-langchain-langgraph.md index 2713995476..d4bd083e12 100644 --- a/docs/en/agent-integrations/07-langchain-langgraph.md +++ b/docs/en/agent-integrations/07-langchain-langgraph.md @@ -11,9 +11,11 @@ pip install langchain-openviking # LangChain adapters pip install "langchain-openviking[langgraph]" # LangGraph middleware support ``` -The integration is released independently from the OpenViking server. The legacy -`openviking.integrations.langchain` namespace has been removed; install the -standalone package and import from `langchain_openviking` instead. +The integration is released independently from the OpenViking server. Starting +with the next server release after v0.5.0, the legacy +`openviking.integrations.langchain` namespace is removed without a compatibility +shim. v0.5.0 still provides it. Install the standalone package and import from +`langchain_openviking` instead; see the [Unreleased migration notes](../about/02-changelog.md#unreleased). ## Connection diff --git a/docs/repository/README_CN.md b/docs/repository/README_CN.md index 1866b679d1..180c21b99e 100644 --- a/docs/repository/README_CN.md +++ b/docs/repository/README_CN.md @@ -311,6 +311,8 @@ Codex 首次启动会停在 `Hooks need review`,选 `Trust all and continue` 详细接入方式请参考 [Integrations](https://openviking.ai/integrations)。 +框架应用请参考 [LangChain/LangGraph 和 Microsoft Agent Framework 集成包](../../integrations/frameworks/README.md),其中也介绍了如何添加其他框架适配器。 + ## 桌面客户端(Beta) 桌面客户端是面向 macOS 和 Windows x64 的控制台(Beta),用于配置支持的本地 Agent 接入、查看会话中的召回与捕获事件,并将本地记忆和技能同步到 OpenViking。 diff --git a/docs/repository/README_JA.md b/docs/repository/README_JA.md index 17107844c1..0e0b1796bb 100644 --- a/docs/repository/README_JA.md +++ b/docs/repository/README_JA.md @@ -318,6 +318,8 @@ Codex は初回起動時に `Hooks need review` で止まるので、`Trust all 設定方法と統合の詳細は [Integrations](https://openviking.ai/integrations) を参照してください。 +フレームワークを使うアプリケーション向けには、[LangChain/LangGraph と Microsoft Agent Framework の統合パッケージ](../../integrations/frameworks/README.md)を参照してください。他のフレームワーク用アダプターを追加する手順も説明しています。 + ## デスクトップアプリ(Beta) デスクトップアプリは macOS と Windows x64 向けのコンソール(Beta)です。対応するローカルエージェントとの連携を設定し、セッションのリコールやキャプチャを確認して、ローカルのメモリとスキルを OpenViking に同期できます。 diff --git a/docs/zh/agent-integrations/07-langchain-langgraph.md b/docs/zh/agent-integrations/07-langchain-langgraph.md index b21c70b3aa..fca4d46bfd 100644 --- a/docs/zh/agent-integrations/07-langchain-langgraph.md +++ b/docs/zh/agent-integrations/07-langchain-langgraph.md @@ -11,8 +11,10 @@ pip install langchain-openviking # LangChain 适配器 pip install "langchain-openviking[langgraph]" # LangGraph middleware ``` -该集成独立于 OpenViking server 发布。旧的 `openviking.integrations.langchain` -命名空间已移除;请安装独立包,并改用 `langchain_openviking` 导入。 +该集成独立于 OpenViking server 发布。从 v0.5.0 之后的下一个服务端版本开始, +旧的 `openviking.integrations.langchain` 命名空间将移除,不提供兼容转发模块; +v0.5.0 仍保留该路径。请安装独立包,并改用 `langchain_openviking` 导入, +详见[未发布版本的迁移说明](../about/02-changelog.md#未发布)。 ## 连接 diff --git a/tests/unit/test_langchain_package_boundary.py b/tests/unit/test_langchain_package_boundary.py index cac75ef804..d1950b8869 100644 --- a/tests/unit/test_langchain_package_boundary.py +++ b/tests/unit/test_langchain_package_boundary.py @@ -23,7 +23,26 @@ def test_server_distribution_does_not_depend_on_standalone_integration(): def test_server_source_excludes_removed_framework_namespace(): - assert not (PROJECT_ROOT / "openviking" / "integrations").exists() + source_files = sorted((PROJECT_ROOT / "openviking" / "integrations").rglob("*.py")) + assert not source_files, f"Remove legacy framework sources: {source_files}" + + +def test_framework_sources_and_tests_use_package_locations(): + retired_roots = [ + PROJECT_ROOT / "tests" / "integration" / "langchain_langgraph", + PROJECT_ROOT / "examples" / "agent-framework", + *(PROJECT_ROOT / "examples").glob("langchain*"), + ] + stale_files = [path for root in retired_roots for path in root.rglob("*.py")] + stale_files.extend( + path + for path in (PROJECT_ROOT / "tests" / "unit").glob("test_langchain_*.py") + if path.name != "test_langchain_package_boundary.py" + ) + stale_paths = sorted(str(path.relative_to(PROJECT_ROOT)) for path in stale_files) + assert not stale_paths, ( + "Move framework sources and tests into integrations/frameworks/: " + ", ".join(stale_paths) + ) def test_standalone_package_has_no_server_imports_at_module_scope(): From 664435f62dd9a505f8932ebd2f4557c3da937b2c Mon Sep 17 00:00:00 2001 From: Hao Zhe Date: Wed, 14 Oct 2026 10:05:05 +0800 Subject: [PATCH 5/8] refactor(tests): keep adapter contracts with the package Signed-off-by: Hao Zhe --- .../tests/unit/test_langchain_imports.py | 36 ++++++ .../tests/unit/test_langchain_uri.py | 85 +++++++++++++ tests/unit/test_langchain_package_boundary.py | 116 ------------------ 3 files changed, 121 insertions(+), 116 deletions(-) create mode 100644 integrations/frameworks/langchain/tests/unit/test_langchain_imports.py create mode 100644 integrations/frameworks/langchain/tests/unit/test_langchain_uri.py diff --git a/integrations/frameworks/langchain/tests/unit/test_langchain_imports.py b/integrations/frameworks/langchain/tests/unit/test_langchain_imports.py new file mode 100644 index 0000000000..85090d9ff6 --- /dev/null +++ b/integrations/frameworks/langchain/tests/unit/test_langchain_imports.py @@ -0,0 +1,36 @@ +from __future__ import annotations + +import os +import subprocess +import sys + + +def test_base_star_import_omits_optional_middleware(tmp_path): + env = os.environ.copy() + env.pop("PYTHONPATH", None) + probe = """ +import importlib.util + +real_find_spec = importlib.util.find_spec +importlib.util.find_spec = ( + lambda name, *args, **kwargs: + None if name == "langchain" else real_find_spec(name, *args, **kwargs) +) + +import langchain_openviking + +assert "OpenVikingContextMiddleware" not in langchain_openviking.__all__ +namespace = {} +exec("from langchain_openviking import *", namespace) +assert "OpenVikingContextMiddleware" not in namespace +assert "OpenVikingRetriever" in namespace +""" + + subprocess.run( + [sys.executable, "-c", probe], + cwd=tmp_path, + env=env, + check=True, + capture_output=True, + text=True, + ) diff --git a/integrations/frameworks/langchain/tests/unit/test_langchain_uri.py b/integrations/frameworks/langchain/tests/unit/test_langchain_uri.py new file mode 100644 index 0000000000..bc2beccce4 --- /dev/null +++ b/integrations/frameworks/langchain/tests/unit/test_langchain_uri.py @@ -0,0 +1,85 @@ +from __future__ import annotations + +import pytest + + +@pytest.mark.parametrize( + ("uri", "expected_parts", "expected_scope", "expected_content_index"), + [ + ( + "viking://~/memories/store/data/users/ada.json", + ("~", "memories", "store", "data", "users", "ada.json"), + "user", + 1, + ), + # Legacy uid-less roots may still sit in older store configs; keep classifying them. + ( + "viking://user/memories/store/data/users/ada.json", + ("user", "memories", "store", "data", "users", "ada.json"), + "user", + 1, + ), + ( + "viking://user/default/memories/store/index/users/ada.md", + ("user", "default", "memories", "store", "index", "users", "ada.md"), + "user", + 2, + ), + ( + "viking://user/default/peers/assistant/resources/store/data.json", + ("user", "default", "peers", "assistant", "resources", "store", "data.json"), + "user", + 4, + ), + ( + "viking://~/peers/assistant/memories/store/index.md", + ("~", "peers", "assistant", "memories", "store", "index.md"), + "user", + 3, + ), + ( + "viking://user/peers/assistant/memories/store/index.md", + ("user", "peers", "assistant", "memories", "store", "index.md"), + "user", + 3, + ), + ( + "viking://agent/default/skills/review/SKILL.md", + ("agent", "default", "skills", "review", "SKILL.md"), + "agent", + 2, + ), + ( + "viking://resources/shared.md", + ("resources", "shared.md"), + "resources", + None, + ), + ( + "viking://user/default/sessions/thread-1", + ("user", "default", "sessions", "thread-1"), + "user", + None, + ), + ( + "/user/default/memories/store/data.json?profile=1", + ("user", "default", "memories", "store", "data.json"), + "user", + 2, + ), + ], +) +def test_private_uri_classification_preserves_server_namespace_shapes( + uri, + expected_parts, + expected_scope, + expected_content_index, +): + pytest.importorskip("langchain_openviking") + from langchain_openviking._uri import classify_uri + + classification = classify_uri(uri) + + assert classification.parts == expected_parts + assert classification.scope == expected_scope + assert classification.content_index == expected_content_index diff --git a/tests/unit/test_langchain_package_boundary.py b/tests/unit/test_langchain_package_boundary.py index d1950b8869..2c9b551c84 100644 --- a/tests/unit/test_langchain_package_boundary.py +++ b/tests/unit/test_langchain_package_boundary.py @@ -6,8 +6,6 @@ import sys from pathlib import Path -import pytest - PROJECT_ROOT = Path(__file__).resolve().parents[2] PACKAGE_ROOT = PROJECT_ROOT / "integrations" / "frameworks" / "langchain" SOURCE_ROOT = PACKAGE_ROOT / "src" @@ -93,38 +91,6 @@ def test_standalone_package_import_does_not_load_full_openviking(tmp_path): assert "openviking" not in sys.modules assert not any(name.startswith("openviking_cli") for name in sys.modules) -assert langchain_openviking.has_request_actor_peer_support() -""" - - subprocess.run( - [sys.executable, "-c", probe], - cwd=tmp_path, - env=env, - check=True, - capture_output=True, - text=True, - ) - - -def test_base_star_import_omits_optional_middleware(tmp_path): - env = os.environ.copy() - env["PYTHONPATH"] = os.pathsep.join((str(SOURCE_ROOT), str(SDK_ROOT))) - probe = """ -import importlib.util - -real_find_spec = importlib.util.find_spec -importlib.util.find_spec = ( - lambda name, *args, **kwargs: - None if name == "langchain" else real_find_spec(name, *args, **kwargs) -) - -import langchain_openviking - -assert "OpenVikingContextMiddleware" not in langchain_openviking.__all__ -namespace = {} -exec("from langchain_openviking import *", namespace) -assert "OpenVikingContextMiddleware" not in namespace -assert "OpenVikingRetriever" in namespace """ subprocess.run( @@ -135,85 +101,3 @@ def test_base_star_import_omits_optional_middleware(tmp_path): capture_output=True, text=True, ) - - -@pytest.mark.parametrize( - ("uri", "expected_parts", "expected_scope", "expected_content_index"), - [ - ( - "viking://~/memories/store/data/users/ada.json", - ("~", "memories", "store", "data", "users", "ada.json"), - "user", - 1, - ), - # Legacy uid-less roots may still sit in older store configs; keep classifying them. - ( - "viking://user/memories/store/data/users/ada.json", - ("user", "memories", "store", "data", "users", "ada.json"), - "user", - 1, - ), - ( - "viking://user/default/memories/store/index/users/ada.md", - ("user", "default", "memories", "store", "index", "users", "ada.md"), - "user", - 2, - ), - ( - "viking://user/default/peers/assistant/resources/store/data.json", - ("user", "default", "peers", "assistant", "resources", "store", "data.json"), - "user", - 4, - ), - ( - "viking://~/peers/assistant/memories/store/index.md", - ("~", "peers", "assistant", "memories", "store", "index.md"), - "user", - 3, - ), - ( - "viking://user/peers/assistant/memories/store/index.md", - ("user", "peers", "assistant", "memories", "store", "index.md"), - "user", - 3, - ), - ( - "viking://agent/default/skills/review/SKILL.md", - ("agent", "default", "skills", "review", "SKILL.md"), - "agent", - 2, - ), - ( - "viking://resources/shared.md", - ("resources", "shared.md"), - "resources", - None, - ), - ( - "viking://user/default/sessions/thread-1", - ("user", "default", "sessions", "thread-1"), - "user", - None, - ), - ( - "/user/default/memories/store/data.json?profile=1", - ("user", "default", "memories", "store", "data.json"), - "user", - 2, - ), - ], -) -def test_private_uri_classification_preserves_server_namespace_shapes( - uri, - expected_parts, - expected_scope, - expected_content_index, -): - pytest.importorskip("langchain_openviking") - from langchain_openviking._uri import classify_uri - - classification = classify_uri(uri) - - assert classification.parts == expected_parts - assert classification.scope == expected_scope - assert classification.content_index == expected_content_index From 4c2dec27d0e3c3c96b1a76876a937512389ba0e6 Mon Sep 17 00:00:00 2001 From: Hao Zhe Date: Wed, 14 Oct 2026 10:14:40 +0800 Subject: [PATCH 6/8] fix(ci): guard framework layout for retired metadata paths Signed-off-by: Hao Zhe --- .github/workflows/framework-layout.yml | 42 +++++++++++++++++++ .github/workflows/python-agent-framework.yml | 9 ++++ integrations/frameworks/langchain/README.md | 6 ++- .../frameworks/langchain/README_CN.md | 5 ++- tests/unit/test_langchain_package_boundary.py | 30 +++++++++++-- 5 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/framework-layout.yml diff --git a/.github/workflows/framework-layout.yml b/.github/workflows/framework-layout.yml new file mode 100644 index 0000000000..92516ce37c --- /dev/null +++ b/.github/workflows/framework-layout.yml @@ -0,0 +1,42 @@ +name: Framework Integration Layout + +on: + pull_request: + paths: + - 'integrations/frameworks/**' + - 'openviking/integrations/**' + - 'examples/langchain*/**' + - 'examples/agent-framework/**' + - 'tests/unit/test_langchain_*.py' + - 'tests/integration/langchain_langgraph/**' + - '.github/workflows/framework-layout.yml' + push: + branches: [main] + paths: + - 'integrations/frameworks/**' + - 'openviking/integrations/**' + - 'examples/langchain*/**' + - 'examples/agent-framework/**' + - 'tests/unit/test_langchain_*.py' + - 'tests/integration/langchain_langgraph/**' + - '.github/workflows/framework-layout.yml' + +permissions: + contents: read + +jobs: + layout: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@v6 + - uses: actions/setup-python@v6 + with: + python-version: '3.12' + - name: Install test runner + run: python -m pip install pytest + - name: Check framework package locations + # These guards need only pytest and Git, without server-test configuration. + run: >- + python -m pytest -q --noconftest --rootdir=. -c /dev/null + tests/unit/test_langchain_package_boundary.py + -k 'server_source_excludes_removed_framework_namespace or framework_sources_and_tests_use_package_locations' diff --git a/.github/workflows/python-agent-framework.yml b/.github/workflows/python-agent-framework.yml index 08c59565ac..8d134ee695 100644 --- a/.github/workflows/python-agent-framework.yml +++ b/.github/workflows/python-agent-framework.yml @@ -4,11 +4,15 @@ on: pull_request: paths: - 'integrations/frameworks/microsoft-agent-framework/**' + - 'examples/agent-framework/**' + - 'tests/unit/test_langchain_package_boundary.py' - '.github/workflows/python-agent-framework.yml' push: branches: [main] paths: - 'integrations/frameworks/microsoft-agent-framework/**' + - 'examples/agent-framework/**' + - 'tests/unit/test_langchain_package_boundary.py' - '.github/workflows/python-agent-framework.yml' permissions: @@ -34,6 +38,11 @@ jobs: python-version: '3.12' - name: Install supported dependencies run: python -m pip install '.[test,dev]' '${{ matrix.maf }}' '${{ matrix.sdk }}' + - name: Check framework package locations + run: >- + python -m pytest -q --noconftest -o addopts='' + ../../../tests/unit/test_langchain_package_boundary.py + -k 'server_source_excludes_removed_framework_namespace or framework_sources_and_tests_use_package_locations' - name: Check package and offline contracts run: | ruff check . diff --git a/integrations/frameworks/langchain/README.md b/integrations/frameworks/langchain/README.md index 9b4ed9eac4..4e9044103c 100644 --- a/integrations/frameworks/langchain/README.md +++ b/integrations/frameworks/langchain/README.md @@ -61,8 +61,10 @@ The package also provides `OpenVikingSessionRecorder`, ## Import migration -The server distribution no longer provides `openviking.integrations.langchain`. -Install this standalone package and change imports to `langchain_openviking`: +Starting with the next server release after v0.5.0, the legacy +`openviking.integrations.langchain` namespace is removed without a compatibility +shim. v0.5.0 still provides it. Install the standalone package and import from +`langchain_openviking` instead; see the [Unreleased migration notes](https://github.com/volcengine/OpenViking/blob/main/docs/en/about/02-changelog.md#unreleased). ```python from langchain_openviking import OpenVikingRetriever diff --git a/integrations/frameworks/langchain/README_CN.md b/integrations/frameworks/langchain/README_CN.md index 4698942a7c..7444d3b159 100644 --- a/integrations/frameworks/langchain/README_CN.md +++ b/integrations/frameworks/langchain/README_CN.md @@ -46,7 +46,10 @@ finally: ## 导入迁移 -服务端包不再提供 `openviking.integrations.langchain`。请安装独立包,并将导入改为: +从 v0.5.0 之后的下一个服务端版本开始,旧的 `openviking.integrations.langchain` +命名空间将移除,不提供兼容转发模块;v0.5.0 仍保留该路径。 +请安装独立包,并改用 `langchain_openviking` 导入, +详见[未发布版本的迁移说明](https://github.com/volcengine/OpenViking/blob/main/docs/zh/about/02-changelog.md#未发布)。 ```python from langchain_openviking import OpenVikingRetriever diff --git a/tests/unit/test_langchain_package_boundary.py b/tests/unit/test_langchain_package_boundary.py index 2c9b551c84..129e8f139c 100644 --- a/tests/unit/test_langchain_package_boundary.py +++ b/tests/unit/test_langchain_package_boundary.py @@ -12,6 +12,30 @@ SDK_ROOT = PROJECT_ROOT / "sdk" / "python" +def _repository_files(root: Path) -> list[Path]: + names = subprocess.check_output( + [ + "git", + "ls-files", + "-z", + "--cached", + "--others", + "--exclude-standard", + "--", + str(root.relative_to(PROJECT_ROOT)), + ], + cwd=PROJECT_ROOT, + text=True, + ).split("\0") + return [ + PROJECT_ROOT / name + for name in names + if name + and "__pycache__" not in Path(name).parts + and ((PROJECT_ROOT / name).exists() or (PROJECT_ROOT / name).is_symlink()) + ] + + def test_server_distribution_does_not_depend_on_standalone_integration(): root_pyproject = (PROJECT_ROOT / "pyproject.toml").read_text(encoding="utf-8") root_lock = (PROJECT_ROOT / "uv.lock").read_text(encoding="utf-8") @@ -21,8 +45,8 @@ def test_server_distribution_does_not_depend_on_standalone_integration(): def test_server_source_excludes_removed_framework_namespace(): - source_files = sorted((PROJECT_ROOT / "openviking" / "integrations").rglob("*.py")) - assert not source_files, f"Remove legacy framework sources: {source_files}" + stale_files = sorted(_repository_files(PROJECT_ROOT / "openviking" / "integrations")) + assert not stale_files, f"Remove legacy framework files: {stale_files}" def test_framework_sources_and_tests_use_package_locations(): @@ -31,7 +55,7 @@ def test_framework_sources_and_tests_use_package_locations(): PROJECT_ROOT / "examples" / "agent-framework", *(PROJECT_ROOT / "examples").glob("langchain*"), ] - stale_files = [path for root in retired_roots for path in root.rglob("*.py")] + stale_files = [path for root in retired_roots for path in _repository_files(root)] stale_files.extend( path for path in (PROJECT_ROOT / "tests" / "unit").glob("test_langchain_*.py") From 59c3387e7d8a679beb7a2c72377911fcf76be016 Mon Sep 17 00:00:00 2001 From: Hao Zhe Date: Wed, 14 Oct 2026 19:56:50 +0800 Subject: [PATCH 7/8] fix(ci): simplify framework migration guards Signed-off-by: Hao Zhe --- .github/workflows/framework-layout.yml | 7 ++- .github/workflows/pr.yml | 2 +- .github/workflows/python-agent-framework.yml | 7 --- .../tests/unit/test_langchain_uri.py | 5 +- tests/unit/test_langchain_package_boundary.py | 62 ++++++++++++------- 5 files changed, 48 insertions(+), 35 deletions(-) diff --git a/.github/workflows/framework-layout.yml b/.github/workflows/framework-layout.yml index 92516ce37c..ae5137a88b 100644 --- a/.github/workflows/framework-layout.yml +++ b/.github/workflows/framework-layout.yml @@ -5,7 +5,8 @@ on: paths: - 'integrations/frameworks/**' - 'openviking/integrations/**' - - 'examples/langchain*/**' + - 'examples/langchain/**' + - 'examples/langchain-langgraph/**' - 'examples/agent-framework/**' - 'tests/unit/test_langchain_*.py' - 'tests/integration/langchain_langgraph/**' @@ -15,7 +16,8 @@ on: paths: - 'integrations/frameworks/**' - 'openviking/integrations/**' - - 'examples/langchain*/**' + - 'examples/langchain/**' + - 'examples/langchain-langgraph/**' - 'examples/agent-framework/**' - 'tests/unit/test_langchain_*.py' - 'tests/integration/langchain_langgraph/**' @@ -26,6 +28,7 @@ permissions: jobs: layout: + name: Framework package locations runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index c3d19c69b5..c3095e83d1 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -181,7 +181,7 @@ jobs: echo "cuvs_changed=false" >> $GITHUB_OUTPUT fi - LANGCHAIN_PATTERN="integrations/frameworks/langchain/|^openviking/integrations/|^tests/unit/test_langchain_[^/]*\.py$|^tests/integration/langchain_langgraph/|^examples/(langchain[^/]*|agent-framework)/|^pyproject\.toml$|^uv\.lock$|\.github/workflows/(pr|python-langchain-release)\.yml" + LANGCHAIN_PATTERN="integrations/frameworks/langchain/|^openviking/integrations/|^tests/unit/test_langchain_[^/]*\.py$|^tests/integration/langchain_langgraph/|^examples/(langchain|langchain-langgraph|agent-framework)/|^pyproject\.toml$|^uv\.lock$|\.github/workflows/(pr|python-langchain-release)\.yml" LANGCHAIN_CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }} HEAD | grep -E "$LANGCHAIN_PATTERN" || true) if [ -n "$LANGCHAIN_CHANGED_FILES" ]; then diff --git a/.github/workflows/python-agent-framework.yml b/.github/workflows/python-agent-framework.yml index 8d134ee695..0f590d67fc 100644 --- a/.github/workflows/python-agent-framework.yml +++ b/.github/workflows/python-agent-framework.yml @@ -5,14 +5,12 @@ on: paths: - 'integrations/frameworks/microsoft-agent-framework/**' - 'examples/agent-framework/**' - - 'tests/unit/test_langchain_package_boundary.py' - '.github/workflows/python-agent-framework.yml' push: branches: [main] paths: - 'integrations/frameworks/microsoft-agent-framework/**' - 'examples/agent-framework/**' - - 'tests/unit/test_langchain_package_boundary.py' - '.github/workflows/python-agent-framework.yml' permissions: @@ -38,11 +36,6 @@ jobs: python-version: '3.12' - name: Install supported dependencies run: python -m pip install '.[test,dev]' '${{ matrix.maf }}' '${{ matrix.sdk }}' - - name: Check framework package locations - run: >- - python -m pytest -q --noconftest -o addopts='' - ../../../tests/unit/test_langchain_package_boundary.py - -k 'server_source_excludes_removed_framework_namespace or framework_sources_and_tests_use_package_locations' - name: Check package and offline contracts run: | ruff check . diff --git a/integrations/frameworks/langchain/tests/unit/test_langchain_uri.py b/integrations/frameworks/langchain/tests/unit/test_langchain_uri.py index bc2beccce4..535582a819 100644 --- a/integrations/frameworks/langchain/tests/unit/test_langchain_uri.py +++ b/integrations/frameworks/langchain/tests/unit/test_langchain_uri.py @@ -2,6 +2,8 @@ import pytest +from langchain_openviking._uri import classify_uri + @pytest.mark.parametrize( ("uri", "expected_parts", "expected_scope", "expected_content_index"), @@ -75,9 +77,6 @@ def test_private_uri_classification_preserves_server_namespace_shapes( expected_scope, expected_content_index, ): - pytest.importorskip("langchain_openviking") - from langchain_openviking._uri import classify_uri - classification = classify_uri(uri) assert classification.parts == expected_parts diff --git a/tests/unit/test_langchain_package_boundary.py b/tests/unit/test_langchain_package_boundary.py index 129e8f139c..cd8d2cb898 100644 --- a/tests/unit/test_langchain_package_boundary.py +++ b/tests/unit/test_langchain_package_boundary.py @@ -13,26 +13,40 @@ def _repository_files(root: Path) -> list[Path]: - names = subprocess.check_output( - [ - "git", - "ls-files", - "-z", - "--cached", - "--others", - "--exclude-standard", - "--", - str(root.relative_to(PROJECT_ROOT)), - ], - cwd=PROJECT_ROOT, - text=True, - ).split("\0") + try: + git_root = subprocess.check_output( + ["git", "rev-parse", "--show-toplevel"], + cwd=PROJECT_ROOT, + text=True, + stderr=subprocess.DEVNULL, + ).strip() + if Path(git_root).resolve() == PROJECT_ROOT.resolve(): + names = subprocess.check_output( + [ + "git", + "ls-files", + "-z", + "--cached", + "--others", + "--exclude-standard", + "--", + str(root.relative_to(PROJECT_ROOT)), + ], + cwd=PROJECT_ROOT, + text=True, + stderr=subprocess.DEVNULL, + ).split("\0") + candidates = [PROJECT_ROOT / name for name in names if name] + else: + candidates = list(root.rglob("*")) + except (OSError, subprocess.CalledProcessError): + # Source archives have no Git metadata; still check their package layout. + candidates = list(root.rglob("*")) return [ - PROJECT_ROOT / name - for name in names - if name - and "__pycache__" not in Path(name).parts - and ((PROJECT_ROOT / name).exists() or (PROJECT_ROOT / name).is_symlink()) + path + for path in candidates + if "__pycache__" not in path.relative_to(PROJECT_ROOT).parts + and (path.is_file() or path.is_symlink()) ] @@ -45,15 +59,19 @@ def test_server_distribution_does_not_depend_on_standalone_integration(): def test_server_source_excludes_removed_framework_namespace(): - stale_files = sorted(_repository_files(PROJECT_ROOT / "openviking" / "integrations")) - assert not stale_files, f"Remove legacy framework files: {stale_files}" + stale_paths = sorted( + str(path.relative_to(PROJECT_ROOT)) + for path in _repository_files(PROJECT_ROOT / "openviking" / "integrations") + ) + assert not stale_paths, "Remove legacy framework files: " + ", ".join(stale_paths) def test_framework_sources_and_tests_use_package_locations(): retired_roots = [ PROJECT_ROOT / "tests" / "integration" / "langchain_langgraph", PROJECT_ROOT / "examples" / "agent-framework", - *(PROJECT_ROOT / "examples").glob("langchain*"), + PROJECT_ROOT / "examples" / "langchain", + PROJECT_ROOT / "examples" / "langchain-langgraph", ] stale_files = [path for root in retired_roots for path in _repository_files(root)] stale_files.extend( From 3650a0a4d9e909a27183f55c69cc758205fe1140 Mon Sep 17 00:00:00 2001 From: Hao Zhe Date: Thu, 15 Oct 2026 14:34:11 +0800 Subject: [PATCH 8/8] docs(integrations): use contributor-facing adapter guidance Signed-off-by: Hao Zhe --- integrations/frameworks/README.md | 33 +++++++++++-------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/integrations/frameworks/README.md b/integrations/frameworks/README.md index 16ff068bf3..23cbd51945 100644 --- a/integrations/frameworks/README.md +++ b/integrations/frameworks/README.md @@ -52,10 +52,14 @@ MCP can expose model-callable OpenViking tools alongside the lifecycle adapter. ## Add an adapter +Refer to the [LangChain/LangGraph adapter](langchain/) and +[Microsoft Agent Framework provider](microsoft-agent-framework/) for examples of +connecting a framework's lifecycle to the OpenViking SDK. Each package includes +its implementation, contract tests, and runnable examples. + Create one package under `integrations/frameworks//` containing its -manifest, `src/`, `tests/`, README, and runnable `examples/`. Use the two existing -adapters as references for the OpenViking contract and inspect the target -framework's current public APIs before choosing its hooks. +manifest, `src/`, `tests/`, README, and runnable `examples/`. Use the target +framework's public lifecycle and message APIs to implement the following contracts. - **Identity and state:** use the application's authenticated OV client and keep a stable mapping from framework conversations to OV sessions. Preserve delivery @@ -87,24 +91,9 @@ minimum and current dependency versions. Verify remote SDK usage does not import the OV server. A documented live smoke should demonstrate capture, extraction, and recall in a new conversation when credentials and a server are available. -### Coding-agent prompt - -> Implement an OpenViking adapter for **[framework and supported versions]** using -> the official **[Python/TypeScript] SDK**. Inspect the framework's current public -> lifecycle and message APIs first. Follow this guide and the MAF/LangChain -> implementations for identity, recall, completed-message capture, and extraction -> policy. Adapt their hooks and state to this framework. Preserve tool evidence; -> exclude injected recall, system instructions, and hidden reasoning. Test full -> and interrupted streams, tool loops, restored sessions, partial writes, and lost -> acknowledgements. Provide a focused package, README, runnable example, and -> offline contract tests. Keep runtime dependencies local to the adapter package. - -This prompt is a development aid. Review generated code and pass the contract -tests before listing the framework as supported. - -## Future candidates +## Other frameworks Google ADK, OpenAI Agents SDK, Vercel AI SDK, CrewAI, LlamaIndex, Mastra, Pydantic AI, -AutoGen/AG2, Strands, and Agno are candidates for additional adapters. Their adapters -are not implemented here. Start with the SDK-based recipe above and add each -integration when its lifecycle, message mapping, and tests are verified. +AutoGen/AG2, Strands, and Agno do not have adapters in this directory. Refer to +[Add an adapter](#add-an-adapter) and the SDK operations above for implementation +and validation guidance.