Skip to content

feat: OpenRouter provider routing and reasoning control#1958

Open
chiefmojo wants to merge 9 commits into
MemTensor:mainfrom
chiefmojo:feat/openrouter-routing
Open

feat: OpenRouter provider routing and reasoning control#1958
chiefmojo wants to merge 9 commits into
MemTensor:mainfrom
chiefmojo:feat/openrouter-routing

Conversation

@chiefmojo

@chiefmojo chiefmojo commented Jun 21, 2026

Copy link
Copy Markdown

Problem

When using OpenRouter as the LLM provider, operators have no way to:

  1. Exclude specific upstream providers from serving requests (provider.ignore)
  2. Set a preferred provider order (provider.order)
  3. Control reasoning effort per model slot (reasoning)

All three are standard OpenRouter-specific request fields that MemOS currently passes through to the HTTP body without any config surface.

Changes

Config schema — adds providerIgnore, providerOrder, and reasoning to LlmSchema and SkillEvolverSchema:

llm:
  provider: openai_compatible
  endpoint: https://openrouter.ai/api/v1
  apiKey: sk-...
  providerIgnore:
    - together
    - deepinfra
  providerOrder:
    - anthropic
    - google
  reasoning:
    enabled: true
    max_tokens: 8000

SkillEvolverSchema:
  provider: openai_compatible
  endpoint: https://openrouter.ai/api/v1
  providerIgnore:
    - novita

Provider layeropenai.ts detects OpenRouter endpoints and injects the provider routing object; reasoning is forwarded unconditionally when set. Non-OpenRouter endpoints are unaffected.

EmbeddingproviderIgnore/providerOrder added to the embedding config schema; openai.ts embedding provider applies the same routing logic.

PipelinebootstrapMemoryCore forwards the new fields to createLlmClient for the skillEvolver slot.

Tests

  • providers.test.ts — reasoning forwarding, routing injection for non/streaming calls, non-OpenRouter passthrough
  • bootstrap-llm-config.test.ts — verifies routing fields propagate to dedicated LLM clients
  • load.test.ts — defaults to empty arrays, accepts explicit values

Memtensor-AI and others added 6 commits June 14, 2026 17:24
docs(memos-local-plugin): clarify install path and stale dir names (MemTensor#1540)

The README's 'Quick start' section told users to use install.sh instead
of npm install, but the warning was buried and users still tried
'npm install -g @memtensor/memos-local-plugin' first. The reporter in
MemTensor#1540 encountered this on a Hermes deployment.

This change:

- Promotes the 'do not run npm install -g' notice to a prominent
  IMPORTANT callout explaining why global install is wrong (no
  agent-home deploy, no config.yaml, no bridge/viewer) and that the
  tarball intentionally ships built artifacts only.
- Adds a Troubleshooting subsection covering the two specific symptoms
  in the bug report: the 'package not found' misread, and the stale
  web/ and site/ directory names (web/ is now viewer/, site/ was
  removed by commit 26e7e3d).
- Mentions install.ps1 for Windows alongside install.sh.
- CHANGELOG: record the docs fix and reference MemTensor#1540.

Documentation-only change; no code or runtime behavior touched.

Co-authored-by: MemOS AutoDev <autodev@memtensor.ai>
Co-authored-by: Matthew <heimixiaozhuang@zju.edu.cn>
…_() got an unexpected keyword a (MemTensor#1889)

fix: remove invalid chunker parameter from SystemParser test instantiation

- SystemParser.__init__() signature changed to (embedder, llm=None)
- Test was still passing chunker=None causing TypeError
- Fixes all 5 failing tests in test_system_parser.py

Fixes MemTensor#1888

Co-authored-by: MemOS AutoDev <autodev@memos.ai>
Co-authored-by: Matthew <heimixiaozhuang@zju.edu.cn>
…tributeError when given None (MemTensor#1884)

* test: add comprehensive tests for clean_json_response (issue MemTensor#1525)

- Add test suite in tests/mem_os/test_format_utils.py
- Cover None input ValueError with diagnostic message
- Cover markdown removal, whitespace stripping, edge cases
- Verify fix for AttributeError when LLM returns None

* style: format clean_json_response tests

---------

Co-authored-by: MemOS AutoDev <autodev@memos.ai>
Co-authored-by: Matthew <heimixiaozhuang@zju.edu.cn>
…date_cube_access — fails for ev (MemTensor#1903)

fix: validate current user not target in share_cube_with_user (MemTensor#1901)

share_cube_with_user(cube_id, target_user_id) called
_validate_cube_access(cube_id, target_user_id), but the validator
signature is (user_id, cube_id). The cube_id therefore landed in the
user_id slot and _validate_user_exists raised
"User '<cube_id>' does not exist or is inactive" for every well-formed
call, making the API unusable.

The in-code comment "Validate current user has access to this cube"
already documented the correct intent: the sharing user (self.user_id)
must have access to the cube being shared, not the target. Switch the
call to self._validate_cube_access(self.user_id, cube_id). The target
user's existence is independently checked on the next line via
validate_user(target_user_id), so that path is unchanged.

Add regression tests in tests/mem_os/test_memos_core.py that pin down:
- validate_user_cube_access is consulted with (self.user_id, cube_id),
- add_user_to_cube is called with (target_user_id, cube_id) on success,
- a missing target raises "Target user '<id>' does not exist".

Closes MemTensor#1901

Co-authored-by: MemOS AutoDev Bot <autodev@memtensor.local>
Co-authored-by: Matthew <heimixiaozhuang@zju.edu.cn>
@Memtensor-AI Memtensor-AI changed the base branch from dev-20260604-v2.0.19 to dev-v2.0.22 July 1, 2026 13:15
@Memtensor-AI

Copy link
Copy Markdown
Collaborator

Automated Test Results: PASSED

Cloud test-engine rerun against dev-v2.0.22 completed successfully.

  • Run: tr-013a21fe-6ec on cloud test-engine 10011
  • memos_local_openclaw/unit: 10 passed, 0 failed, 0 skipped
  • memos_local_plugin/unit: 90 passed, 0 failed, 0 skipped

Manual code review is still required before merge.

@Memtensor-AI

Copy link
Copy Markdown
Collaborator

Conflict status update: I verified locally that refs/pull/1958/head cleanly merges with dev-v2.0.22, and the previous cloud test-engine run passed (tr-013a21fe-6ec, 100/100). However, pushing the merge commit back to the PR head failed because the head fork repository is not accessible (Repository not found).

Current conclusion: automated tests passed, but the PR cannot be merged while GitHub still reports it as conflicting. The branch needs to be updated by the author/maintainer, or a replacement branch/PR needs to be created from the locally clean merge commit and then retested.

@CarltonXiang CarltonXiang deleted the branch MemTensor:main July 3, 2026 07:25
@syzsunshine219 syzsunshine219 reopened this Jul 3, 2026
@syzsunshine219 syzsunshine219 added the needs-audit Requires manual audit before merge label Jul 3, 2026
@syzsunshine219 syzsunshine219 changed the base branch from dev-v2.0.22 to main July 3, 2026 08:21
…ting

# Conflicts:
#	apps/memos-local-plugin/core/pipeline/memory-core.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-audit Requires manual audit before merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants