mirror of
https://github.com/nexu-io/open-design.git
synced 2026-10-27 09:51:12 +01:00
* fix: forward BYOK chat model to memory extraction (#5162) Root cause: Two issues preventing non-OpenAI BYOK providers (e.g. MiniMax) from working with memory-llm extraction: 1. Web side (ProjectView.tsx): The BYOK chatProvider snapshot sent to /api/memory/extract was missing the `model` field. Without it, pickProvider() fell through to PROVIDER_DEFAULTS.openai.model ('gpt-4o-mini'), which doesn't exist on non-OpenAI endpoints. 2. Daemon route (memory.ts): The /api/memory/extract POST handler did not extract body.chatModel, unlike every other memory route. Even when the web side passes a model, it was silently dropped. Changes: - ProjectView.tsx: Add `model: byokOpenCodeProvider.model` to the BYOK chatProvider snapshot so pickProvider() can use the user's actual chat model (e.g. 'MiniMax-M3'). - routes/memory.ts: Read `body.chatModel` and forward it to extractWithLLM options, matching the pattern used by all other memory routes. Testing: typecheck passes for apps/web (affected packages). The daemon typecheck requires pre-built @open-design/release which is a separate toolchain concern. * fix(contracts): add model field to ByokChatProviderConfig for BYOK memory extraction (#5177) The web-side memory snapshot was reading byokOpenCodeProvider.model but the BYOK config contract had no model property, causing a compile-time type error. Add an optional model field so the daemon can forward the user's chat-model picker choice to memory extraction. * fix(byok): copy config.model into byokOpenCodeProvider snapshot Address review comment on PR #5177: byokOpenCodeProviderFromConfig() did not copy config.model into the returned ByokChatProviderConfig, so byokChatProvider.model serialized as undefined and /api/memory/extract fell back to the hardcoded default (gpt-4o-mini) for OpenAI-compatible BYOK endpoints like MiniMax. Threading config.model through ensures the chat-selected model reaches memory extraction. Reviewed-by: mrcfps (review comments on ProjectView.tsx:5049) * test: add model field to BYOK payload expectations in web workspace tests * fix(daemon): forward BYOK chatProvider to post-turn memory extraction The daemon close handler creates memoryOptions for pickProvider() but never forwarded the per-call BYOK provider snapshot ('byokProvider' from the chat request body). This meant post-turn LLM memory extraction always fell through to environment/default provider detection instead of using the user's selected BYOK provider and endpoint. Added 'chatProvider: byokProvider ?? null' to the memoryOptions object so pickProvider() can run 'Same as chat' extraction against the user's actual provider/config, matching the behavior of the pre-turn /api/memory/extract path. Addresses reviewer feedback on PR #5177 (fix #5162). * fix(daemon): normalize byokProvider shape for post-turn memory extraction (#5177) The close handler forwarded byokProvider ({ protocol, ... }) directly as chatProvider, but memory-llm.pickProvider expects { provider, ... } with provider being a PROVIDER_DEFAULTS key. Now we map protocol → provider the same way the web pre-turn path does (ProjectView.tsx L5894). * fix(daemon): support keyless BYOK endpoints in post-turn memory extraction (#5177) Three-part fix for keyless BYOK (local vLLM / Ollama / openai-compatible servers with requiresApiKey=false): 1. server.ts normalization: thread requiresApiKey through to the memoryChatProvider snapshot so pickProvider() can distinguish keyless endpoints from missing-provider cases. 2. memory-llm pickProvider() BYOK gate: relax the apiKey guard so endpoints explicitly marked with requiresApiKey=false enter the BYOK branch instead of falling through to env/media-config fallbacks (which would route to unrelated OpenAI credentials / gpt-4o-mini). 3. memory-llm callOpenAI(): conditionally emit Authorization header only when apiKey is non-empty, preventing empty Bearer from being sent to keyless local servers that would reject it.