khwan (Python client)
The Khwan hosted client — a thin HTTP wrapper with no engine code. Khwan is a memory layer (memory + constitutional identity + coherence + learning) that runs on our server; you bring your own model.
Khwan never generates text. It is a pure AI-memory layer — you always call
your own model. The only loop is prepare → your model → record.
pip install khwan
The memory loop — you call your own model
from khwan import Khwan
kw = Khwan(api_key="kwk_live_xxx", user_id="alice")
turn = kw.prepare("remember I prefer short answers in Thai") # Khwan builds context, no LLM
answer = your_model(turn.messages) # YOUR model + key
kw.record(turn, answer) # Khwan persists + learns
# `record` waits by default, on purpose: `prepare` for the next turn reads what
# has been written, so a record still in flight drops this turn from the next
# turn's context — only under load, which makes it read as flaky memory rather
# than as a race. Skip the wait when the turn is the last one:
kw.record(turn, answer, background=True) # → {"queued": True}
Gate the answer, review what it learned
v = kw.verify(turn, draft) # score a draft BEFORE you ship it
if not v["ok"]:
... # regenerate, or route to a human
for l in kw.lessons(): # the standing rules it distilled
print(l["response_text"], "←", l["source_link"])
kw.delete_lesson(bad_id) # the only negative signal in the system
Own the learning step
prepare → your model → record covers answering. The same shape covers learning —
Khwan clusters the turns, your model writes the rule, so no packet text reaches
a provider Khwan chose:
kw.synthesize(distill=lambda system, prompt: my_llm(system, prompt))
turn.messages is a standard [{role, content}] array with Khwan's value baked
into the system prompt (learned lessons + constitution + retrieved memory + coherence).
your_model is just your normal LLM call:
import anthropic
client = anthropic.Anthropic(api_key="sk-ant-...") # your key, Khwan never sees it
def your_model(messages):
system = next((m["content"] for m in messages if m["role"] == "system"), "")
chat = [m for m in messages if m["role"] != "system"]
r = client.messages.create(model="claude-sonnet-4-6", max_tokens=1024,
system=system, messages=chat)
return r.content[0].text
Isolated cores
One account can hold many cores — fully separate brains, each with its own
memory, identity, and learning. Point a client at one with core:
test = Khwan(api_key="kwk_live_xxx", user_id="alice", core="test")
client1 = Khwan(api_key="kwk_live_xxx", user_id="alice", core="client1")
kw.cores() # list the account's cores (the default core is included)
test and client1 never share memory. Omit core for the account's default brain.
On-prem
Same code, point at your instance:
kw = Khwan(api_key="kwk_...", user_id="alice",
base_url="https://khwan.internal.acme.com")
memory=/embedder= are server-managed and rejected here — they exist only in the
on-prem engine, shipped under license.
Release files for khwan 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| khwan-0.2.0.tar.gz | 10.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| khwan-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.4 kB
Release files / khwan-0.2.0.tar.gz
| Download URL | khwan-0.2.0.tar.gz |
|---|---|
| Size | 10.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6302ab439ccacd9698419534720caf5a614cfb698d183dbff05f82d263deb067
|
|
BLAKE2b-256 checksum How to use checksums |
b0961b8fb80ca5e542e36730de97a1bae5ddb19ed4f0f4bb485e8d5e77724184
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.4
|
Release files / khwan-0.2.0-py3-none-any.whl
| Download URL | khwan-0.2.0-py3-none-any.whl |
|---|---|
| Size | 8.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7be23f1359f01f7fac18959f3c9abbca974ed30914517a037207f8252afa71f3
|
|
BLAKE2b-256 checksum How to use checksums |
efbfc693d26b84aabaaf1bc106d15908f0b82fb0fb693c25aad3e78729c74d20
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.4
|