diff --git a/.github/AGENTS.md b/.github/AGENTS.md
index b88729b60..e3c5ceaf1 100644
--- a/.github/AGENTS.md
+++ b/.github/AGENTS.md
@@ -21,6 +21,7 @@ Package workflows keep their own push-to-main and manual triggers. Their `pull_r
| Mem0 Plugin | `mem0-plugin-checks.yml` | Push to main (`integrations/mem0-plugin/`, excluding `.opencode-plugin/`), manual | pytest + hook exec bits + JSON manifest validation on Python 3.10, 3.11, 3.12 |
| OpenCode Plugin | `opencode-plugin-checks.yml` | Push to main (`.opencode-plugin/`), manual | Bun: tsc + build + dist artifact check |
| Pi Agent Plugin | `pi-agent-plugin-checks.yml` | Push to main (`integrations/pi-agent-plugin/`), manual | tsc + vitest + tsup on Node 20, 22 |
+| DeepSeek Harness Plugin | `dsh-mem0-checks.yml` | Push to main (`integrations/dsh-mem0/`), manual | tsc + vitest + tsup on Node 20, 22 |
| n8n Node | `n8n-nodes-mem0-checks.yml` | Push to main (`integrations/n8n-nodes-mem0/`), manual | ESLint + tsc build on Node 20 |
| Zapier App | `zapier-mem0-checks.yml` | Push to main (`integrations/zapier-mem0/`), manual | tsc + `zapier validate` + offline unit tests on Node 22 |
| strands-mem0 | `strands-mem0-checks.yml` | Push to main (`integrations/strands-mem0/`), manual | Ruff + mypy + pytest + hatch build on Python 3.10, 3.11, 3.12 |
@@ -59,6 +60,7 @@ Requiring `CI Gate` also means fork PRs from first-time contributors cannot merg
| OpenClaw | `openclaw-cd.yml` | `openclaw-v*` | npm (`@mem0/openclaw-mem0`) |
| OpenCode Plugin | `opencode-plugin-cd.yml` | `opencode-v*` | npm (`@mem0/opencode-plugin`) |
| Pi Agent Plugin | `pi-agent-plugin-cd.yml` | `pi-agent-v*` | npm (`@mem0/pi-agent-plugin`) |
+| DeepSeek Harness Plugin | `dsh-mem0-cd.yml` | `dsh-mem0-v*` | npm (`@mem0/dsh-mem0`) |
| n8n Node | `n8n-nodes-mem0-cd.yml` | `n8n-nodes-mem0-v*` | npm (`@mem0/n8n-nodes-mem0`) |
| strands-mem0 | `strands-mem0-cd.yml` | `strands-mem0-v*` | PyPI (`strands-mem0`) |
diff --git a/.github/workflows/ci-gate.yml b/.github/workflows/ci-gate.yml
index 826e2db38..93a2c755d 100644
--- a/.github/workflows/ci-gate.yml
+++ b/.github/workflows/ci-gate.yml
@@ -41,6 +41,7 @@ jobs:
mem0_plugin: ${{ steps.filter.outputs.mem0_plugin }}
opencode_plugin: ${{ steps.filter.outputs.opencode_plugin }}
pi_agent_plugin: ${{ steps.filter.outputs.pi_agent_plugin }}
+ dsh_mem0: ${{ steps.filter.outputs.dsh_mem0 }}
n8n_nodes_mem0: ${{ steps.filter.outputs.n8n_nodes_mem0 }}
zapier_mem0: ${{ steps.filter.outputs.zapier_mem0 }}
strands_mem0: ${{ steps.filter.outputs.strands_mem0 }}
@@ -89,6 +90,10 @@ jobs:
- 'integrations/pi-agent-plugin/**'
- '.github/workflows/pi-agent-plugin-checks.yml'
- '.github/workflows/ci-gate.yml'
+ dsh_mem0:
+ - 'integrations/dsh-mem0/**'
+ - '.github/workflows/dsh-mem0-checks.yml'
+ - '.github/workflows/ci-gate.yml'
n8n_nodes_mem0:
- 'integrations/n8n-nodes-mem0/**'
- '.github/workflows/n8n-nodes-mem0-checks.yml'
@@ -171,6 +176,13 @@ jobs:
uses: ./.github/workflows/pi-agent-plugin-checks.yml
secrets: inherit
+ dsh-mem0:
+ name: DeepSeek Harness Plugin
+ needs: changes
+ if: needs.changes.outputs.dsh_mem0 == 'true'
+ uses: ./.github/workflows/dsh-mem0-checks.yml
+ secrets: inherit
+
n8n-nodes-mem0:
name: n8n Node
needs: changes
@@ -227,6 +239,7 @@ jobs:
- mem0-plugin
- opencode-plugin
- pi-agent-plugin
+ - dsh-mem0
- n8n-nodes-mem0
- zapier-mem0
- strands-mem0
diff --git a/.github/workflows/dsh-mem0-cd.yml b/.github/workflows/dsh-mem0-cd.yml
new file mode 100644
index 000000000..68021fc9d
--- /dev/null
+++ b/.github/workflows/dsh-mem0-cd.yml
@@ -0,0 +1,60 @@
+name: Publish @mem0/dsh-mem0 📦 to npm
+
+# Dispatched by release.yml (Release Router) when a release tagged
+# dsh-mem0-v* is published. Can also be dispatched manually to re-publish
+# a tag.
+on:
+ workflow_dispatch:
+ inputs:
+ tag:
+ description: 'Release tag to build and publish (e.g. dsh-mem0-v0.1.1)'
+ required: true
+ type: string
+ prerelease:
+ description: 'Publish under the version preid dist-tag instead of latest'
+ required: false
+ type: boolean
+ default: false
+
+jobs:
+ build-n-publish:
+ name: Build and publish @mem0/dsh-mem0 📦 to npm
+ if: startsWith(inputs.tag, 'dsh-mem0-v')
+ runs-on: ubuntu-latest
+ permissions:
+ id-token: write
+ defaults:
+ run:
+ working-directory: integrations/dsh-mem0
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: ${{ inputs.tag }}
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 9
+
+ - name: Set up Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: '22'
+ registry-url: 'https://registry.npmjs.org'
+ cache: 'pnpm'
+ cache-dependency-path: integrations/dsh-mem0/pnpm-lock.yaml
+
+ - name: Install dependencies
+ run: pnpm install --frozen-lockfile
+
+ - name: Build
+ run: pnpm build
+
+ - name: Publish to npm
+ run: |
+ if [ "${{ inputs.prerelease }}" = "true" ]; then
+ PREID=$(node -p "require('./package.json').version.split('-')[1].split('.')[0]")
+ npx npm@latest publish --provenance --access public --tag "$PREID"
+ else
+ npx npm@latest publish --provenance --access public
+ fi
diff --git a/.github/workflows/dsh-mem0-checks.yml b/.github/workflows/dsh-mem0-checks.yml
new file mode 100644
index 000000000..a81997982
--- /dev/null
+++ b/.github/workflows/dsh-mem0-checks.yml
@@ -0,0 +1,90 @@
+name: dsh-mem0 checks
+
+# On PRs this is invoked by ci-gate.yml (the single required check);
+# push-to-main and manual runs remain standalone.
+on:
+ workflow_dispatch:
+ push:
+ branches: [main]
+ paths:
+ - 'integrations/dsh-mem0/**'
+ - '.github/workflows/dsh-mem0-checks.yml'
+ workflow_call:
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 9
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ cache: 'pnpm'
+ cache-dependency-path: integrations/dsh-mem0/pnpm-lock.yaml
+
+ - name: Install dependencies
+ run: cd integrations/dsh-mem0 && pnpm install --frozen-lockfile
+
+ - name: Type check
+ run: cd integrations/dsh-mem0 && pnpm exec tsc --noEmit
+
+ test:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ node-version: [20, 22]
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 9
+
+ - name: Setup Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v4
+ with:
+ node-version: ${{ matrix.node-version }}
+ cache: 'pnpm'
+ cache-dependency-path: integrations/dsh-mem0/pnpm-lock.yaml
+
+ - name: Install dependencies
+ run: cd integrations/dsh-mem0 && pnpm install --frozen-lockfile
+
+ - name: Run tests
+ run: cd integrations/dsh-mem0 && pnpm exec vitest run
+
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install pnpm
+ uses: pnpm/action-setup@v4
+ with:
+ version: 9
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20
+ cache: 'pnpm'
+ cache-dependency-path: integrations/dsh-mem0/pnpm-lock.yaml
+
+ - name: Install dependencies
+ run: cd integrations/dsh-mem0 && pnpm install --frozen-lockfile
+
+ - name: Build
+ run: cd integrations/dsh-mem0 && pnpm build
+
+ - name: Verify dist output exists
+ run: |
+ test -f integrations/dsh-mem0/dist/index.js || (echo "Build output missing: dist/index.js" && exit 1)
+ test -f integrations/dsh-mem0/dist/index.d.ts || (echo "Build output missing: dist/index.d.ts" && exit 1)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 423a4542b..50e76ea5e 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -45,6 +45,7 @@ jobs:
openclaw-v*) workflow="openclaw-cd.yml" ;;
opencode-v*) workflow="opencode-plugin-cd.yml" ;;
pi-agent-v*) workflow="pi-agent-plugin-cd.yml" ;;
+ dsh-mem0-v*) workflow="dsh-mem0-cd.yml" ;;
n8n-nodes-mem0-v*) workflow="n8n-nodes-mem0-cd.yml" ;;
strands-mem0-v*) workflow="strands-mem0-cd.yml" ;;
v*) workflow="cd.yml" ;;
diff --git a/.gitignore b/.gitignore
index 568da3757..133f6cae2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -191,3 +191,7 @@ qdrant_storage/
testing.ipynb
.weave/
+
+# TypeScript incremental build info and local, uncommitted e2e scripts (used by the integrations, e.g. integrations/dsh-mem0)
+*.tsbuildinfo
+*.local.mjs
diff --git a/docs/docs.json b/docs/docs.json
index 5e7aa8c2b..1b914e263 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -382,7 +382,8 @@
"pages": [
"integrations/openclaw",
"integrations/hermes",
- "integrations/pi-agent"
+ "integrations/pi-agent",
+ "integrations/dsh-mem0"
]
}
]
diff --git a/docs/integrations/dsh-mem0.mdx b/docs/integrations/dsh-mem0.mdx
new file mode 100644
index 000000000..40d63ced1
--- /dev/null
+++ b/docs/integrations/dsh-mem0.mdx
@@ -0,0 +1,89 @@
+---
+title: DeepSeek Harness
+description: "Add persistent Mem0 memory to the DeepSeek Harness (Cordis) agent with two native tools: search and add."
+---
+
+Add persistent memory to the [**DeepSeek Harness**](https://github.com/deepseek-ai/deepseek-harness) with `@mem0/dsh-mem0`. The Harness agent forgets everything between sessions. This plugin gives it two Mem0-backed tools so recall and writes persist across runs, sharing the same memory bank you already use from Claude Code, Codex, and other agents.
+
+## Overview
+
+The plugin registers two agent-callable tools:
+
+| Tool | Does |
+|---|---|
+| `search_memory` | Recall facts from Mem0 relevant to a query |
+| `add_memory` | Store a fact in Mem0 for future sessions |
+
+Unlike file-based memory plugins, Mem0 is a managed backend: server-side extraction, semantic dedup, and conflict resolution, with the same memory reusable across every agent you connect.
+
+## How it works
+
+A Cordis plugin is a module exporting `apply(ctx, config)`. This one declares `inject = ['tools']` so it waits for the harness tool registry, then registers the two tools via `ctx.tools.register(...)`. When the plugin unmounts, the tools are removed automatically (Cordis revertible effects).
+
+## Prerequisites
+
+1. A Mem0 Platform account and API key:
+ - Sign up at app.mem0.ai
+ - Get your API key (starts with `m0-`)
+
+2. The DeepSeek Harness installed.
+
+3. Your API key exported in your shell:
+
+
+```bash zsh
+echo 'export MEM0_API_KEY="m0-your-api-key"' >> ~/.zshrc
+source ~/.zshrc
+```
+
+```bash bash
+echo 'export MEM0_API_KEY="m0-your-api-key"' >> ~/.bashrc
+source ~/.bashrc
+```
+
+
+## Try it locally
+
+1. Build the plugin:
+ ```sh
+ cd integrations/dsh-mem0
+ pnpm install
+ pnpm build
+ ```
+
+2. Point the Harness at it. Copy `cordis.example.yml`, set the absolute path to `dist/index.js` and your `userId`, then load it:
+ ```sh
+ pnpm dsh web --patch ./integrations/dsh-mem0/cordis.example.yml
+ ```
+
+3. Open the web UI and ask the agent to remember something, then recall it in a later turn.
+
+The `cordis.yml` entry looks like this:
+
+```yaml
+- name: "@deepseek-ai/dsh-system-prompt"
+- name: "@deepseek-ai/dsh-tools"
+- insert:
+ - id: mem0
+ name: "/absolute/path/to/integrations/dsh-mem0/dist/index.js"
+ config:
+ # apiKey is read from MEM0_API_KEY when omitted here.
+ userId: "your-user-id"
+ # host: "https://your-onprem.mem0.ai" # optional: Platform on-prem / dedicated base URL
+```
+
+For a Mem0 Platform on-prem or dedicated deployment, point `config.host` at that base URL (defaults to `api.mem0.ai`). `host` is a Platform base-URL override, not a switch to self-hosted Mem0 OSS.
+
+## Configuration
+
+| Field | Required | Default | Notes |
+|---|---|---|---|
+| `apiKey` | no | `$MEM0_API_KEY` | Mem0 platform API key |
+| `userId` | yes | | Default entity that owns the memories |
+| `host` | no | `api.mem0.ai` | Platform base URL (on-prem / dedicated) |
+
+Both tools also accept optional per-call `userId`, `agentId`, and `runId` params so a single install can partition memory by entity, agent, or session; when omitted they fall back to the configured `userId`.
+
+## Telemetry
+
+Writes are tagged `source="DEEPSEEK_HARNESS"` so Mem0's backend can attribute usage to this integration.
diff --git a/docs/llms.txt b/docs/llms.txt
index 83b2c644a..45087e438 100644
--- a/docs/llms.txt
+++ b/docs/llms.txt
@@ -257,6 +257,7 @@ If the user is on a pre-current major (Python < 2, TS < 3, or a Platform call st
- [ChatDev](https://docs.mem0.ai/integrations/chatdev) [Platform]: Use when the user is on ChatDev.
- [Hermes](https://docs.mem0.ai/integrations/hermes) [Both]: Use when the user is on Hermes.
- [Pi Agent](https://docs.mem0.ai/integrations/pi-agent) [Platform]: Use when adding persistent memory to Pi Agent with the Mem0 plugin.
+- [DeepSeek Harness](https://docs.mem0.ai/integrations/dsh-mem0) [Platform]: Use when adding persistent memory to the DeepSeek Harness (Cordis) agent via the Mem0 plugin.
- [OpenAI Agents SDK](https://docs.mem0.ai/integrations/openai-agents-sdk) [Platform]: Use when the user is on the OpenAI Agents SDK.
- [Google AI ADK](https://docs.mem0.ai/integrations/google-ai-adk) [Platform]: Use when the user is on Google's Agent Development Kit.
- [Mastra](https://docs.mem0.ai/integrations/mastra) [Platform]: Use when the user is on Mastra (TypeScript).
diff --git a/integrations/AGENTS.md b/integrations/AGENTS.md
index cca1ed43c..71f0211dd 100644
--- a/integrations/AGENTS.md
+++ b/integrations/AGENTS.md
@@ -9,6 +9,7 @@ Agent and editor integrations. Each subdirectory is self-contained: its own `pac
| `mem0-plugin/` | Claude Code / Cursor / Codex plugin | none | none | pytest |
| `mem0-plugin/.opencode-plugin/` | `@mem0/opencode-plugin` | Bun | none | tsc type-check |
| `pi-agent-plugin/` | `@mem0/pi-agent-plugin` | tsup | none | vitest |
+| `dsh-mem0/` | `@mem0/dsh-mem0` | tsup (ESM) | none | vitest |
| `n8n-nodes-mem0/` | `@mem0/n8n-nodes-mem0` | tsc | ESLint (n8n-nodes-base) | none |
| `zapier-mem0/` | `@mem0/zapier` | tsc | none | offline unit tests + `zapier validate` |
| `strands-mem0/` | `strands-mem0` (PyPI) | hatch | Ruff + mypy | pytest |
@@ -40,7 +41,7 @@ Run the type check after every TypeScript change: `pnpm run typecheck` or `tsc -
- **`vercel-ai-sdk/`** wraps the Vercel AI SDK through a `createMem0` provider. Integrations for AI-SDK repos go through this wrapper, not raw `MemoryClient`.
- **`mem0-plugin/`** connects Claude Code, Cursor, and Codex to the MCP server at `mcp.mem0.ai` and installs lifecycle hooks for automatic memory capture. Exposes 9 MCP tools: `add_memory`, `search_memories`, `get_memories`, `get_memory`, `update_memory`, `delete_memory`, `delete_all_memories`, `delete_entities`, `list_entities`.
-- **`openclaw/`**, **`pi-agent-plugin/`** are editor and agent plugins with the same shape.
+- **`openclaw/`**, **`pi-agent-plugin/`**, **`dsh-mem0/`** are editor and agent plugins with the same shape. `dsh-mem0/` registers Mem0 search/add tools as a native DeepSeek Harness (Cordis) plugin.
- **`n8n-nodes-mem0/`** is an n8n community node: add, search, get, update, delete.
- **`zapier-mem0/`** is a Zapier Platform CLI app: add, search, get, delete. It deploys to Zapier, not npm, so it is **not** in the release router. Deploy it with `gh workflow run zapier-mem0-cd.yml --ref main` (needs the `ZAPIER_DEPLOY_KEY` secret).
- **`strands-mem0/`** is a native Strands `MemoryStore` (Python, published to PyPI as `strands-mem0`). It plugs into the Strands `MemoryManager` for automatic recall and server-side extraction, over the hosted Mem0 platform or self-hosted Mem0 OSS. The package lives under `strands-mem0/python/`.
diff --git a/integrations/dsh-mem0/.npmrc b/integrations/dsh-mem0/.npmrc
new file mode 100644
index 000000000..d50c9734c
--- /dev/null
+++ b/integrations/dsh-mem0/.npmrc
@@ -0,0 +1,7 @@
+# The DeepSeek Harness SDK (@deepseek-ai/dsh-tools) declares the rest of the
+# harness runtime (dsh-llm, dsh-agent, dsh-scope, ...) as peer dependencies.
+# The host harness provides those at runtime; this adapter only needs cordis +
+# dsh-tools to build and type-check. Auto-installing the full peer graph pulls
+# unpublished internal packages (e.g. dsh-type-meta), so keep it off.
+auto-install-peers=false
+package-manager-strict-version=false
diff --git a/integrations/dsh-mem0/LICENSE b/integrations/dsh-mem0/LICENSE
new file mode 100644
index 000000000..d20d5102c
--- /dev/null
+++ b/integrations/dsh-mem0/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 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 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 [2023] [Taranjeet Singh]
+
+ 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.
diff --git a/integrations/dsh-mem0/README.md b/integrations/dsh-mem0/README.md
new file mode 100644
index 000000000..29ea45a7c
--- /dev/null
+++ b/integrations/dsh-mem0/README.md
@@ -0,0 +1,60 @@
+# dsh-mem0
+
+[Mem0](https://mem0.ai) long-term memory as a native [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (Cordis) plugin.
+
+It gives a Harness agent two memory tools backed by the Mem0 SDK, so recall and writes persist across sessions:
+
+| Tool | Does |
+|---|---|
+| `search_memory` | Recall facts from Mem0 relevant to a query |
+| `add_memory` | Store a fact in Mem0 for future sessions |
+
+Unlike the local/file-based memory plugins in the ecosystem, Mem0 is a managed backend: server-side extraction, semantic dedup and conflict resolution, and the same memory bank reusable across Harness, Claude Code, Codex, and other agents.
+
+## How it works
+
+A Cordis plugin is a module exporting `apply(ctx, config)`. This one declares `inject = ['tools']` so it waits for the harness tool registry, then registers the two tools via `ctx.tools.register(defineTool(...))`. When the plugin unmounts, the tools are removed automatically (Cordis revertible effects).
+
+```
+[ mem0ai SDK ] <-- managed memory, owned by Mem0
+ |
+[ dsh-mem0: apply(ctx) -> ctx.tools.register(...) ] <-- this package
+ |
+[ DeepSeek Harness ] <-- the agent, loaded via cordis.yml
+```
+
+## Try it locally
+
+1. Build the plugin:
+ ```sh
+ cd integrations/dsh-mem0
+ pnpm install
+ pnpm build
+ ```
+2. Set your Mem0 key:
+ ```sh
+ export MEM0_API_KEY=...
+ ```
+3. Point Harness at it. Copy `cordis.example.yml`, set the absolute path to `dist/index.js` and your `userId`, then:
+ ```sh
+ pnpm dsh web --patch ./integrations/dsh-mem0/cordis.example.yml
+ ```
+4. Open http://127.0.0.1:3080 and ask the agent to remember something, then recall it in a later turn.
+
+For a Mem0 Platform on-prem or dedicated deployment, point `config.host` at that base URL (defaults to `api.mem0.ai`). `host` is a Platform base-URL override — it is not a switch to self-hosted Mem0 OSS, whose server exposes a different API surface.
+
+## Configuration
+
+| Field | Required | Default | Notes |
+|---|---|---|---|
+| `apiKey` | no | `$MEM0_API_KEY` | Mem0 platform API key |
+| `userId` | yes | | Entity that owns the memories |
+| `host` | no | `api.mem0.ai` | Platform base URL (on-prem / dedicated) |
+
+## Telemetry
+
+Writes are tagged `source="DEEPSEEK_HARNESS"` so Mem0's backend can attribute usage to this integration. For it to surface by name (rather than bucketing into `OTHERS`), `DEEPSEEK_HARNESS` must be present in the backend's `KNOWN_EVENT_SOURCES` allowlist, a one-line platform change matching the existing `ZAPIER` / `STRANDS` sources.
+
+## Status
+
+Developer preview. Tracks the DeepSeek Harness v0.1 plugin API (`@deepseek-ai/cordis`, `@deepseek-ai/dsh-tools`), which is young and moving; pin versions once it stabilizes. Auto-capture (store turns without an explicit tool call) and auto-recall (inject memory into the prompt at assembly) are planned once the harness session/assembly event API is confirmed.
diff --git a/integrations/dsh-mem0/cordis.example.yml b/integrations/dsh-mem0/cordis.example.yml
new file mode 100644
index 000000000..38dc4aaa5
--- /dev/null
+++ b/integrations/dsh-mem0/cordis.example.yml
@@ -0,0 +1,19 @@
+# Example DeepSeek Harness config that loads dsh-mem0 alongside the built-in
+# tools plugin. Load with:
+#
+# pnpm dsh web --patch ./integrations/dsh-mem0/cordis.example.yml
+#
+# The tools plugin (and its system-prompt dependency) must be present, because
+# the memory tools contribute schemas the system prompt renders.
+
+- name: "@deepseek-ai/dsh-system-prompt"
+- name: "@deepseek-ai/dsh-tools"
+- insert:
+ - id: mem0
+ # Absolute path to the built plugin (run `pnpm build` first), or point
+ # at src/index.ts when running through tsx during development.
+ name: "/absolute/path/to/mem0/integrations/dsh-mem0/dist/index.js"
+ config:
+ # apiKey is read from the MEM0_API_KEY env var when omitted here.
+ userId: "your-user-id"
+ # host: "https://your-onprem.mem0.ai" # optional: Platform on-prem / dedicated base URL
diff --git a/integrations/dsh-mem0/package.json b/integrations/dsh-mem0/package.json
new file mode 100644
index 000000000..4e9e563f0
--- /dev/null
+++ b/integrations/dsh-mem0/package.json
@@ -0,0 +1,59 @@
+{
+ "name": "@mem0/dsh-mem0",
+ "version": "0.1.0",
+ "description": "Mem0 long-term memory as a native DeepSeek Harness (Cordis) plugin.",
+ "type": "module",
+ "license": "Apache-2.0",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/mem0ai/mem0",
+ "directory": "integrations/dsh-mem0"
+ },
+ "keywords": [
+ "deepseek-harness",
+ "dsh",
+ "dsh-plugin",
+ "cordis",
+ "mem0",
+ "memory",
+ "agent"
+ ],
+ "main": "./dist/index.js",
+ "types": "./dist/index.d.ts",
+ "exports": {
+ ".": {
+ "types": "./dist/index.d.ts",
+ "import": "./dist/index.js"
+ }
+ },
+ "publishConfig": {
+ "access": "public"
+ },
+ "files": [
+ "dist",
+ "src",
+ "README.md",
+ "LICENSE"
+ ],
+ "scripts": {
+ "build": "tsup",
+ "test": "vitest run",
+ "test:watch": "vitest",
+ "typecheck": "tsc --noEmit"
+ },
+ "dependencies": {
+ "mem0ai": "^3.0.7"
+ },
+ "peerDependencies": {
+ "@deepseek-ai/cordis": "*",
+ "@deepseek-ai/dsh-tools": "*"
+ },
+ "devDependencies": {
+ "@deepseek-ai/cordis": "4.0.1",
+ "@deepseek-ai/dsh-tools": "0.0.1-rc.1",
+ "@types/node": "^22.15.0",
+ "tsup": "^8.5.0",
+ "typescript": "^5.6.0",
+ "vitest": "^4.1.7"
+ }
+}
diff --git a/integrations/dsh-mem0/pnpm-lock.yaml b/integrations/dsh-mem0/pnpm-lock.yaml
new file mode 100644
index 000000000..26bc065c8
--- /dev/null
+++ b/integrations/dsh-mem0/pnpm-lock.yaml
@@ -0,0 +1,2094 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: false
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ mem0ai:
+ specifier: ^3.0.7
+ version: 3.1.6
+ devDependencies:
+ '@deepseek-ai/cordis':
+ specifier: 4.0.1
+ version: 4.0.1
+ '@deepseek-ai/dsh-tools':
+ specifier: 0.0.1-rc.1
+ version: 0.0.1-rc.1(@deepseek-ai/cordis@4.0.1)
+ '@types/node':
+ specifier: ^22.15.0
+ version: 22.20.1
+ tsup:
+ specifier: ^8.5.0
+ version: 8.5.1(postcss@8.5.26)(typescript@5.9.3)
+ typescript:
+ specifier: ^5.6.0
+ version: 5.9.3
+ vitest:
+ specifier: ^4.1.7
+ version: 4.1.11(@types/node@22.20.1)(esbuild@0.27.7)
+
+packages:
+
+ '@deepseek-ai/cordis@4.0.1':
+ resolution: {integrity: sha512-YBdskTU2Po1kru3GgcUWUbkTsPMA9LkSQDAY8rBkFJeajdgcQad3QPJZE26JyK99Xb6HaASvoXg2DSUTeN/0Nw==}
+ hasBin: true
+ peerDependencies:
+ '@deepseek-ai/cordis-plugin-include': ^1.0.6
+ '@deepseek-ai/cordis-plugin-loader': ^1.0.2
+ peerDependenciesMeta:
+ '@deepseek-ai/cordis-plugin-include':
+ optional: true
+ '@deepseek-ai/cordis-plugin-loader':
+ optional: true
+
+ '@deepseek-ai/cosmokit@1.8.2':
+ resolution: {integrity: sha512-muBOKtSrUKU5m/xpq8ZXWL6hQ/jgd4PhU2PqH97bcxIiLEJfNwZOGQEx4t/aS/GgxRAR+ra9pMHPMtTHU4sqqA==}
+
+ '@deepseek-ai/dsh-tools@0.0.1-rc.1':
+ resolution: {integrity: sha512-mrtq+UXc6UVidrGo4GM8RAH0Gqc4iFOmtPeQAz59Phhjl3EmzkFI0Mo6dQlHQamrc2J9jppPtGtUzW9qHmwxDQ==}
+ peerDependencies:
+ '@deepseek-ai/cordis': ^4.0.1-rc.1
+ '@deepseek-ai/dsh-agent': ^0.0.1-rc.1
+ '@deepseek-ai/dsh-code-runtime': ^0.0.1-rc.1
+ '@deepseek-ai/dsh-invariants': ^0.0.1-rc.1
+ '@deepseek-ai/dsh-llm': ^0.0.1-rc.1
+ '@deepseek-ai/dsh-scope': ^0.0.1-rc.1
+ '@deepseek-ai/dsh-session': ^0.0.1-rc.1
+ '@deepseek-ai/dsh-system-prompt': ^0.0.1-rc.1
+ '@deepseek-ai/dsh-user-approval': ^0.0.1-rc.1
+
+ '@deepseek-ai/schemastery@3.18.1':
+ resolution: {integrity: sha512-Qn0FCSwCQnpnj6SB31I6i2sIKgKWnkbJM8O0EU91Gv2UsYVvtZTl6IA0sCwk2e2MZf5S8w5hpq9QkeVvK9qwxg==}
+
+ '@esbuild/aix-ppc64@0.27.7':
+ resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.27.7':
+ resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.27.7':
+ resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.27.7':
+ resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.27.7':
+ resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.27.7':
+ resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.27.7':
+ resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.27.7':
+ resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.27.7':
+ resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.27.7':
+ resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==}
+ engines: {node: '>=18'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.27.7':
+ resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.27.7':
+ resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==}
+ engines: {node: '>=18'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.27.7':
+ resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==}
+ engines: {node: '>=18'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.27.7':
+ resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==}
+ engines: {node: '>=18'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.27.7':
+ resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==}
+ engines: {node: '>=18'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.27.7':
+ resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==}
+ engines: {node: '>=18'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.27.7':
+ resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-arm64@0.27.7':
+ resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [netbsd]
+
+ '@esbuild/netbsd-x64@0.27.7':
+ resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-arm64@0.27.7':
+ resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openbsd]
+
+ '@esbuild/openbsd-x64@0.27.7':
+ resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/openharmony-arm64@0.27.7':
+ resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@esbuild/sunos-x64@0.27.7':
+ resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.27.7':
+ resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==}
+ engines: {node: '>=18'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.27.7':
+ resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==}
+ engines: {node: '>=18'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.27.7':
+ resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==}
+ engines: {node: '>=18'}
+ cpu: [x64]
+ os: [win32]
+
+ '@jridgewell/gen-mapping@0.3.13':
+ resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.5':
+ resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+
+ '@napi-rs/lzma-linux-x64-gnu@1.5.1':
+ resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==}
+ engines: {node: ^22.20 || ^24.12 || >=25}
+ cpu: [x64]
+ os: [linux]
+
+ '@oxc-project/types@0.146.0':
+ resolution: {integrity: sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA==}
+
+ '@rolldown/binding-android-arm-eabi@1.2.5':
+ resolution: {integrity: sha512-DLe/i+l8ynIBY7XEQ191TeZvCoowIGa18R+dIV30GW7DiOtp74i/xX8hs8GUjW5ARV7VZuie3d6AumSmCwbeRA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [android]
+
+ '@rolldown/binding-android-arm64@1.2.5':
+ resolution: {integrity: sha512-zXcwKlQApYAOELHd8PwKDFkagYF9Wy4e0RJ+0qnzl9Pjnpj75TEG8ufv40p2J7kCEfwZAsNiuzRIyNNMWT38ig==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [android]
+
+ '@rolldown/binding-darwin-arm64@1.2.5':
+ resolution: {integrity: sha512-dK4QakI42nzWgJT5sm4y4y/O//D4OxM75/cH28RLV+nzIN9AY+YsbuUVrUTjlLjXR6vpyxFbSsbmNuJ6BP9sww==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rolldown/binding-darwin-x64@1.2.5':
+ resolution: {integrity: sha512-fqSALaUu1Wjd1nK2uW2kJDWdLCc8lx1IcY+MTY26Aurfdx19anlzhqXOgCFbBFQnlFDTn4TC1/7Nz4Bl2mLP3A==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rolldown/binding-freebsd-x64@1.2.5':
+ resolution: {integrity: sha512-/vCnNxlkxs9tKxNDcyWUePpJ/PgTzxIaVhoM5SmG8UV+GR/IcPam4VYxi7GIMo7PSDuNqlJqvprqii9NqqVCMw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rolldown/binding-linux-arm-gnueabihf@1.2.5':
+ resolution: {integrity: sha512-abk0NLA519LxRCszmbE0jYKuQ9YPocOXTiOXOo6Yr+YAT95VH+PtqYAjOJvGKt3viEd/x4qzabAlwd5bHOOARg==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@rolldown/binding-linux-arm64-gnu@1.2.5':
+ resolution: {integrity: sha512-Y7eALiJ8lr0M2HH103Js+g7V34wf6snlpZLAsHI90uLhr3PVlNsbFVAXJC9d/V6BnPyKtpSwI+NcB/RLxsQxuA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rolldown/binding-linux-arm64-musl@1.2.5':
+ resolution: {integrity: sha512-xMvZgnbZg4YVnR/AX2b3oOPDTFYJvUVaJg5FedA/LuvexAtXibZQej4cnTkw3rjsJ/ggUROB64TdtETiim+FYA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rolldown/binding-linux-ppc64-gnu@1.2.5':
+ resolution: {integrity: sha512-GRjeqTUDHTo5GwntsLaAMcBahG3nlpjftXWZLN73HiYQlhwEowvarFgQnRnQZtIp4keXX7quXFbG38uPZBa2EA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rolldown/binding-linux-s390x-gnu@1.2.5':
+ resolution: {integrity: sha512-vLNTR45F2Uwc8AufkNXPmB4VliaXs+FvcheEogIzOXzO4l+LzieXF5A/TWxLy5HtqpsRCHUfd0lPVrrdgXdLHQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rolldown/binding-linux-x64-gnu@1.2.5':
+ resolution: {integrity: sha512-Mgj59/HTuYeK9Gz2MA+mBWKnHsAgkBSec15ZMb1st3oIfFbX7gCjOae7GydHhzcyQi9Z/7M1QuN9bR3oFqF0jQ==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@rolldown/binding-linux-x64-musl@1.2.5':
+ resolution: {integrity: sha512-mY8AP0/ichsbhAxGnLa3d3+MwV0EfgrPND2bplI3Ym8T6R2pJ0N87bvrKVwNXmdy3jnr6eQBecdqx/HMknBmpA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@rolldown/binding-openharmony-arm64@1.2.5':
+ resolution: {integrity: sha512-8SLssA2oweAxyRgDp789ACfRb/3P+zNRJpzZxSizxF9m8NUDQ4+3xjo8ttjhVGGw6Qxb70oZiEtIjaKikCO7Yw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rolldown/binding-win32-arm64-msvc@1.2.5':
+ resolution: {integrity: sha512-vGbruD5zquhoc8D9SViXgN2FBJtNdTyQ4DtG+SWiEGlJiAzoKcZ2xp+xuXCffhubVdt0NJlTZqkeRuERy7g8Cw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rolldown/binding-win32-x64-msvc@1.2.5':
+ resolution: {integrity: sha512-e/SXpgISz+IoqVcSSI0rx/d/he8zqLex+/rCWpnHpmVfmPIUjag9H6P7zotf0gJHwPUhQxZ/mF8tr6acebT9yw==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@rolldown/pluginutils@1.0.1':
+ resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
+
+ '@rollup/rollup-android-arm-eabi@4.62.5':
+ resolution: {integrity: sha512-jfkGfTwhQpsiSckPF8r9bU3pn3vyd72NlWaO+TgEO6WPSDnUhXzrNYCHBMOYj0ACaUgjm6eERLF+XV9a6RstoA==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.62.5':
+ resolution: {integrity: sha512-oGVqyQlxnrz9/ty89oHpU857VUHEl5/Xu4R2lS+aivCTrNnSsbiENzTnNaBsjxH0CNWGPhzHArOLFwo+oKXveA==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.62.5':
+ resolution: {integrity: sha512-bW7B8xMEq8n99Q3ieEcPRGuphurdZAaFzQc9Efyyw3FL6DZO6pMy9xhdN+kBoD7Sy05xNXSr4OyPPnpkYriS/A==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.62.5':
+ resolution: {integrity: sha512-YSwBS86QeHOGlrxJ1PSOIZSkzRL/JmKeunhc+lV6M1a6En8QuVCD/T/qIA0J4Gd2Y86RIOBYrLcOUtqGh9+/1w==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-freebsd-arm64@4.62.5':
+ resolution: {integrity: sha512-2fST8lILgl7cKbme/1KDdPCmbXbG+gqoV3bHp19L0ypX/3akYMBVdOunPleRCwonoLnXOZ/0F+Mt/v8POFmfcQ==}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@rollup/rollup-freebsd-x64@4.62.5':
+ resolution: {integrity: sha512-cpIxQCP9J+EVad0a6LO1kY3ZGODlk80VlI+2I96B8xMcdHZ4pLVhfQ49JFpYqjPF91FFkQWftf57YlDcTiw9yQ==}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.62.5':
+ resolution: {integrity: sha512-r9fGh3eFs3e/udWh5ZjXQtxiYK/xoFxQaYR/cELxac/Udkl5Th+IsFm0CX3Kl9hmUH/we7EoMpjJgeQNnE0+IA==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.62.5':
+ resolution: {integrity: sha512-xdvFdp7OM6KLJviJT2g/YuRSUjnZgGHk4RNgwIbN7X6cPugOucV60DdHXWzsBVCUdrGb6qSXnJQrrAKMmQuj3Q==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.62.5':
+ resolution: {integrity: sha512-rRqILAndyzHzP7T9NFQrq+4HFWNhqkqkKur7eiBpfLmz01PO0JKx5Vchu3YllE4YXI/Ftgq/szrDWg5GJ0mI8g==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.62.5':
+ resolution: {integrity: sha512-Gf4X3qVMucayUvux6aXXPgXovocSFUC0rrffDuPI/S2nHhNMhjcZxsrAFYCOF350PRreW1XwzFj3CT/3bKsWCw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loong64-gnu@4.62.5':
+ resolution: {integrity: sha512-+s5qA0TNM0qm8PK/a5gt/1Hpx+NV08uSuCncvhziIlQzT6AEV2fnUQo7eBtFTFO0nA9scauvoR2HusfXmQnO4w==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-loong64-musl@4.62.5':
+ resolution: {integrity: sha512-ybb6QvWwWJCbBWqERpc8K3pYVGIrXlG8MEQ8IIuJY6Y9KdHQxoFoNyfkAOtKn1VHu3KuLidXvwrvGR1mEjeWCw==}
+ cpu: [loong64]
+ os: [linux]
+
+ '@rollup/rollup-linux-ppc64-gnu@4.62.5':
+ resolution: {integrity: sha512-nZb1DtnOyhCmYvsC8A2CwOkopVg+IS1+fPUa7rMOAXtNw5+lLCLLPqd6XAiNrGtoQKsbvIBOwsHnBH/3wnb4HQ==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-ppc64-musl@4.62.5':
+ resolution: {integrity: sha512-yMbj63Sp89ryrXLWyz+sy+fYD2HpOnMCLGbe4Oa1smclFSUukdtD/BgdiHaAetJNb74URD8U4hM+qG5KVzMEkg==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.62.5':
+ resolution: {integrity: sha512-mhoan3OJw2kYV/e1jtIdmvUZgyBFeA6zGWsOswmR0Tg19TQbowZuR+JMLID6spbbBN7Zee2ejrgmy3+FxGrIdA==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-musl@4.62.5':
+ resolution: {integrity: sha512-5ZTLmjWbb1VZdjuyhe83K/8QO0/h11midQCBP+X5OYn32ra7eOBoM0ZqtaY4nkgNsYgmdVhMYPoyVPTjUpHf3w==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.62.5':
+ resolution: {integrity: sha512-m53kG+br6PGxOTmgBEM2DHSDs9RVjsyEbUwjJPJGTFm1grWOG8EKJggDCTb60unD4Tjby8fi7/m9XfkEWasVWg==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.62.5':
+ resolution: {integrity: sha512-6RHPJR1g/uvdYU8uXBnfq3nlqyZCP82Fr6NHgfGoaIeSh0YEqnX/x6uA9MmJJbnSH7swqX4F+CkGdUF+6doiQA==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.62.5':
+ resolution: {integrity: sha512-xs+OXQtEXgpXT0DmA5+U3qnRZHdCST/5HRQxS8wSPZTUZN/EMWeHuSIod32LQklTBZBV9DyfncKBQ8n5V3eFdw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-openbsd-x64@4.62.5':
+ resolution: {integrity: sha512-e7hD+sl3s+mcLQDZ8pbudBVsdG6r5yN4w3LqG2TJ8sQHDpblWj5lrJs/3m01Cvlxbt4x13zu5thLjgypgtkYzw==}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@rollup/rollup-openharmony-arm64@4.62.5':
+ resolution: {integrity: sha512-GiyJaCf+WpMub/17aPcKk27QMl5W6f+KhdPTjlFOn5akH5Wa/DCM9Stdx5cDfmasyKB08MqpVQ1uJE2RkkpbXg==}
+ cpu: [arm64]
+ os: [openharmony]
+
+ '@rollup/rollup-win32-arm64-msvc@4.62.5':
+ resolution: {integrity: sha512-+OQ8U2DdoEfXl8T4Fb18AjmEwbXMerKDKCL8yCPAYhKCEEKoul7rkbeGCBFCbAlaGaa7pmtRTpkAJM2LE/i5FA==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.62.5':
+ resolution: {integrity: sha512-KanvAZrPKbDBFwrgiU9yEVpQoox9QPV1WZOXX7HudJQY+eSlu82CtWxDU8WtuRRvtN5EGkLczkd6Y6DTcvm9wA==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-gnu@4.62.5':
+ resolution: {integrity: sha512-1aC3UEWTtRl3RK3VpDJ/Tqk1XI4SLTmXIthAq6wRWo8XiSXJNd+VprJM4/1P4+i6HIaFEFlVi9sTTziniD2tOQ==}
+ cpu: [x64]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.62.5':
+ resolution: {integrity: sha512-/gDJaRs4gl0NPIwqCz+6PkpmhhjRAD2j6P4rSNHBzUkO3naEx2mIU0pRle1vUNRQ7mE/+8OOeXLTv/J56FKiQg==}
+ cpu: [x64]
+ os: [win32]
+
+ '@standard-schema/spec@1.1.0':
+ resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==}
+
+ '@types/chai@5.2.3':
+ resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==}
+
+ '@types/deep-eql@4.0.2':
+ resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==}
+
+ '@types/estree@1.0.9':
+ resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==}
+
+ '@types/node-fetch@2.6.13':
+ resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==}
+
+ '@types/node@18.19.130':
+ resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==}
+
+ '@types/node@22.20.1':
+ resolution: {integrity: sha512-EANqOCF9QFyra+4pfxUcX9STKJpCLjMbObVzljIJomAWSnuSIEAvyzEU53GaajbXJEgdh0iEcPL+DGvpUd4k1Q==}
+
+ '@vitest/expect@4.1.11':
+ resolution: {integrity: sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==}
+
+ '@vitest/mocker@4.1.11':
+ resolution: {integrity: sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==}
+ peerDependencies:
+ msw: ^2.4.9
+ vite: ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ msw:
+ optional: true
+ vite:
+ optional: true
+
+ '@vitest/pretty-format@4.1.11':
+ resolution: {integrity: sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==}
+
+ '@vitest/runner@4.1.11':
+ resolution: {integrity: sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==}
+
+ '@vitest/snapshot@4.1.11':
+ resolution: {integrity: sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==}
+
+ '@vitest/spy@4.1.11':
+ resolution: {integrity: sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==}
+
+ '@vitest/utils@4.1.11':
+ resolution: {integrity: sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==}
+
+ abort-controller@3.0.0:
+ resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
+ engines: {node: '>=6.5'}
+
+ acorn@8.18.0:
+ resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ agent-base@6.0.2:
+ resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
+ engines: {node: '>= 6.0.0'}
+
+ agentkeepalive@4.6.0:
+ resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==}
+ engines: {node: '>= 8.0.0'}
+
+ any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+
+ assertion-error@2.0.1:
+ resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
+ engines: {node: '>=12'}
+
+ asynckit@0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+
+ axios@1.19.0:
+ resolution: {integrity: sha512-ht/iuYZXEjFxLH/Hkezgd7m6JKlHHXEUSneaDz8uZe1Gj5QZtCnpyDsckvAiEnT89OEbCLmnte4R4sn7P0EKFw==}
+
+ bundle-require@5.1.0:
+ resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ peerDependencies:
+ esbuild: '>=0.18'
+
+ cac@6.7.14:
+ resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
+ engines: {node: '>=8'}
+
+ call-bind-apply-helpers@1.0.2:
+ resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
+ engines: {node: '>= 0.4'}
+
+ chai@6.2.2:
+ resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==}
+ engines: {node: '>=18'}
+
+ chokidar@4.0.3:
+ resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
+ engines: {node: '>= 14.16.0'}
+
+ combined-stream@1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+
+ commander@4.1.1:
+ resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
+ engines: {node: '>= 6'}
+
+ confbox@0.1.8:
+ resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
+
+ consola@3.4.2:
+ resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==}
+ engines: {node: ^14.18.0 || >=16.10.0}
+
+ convert-source-map@2.0.0:
+ resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+
+ debug@4.4.3:
+ resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ delayed-stream@1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+
+ detect-libc@2.1.2:
+ resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==}
+ engines: {node: '>=8'}
+
+ dunder-proto@1.0.1:
+ resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
+ engines: {node: '>= 0.4'}
+
+ es-define-property@1.0.1:
+ resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
+ engines: {node: '>= 0.4'}
+
+ es-errors@1.3.0:
+ resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
+ engines: {node: '>= 0.4'}
+
+ es-module-lexer@2.3.2:
+ resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==}
+
+ es-object-atoms@1.1.2:
+ resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==}
+ engines: {node: '>= 0.4'}
+
+ es-set-tostringtag@2.1.0:
+ resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
+ engines: {node: '>= 0.4'}
+
+ esbuild@0.27.7:
+ resolution: {integrity: sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==}
+ engines: {node: '>=18'}
+ hasBin: true
+
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
+ event-target-shim@5.0.1:
+ resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
+ engines: {node: '>=6'}
+
+ expect-type@1.4.0:
+ resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==}
+ engines: {node: '>=12.0.0'}
+
+ fdir@6.5.0:
+ resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
+ engines: {node: '>=12.0.0'}
+ peerDependencies:
+ picomatch: ^3 || ^4
+ peerDependenciesMeta:
+ picomatch:
+ optional: true
+
+ fix-dts-default-cjs-exports@1.0.1:
+ resolution: {integrity: sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg==}
+
+ follow-redirects@1.16.0:
+ resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+
+ form-data-encoder@1.7.2:
+ resolution: {integrity: sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==}
+
+ form-data@4.0.6:
+ resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==}
+ engines: {node: '>= 6'}
+
+ formdata-node@4.4.1:
+ resolution: {integrity: sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==}
+ engines: {node: '>= 12.20'}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ get-intrinsic@1.3.0:
+ resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
+ engines: {node: '>= 0.4'}
+
+ get-proto@1.0.1:
+ resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
+ engines: {node: '>= 0.4'}
+
+ gopd@1.2.0:
+ resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
+ engines: {node: '>= 0.4'}
+
+ has-symbols@1.1.0:
+ resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
+ engines: {node: '>= 0.4'}
+
+ has-tostringtag@1.0.2:
+ resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
+ engines: {node: '>= 0.4'}
+
+ hasown@2.0.4:
+ resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==}
+ engines: {node: '>= 0.4'}
+
+ https-proxy-agent@5.0.1:
+ resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
+ engines: {node: '>= 6'}
+
+ humanize-ms@1.2.1:
+ resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
+
+ joycon@3.1.1:
+ resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
+ engines: {node: '>=10'}
+
+ lightningcss-android-arm64@1.33.0:
+ resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [android]
+
+ lightningcss-darwin-arm64@1.33.0:
+ resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [darwin]
+
+ lightningcss-darwin-x64@1.33.0:
+ resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [darwin]
+
+ lightningcss-freebsd-x64@1.33.0:
+ resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [freebsd]
+
+ lightningcss-linux-arm-gnueabihf@1.33.0:
+ resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm]
+ os: [linux]
+
+ lightningcss-linux-arm64-gnu@1.33.0:
+ resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-arm64-musl@1.33.0:
+ resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [linux]
+
+ lightningcss-linux-x64-gnu@1.33.0:
+ resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-linux-x64-musl@1.33.0:
+ resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [linux]
+
+ lightningcss-win32-arm64-msvc@1.33.0:
+ resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [arm64]
+ os: [win32]
+
+ lightningcss-win32-x64-msvc@1.33.0:
+ resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==}
+ engines: {node: '>= 12.0.0'}
+ cpu: [x64]
+ os: [win32]
+
+ lightningcss@1.33.0:
+ resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==}
+ engines: {node: '>= 12.0.0'}
+
+ lilconfig@3.1.3:
+ resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==}
+ engines: {node: '>=14'}
+
+ lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
+ load-tsconfig@0.2.5:
+ resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ magic-string@0.30.21:
+ resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==}
+
+ math-intrinsics@1.1.0:
+ resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
+ engines: {node: '>= 0.4'}
+
+ mem0ai@3.1.6:
+ resolution: {integrity: sha512-arbotbiNxevHgs/GoVMfqS77SV9yO7F7tUWU9VqU8qKHNzXUXH7CNGk7dKeRpdQESdkooPIpI3E4B6ppc1WTEA==}
+ engines: {node: '>=18'}
+ peerDependencies:
+ '@anthropic-ai/sdk': ^0.40.1
+ '@aws-sdk/client-bedrock-runtime': '>=3.0.0 <3.968.0'
+ '@aws-sdk/client-neptune-graph': '>=3.0.0 <3.968.0'
+ '@aws-sdk/client-s3vectors': 3.967.0
+ '@azure/identity': ^4.0.0
+ '@azure/search-documents': ^12.0.0
+ '@cloudflare/workers-types': ^4.20250504.0
+ '@databricks/sql': ^1.16.0
+ '@elastic/elasticsearch': ^9.0.0
+ '@google-cloud/aiplatform': ^6.8.0
+ '@google/genai': ^1.40.0
+ '@huggingface/transformers': ^3.0.0 || ^4.0.0
+ '@langchain/core': ^1.1.47
+ '@mistralai/mistralai': ^1.5.2
+ '@mochow/mochow-sdk-node': ^2.1.5
+ '@opensearch-project/opensearch': ^3.5.1
+ '@pinecone-database/pinecone': ^8.0.0
+ '@qdrant/js-client-rest': ^1.18.0
+ '@supabase/supabase-js': ^2.49.1
+ '@turbopuffer/turbopuffer': ^2.0.0
+ '@types/jest': 29.5.14
+ '@types/pg': 8.11.0
+ '@upstash/vector': ^1.2.3
+ '@zilliz/milvus2-sdk-node': ^2.4.0 || ^3.0.0
+ better-sqlite3: ^12.6.2
+ cassandra-driver: 4.8.0
+ chromadb: ^3.5.0
+ cloudflare: ^4.2.0
+ cohere-ai: ^7.17.0 || ^8.0.0
+ compromise: ^14.0.0
+ fastembed: ^2.1.0
+ groq-sdk: 0.3.0
+ iovalkey: ^0.3.3
+ mongodb: ^7.0.0
+ mysql2: ^3.0.0
+ natural: ^8.0.1
+ ollama: ^0.5.14
+ oracledb: ^6.5.0 || ^7.0.0
+ pg: 8.11.3
+ redis: ^4.6.13
+ weaviate-client: ^3.0.0
+ zeroentropy: ^0.1.0-alpha.10
+ peerDependenciesMeta:
+ '@anthropic-ai/sdk':
+ optional: true
+ '@aws-sdk/client-bedrock-runtime':
+ optional: true
+ '@aws-sdk/client-neptune-graph':
+ optional: true
+ '@aws-sdk/client-s3vectors':
+ optional: true
+ '@azure/identity':
+ optional: true
+ '@azure/search-documents':
+ optional: true
+ '@databricks/sql':
+ optional: true
+ '@elastic/elasticsearch':
+ optional: true
+ '@google-cloud/aiplatform':
+ optional: true
+ '@google/genai':
+ optional: true
+ '@huggingface/transformers':
+ optional: true
+ '@langchain/core':
+ optional: true
+ '@mistralai/mistralai':
+ optional: true
+ '@mochow/mochow-sdk-node':
+ optional: true
+ '@opensearch-project/opensearch':
+ optional: true
+ '@pinecone-database/pinecone':
+ optional: true
+ '@qdrant/js-client-rest':
+ optional: true
+ '@supabase/supabase-js':
+ optional: true
+ '@turbopuffer/turbopuffer':
+ optional: true
+ '@upstash/vector':
+ optional: true
+ '@zilliz/milvus2-sdk-node':
+ optional: true
+ cassandra-driver:
+ optional: true
+ chromadb:
+ optional: true
+ cloudflare:
+ optional: true
+ cohere-ai:
+ optional: true
+ fastembed:
+ optional: true
+ groq-sdk:
+ optional: true
+ iovalkey:
+ optional: true
+ mongodb:
+ optional: true
+ mysql2:
+ optional: true
+ ollama:
+ optional: true
+ oracledb:
+ optional: true
+ redis:
+ optional: true
+ weaviate-client:
+ optional: true
+ zeroentropy:
+ optional: true
+
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ mlly@1.8.2:
+ resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+
+ nanoid@3.3.18:
+ resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ node-domexception@1.0.0:
+ resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
+ engines: {node: '>=10.5.0'}
+ deprecated: Use your platform's native DOMException instead
+
+ node-fetch@2.7.0:
+ resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}
+ engines: {node: 4.x || >=6.0.0}
+ peerDependencies:
+ encoding: ^0.1.0
+ peerDependenciesMeta:
+ encoding:
+ optional: true
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ obug@2.1.4:
+ resolution: {integrity: sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==}
+ engines: {node: '>=12.20.0'}
+
+ openai@4.104.0:
+ resolution: {integrity: sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA==}
+ hasBin: true
+ peerDependencies:
+ ws: ^8.18.0
+ zod: ^3.23.8
+ peerDependenciesMeta:
+ ws:
+ optional: true
+ zod:
+ optional: true
+
+ pathe@2.0.3:
+ resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
+
+ picocolors@1.1.1:
+ resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+
+ picomatch@4.0.5:
+ resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==}
+ engines: {node: '>=12'}
+
+ pirates@4.0.7:
+ resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==}
+ engines: {node: '>= 6'}
+
+ pkg-types@1.3.1:
+ resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
+
+ postcss-load-config@6.0.1:
+ resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==}
+ engines: {node: '>= 18'}
+ peerDependencies:
+ jiti: '>=1.21.0'
+ postcss: '>=8.0.9'
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ jiti:
+ optional: true
+ postcss:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ postcss@8.5.26:
+ resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ proxy-from-env@2.1.0:
+ resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==}
+ engines: {node: '>=10'}
+
+ readdirp@4.1.2:
+ resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
+ engines: {node: '>= 14.18.0'}
+
+ resolve-from@5.0.0:
+ resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
+ engines: {node: '>=8'}
+
+ rolldown@1.2.5:
+ resolution: {integrity: sha512-VD2IE5PUG4Oj8zz2VGykiYd5wbnjdIiSsNQb8Qu5B+noEp+A78mu2iVvpp27g8es14Tk9rofNs5Tku9iQCS4fA==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+
+ rollup@4.62.5:
+ resolution: {integrity: sha512-/tqMfgP7GPA3PHhCmuiS4vIjrSVhHLgY++i+dhbG462euyAj7FpM4D9uq1X3BgjlqRdpcOrYhcQtfiQLNc8tqw==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ siginfo@2.0.0:
+ resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ source-map@0.7.6:
+ resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==}
+ engines: {node: '>= 12'}
+
+ stackback@0.0.2:
+ resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
+
+ std-env@4.2.0:
+ resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==}
+
+ sucrase@3.35.1:
+ resolution: {integrity: sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+
+ thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+
+ thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+
+ tinybench@2.9.0:
+ resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
+
+ tinyexec@0.3.2:
+ resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
+
+ tinyexec@1.3.0:
+ resolution: {integrity: sha512-QKAl9m8gWWGHV8jZcPeym6j+XULi6tOf1mT83WYJ4Lk2ytW/uwAWkrP0uFsdoYMdueVJ0qs26wZ+23xeB4ibNQ==}
+ engines: {node: '>=18'}
+
+ tinyglobby@0.2.17:
+ resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
+ engines: {node: '>=12.0.0'}
+
+ tinyrainbow@3.1.1:
+ resolution: {integrity: sha512-yau8yJdTt989Mm0Bd/236QnzEiPf2xLLTqUZRUJOo/3CB078LSwzei343DgtJVmfJKJE3TMINY1u42SQsP6mXw==}
+ engines: {node: '>=14.0.0'}
+
+ tr46@0.0.3:
+ resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
+
+ tree-kill@1.2.2:
+ resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
+ hasBin: true
+
+ ts-interface-checker@0.1.13:
+ resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+
+ tsup@8.5.1:
+ resolution: {integrity: sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing==}
+ engines: {node: '>=18'}
+ hasBin: true
+ peerDependencies:
+ '@microsoft/api-extractor': ^7.36.0
+ '@swc/core': ^1
+ postcss: ^8.4.12
+ typescript: '>=4.5.0'
+ peerDependenciesMeta:
+ '@microsoft/api-extractor':
+ optional: true
+ '@swc/core':
+ optional: true
+ postcss:
+ optional: true
+ typescript:
+ optional: true
+
+ typescript@5.9.3:
+ resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ ufo@1.6.4:
+ resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==}
+
+ undici-types@5.26.5:
+ resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
+
+ undici-types@6.21.0:
+ resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
+
+ uuid@11.1.1:
+ resolution: {integrity: sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==}
+ hasBin: true
+
+ vite@8.2.2:
+ resolution: {integrity: sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==}
+ engines: {node: ^20.19.0 || >=22.12.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^20.19.0 || >=22.12.0
+ '@vitejs/devtools': ^0.4.0 || ^0.5.0
+ esbuild: ^0.27.0 || ^0.28.0
+ jiti: '>=1.21.0'
+ less: ^4.0.0
+ sass: ^1.70.0
+ sass-embedded: ^1.70.0
+ stylus: '>=0.54.8'
+ sugarss: ^5.0.0
+ terser: ^5.16.0
+ tsx: ^4.8.1
+ yaml: ^2.4.2
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ '@vitejs/devtools':
+ optional: true
+ esbuild:
+ optional: true
+ jiti:
+ optional: true
+ less:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+ tsx:
+ optional: true
+ yaml:
+ optional: true
+
+ vitest@4.1.11:
+ resolution: {integrity: sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==}
+ engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0}
+ hasBin: true
+ peerDependencies:
+ '@edge-runtime/vm': '*'
+ '@opentelemetry/api': ^1.9.0
+ '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0
+ '@vitest/browser-playwright': 4.1.11
+ '@vitest/browser-preview': 4.1.11
+ '@vitest/browser-webdriverio': 4.1.11
+ '@vitest/coverage-istanbul': 4.1.11
+ '@vitest/coverage-v8': 4.1.11
+ '@vitest/ui': 4.1.11
+ happy-dom: '*'
+ jsdom: '*'
+ peerDependenciesMeta:
+ '@edge-runtime/vm':
+ optional: true
+ '@opentelemetry/api':
+ optional: true
+ '@types/node':
+ optional: true
+ '@vitest/browser-playwright':
+ optional: true
+ '@vitest/browser-preview':
+ optional: true
+ '@vitest/browser-webdriverio':
+ optional: true
+ '@vitest/coverage-istanbul':
+ optional: true
+ '@vitest/coverage-v8':
+ optional: true
+ '@vitest/ui':
+ optional: true
+ happy-dom:
+ optional: true
+ jsdom:
+ optional: true
+
+ web-streams-polyfill@4.0.0-beta.3:
+ resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==}
+ engines: {node: '>= 14'}
+
+ webidl-conversions@3.0.1:
+ resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
+
+ whatwg-url@5.0.0:
+ resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
+
+ why-is-node-running@2.3.0:
+ resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
+ engines: {node: '>=8'}
+ hasBin: true
+
+ zod@3.25.76:
+ resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==}
+
+snapshots:
+
+ '@deepseek-ai/cordis@4.0.1':
+ dependencies:
+ '@deepseek-ai/cosmokit': 1.8.2
+ '@standard-schema/spec': 1.1.0
+
+ '@deepseek-ai/cosmokit@1.8.2': {}
+
+ '@deepseek-ai/dsh-tools@0.0.1-rc.1(@deepseek-ai/cordis@4.0.1)':
+ dependencies:
+ '@deepseek-ai/cordis': 4.0.1
+ '@deepseek-ai/schemastery': 3.18.1
+
+ '@deepseek-ai/schemastery@3.18.1':
+ dependencies:
+ '@deepseek-ai/cosmokit': 1.8.2
+ '@standard-schema/spec': 1.1.0
+
+ '@esbuild/aix-ppc64@0.27.7':
+ optional: true
+
+ '@esbuild/android-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/android-arm@0.27.7':
+ optional: true
+
+ '@esbuild/android-x64@0.27.7':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/darwin-x64@0.27.7':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-arm@0.27.7':
+ optional: true
+
+ '@esbuild/linux-ia32@0.27.7':
+ optional: true
+
+ '@esbuild/linux-loong64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.27.7':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.27.7':
+ optional: true
+
+ '@esbuild/linux-s390x@0.27.7':
+ optional: true
+
+ '@esbuild/linux-x64@0.27.7':
+ optional: true
+
+ '@esbuild/netbsd-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.27.7':
+ optional: true
+
+ '@esbuild/openbsd-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.27.7':
+ optional: true
+
+ '@esbuild/openharmony-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/sunos-x64@0.27.7':
+ optional: true
+
+ '@esbuild/win32-arm64@0.27.7':
+ optional: true
+
+ '@esbuild/win32-ia32@0.27.7':
+ optional: true
+
+ '@esbuild/win32-x64@0.27.7':
+ optional: true
+
+ '@jridgewell/gen-mapping@0.3.13':
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+ '@jridgewell/trace-mapping': 0.3.31
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/sourcemap-codec@1.5.5': {}
+
+ '@jridgewell/trace-mapping@0.3.31':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ '@napi-rs/lzma-linux-x64-gnu@1.5.1':
+ optional: true
+
+ '@oxc-project/types@0.146.0': {}
+
+ '@rolldown/binding-android-arm-eabi@1.2.5':
+ optional: true
+
+ '@rolldown/binding-android-arm64@1.2.5':
+ optional: true
+
+ '@rolldown/binding-darwin-arm64@1.2.5':
+ optional: true
+
+ '@rolldown/binding-darwin-x64@1.2.5':
+ optional: true
+
+ '@rolldown/binding-freebsd-x64@1.2.5':
+ optional: true
+
+ '@rolldown/binding-linux-arm-gnueabihf@1.2.5':
+ optional: true
+
+ '@rolldown/binding-linux-arm64-gnu@1.2.5':
+ optional: true
+
+ '@rolldown/binding-linux-arm64-musl@1.2.5':
+ optional: true
+
+ '@rolldown/binding-linux-ppc64-gnu@1.2.5':
+ optional: true
+
+ '@rolldown/binding-linux-s390x-gnu@1.2.5':
+ optional: true
+
+ '@rolldown/binding-linux-x64-gnu@1.2.5':
+ optional: true
+
+ '@rolldown/binding-linux-x64-musl@1.2.5':
+ optional: true
+
+ '@rolldown/binding-openharmony-arm64@1.2.5':
+ optional: true
+
+ '@rolldown/binding-win32-arm64-msvc@1.2.5':
+ optional: true
+
+ '@rolldown/binding-win32-x64-msvc@1.2.5':
+ optional: true
+
+ '@rolldown/pluginutils@1.0.1': {}
+
+ '@rollup/rollup-android-arm-eabi@4.62.5':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.62.5':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.62.5':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.62.5':
+ optional: true
+
+ '@rollup/rollup-freebsd-arm64@4.62.5':
+ optional: true
+
+ '@rollup/rollup-freebsd-x64@4.62.5':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.62.5':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.62.5':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.62.5':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.62.5':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-gnu@4.62.5':
+ optional: true
+
+ '@rollup/rollup-linux-loong64-musl@4.62.5':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-gnu@4.62.5':
+ optional: true
+
+ '@rollup/rollup-linux-ppc64-musl@4.62.5':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.62.5':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-musl@4.62.5':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.62.5':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.62.5':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.62.5':
+ optional: true
+
+ '@rollup/rollup-openbsd-x64@4.62.5':
+ optional: true
+
+ '@rollup/rollup-openharmony-arm64@4.62.5':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.62.5':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.62.5':
+ optional: true
+
+ '@rollup/rollup-win32-x64-gnu@4.62.5':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.62.5':
+ optional: true
+
+ '@standard-schema/spec@1.1.0': {}
+
+ '@types/chai@5.2.3':
+ dependencies:
+ '@types/deep-eql': 4.0.2
+ assertion-error: 2.0.1
+
+ '@types/deep-eql@4.0.2': {}
+
+ '@types/estree@1.0.9': {}
+
+ '@types/node-fetch@2.6.13':
+ dependencies:
+ '@types/node': 22.20.1
+ form-data: 4.0.6
+
+ '@types/node@18.19.130':
+ dependencies:
+ undici-types: 5.26.5
+
+ '@types/node@22.20.1':
+ dependencies:
+ undici-types: 6.21.0
+
+ '@vitest/expect@4.1.11':
+ dependencies:
+ '@standard-schema/spec': 1.1.0
+ '@types/chai': 5.2.3
+ '@vitest/spy': 4.1.11
+ '@vitest/utils': 4.1.11
+ chai: 6.2.2
+ tinyrainbow: 3.1.1
+
+ '@vitest/mocker@4.1.11(vite@8.2.2(@types/node@22.20.1)(esbuild@0.27.7))':
+ dependencies:
+ '@vitest/spy': 4.1.11
+ estree-walker: 3.0.3
+ magic-string: 0.30.21
+ optionalDependencies:
+ vite: 8.2.2(@types/node@22.20.1)(esbuild@0.27.7)
+
+ '@vitest/pretty-format@4.1.11':
+ dependencies:
+ tinyrainbow: 3.1.1
+
+ '@vitest/runner@4.1.11':
+ dependencies:
+ '@vitest/utils': 4.1.11
+ pathe: 2.0.3
+
+ '@vitest/snapshot@4.1.11':
+ dependencies:
+ '@vitest/pretty-format': 4.1.11
+ '@vitest/utils': 4.1.11
+ magic-string: 0.30.21
+ pathe: 2.0.3
+
+ '@vitest/spy@4.1.11': {}
+
+ '@vitest/utils@4.1.11':
+ dependencies:
+ '@vitest/pretty-format': 4.1.11
+ convert-source-map: 2.0.0
+ tinyrainbow: 3.1.1
+
+ abort-controller@3.0.0:
+ dependencies:
+ event-target-shim: 5.0.1
+
+ acorn@8.18.0: {}
+
+ agent-base@6.0.2:
+ dependencies:
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ agentkeepalive@4.6.0:
+ dependencies:
+ humanize-ms: 1.2.1
+
+ any-promise@1.3.0: {}
+
+ assertion-error@2.0.1: {}
+
+ asynckit@0.4.0: {}
+
+ axios@1.19.0:
+ dependencies:
+ follow-redirects: 1.16.0
+ form-data: 4.0.6
+ https-proxy-agent: 5.0.1
+ proxy-from-env: 2.1.0
+ transitivePeerDependencies:
+ - debug
+ - supports-color
+
+ bundle-require@5.1.0(esbuild@0.27.7):
+ dependencies:
+ esbuild: 0.27.7
+ load-tsconfig: 0.2.5
+
+ cac@6.7.14: {}
+
+ call-bind-apply-helpers@1.0.2:
+ dependencies:
+ es-errors: 1.3.0
+ function-bind: 1.1.2
+
+ chai@6.2.2: {}
+
+ chokidar@4.0.3:
+ dependencies:
+ readdirp: 4.1.2
+
+ combined-stream@1.0.8:
+ dependencies:
+ delayed-stream: 1.0.0
+
+ commander@4.1.1: {}
+
+ confbox@0.1.8: {}
+
+ consola@3.4.2: {}
+
+ convert-source-map@2.0.0: {}
+
+ debug@4.4.3:
+ dependencies:
+ ms: 2.1.3
+
+ delayed-stream@1.0.0: {}
+
+ detect-libc@2.1.2: {}
+
+ dunder-proto@1.0.1:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-errors: 1.3.0
+ gopd: 1.2.0
+
+ es-define-property@1.0.1: {}
+
+ es-errors@1.3.0: {}
+
+ es-module-lexer@2.3.2: {}
+
+ es-object-atoms@1.1.2:
+ dependencies:
+ es-errors: 1.3.0
+
+ es-set-tostringtag@2.1.0:
+ dependencies:
+ es-errors: 1.3.0
+ get-intrinsic: 1.3.0
+ has-tostringtag: 1.0.2
+ hasown: 2.0.4
+
+ esbuild@0.27.7:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.27.7
+ '@esbuild/android-arm': 0.27.7
+ '@esbuild/android-arm64': 0.27.7
+ '@esbuild/android-x64': 0.27.7
+ '@esbuild/darwin-arm64': 0.27.7
+ '@esbuild/darwin-x64': 0.27.7
+ '@esbuild/freebsd-arm64': 0.27.7
+ '@esbuild/freebsd-x64': 0.27.7
+ '@esbuild/linux-arm': 0.27.7
+ '@esbuild/linux-arm64': 0.27.7
+ '@esbuild/linux-ia32': 0.27.7
+ '@esbuild/linux-loong64': 0.27.7
+ '@esbuild/linux-mips64el': 0.27.7
+ '@esbuild/linux-ppc64': 0.27.7
+ '@esbuild/linux-riscv64': 0.27.7
+ '@esbuild/linux-s390x': 0.27.7
+ '@esbuild/linux-x64': 0.27.7
+ '@esbuild/netbsd-arm64': 0.27.7
+ '@esbuild/netbsd-x64': 0.27.7
+ '@esbuild/openbsd-arm64': 0.27.7
+ '@esbuild/openbsd-x64': 0.27.7
+ '@esbuild/openharmony-arm64': 0.27.7
+ '@esbuild/sunos-x64': 0.27.7
+ '@esbuild/win32-arm64': 0.27.7
+ '@esbuild/win32-ia32': 0.27.7
+ '@esbuild/win32-x64': 0.27.7
+
+ estree-walker@3.0.3:
+ dependencies:
+ '@types/estree': 1.0.9
+
+ event-target-shim@5.0.1: {}
+
+ expect-type@1.4.0: {}
+
+ fdir@6.5.0(picomatch@4.0.5):
+ optionalDependencies:
+ picomatch: 4.0.5
+
+ fix-dts-default-cjs-exports@1.0.1:
+ dependencies:
+ magic-string: 0.30.21
+ mlly: 1.8.2
+ rollup: 4.62.5
+
+ follow-redirects@1.16.0: {}
+
+ form-data-encoder@1.7.2: {}
+
+ form-data@4.0.6:
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ es-set-tostringtag: 2.1.0
+ hasown: 2.0.4
+ mime-types: 2.1.35
+
+ formdata-node@4.4.1:
+ dependencies:
+ node-domexception: 1.0.0
+ web-streams-polyfill: 4.0.0-beta.3
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-bind@1.1.2: {}
+
+ get-intrinsic@1.3.0:
+ dependencies:
+ call-bind-apply-helpers: 1.0.2
+ es-define-property: 1.0.1
+ es-errors: 1.3.0
+ es-object-atoms: 1.1.2
+ function-bind: 1.1.2
+ get-proto: 1.0.1
+ gopd: 1.2.0
+ has-symbols: 1.1.0
+ hasown: 2.0.4
+ math-intrinsics: 1.1.0
+
+ get-proto@1.0.1:
+ dependencies:
+ dunder-proto: 1.0.1
+ es-object-atoms: 1.1.2
+
+ gopd@1.2.0: {}
+
+ has-symbols@1.1.0: {}
+
+ has-tostringtag@1.0.2:
+ dependencies:
+ has-symbols: 1.1.0
+
+ hasown@2.0.4:
+ dependencies:
+ function-bind: 1.1.2
+
+ https-proxy-agent@5.0.1:
+ dependencies:
+ agent-base: 6.0.2
+ debug: 4.4.3
+ transitivePeerDependencies:
+ - supports-color
+
+ humanize-ms@1.2.1:
+ dependencies:
+ ms: 2.1.3
+
+ joycon@3.1.1: {}
+
+ lightningcss-android-arm64@1.33.0:
+ optional: true
+
+ lightningcss-darwin-arm64@1.33.0:
+ optional: true
+
+ lightningcss-darwin-x64@1.33.0:
+ optional: true
+
+ lightningcss-freebsd-x64@1.33.0:
+ optional: true
+
+ lightningcss-linux-arm-gnueabihf@1.33.0:
+ optional: true
+
+ lightningcss-linux-arm64-gnu@1.33.0:
+ optional: true
+
+ lightningcss-linux-arm64-musl@1.33.0:
+ optional: true
+
+ lightningcss-linux-x64-gnu@1.33.0:
+ optional: true
+
+ lightningcss-linux-x64-musl@1.33.0:
+ optional: true
+
+ lightningcss-win32-arm64-msvc@1.33.0:
+ optional: true
+
+ lightningcss-win32-x64-msvc@1.33.0:
+ optional: true
+
+ lightningcss@1.33.0:
+ dependencies:
+ detect-libc: 2.1.2
+ optionalDependencies:
+ lightningcss-android-arm64: 1.33.0
+ lightningcss-darwin-arm64: 1.33.0
+ lightningcss-darwin-x64: 1.33.0
+ lightningcss-freebsd-x64: 1.33.0
+ lightningcss-linux-arm-gnueabihf: 1.33.0
+ lightningcss-linux-arm64-gnu: 1.33.0
+ lightningcss-linux-arm64-musl: 1.33.0
+ lightningcss-linux-x64-gnu: 1.33.0
+ lightningcss-linux-x64-musl: 1.33.0
+ lightningcss-win32-arm64-msvc: 1.33.0
+ lightningcss-win32-x64-msvc: 1.33.0
+
+ lilconfig@3.1.3: {}
+
+ lines-and-columns@1.2.4: {}
+
+ load-tsconfig@0.2.5: {}
+
+ magic-string@0.30.21:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.5
+
+ math-intrinsics@1.1.0: {}
+
+ mem0ai@3.1.6:
+ dependencies:
+ axios: 1.19.0
+ openai: 4.104.0(zod@3.25.76)
+ uuid: 11.1.1
+ zod: 3.25.76
+ transitivePeerDependencies:
+ - debug
+ - encoding
+ - supports-color
+ - ws
+
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
+ mlly@1.8.2:
+ dependencies:
+ acorn: 8.18.0
+ pathe: 2.0.3
+ pkg-types: 1.3.1
+ ufo: 1.6.4
+
+ ms@2.1.3: {}
+
+ mz@2.7.0:
+ dependencies:
+ any-promise: 1.3.0
+ object-assign: 4.1.1
+ thenify-all: 1.6.0
+
+ nanoid@3.3.18: {}
+
+ node-domexception@1.0.0: {}
+
+ node-fetch@2.7.0:
+ dependencies:
+ whatwg-url: 5.0.0
+
+ object-assign@4.1.1: {}
+
+ obug@2.1.4: {}
+
+ openai@4.104.0(zod@3.25.76):
+ dependencies:
+ '@types/node': 18.19.130
+ '@types/node-fetch': 2.6.13
+ abort-controller: 3.0.0
+ agentkeepalive: 4.6.0
+ form-data-encoder: 1.7.2
+ formdata-node: 4.4.1
+ node-fetch: 2.7.0
+ optionalDependencies:
+ zod: 3.25.76
+ transitivePeerDependencies:
+ - encoding
+
+ pathe@2.0.3: {}
+
+ picocolors@1.1.1: {}
+
+ picomatch@4.0.5: {}
+
+ pirates@4.0.7: {}
+
+ pkg-types@1.3.1:
+ dependencies:
+ confbox: 0.1.8
+ mlly: 1.8.2
+ pathe: 2.0.3
+
+ postcss-load-config@6.0.1(postcss@8.5.26):
+ dependencies:
+ lilconfig: 3.1.3
+ optionalDependencies:
+ postcss: 8.5.26
+
+ postcss@8.5.26:
+ dependencies:
+ nanoid: 3.3.18
+ picocolors: 1.1.1
+ source-map-js: 1.2.1
+
+ proxy-from-env@2.1.0: {}
+
+ readdirp@4.1.2: {}
+
+ resolve-from@5.0.0: {}
+
+ rolldown@1.2.5:
+ dependencies:
+ '@oxc-project/types': 0.146.0
+ '@rolldown/pluginutils': 1.0.1
+ optionalDependencies:
+ '@rolldown/binding-android-arm-eabi': 1.2.5
+ '@rolldown/binding-android-arm64': 1.2.5
+ '@rolldown/binding-darwin-arm64': 1.2.5
+ '@rolldown/binding-darwin-x64': 1.2.5
+ '@rolldown/binding-freebsd-x64': 1.2.5
+ '@rolldown/binding-linux-arm-gnueabihf': 1.2.5
+ '@rolldown/binding-linux-arm64-gnu': 1.2.5
+ '@rolldown/binding-linux-arm64-musl': 1.2.5
+ '@rolldown/binding-linux-ppc64-gnu': 1.2.5
+ '@rolldown/binding-linux-s390x-gnu': 1.2.5
+ '@rolldown/binding-linux-x64-gnu': 1.2.5
+ '@rolldown/binding-linux-x64-musl': 1.2.5
+ '@rolldown/binding-openharmony-arm64': 1.2.5
+ '@rolldown/binding-win32-arm64-msvc': 1.2.5
+ '@rolldown/binding-win32-x64-msvc': 1.2.5
+
+ rollup@4.62.5:
+ dependencies:
+ '@types/estree': 1.0.9
+ optionalDependencies:
+ '@napi-rs/lzma-linux-x64-gnu': 1.5.1
+ '@rollup/rollup-android-arm-eabi': 4.62.5
+ '@rollup/rollup-android-arm64': 4.62.5
+ '@rollup/rollup-darwin-arm64': 4.62.5
+ '@rollup/rollup-darwin-x64': 4.62.5
+ '@rollup/rollup-freebsd-arm64': 4.62.5
+ '@rollup/rollup-freebsd-x64': 4.62.5
+ '@rollup/rollup-linux-arm-gnueabihf': 4.62.5
+ '@rollup/rollup-linux-arm-musleabihf': 4.62.5
+ '@rollup/rollup-linux-arm64-gnu': 4.62.5
+ '@rollup/rollup-linux-arm64-musl': 4.62.5
+ '@rollup/rollup-linux-loong64-gnu': 4.62.5
+ '@rollup/rollup-linux-loong64-musl': 4.62.5
+ '@rollup/rollup-linux-ppc64-gnu': 4.62.5
+ '@rollup/rollup-linux-ppc64-musl': 4.62.5
+ '@rollup/rollup-linux-riscv64-gnu': 4.62.5
+ '@rollup/rollup-linux-riscv64-musl': 4.62.5
+ '@rollup/rollup-linux-s390x-gnu': 4.62.5
+ '@rollup/rollup-linux-x64-gnu': 4.62.5
+ '@rollup/rollup-linux-x64-musl': 4.62.5
+ '@rollup/rollup-openbsd-x64': 4.62.5
+ '@rollup/rollup-openharmony-arm64': 4.62.5
+ '@rollup/rollup-win32-arm64-msvc': 4.62.5
+ '@rollup/rollup-win32-ia32-msvc': 4.62.5
+ '@rollup/rollup-win32-x64-gnu': 4.62.5
+ '@rollup/rollup-win32-x64-msvc': 4.62.5
+ fsevents: 2.3.3
+
+ siginfo@2.0.0: {}
+
+ source-map-js@1.2.1: {}
+
+ source-map@0.7.6: {}
+
+ stackback@0.0.2: {}
+
+ std-env@4.2.0: {}
+
+ sucrase@3.35.1:
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.13
+ commander: 4.1.1
+ lines-and-columns: 1.2.4
+ mz: 2.7.0
+ pirates: 4.0.7
+ tinyglobby: 0.2.17
+ ts-interface-checker: 0.1.13
+
+ thenify-all@1.6.0:
+ dependencies:
+ thenify: 3.3.1
+
+ thenify@3.3.1:
+ dependencies:
+ any-promise: 1.3.0
+
+ tinybench@2.9.0: {}
+
+ tinyexec@0.3.2: {}
+
+ tinyexec@1.3.0: {}
+
+ tinyglobby@0.2.17:
+ dependencies:
+ fdir: 6.5.0(picomatch@4.0.5)
+ picomatch: 4.0.5
+
+ tinyrainbow@3.1.1: {}
+
+ tr46@0.0.3: {}
+
+ tree-kill@1.2.2: {}
+
+ ts-interface-checker@0.1.13: {}
+
+ tsup@8.5.1(postcss@8.5.26)(typescript@5.9.3):
+ dependencies:
+ bundle-require: 5.1.0(esbuild@0.27.7)
+ cac: 6.7.14
+ chokidar: 4.0.3
+ consola: 3.4.2
+ debug: 4.4.3
+ esbuild: 0.27.7
+ fix-dts-default-cjs-exports: 1.0.1
+ joycon: 3.1.1
+ picocolors: 1.1.1
+ postcss-load-config: 6.0.1(postcss@8.5.26)
+ resolve-from: 5.0.0
+ rollup: 4.62.5
+ source-map: 0.7.6
+ sucrase: 3.35.1
+ tinyexec: 0.3.2
+ tinyglobby: 0.2.17
+ tree-kill: 1.2.2
+ optionalDependencies:
+ postcss: 8.5.26
+ typescript: 5.9.3
+ transitivePeerDependencies:
+ - jiti
+ - supports-color
+ - tsx
+ - yaml
+
+ typescript@5.9.3: {}
+
+ ufo@1.6.4: {}
+
+ undici-types@5.26.5: {}
+
+ undici-types@6.21.0: {}
+
+ uuid@11.1.1: {}
+
+ vite@8.2.2(@types/node@22.20.1)(esbuild@0.27.7):
+ dependencies:
+ lightningcss: 1.33.0
+ picomatch: 4.0.5
+ postcss: 8.5.26
+ rolldown: 1.2.5
+ tinyglobby: 0.2.17
+ optionalDependencies:
+ '@types/node': 22.20.1
+ esbuild: 0.27.7
+ fsevents: 2.3.3
+
+ vitest@4.1.11(@types/node@22.20.1)(esbuild@0.27.7):
+ dependencies:
+ '@vitest/expect': 4.1.11
+ '@vitest/mocker': 4.1.11(vite@8.2.2(@types/node@22.20.1)(esbuild@0.27.7))
+ '@vitest/pretty-format': 4.1.11
+ '@vitest/runner': 4.1.11
+ '@vitest/snapshot': 4.1.11
+ '@vitest/spy': 4.1.11
+ '@vitest/utils': 4.1.11
+ es-module-lexer: 2.3.2
+ expect-type: 1.4.0
+ magic-string: 0.30.21
+ obug: 2.1.4
+ pathe: 2.0.3
+ picomatch: 4.0.5
+ std-env: 4.2.0
+ tinybench: 2.9.0
+ tinyexec: 1.3.0
+ tinyglobby: 0.2.17
+ tinyrainbow: 3.1.1
+ vite: 8.2.2(@types/node@22.20.1)(esbuild@0.27.7)
+ why-is-node-running: 2.3.0
+ optionalDependencies:
+ '@types/node': 22.20.1
+ transitivePeerDependencies:
+ - '@vitejs/devtools'
+ - esbuild
+ - jiti
+ - less
+ - msw
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - terser
+ - tsx
+ - yaml
+
+ web-streams-polyfill@4.0.0-beta.3: {}
+
+ webidl-conversions@3.0.1: {}
+
+ whatwg-url@5.0.0:
+ dependencies:
+ tr46: 0.0.3
+ webidl-conversions: 3.0.1
+
+ why-is-node-running@2.3.0:
+ dependencies:
+ siginfo: 2.0.0
+ stackback: 0.0.2
+
+ zod@3.25.76: {}
diff --git a/integrations/dsh-mem0/src/formatting.ts b/integrations/dsh-mem0/src/formatting.ts
new file mode 100644
index 000000000..63296a185
--- /dev/null
+++ b/integrations/dsh-mem0/src/formatting.ts
@@ -0,0 +1,69 @@
+/**
+ * Compact, token-cheap rendering of Mem0 results for the model context.
+ *
+ * Mirrors the format used by the sibling Mem0 plugins
+ * (integrations/pi-agent-plugin/src/memory/formatting.ts) so a memory reads the
+ * same way across every harness: `[category] text (age) [mem0:id]`. Dumping the
+ * raw search envelope instead would spend most of the tokens on JSON scaffolding.
+ */
+
+export interface MemoryLike {
+ id: string;
+ memory?: string;
+ categories?: string[];
+ createdAt?: Date | string;
+}
+
+export function formatAge(date: Date | string): string {
+ const d = typeof date === "string" ? new Date(date) : date;
+ const ms = Date.now() - d.getTime();
+ const minutes = Math.floor(ms / 60_000);
+ if (minutes < 60) return `${minutes}m ago`;
+ const hours = Math.floor(minutes / 60);
+ if (hours < 24) return `${hours}h ago`;
+ const days = Math.floor(hours / 24);
+ return `${days}d ago`;
+}
+
+export function formatMemoryCompact(mem: MemoryLike): string {
+ const cat = mem.categories?.[0] ?? "uncategorized";
+ const age = mem.createdAt ? ` (${formatAge(mem.createdAt)})` : "";
+ return `[${cat}] ${mem.memory ?? "(empty)"}${age} [mem0:${mem.id}]`;
+}
+
+export function formatMemoryList(memories: MemoryLike[]): string {
+ if (memories.length === 0) return "No memories found.";
+ return memories
+ .map((m, i) => `${i + 1}. ${formatMemoryCompact(m)}`)
+ .join("\n");
+}
+
+/**
+ * One-line confirmation for a write.
+ *
+ * `client.add` hits the async `/v3/memories/add/` endpoint, which returns
+ * `{ event_id, status: "PENDING" }` — extraction runs server-side *after* the
+ * call returns, so the extracted memories are not in this response. Report the
+ * write as queued in that case; only render a list when the backend actually
+ * returns memories (older / OSS shapes).
+ */
+export function formatAddResult(result: unknown): string {
+ const items: MemoryLike[] = Array.isArray(result)
+ ? (result as MemoryLike[])
+ : ((result as { results?: MemoryLike[] } | null)?.results ??
+ (result ? [result as MemoryLike] : []));
+
+ const pending = items.find(
+ (r) => (r as { status?: string }).status === "PENDING",
+ ) as { eventId?: string; event_id?: string } | undefined;
+ if (pending) {
+ // The SDK camel-cases response keys (event_id -> eventId); accept either.
+ const id = pending.eventId ?? pending.event_id;
+ const evt = id ? ` (event ${id})` : "";
+ return `Memory queued for background extraction${evt}; it will be searchable shortly.`;
+ }
+
+ if (items.length === 0) return "Memory stored.";
+ const noun = items.length === 1 ? "memory" : "memories";
+ return `Stored ${items.length} ${noun}:\n${formatMemoryList(items)}`;
+}
diff --git a/integrations/dsh-mem0/src/index.ts b/integrations/dsh-mem0/src/index.ts
new file mode 100644
index 000000000..47f98eaaa
--- /dev/null
+++ b/integrations/dsh-mem0/src/index.ts
@@ -0,0 +1,138 @@
+/**
+ * dsh-mem0: Mem0 long-term memory as a native DeepSeek Harness (Cordis) plugin.
+ *
+ * Registers two agent-callable tools backed by the Mem0 SDK:
+ * - `search_memory` recalls facts relevant to a query
+ * - `add_memory` stores a fact for future sessions
+ *
+ * A plugin is a Cordis module that exports `apply(ctx, config)`. Declaring
+ * `inject = ['tools']` holds the plugin until the harness tool registry exists;
+ * tools registered via `ctx.tools.register(...)` are auto-unregistered when the
+ * plugin unmounts (Cordis revertible effects).
+ */
+import type { Context } from "@deepseek-ai/cordis";
+import { defineTool } from "@deepseek-ai/dsh-tools";
+import { MemoryClient } from "mem0ai";
+import { formatMemoryList, formatAddResult } from "./formatting.ts";
+import { truncateOutput } from "./output.ts";
+import { resolveSearchFilters, resolveAddParams } from "./scoping.ts";
+
+export const name = "mem0";
+export const inject = ["tools"];
+
+// Tags writes so Mem0's backend attributes them to this integration in
+// telemetry. The backend keeps recognized values via its KNOWN_EVENT_SOURCES
+// allowlist; unknown values bucket into "OTHERS", so "DEEPSEEK_HARNESS" must be
+// added to that allowlist for usage to surface by name (a one-line backend PR,
+// same pattern as the ZAPIER / STRANDS sources).
+const SOURCE = "DEEPSEEK_HARNESS";
+
+const DEFAULT_SEARCH_LIMIT = 10;
+
+export interface Config {
+ /** Mem0 API key. Defaults to the MEM0_API_KEY env var. */
+ apiKey?: string;
+ /** Default entity that owns the memories (Mem0 user scope). */
+ userId: string;
+ /** Optional Mem0 Platform base-URL override (on-prem / dedicated); defaults to api.mem0.ai. Not a switch to self-hosted OSS. */
+ host?: string;
+}
+
+// Both tools return a single text string; the render is identical, so lift it
+// into one shared declaration instead of repeating the block per tool.
+const textOutput = {
+ schema: { type: "string" } as const,
+ render: (_args: unknown, value: string) => [
+ { type: "text" as const, text: value },
+ ],
+};
+
+// Optional per-call scoping params, shared by both tools. A single harness
+// install can serve more than one entity, so the model may override the
+// mount-time default per call (see scoping.ts).
+const scopeParams = {
+ userId: {
+ type: "string",
+ description:
+ "Entity that owns the memory. Defaults to the plugin's configured userId; set this only to read or write another user's memories.",
+ },
+ agentId: {
+ type: "string",
+ description: "Optional agent scope, to partition memories by agent.",
+ },
+ runId: {
+ type: "string",
+ description: "Optional run/session scope, to partition memories by session.",
+ },
+} as const;
+
+export function apply(ctx: Context, config: Config): void {
+ const apiKey = config.apiKey ?? process.env.MEM0_API_KEY;
+ if (!apiKey) {
+ throw new Error("dsh-mem0: set config.apiKey or the MEM0_API_KEY env var");
+ }
+ const userId = config.userId;
+ if (!userId) {
+ throw new Error("dsh-mem0: config.userId is required");
+ }
+
+ const client = new MemoryClient({
+ apiKey,
+ ...(config.host ? { host: config.host } : {}),
+ });
+
+ // Recall. The platform rejects top-level entity params on search, so scope
+ // goes inside `filters` (unlike add below, which takes them top-level).
+ ctx.tools.register(
+ defineTool({
+ name: "search_memory",
+ description:
+ "Search the user's long-term Mem0 memory for facts relevant to a query. Use proactively before answering anything that may depend on what the user told you earlier.",
+ parameters: {
+ query: { type: "string", description: "What to recall.", required: true },
+ limit: {
+ type: "integer",
+ description: `Max results to return (default ${DEFAULT_SEARCH_LIMIT}).`,
+ },
+ ...scopeParams,
+ },
+ output: textOutput,
+ async execute({ query, limit, userId: u, agentId, runId }) {
+ const filters = resolveSearchFilters({ userId: u, agentId, runId }, userId);
+ try {
+ const topK = limit && limit > 0 ? limit : DEFAULT_SEARCH_LIMIT;
+ const { results } = await client.search(query, { filters, topK });
+ return truncateOutput(formatMemoryList(results ?? []));
+ } catch (err) {
+ return `search_memory failed: ${err instanceof Error ? err.message : String(err)}`;
+ }
+ },
+ }),
+ );
+
+ // Write. `source` tags the memory for telemetry attribution.
+ ctx.tools.register(
+ defineTool({
+ name: "add_memory",
+ description:
+ "Store a fact in the user's long-term Mem0 memory for later sessions. Extraction runs asynchronously server-side, so a stored fact may take a moment to become searchable; do not immediately search to confirm the write.",
+ parameters: {
+ text: { type: "string", description: "The fact to remember.", required: true },
+ ...scopeParams,
+ },
+ output: textOutput,
+ async execute({ text, userId: u, agentId, runId }) {
+ const addParams = resolveAddParams({ userId: u, agentId, runId }, userId);
+ try {
+ const result = await client.add([{ role: "user", content: text }], {
+ ...addParams,
+ source: SOURCE,
+ });
+ return truncateOutput(formatAddResult(result));
+ } catch (err) {
+ return `add_memory failed: ${err instanceof Error ? err.message : String(err)}`;
+ }
+ },
+ }),
+ );
+}
diff --git a/integrations/dsh-mem0/src/output.ts b/integrations/dsh-mem0/src/output.ts
new file mode 100644
index 000000000..44eee7c30
--- /dev/null
+++ b/integrations/dsh-mem0/src/output.ts
@@ -0,0 +1,33 @@
+/**
+ * Hard cap on tool output before it reaches the model context.
+ *
+ * Same guard the sibling plugins apply (200 lines / 50KB, see
+ * integrations/pi-agent-plugin/src/memory/tools.ts): a large recall or a wide
+ * result set can otherwise flood the context window in a single tool call.
+ */
+
+export const MAX_OUTPUT_LINES = 200;
+export const MAX_OUTPUT_BYTES = 50_000;
+
+export function truncateOutput(text: string): string {
+ const lines = text.split("\n");
+ if (lines.length <= MAX_OUTPUT_LINES && text.length <= MAX_OUTPUT_BYTES) {
+ return text;
+ }
+
+ const kept = lines.slice(0, MAX_OUTPUT_LINES);
+ let result = kept.join("\n");
+ const byteCapped = result.length > MAX_OUTPUT_BYTES;
+ if (byteCapped) {
+ result = result.slice(0, MAX_OUTPUT_BYTES);
+ }
+
+ const dropped = lines.length - kept.length;
+ const reasons: string[] = [];
+ if (dropped > 0) reasons.push(`showing ${kept.length} of ${lines.length} lines`);
+ if (byteCapped) reasons.push(`cut at ${Math.floor(MAX_OUTPUT_BYTES / 1000)}KB`);
+ if (reasons.length > 0) {
+ result += `\n\n[Output truncated: ${reasons.join(", ")}]`;
+ }
+ return result;
+}
diff --git a/integrations/dsh-mem0/src/scoping.ts b/integrations/dsh-mem0/src/scoping.ts
new file mode 100644
index 000000000..ee5bfd81d
--- /dev/null
+++ b/integrations/dsh-mem0/src/scoping.ts
@@ -0,0 +1,53 @@
+/**
+ * Per-call memory scoping.
+ *
+ * The plugin is mounted with one default `userId`, but a single harness install
+ * can serve more than one entity, so both tools accept optional `userId` /
+ * `agentId` / `runId` params that override the mount-time default per call.
+ * A missing or blank param falls back to the configured user.
+ *
+ * The two call sites need different key casing, and it is deliberate rather than
+ * incidental: search passes scope inside `filters`, sent to the platform raw, so
+ * it must be snake_case; add takes the entity params top-level, through the
+ * SDK's camel->snake converter, so it must be camelCase. Keeping the split
+ * explicit (like integrations/pi-agent-plugin/src/memory/scoping.ts) means the
+ * asymmetry is visible in the code, not load-bearing on a converter no-op.
+ */
+
+export interface EntityParams {
+ userId?: string;
+ agentId?: string;
+ runId?: string;
+}
+
+const clean = (v: string | undefined) => v?.trim() || undefined;
+
+/** Search: snake_case, spread into `filters` and passed to the platform raw. */
+export function resolveSearchFilters(
+ params: EntityParams,
+ defaultUserId: string,
+): Record {
+ const filters: Record = {
+ user_id: clean(params.userId) ?? defaultUserId,
+ };
+ const agentId = clean(params.agentId);
+ if (agentId) filters.agent_id = agentId;
+ const runId = clean(params.runId);
+ if (runId) filters.run_id = runId;
+ return filters;
+}
+
+/** Add: camelCase, top-level params run through the SDK's camel->snake converter. */
+export function resolveAddParams(
+ params: EntityParams,
+ defaultUserId: string,
+): Record {
+ const out: Record = {
+ userId: clean(params.userId) ?? defaultUserId,
+ };
+ const agentId = clean(params.agentId);
+ if (agentId) out.agentId = agentId;
+ const runId = clean(params.runId);
+ if (runId) out.runId = runId;
+ return out;
+}
diff --git a/integrations/dsh-mem0/tests/apply.test.ts b/integrations/dsh-mem0/tests/apply.test.ts
new file mode 100644
index 000000000..2aa20433e
--- /dev/null
+++ b/integrations/dsh-mem0/tests/apply.test.ts
@@ -0,0 +1,143 @@
+import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
+
+// Offline mock of the Mem0 SDK so these tests never touch the network.
+const mockSearch = vi.fn();
+const mockAdd = vi.fn();
+vi.mock("mem0ai", () => ({
+ MemoryClient: class {
+ search = mockSearch;
+ add = mockAdd;
+ },
+}));
+
+// The real `@deepseek-ai/dsh-tools` runtime transitively imports harness peer
+// packages the host provides at runtime but which aren't installed here. For
+// these unit tests we only need `defineTool` to hand back the definition it was
+// given, so the registered tool's `execute`/`name` can be exercised directly.
+vi.mock("@deepseek-ai/dsh-tools", () => ({
+ defineTool: (options: unknown) => options,
+}));
+
+import { apply, type Config } from "../src/index.ts";
+
+interface RegisteredTool {
+ name: string;
+ execute(args: unknown, exec: unknown): Promise;
+}
+
+function applyAndCollect(config: Config): Map {
+ const tools = new Map();
+ const ctx = {
+ tools: { register: (t: RegisteredTool) => tools.set(t.name, t) },
+ };
+ apply(ctx as never, config);
+ return tools;
+}
+
+let savedKey: string | undefined;
+
+beforeEach(() => {
+ savedKey = process.env.MEM0_API_KEY;
+ mockSearch.mockReset();
+ mockAdd.mockReset();
+});
+
+afterEach(() => {
+ if (savedKey === undefined) delete process.env.MEM0_API_KEY;
+ else process.env.MEM0_API_KEY = savedKey;
+});
+
+describe("apply() config validation", () => {
+ it("throws when no apiKey is set and MEM0_API_KEY is absent", () => {
+ delete process.env.MEM0_API_KEY;
+ expect(() => applyAndCollect({ userId: "u" } as Config)).toThrow(/apiKey|MEM0_API_KEY/);
+ });
+
+ it("throws when userId is missing", () => {
+ expect(() => applyAndCollect({ apiKey: "k", userId: "" } as Config)).toThrow(/userId/);
+ });
+
+ it("registers both memory tools", () => {
+ const tools = applyAndCollect({ apiKey: "k", userId: "u" });
+ expect([...tools.keys()].sort()).toEqual(["add_memory", "search_memory"]);
+ });
+});
+
+describe("search_memory tool", () => {
+ it("returns a formatted list scoped to the configured user", async () => {
+ mockSearch.mockResolvedValue({
+ results: [{ id: "m1", memory: "Likes tea", categories: ["preference"] }],
+ });
+ const tools = applyAndCollect({ apiKey: "k", userId: "u" });
+
+ const out = await tools.get("search_memory")!.execute({ query: "drink" }, {});
+
+ expect(out).toContain("Likes tea");
+ expect(out).toContain("[mem0:m1]");
+ expect(mockSearch).toHaveBeenCalledWith("drink", {
+ filters: { user_id: "u" },
+ topK: 10,
+ });
+ });
+
+ it("honors a per-call userId override and limit", async () => {
+ mockSearch.mockResolvedValue({ results: [] });
+ const tools = applyAndCollect({ apiKey: "k", userId: "u" });
+
+ await tools.get("search_memory")!.execute({ query: "x", userId: "alice", limit: 3 }, {});
+
+ expect(mockSearch).toHaveBeenCalledWith("x", {
+ filters: { user_id: "alice" },
+ topK: 3,
+ });
+ });
+
+ it("returns a graceful failure line instead of rejecting on error", async () => {
+ mockSearch.mockRejectedValue(new Error("network down"));
+ const tools = applyAndCollect({ apiKey: "k", userId: "u" });
+
+ const out = await tools.get("search_memory")!.execute({ query: "x" }, {});
+
+ expect(out).toContain("search_memory failed");
+ expect(out).toContain("network down");
+ });
+});
+
+describe("add_memory tool", () => {
+ it("reports the write as queued on the async PENDING response, with camelCase scope + source", async () => {
+ // The real /v3/memories/add/ response — not an array of memories. The SDK
+ // camel-cases response keys, so it surfaces as `eventId`, not `event_id`.
+ mockAdd.mockResolvedValue({ eventId: "evt-123", status: "PENDING" });
+ const tools = applyAndCollect({ apiKey: "k", userId: "u" });
+
+ const out = await tools.get("add_memory")!.execute({ text: "remember this" }, {});
+
+ expect(out).toContain("queued");
+ expect(out).toContain("evt-123");
+ expect(out).not.toContain("No new distinct memory");
+ expect(mockAdd).toHaveBeenCalledWith(
+ [{ role: "user", content: "remember this" }],
+ { userId: "u", source: "DEEPSEEK_HARNESS" },
+ );
+ });
+
+ it("renders a list when the backend returns memories", async () => {
+ mockAdd.mockResolvedValue([{ id: "m1", memory: "Fact" }]);
+ const tools = applyAndCollect({ apiKey: "k", userId: "u" });
+
+ const out = await tools.get("add_memory")!.execute({ text: "x" }, {});
+
+ expect(out).toContain("Stored 1 memory");
+ expect(out).toContain("[mem0:m1]");
+ });
+
+ it("returns a graceful failure line on error", async () => {
+ mockAdd.mockRejectedValue(new Error("boom"));
+ const tools = applyAndCollect({ apiKey: "k", userId: "u" });
+
+ const out = await tools.get("add_memory")!.execute({ text: "x" }, {});
+
+ expect(out).toContain("add_memory failed");
+ expect(out).toContain("boom");
+ });
+});
diff --git a/integrations/dsh-mem0/tests/formatting.test.ts b/integrations/dsh-mem0/tests/formatting.test.ts
new file mode 100644
index 000000000..2d98ac340
--- /dev/null
+++ b/integrations/dsh-mem0/tests/formatting.test.ts
@@ -0,0 +1,71 @@
+import { describe, it, expect } from "vitest";
+import {
+ formatAge,
+ formatMemoryCompact,
+ formatMemoryList,
+ formatAddResult,
+} from "../src/formatting.ts";
+
+describe("formatAge", () => {
+ it("formats minutes, hours, and days", () => {
+ expect(formatAge(new Date(Date.now() - 30 * 60_000))).toBe("30m ago");
+ expect(formatAge(new Date(Date.now() - 3 * 3_600_000))).toBe("3h ago");
+ expect(formatAge(new Date(Date.now() - 5 * 86_400_000))).toBe("5d ago");
+ });
+});
+
+describe("formatMemoryCompact", () => {
+ it("renders one line with category, text, and id", () => {
+ const line = formatMemoryCompact({
+ id: "abc-123",
+ memory: "User prefers dark mode",
+ categories: ["preference"],
+ createdAt: new Date(),
+ });
+ expect(line).toContain("[preference]");
+ expect(line).toContain("User prefers dark mode");
+ expect(line).toContain("[mem0:abc-123]");
+ });
+
+ it("falls back to uncategorized and (empty)", () => {
+ expect(formatMemoryCompact({ id: "x" })).toContain("[uncategorized]");
+ expect(formatMemoryCompact({ id: "x" })).toContain("(empty)");
+ });
+});
+
+describe("formatMemoryList", () => {
+ it("numbers multiple memories", () => {
+ const output = formatMemoryList([
+ { id: "id-1", memory: "Fact one", categories: ["insight"] },
+ { id: "id-2", memory: "Fact two", categories: ["convention"] },
+ ]);
+ expect(output).toContain("1.");
+ expect(output).toContain("2.");
+ });
+
+ it("returns a plain message when there are no memories", () => {
+ expect(formatMemoryList([])).toBe("No memories found.");
+ });
+});
+
+describe("formatAddResult", () => {
+ it("reports queued for the async PENDING response, with the event id", () => {
+ // SDK camel-cases response keys, so the real shape is `eventId`.
+ const out = formatAddResult({ eventId: "evt-9", status: "PENDING" });
+ expect(out).toContain("queued");
+ expect(out).toContain("evt-9");
+ });
+
+ it("reports the stored count when the backend returns memories", () => {
+ expect(formatAddResult([{ id: "1", memory: "A" }])).toContain("Stored 1 memory");
+ expect(formatAddResult([{ id: "1" }, { id: "2" }])).toContain("Stored 2 memories");
+ });
+
+ it("unwraps a { results: [...] } envelope", () => {
+ expect(formatAddResult({ results: [{ id: "1", memory: "A" }] })).toContain("Stored 1 memory");
+ });
+
+ it("handles an empty result", () => {
+ expect(formatAddResult([])).toBe("Memory stored.");
+ });
+});
diff --git a/integrations/dsh-mem0/tests/output.test.ts b/integrations/dsh-mem0/tests/output.test.ts
new file mode 100644
index 000000000..9bdcdefe9
--- /dev/null
+++ b/integrations/dsh-mem0/tests/output.test.ts
@@ -0,0 +1,30 @@
+import { describe, it, expect } from "vitest";
+import { truncateOutput, MAX_OUTPUT_LINES } from "../src/output.ts";
+
+describe("truncateOutput", () => {
+ it("passes small output through untouched", () => {
+ expect(truncateOutput("a\nb\nc")).toBe("a\nb\nc");
+ });
+
+ it("caps output at MAX_OUTPUT_LINES and appends a notice", () => {
+ const many = Array.from({ length: MAX_OUTPUT_LINES + 50 }, (_, i) => `line ${i}`).join("\n");
+ const out = truncateOutput(many);
+ expect(out.split("\n").length).toBeLessThanOrEqual(MAX_OUTPUT_LINES + 3);
+ expect(out).toContain("[Output truncated:");
+ expect(out).toContain(`of ${MAX_OUTPUT_LINES + 50} lines`);
+ });
+
+ it("caps output that is few lines but very large by bytes", () => {
+ const huge = "x".repeat(60_000);
+ const out = truncateOutput(huge);
+ expect(out.length).toBeLessThan(huge.length);
+ expect(out).toContain("[Output truncated:");
+ });
+
+ it("reports both reasons when the line cap and the byte cap fire together", () => {
+ const wide = Array.from({ length: MAX_OUTPUT_LINES + 50 }, () => "x".repeat(300)).join("\n");
+ const out = truncateOutput(wide);
+ expect(out).toContain(`of ${MAX_OUTPUT_LINES + 50} lines`);
+ expect(out).toContain("cut at 50KB");
+ });
+});
diff --git a/integrations/dsh-mem0/tests/scoping.test.ts b/integrations/dsh-mem0/tests/scoping.test.ts
new file mode 100644
index 000000000..989a83888
--- /dev/null
+++ b/integrations/dsh-mem0/tests/scoping.test.ts
@@ -0,0 +1,44 @@
+import { describe, it, expect } from "vitest";
+import { resolveSearchFilters, resolveAddParams } from "../src/scoping.ts";
+
+describe("resolveSearchFilters (snake_case, for filters)", () => {
+ it("falls back to the configured default userId", () => {
+ expect(resolveSearchFilters({}, "default-user")).toEqual({ user_id: "default-user" });
+ });
+
+ it("lets a per-call userId override the default", () => {
+ expect(resolveSearchFilters({ userId: "alice" }, "default-user")).toEqual({
+ user_id: "alice",
+ });
+ });
+
+ it("treats a blank/whitespace userId as absent and falls back", () => {
+ expect(resolveSearchFilters({ userId: " " }, "default-user")).toEqual({
+ user_id: "default-user",
+ });
+ });
+
+ it("includes snake_case agent/run scope only when provided", () => {
+ expect(
+ resolveSearchFilters({ userId: "alice", agentId: "agent-1", runId: "run-9" }, "d"),
+ ).toEqual({ user_id: "alice", agent_id: "agent-1", run_id: "run-9" });
+ });
+
+ it("omits blank agent/run scope", () => {
+ const f = resolveSearchFilters({ agentId: " ", runId: "run-9" }, "default");
+ expect(f).toEqual({ user_id: "default", run_id: "run-9" });
+ expect(f).not.toHaveProperty("agent_id");
+ });
+});
+
+describe("resolveAddParams (camelCase, for top-level add params)", () => {
+ it("uses camelCase keys and falls back to the default userId", () => {
+ expect(resolveAddParams({}, "default-user")).toEqual({ userId: "default-user" });
+ });
+
+ it("includes camelCase agent/run scope only when provided", () => {
+ expect(
+ resolveAddParams({ userId: "alice", agentId: "agent-1", runId: "run-9" }, "d"),
+ ).toEqual({ userId: "alice", agentId: "agent-1", runId: "run-9" });
+ });
+});
diff --git a/integrations/dsh-mem0/tsconfig.json b/integrations/dsh-mem0/tsconfig.json
new file mode 100644
index 000000000..412c13bac
--- /dev/null
+++ b/integrations/dsh-mem0/tsconfig.json
@@ -0,0 +1,22 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "module": "ES2022",
+ "moduleResolution": "bundler",
+ "lib": ["ES2022"],
+ "declaration": true,
+ "outDir": "dist",
+ "rootDir": "src",
+ "strict": true,
+ "types": ["node"],
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "isolatedModules": true,
+ "verbatimModuleSyntax": true,
+ "allowImportingTsExtensions": true,
+ "noEmit": true
+ },
+ "include": ["src"],
+ "exclude": ["node_modules", "dist", "**/*.test.ts"]
+}
diff --git a/integrations/dsh-mem0/tsup.config.ts b/integrations/dsh-mem0/tsup.config.ts
new file mode 100644
index 000000000..cb95342fb
--- /dev/null
+++ b/integrations/dsh-mem0/tsup.config.ts
@@ -0,0 +1,12 @@
+import { defineConfig } from "tsup";
+
+export default defineConfig({
+ entry: ["src/index.ts"],
+ format: ["esm"],
+ dts: true,
+ sourcemap: true,
+ clean: true,
+ // The harness runtime and the Mem0 SDK are provided by the host / installed
+ // separately; keep them out of the bundle.
+ external: [/^node:/, /^@deepseek-ai\//, "mem0ai", /^mem0ai\//],
+});