📝 QWEN_MEMPROXY_MANUAL.mdv4.6.0 · 2026-10-19

qwen_memproxy.py and QwenMemProxy.sh — Manual

Project: Project AI Chatbot Memstore Version: qwen_memproxy.py 1.4.1, stages/contextdef_stage.py 1.0.1, stages/hotwords_rag_stage.py 1.0.0, stages/hotwords_store_stage.py 1.0.0, QwenMemProxy.sh 1.0.2 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
05b http://clone:8091/ Qwen2.5-0.5B server on 8081

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

Using it

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

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. 05b
system Adds the facts to the end of the system message. 4b

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:

contextdef_stage.py  order=10  timeout=120
hotwords.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

stages/contextdef_stage.py hooks in at before-model, order 10, and needs contextdef_05b.py next to the proxy (the start-up warning says if it is missing). It runs contextdef_05b.py unchanged on the query and returns the subject, intent and terms.

Options (qwen_memproxy.py)

Option Meaning
--profile 4b|05b 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 05b (or 4b) 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
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.