📝 QWEN_MEMPROXY_MANUAL.mdv4.6.2 · 2026-10-28

qwen_memproxy.py and QwenMemProxy.sh — Manual

Project: Project AI Chatbot Memstore Version: qwen_memproxy.py 1.4.2, stages/hotwords_rag_stage.py 1.0.0, stages/hotwords_store_stage.py 1.0.0, QwenMemProxy.sh 1.0.4 Date: 2026-10-27 Another collaboration between Andrew.human and Claude.ai

Written to be read by people and by AI models.

What it is

The llama-server web page ignores the system text the server offers it, so memory set at server start never reached the page. qwen_memproxy.py is a go-between that sits in front of a llama-server. It forwards every request unchanged (the web page, the API, streamed replies) except chat requests, to which it adds the operator-approved memstore entries as background facts. It never changes the memory store.

Ports

Profile Open this Forwards to
4b http://clone:8090/ Qwen3-4B server on 8080
4b2 http://clone:8092/ second Qwen3-4B server on 8082 (Qwen34B-LLM2.sh)

The Qwen servers and their ports are unchanged. Anything that talks to port 8080 or 8082 directly (such as qwen_memchat.py) works as before, without the go-between.

Using it

sh Qwen34B.sh               (start the Qwen server first)
sh QwenMemProxy.sh 4b (start the go-between; open http://clone:8090/)
sh QwenMemProxy.sh stop 4b (ordered stop; do this before stopping the Qwen server)

The second 4B is the same with `Qwen34B-LLM2.sh` and `4b2` (go-between on http://clone:8092/).

QwenMemProxy.sh uses python3.8 for the go-between and python3.6 to read memstore (the Clone's python3.8 has no SQLite), and the database at $MEMSTORE_DB or else /root/memstore/memstore.db. Its log goes in /root/qwen_logs/memproxy_PROFILE_DATE.log and records start, stop and the entry count whenever it changes.

Where the facts go (--place)

Setting What it does Default for
user Puts the facts in front of the latest question only, as "Facts about me ... My question: ...". Earlier turns are untouched, and the page's own chat view shows only what you typed. none (choose it with --place user)
system Adds the facts to the end of the system message. 4b, 4b2

Why: a very small model (the 0.5B) gave little weight to system text and answered "Windows" despite the facts being present. Text next to the question is weighed more. For the 4B the system message is better because that part of the prompt is cached by the server, while facts in the question add about 100 tokens of reading (roughly 20 seconds at the 4B's speed) to every message. These defaults are untested guesses on real models; change with --place if the other works better.

How the memory is added

Stages: programs the proxy hooks in by itself

A stage is a small program in the stages folder (--stages DIR, default stages next to qwen_memproxy.py, normally /root/memstore/stages). The proxy scans the folder when it starts and again for every chat query, so a program added or removed later is hooked in or out without a restart. Each change is written to the log once.

The program says where it hooks in. Its header (first 80 lines) carries tag lines, in the same style as @version and @date:

 * @hook    before-model
* @order 10

Hook points

Hook point When it runs What it may return
before-model Before the query is forwarded to the model context (text added after the question, under "[About this question, worked out automatically and possibly imperfect]"); memory (text that replaces the memory entries for later stages and for what is sent)
after-reply After the whole reply has gone to the page, in a separate thread so the page is not kept waiting Nothing is used; the output is only logged
each-word Planned, for the work done one next-word candidate at a time. A program tagged with it is reported as not runnable yet

A query that starts with remember: runs no stages.

What a stage receives and returns

A minimal stage:

# @hook    before-model
import json, sys
order = json.load(sys.stdin)
print(json.dumps({"context": "The question has %d words." % len(order["query"].split())}))

The control file

stages.control in the stages folder (or any file given with --control FILE) is optional. One line per program; # starts a comment:

hotwords_rag_stage.py    order=20  timeout=60
hotwords_store_stage.py enabled=no

Keys: enabled=yes|no, order=N, timeout=S. A line overrides the program's own header for those keys; the hook point can only be set by the program. A line that names a program not in the folder, or that the proxy cannot read, is reported in the log. The file is read again for every chat query. One folder with several control files (--control) is a convenient way to keep a set of experiments.

hotwords_rag_stage.py (the RAG step)

stages/hotwords_rag_stage.py hooks in at before-model, order 20, and needs hotwords.py next to the proxy.

hotwords_store_stage.py (feeds the RAG)

stages/hotwords_store_stage.py hooks in at after-reply, order 50, and needs hotwords.py next to the proxy.

contextdef_stage.py (removed)

The context-definition stage needed the Qwen2.5-0.5B on port 8081 and was removed with it in 1.4.2. contextdef_stage.py 1.0.2 is in Memstore_Clone_v1.0.13.zip and contextdef_05b.py 1.1.0 in ContextDef05b_v1.1.0.zip; both can be put back (the stage into the stages folder, the script next to qwen_memproxy.py). The script reads CTXDEF_URL if it should talk to another server.

Options (qwen_memproxy.py)

Option Meaning
--profile 4b|4b2 Ports as in the table. Default 4b.
--listen-port N, --upstream-port N Override the profile.
--host ADDR Address to listen on. Default 0.0.0.0.
--memstore PATH, --python PATH, --db FILE, --limit N As for qwen_memchat.py.
--place system|user Where the facts go (see above).
--drop-tools WORDS The llama-server web page offers the model its own tools. A tool whose name or description contains one of these comma-separated words is removed before the request is forwarded. Default none for both profiles (every tool passes through). runtime removes the page's get_info tool ("Get runtime info (OS name)"; the page's other tool is get_datetime): it reports the browser PC's operating system, and the 0.5B answered "Windows" from it instead of using the memory. On the 0.5B even the harmless get_datetime made some answers wander or start writing a tool call; --drop-tools all removes both if that happens again. none lets every tool through; all removes every tool. The log lists the tools the page offers (once per set) and what was dropped, so the real names can be checked.
--refresh S Seconds between memory re-reads. Default 5.
--stages DIR Folder of stage programs. Default stages next to qwen_memproxy.py. none switches stages off, which is the way to get a plain run for comparison.
--control FILE Control file for the stages. Default stages.control inside the stages folder.
--stage-timeout S Seconds a stage may take before it is stopped. Default 120.
--stage-python PATH Python used to run .py stages. Default: the one running the proxy.
--quiet One log line per chat query, instead of the full detail. Verbose is the default.

It prints qwen_memproxy 1.1.0 (2026-10-26) once at start, to its log.

Limits

Exit codes

0 stopped normally, 2 the port could not be opened (often because one is already running).

Ordered shutdown

sh QwenMemProxy.sh stop 4b (or 4b2) asks the program to stop itself and finish cleanly. Stop the go-between first, then the Qwen server in your usual way.

Saving a fact from the chat (remember:)

Start a message with remember: and the text after it is saved to the memory store.

Example: remember: my name is Andrew

Version history

Version Date Change
launcher 1.0.4 2026-10-27 QwenMemProxy.sh 1.0.4 only: the start-up output now shows the memory entries. The program logs "listening" before it reads the memory store, and the launcher printed the log as soon as it saw "listening", so the memory: N approved entries line was usually missing. It now waits up to 30 s for that line (or memory unavailable) and prints the database file in use.
1.4.2 2026-10-27 qwen_memproxy.py and QwenMemProxy.sh 1.0.3: profile 05b removed (with Qwen25_05B.sh, stages/contextdef_stage.py, and the 05b profile in qwen_memchat.py 1.0.3 and qwen_propose.py 1.1.2); profile 4b2 added (go-between on 8092, server on 8082). The 4b2 edit had been made to 1.4.0 and labelled 1.4.1, which clashed with the real 1.4.1, so the merged file is 1.4.2. Qwen34B.sh (now -t 2) and Qwen34B-LLM2.sh are the operator's own and included unchanged.
stage 1.0.2 2026-10-27 stages/contextdef_stage.py 1.0.2 only (proxy 1.4.1 and the other stages unchanged): needs contextdef_05b.py 1.1.0; exit code 1 no longer discards the result; the subject is sent only when it is in the query; intent removed from the output; a server error is reported with its text. Package Memstore_Clone_v1.0.13.
1.4.1 2026-10-27 qwen_memproxy.py: @needs header line with a start-up warning for missing files; work order gains sql_python and profile. New stages/hotwords_rag_stage.py 1.0.0 and stages/hotwords_store_stage.py 1.0.0 (around hotwords.py 2.1.0). contextdef_stage.py 1.0.1 (adds @needs). stages.control is no longer in the package, so an edited copy is not overwritten.
1.4.0 2026-10-27 qwen_memproxy.py: stages. The proxy scans a folder for .py and .sh programs and hooks each in at the point its @hook header line names (before-model or after-reply; each-word is reserved), ordered by @order. Optional control file. Verbose log by default (--quiet to reduce). New stages/contextdef_stage.py 1.0.0 runs contextdef_05b.py.
1.3.1 2026-10-27 qwen_memproxy.py: --drop-tools default is now none for both profiles, so every page tool passes through (was all for 05b, runtime for 4b).
1.3.0 2026-10-27 qwen_memproxy.py: a message starting with remember: saves the rest as an approved fact.
1.2.1 2026-10-27 qwen_memproxy.py: --drop-tools default is now per profile: all for 05b, runtime for 4b.
1.2.0 2026-10-27 qwen_memproxy.py: added --drop-tools (default runtime) to remove page tools before forwarding; the tools the page offers are logged once.
1.1.0 2026-10-26 qwen_memproxy.py: added --place system|user. QwenMemProxy.sh 1.0.2: reports FAILED and exits 1 when the program never starts listening.
1.0.1 2026-10-26 Per-request log line. QwenMemProxy.sh waits up to 30 s for start-up.
1.0.0 2026-10-26 First release of qwen_memproxy.py and QwenMemProxy.sh.