Skip to content

Fix #2308: LLM facade drops opts.op before providers — per-op provider switches (e.g. think - #2309

Merged
Hun-ger merged 1 commit into
MemTensor:fix-20260902-local-pluginfrom
Memtensor-AI:bugfix/autodev-2308-20260829212023996
Sep 3, 2026
Merged

Fix #2308: LLM facade drops opts.op before providers — per-op provider switches (e.g. think#2309
Hun-ger merged 1 commit into
MemTensor:fix-20260902-local-pluginfrom
Memtensor-AI:bugfix/autodev-2308-20260829212023996

Conversation

@Memtensor-AI

@Memtensor-AI Memtensor-AI commented Aug 29, 2026

Copy link
Copy Markdown
Collaborator

Description

Fix #2308: the LLM facade in apps/memos-local-plugin/core/llm/client.ts no longer drops opts.op when it hands ProviderCallInput to provider.complete() / provider.stream(). Two-line change: extend ProviderCallInput in core/llm/types.ts with an optional op?: string, and copy opts?.op inside buildCallInput(). op stays optional so providers must not assume it is set; no public LlmClient surface change and no new error codes.

This unblocks the OpenRouter/DeepSeek reasoning kill-switch reported in the issue (opts.op === "capture.summarize" inside a provider's request builder can now actually evaluate true). Landing the per-op switch itself — e.g. body.thinking = { type: "disabled" } in providers/openai.ts — is a routing-policy decision left as a follow-up so operators can review it independently.

Tests: added 4 new unit tests under a new "op propagation (issue #2308)" describe block in tests/unit/llm/client.test.ts covering complete / completeJson / stream forwarding plus the "no op supplied" case. Verification: all 84 LLM unit tests green (5 files: client / providers / json-mode / prompts / fetcher), tsc -p tsconfig.json --noEmit clean. The 46 pre-existing failing test files in the broader unit suite (memory/l3/subscriber etc.) were verified unchanged against the base branch via git stash and are unrelated to this fix.

Confidence: 0.85 — root cause and fix were both explicit in the issue with local verification by the reporter.

Related Issue (Required): Fixes #2308

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (does not change functionality, e.g. code style improvements, linting)
  • Documentation update

How Has This Been Tested?

Added four focused unit tests covering complete, completeJson, streaming fallback, and calls without an explicit op. Existing PR checks passed before retargeting and will be rerun against the updated base.

  • Unit Test
  • Test Script Or Test Steps (please provide)
  • Pipeline Automated API Test (please provide)

Checklist

  • I have performed a self-review of my own code
  • I have commented my code in hard-to-understand areas
  • I have added tests that prove my fix is effective or that my feature works
  • I have created related documentation issue/PR in MemOS-Docs (if applicable)
  • I have linked the issue to this PR (if applicable)
  • I have mentioned the person who will review this PR

@whipser030, @hijzy please review this PR.

Reviewer Checklist

`LlmClient.buildCallInput()` dropped `opts.op` when constructing the
`ProviderCallInput` object handed to `provider.complete()` / `stream()`.
Callers set `op` for every logical call site (e.g. `capture.summarize`,
`retrieval.filter`, `skill.evolve`) but only the audit / metrics paths
inside the facade saw the tag — providers never did.

As a result any per-op provider behavior (request-body tweaks, routing
overrides, reasoning kill-switches keyed on
`opts.op === "capture.summarize"`) silently could never fire. The
issue-reported symptom: OpenRouter DeepSeek reasoning models burn full
token budget and double latency on `capture.summarize` because the
recommended `thinking: { type: "disabled" }` switch is unreachable.

Fix:
- extend `ProviderCallInput` with optional `op?: string`
- copy `opts?.op` in `buildCallInput()`

Field stays optional so providers must not assume it is set. No public
LlmClient surface change; consumers keep calling `complete` /
`completeJson` / `stream` unchanged.

Added 4 unit tests in `tests/unit/llm/client.test.ts` under an
"op propagation (issue MemTensor#2308)" describe block covering complete /
completeJson / stream forwarding and the "no op supplied" case.
@Memtensor-AI Memtensor-AI added ai:generated Generated or modified by AI | 由 AI 生成或修改 area:plugin OpenClaw & Hermes status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Aug 29, 2026
@Memtensor-AI

Copy link
Copy Markdown
Collaborator Author

🤖 Open Code Review

Target: PR #2309
Task: aca74652f3c40919
Base: dev-v2.0.30
Head: bugfix/autodev-2308-20260829212023996
Head SHA: 2ed904fd0031ba2ab1a2228944687078a4458649

OpenCodeReview: Review complete: 0 finding(s) across 2 selected item(s).

Generated by cloud-assistant via Open Code Review.

@Memtensor-AI

Copy link
Copy Markdown
Collaborator Author

✅ Automated Test Results: PASSED

All tests passed (29/29 executed). memos_local_plugin/unit: 29/29. Duration: 3s [advisory, non-gating] AI-generated tests on branch test/auto-gen-aca74652f3c40919-20260830053736: 17/17 passed — these do NOT affect the PR verdict; review the branch manually.

Branch: bugfix/autodev-2308-20260829212023996

@Memtensor-AI Memtensor-AI added status:ready Ready for implementation; waiting for assignee or AI dispatch | 可进入实现,等待认领或派发 and removed status:in-progress Someone or AI is working on it | 人工或 AI 正在处理 labels Aug 29, 2026
@Hun-ger
Hun-ger changed the base branch from dev-v2.0.30 to fix-20260902-local-plugin September 3, 2026 12:27
@Hun-ger
Hun-ger merged commit e9e4f70 into MemTensor:fix-20260902-local-plugin Sep 3, 2026
19 checks passed
@Hun-ger

Hun-ger commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Merged into fix-20260902-local-plugin while preserving the original commit (2ed904fd). Maintainer follow-up 4fb4fa01 adds direct coverage for the native provider.stream() path and clarifies the no-op assertion.

Verification on the updated branch:

  • npm run lint — passed
  • vitest run tests/unit/llm — 5 files, 86 tests passed

The provider-specific per-operation reasoning policy remains intentionally separate from this transport/plumbing fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai:generated Generated or modified by AI | 由 AI 生成或修改 area:plugin OpenClaw & Hermes status:ready Ready for implementation; waiting for assignee or AI dispatch | 可进入实现,等待认领或派发

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants