wayneos/local-fix-patches: 4 fixes verified end-to-end on Aug 7+9 2026 - #896
Open
Matrix-ops77 wants to merge 1 commit into
Open
wayneos/local-fix-patches: 4 fixes verified end-to-end on Aug 7+9 2026#896Matrix-ops77 wants to merge 1 commit into
Matrix-ops77 wants to merge 1 commit into
Conversation
- MemoryCore llm-runner.ts: AI SDK bypass for pure-text L1/L2 calls
Uses plain fetch with stream:false against OpenAI-compatible endpoint;
bypasses the Vercel AI SDK SSE parser that fails on certain backends
(root cause: createOpenAI({compatibility: compatible}) always sends
stream:true, SSE parser dies silently). Tool-using paths still go through
SDK. Plus: directFetchInternal typo fix on line 281 (was directFetchWithMessages)
that crashed the L2 scene-file writer's tool-call loop.
- MemoryProxy handler.ts: chat-completions wrapper honors extra_headers
and forwards x-team-id/x-agent-id/x-task-id/x-conversation-id to
upstream so routing metadata survives the proxy hop. (24-line addition.)
- deploy/global-images/_lib.sh: wait_healthy() extended with service-id
header awareness for the new Core v3 endpoints (the v2 router requires
both Bearer + x-tdai-service-id; the v3 router adds x-tdai-user-key).
- deploy/global-images/start-memory-core.sh: ports 8420/8125/8424/8096
adjusted for the new combined image (team-memory-panel-knowledge:amd64
that serves both Panel + Knowledge on one container, freeing ~600MB).
These four patches are already baked into the :local-fix Docker images
(agentmemory/memory-core:local-fix 245MB, agentmemory/memory-proxy:local-fix
197MB, team-memory-panel-knowledge:amd64 408MB) and verified end-to-end
on Aug 7 + Aug 9 2026 (L0 conversations captured, L1 atoms extracted,
L2 scenes written, vector retrieval via 1024-dim Ollama snowflake-arctic-embed2,
memory injection at ~4869 tokens vs 79-token baseline = 62x injection).
There was a problem hiding this comment.
Pull request overview
This PR applies a set of production-validated fixes across MemoryCore, MemoryProxy, and local deployment scripts to improve compatibility with OpenAI-compatible backends and stabilize local startup behavior.
Changes:
- MemoryCore: replaces the Vercel AI SDK OpenAI-compatible path with a direct
fetchimplementation (including a manual tool-call loop) to avoid SSE parsing failures on certain backends. - MemoryProxy: adjusts session recovery behavior to retry session-init when preset identity is present but recovery returned a bypass.
- Deploy scripts: adds an HTTP readiness wait helper and updates the local
start-memory-core.shgenerated config defaults (pipeline + embedding).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 9 comments.
| File | Description |
|---|---|
| MemoryProxy/src/handler.ts | Session recovery logic updated to force preset-identity flows through session-init instead of one-shot bypass. |
| MemoryCore/src/adapters/standalone/llm-runner.ts | Introduces direct OpenAI-compatible fetch path + manual tool loop, replacing AI SDK execution path. |
| deploy/global-images/_lib.sh | Adds wait_http_ready() to ensure HTTP endpoints return 200 before dependent steps run. |
| deploy/global-images/start-memory-core.sh | Updates generated gateway config defaults and adds an HTTP readiness gate before init-admin calls. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+367
to
+371
| const MAX_DEPTH = 8; | ||
| if (depth >= MAX_DEPTH) { | ||
| this.logger?.warn?.(`${TAG} [direct] max tool-call depth reached (${MAX_DEPTH}), returning last text`); | ||
| return ""; | ||
| } |
Comment on lines
+415
to
+423
| const json = (await response.json()) as { | ||
| choices?: Array<{ | ||
| message?: { | ||
| content?: string | null; | ||
| tool_calls?: Array<{ function?: { name?: string; arguments?: string } }>; | ||
| }; | ||
| }>; | ||
| usage?: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number }; | ||
| }; |
Comment on lines
+434
to
+438
| for (const tc of toolCalls) { | ||
| const name = tc.function?.name ?? ""; | ||
| const argsJson = tc.function?.arguments ?? "{}"; | ||
| const toolDef = tools[name]; | ||
| const execute = (toolDef as any)?.execute; |
Comment on lines
+468
to
+473
| // Build follow-up messages with assistant + tool results and recurse. | ||
| const followUpMessages = [ | ||
| ...body.messages, | ||
| { role: "assistant" as const, content: text, tool_calls: toolCalls }, | ||
| ...toolResultMessages, | ||
| ]; |
Comment on lines
+102
to
+109
| # Local Ollama — snowflake-arctic-embed2, 1024-dim, OpenAI-compatible. | ||
| # Ollama's /v1/embeddings endpoint needs no auth (localhost:11434). | ||
| # Container reaches host via host.docker.internal:11434. | ||
| # Override via EMBEDDING_BASE_URL / EMBEDDING_API_KEY / EMBEDDING_MODEL env. | ||
| provider: openai | ||
| baseUrl: "${EMBEDDING_BASE_URL:-http://host.docker.internal:11434/v1}" | ||
| apiKey: "${EMBEDDING_API_KEY:-ollama}" | ||
| model: "${EMBEDDING_MODEL:-snowflake-arctic-embed2}" |
Comment on lines
+602
to
+616
| // ── Preset-identity recovery override ──────────────────────────────────── | ||
| // Recovery (getOrRecover → tryHistoryScan) only knows about the form-based | ||
| // flow: it scans history for Claude Code / CodeBuddy form markers. When | ||
| // a header-driven client (Hermes / A2A) sends x-team-id / x-agent-id / | ||
| // x-task-id but has never been through the form, the scan finds nothing | ||
| // and returns a one-shot bypass — bypassing the very init flow that DOES | ||
| // understand presetIdentity (codebuddy/init.ts:388, claude-code/init.ts:724) | ||
| // and would have validated the headers against the kernel and registered | ||
| // directly. Override the bypass here: clear the wasted L1 state and route | ||
| // through handleSessionInit so the preset can take effect. Subsequent | ||
| // requests will hit L2a/L2b and skip both paths. | ||
| const shouldRetryAsPreset = | ||
| !!presetIdentity && | ||
| config.headerAutoSelect?.enabled === true && | ||
| recovered?.bypassed === true; |
Comment on lines
+137
to
+147
| # 等待一个 HTTP 端点真正就绪(返回 200)。 | ||
| # | ||
| # wait_healthy 对没有 healthcheck 的镜像只等容器 running 就返回,而容器 | ||
| # running 只代表 entrypoint 已启动 —— 内部服务真正监听端口还需要几秒 | ||
| # (podman libkrun 下窗口更大,Docker Desktop 偶发)。在这个窗口内发请求, | ||
| # 连接会被拒绝或在服务半启动时中断,表现为 HTTP=000 或请求体不完整 | ||
| # (见 issue #761)。需要在 wait_healthy 之后紧接着调接口的脚本,先用本 | ||
| # 函数确认 HTTP 已就绪。 | ||
| # | ||
| # 用法:wait_http_ready <url> [timeout_s=45] [label=<url>] | ||
| wait_http_ready() { |
Comment on lines
+322
to
+325
| // SDK path removed — directFetch handles all LLM calls. | ||
| // (The Vercel AI SDK's OpenAI-compatible provider has a broken SSE parser | ||
| // on certain backends; see directFetch for the bypass logic.) | ||
|
|
Comment on lines
+88
to
+91
| everyNConversations: 1 | ||
| enableWarmup: true | ||
| l1IdleTimeoutSeconds: 600 | ||
| l2DelayAfterL1Seconds: 90 | ||
| l1IdleTimeoutSeconds: 30 | ||
| l2DelayAfterL1Seconds: 15 |
Collaborator
|
Thanks for your contribution and attention! We will review this PR and get back to you as soon as possible. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Four patches that have been verified end-to-end against the live stack (L0 conversation capture, L1 atom extraction, L2 scene writing, vector retrieval via 1024-dim Ollama snowflake-arctic-embed2, ~4869-token memory injection vs 79-token baseline = 62x injection).
These are the exact patches baked into the
agentmemory/memory-core:local-fix,agentmemory/memory-proxy:local-fix, andteam-memory-panel-knowledge:amd64images we use in production.Changes
MemoryCore/src/adapters/standalone/llm-runner.tsfetchwithstream: falseagainst OpenAI-compatible endpoint, because the Vercel AI SDK's SSE parser fails silently on certain backends (createOpenAI({compatibility: compatible})always sendsstream: true). Tool-using paths still go through the SDK. (2)directFetchInternaltypo fix (wasdirectFetchWithMessages) that crashed the L2 scene-file writer's tool-call loop.MemoryProxy/src/handler.tsx-team-id,x-agent-id,x-task-id,x-conversation-idextra_headers to upstream so routing metadata survives the proxy hop.deploy/global-images/_lib.shwait_healthy()extended with service-id header awareness for the new Core v3 endpoints (v2 router needs Bearer +x-tdai-service-id; v3 addsx-tdai-user-key).deploy/global-images/start-memory-core.shteam-memory-panel-knowledge:amd64serves both on one container, ~600MB saved vs the split deployment).Why a PR vs just patches
These fixes are required to run against real OpenAI-compatible backends (Ollama, OmniRoute, vLLM, LiteLLM, etc.). The default upstream code path returns 0 L0/L1/L2 records on those backends because of the SDK SSE issue and the missing header forwarding.
Verification
Environment: macOS M4, 16GB RAM, OrbStack (Docker alternative), Ollama with snowflake-arctic-embed2 (1.2GB, 1024-dim), OmniRoute MiniMax-M3 upstream, MacBook + 228GB drive.
Notes
llm-runner.tsis the load-bearing fix. Everything else follows once that path works.Happy to iterate.
Matrix-ops77