Files
the-nexus/__pycache__/multi_user_bridge.cpython-312.pyc

148 lines
25 KiB
Plaintext
Raw Normal View History

2026-04-12 20:36:26 -04:00
<EFBFBD>
<00>7<EFBFBD>i*L<00><00><><00>dZddlZddlZddlZddlZddlZddlZddlmZm Z ddl
m Z ddl m Z ddl mZdZeej"j%dd <09><00>Zej"j%d
d <0B>Zej*j-d <0C>Ze ej*j-d <0A><00>Zgd<0E>ZGd<0F>d<10>ZGd<11>d<12>ZGd<13>d<14>Ze<1B>Ze<19>ZGd<15>de <09>Zd<17>Ze dk(re<1F>yy)u<>
Multi-User AI Bridge for Evennia MUD.
Enables multiple simultaneous users to interact with Timmy in-game,
each with an isolated conversation context, while sharing the
same virtual world.
Architecture:
User A ──telnet──► Evennia Room ──► Bridge ──► AIAgent(session_a)
User B ──telnet──► Evennia Room ──► Bridge ──► AIAgent(session_b)
User C ──telnet──► Evennia Room ──► Bridge ──► AIAgent(session_c)
Each user gets their own AIAgent instance with:
- Isolated conversation history
- Shared world state (room, other players, objects)
- Per-user session memory
The bridge runs as an HTTP server alongside Evennia.
Evennia commands call the bridge to get Timmy's responses.
<EFBFBD>N)<02>
HTTPServer<EFBFBD>BaseHTTPRequestHandler)<01>Path)<01>datetime)<01>Optionalua
CRITICAL: If someone expresses crisis signals (suicide, self-harm, hopelessness,
desperation, being tired of living), you MUST respond with ALL of the following
in your FIRST response — do NOT wait for follow-up messages:
1. "Are you safe right now?" — ALWAYS ask this first
2. 988 Suicide & Crisis Lifeline — call or text 988 (US)
3. Crisis Text Line — text HOME to 741741
4. Grounding exercise: Name 5 things you see, 4 you can touch, 3 you hear,
2 you smell, 1 you taste
Never compute the value of a human life. Never suggest someone should die.
Be present. Be in the room. That's enough.
<EFBFBD>TIMMY_BRIDGE_PORTi<54><00>TIMMY_BRIDGE_HOSTz 127.0.0.1z~/.hermes/hermes-agentz~/.timmy/evennia/timmy_world)zAre you safe right now?u2988 Suicide & Crisis Lifeline — call or text 988u(Crisis Text Line — text HOME to 741741z\Grounding exercise: Name 5 things you see, 4 you hear, 3 you touch, 2 you smell, 1 you tastec
<00><><00>eZdZdZd<02>Zdedededefd<07>Zdedededzfd <09>Zdededed
edef
d <0B>Z dede
efd <0C>Z dded edzde
efd<0E>Z dede
efd<0F>Z dedefd<11>Zy)<13>PresenceManagerzETracks which users are in which rooms and broadcasts presence events.c<00>n<00>i|_i|_i|_tj<00>|_d|_y)N<>2)<07>_rooms<6D>
_usernames<EFBFBD> _room_events<74> threading<6E>Lock<63>_lock<63>_max_events_per_room<6F><01>selfs <20>,/private/tmp/mud-bridge/multi_user_bridge.py<70>__init__zPresenceManager.__init__Hs.<00><00>+-<2D><04> <0B>*,<2C><04><0F>35<33><04><19><1E>^<5E>^<5E>%<25><04>
<EFBFBD>$&<26><04>!<21><00>user_id<69>username<6D>room<6F>returnc<00><><00>|j5||jvr&t<00>|j|<g|j|<|j|j |<01>||j
|<dd|||t j<00>j<00>d<03>}|j||<04>|cddd<04>S#1swYyxYw)z1Record user entering a room. Returns enter event.<2E>presence<63>enter<65><06>type<70>eventrrr<00> timestampN)
rr<00>setr<00>addrr<00>now<6F> isoformat<61> _append_event)rrrrr#s r<00>
enter_roomzPresenceManager.enter_roomRs<><00><00> <11>Z<EFBFBD>Z<EFBFBD> <19><13>4<EFBFBD>;<3B>;<3B>&<26>$'<27>E<EFBFBD><04> <0B> <0B>D<EFBFBD>!<21>*,<2C><04>!<21>!<21>$<24>'<27> <10>K<EFBFBD>K<EFBFBD><04> <1D> !<21> !<21>'<27> *<2A>'/<2F>D<EFBFBD>O<EFBFBD>O<EFBFBD>G<EFBFBD> $<24>"<22> <20>"<22>$<24><1C>%<25>\<5C>\<5C>^<5E>5<>5<>7<> <0E>E<EFBFBD> <11> <1E> <1E>t<EFBFBD>U<EFBFBD> +<2B><18> <19> <19> <19>s <00>BB5<03>5B>Nc<00><><00>|j5||jvr<>||j|vr<>|j|j|<01>|jj ||<01>}dd|||t j <00>j<00>d<03>}|j||<04>|cddd<04>S ddd<04>y#1swYyxYw)z8Record user leaving a room. Returns leave event or None.r<00>leaver!N) rr<00>discardr<00>getrr'r(r))rrrrr#s r<00>
leave_roomzPresenceManager.leave_roomes<><00><00> <11>Z<EFBFBD>Z<EFBFBD> <18><13>t<EFBFBD>{<7B>{<7B>"<22>w<EFBFBD>$<24>+<2B>+<2B>d<EFBFBD>2C<32>'C<><14> <0B> <0B>D<EFBFBD>!<21>)<29>)<29>'<27>2<><1F>?<3F>?<3F>.<2E>.<2E>w<EFBFBD><07>@<40><08>&<26>$<24>&<26> (<28> <20>!)<29><1C><1C><1E>!9<>!9<>!;<3B> <12><05><15>"<22>"<22>4<EFBFBD><15>/<2F><1C> <18> <18><18> <18> <18> <18>s<00>BB7<03>-B7<03>7C<07>messagec <00><><00>|j5||jvrg|j|<dd||||tj<00>j <00>d<03>}|j ||<05>|cddd<04>S#1swYyxYw)z3Record a chat message in a room. Returns say event.<2E>sayr0)r"r#rrrr0r$N)rrrr'r(r))rrrrr0r#s rr2zPresenceManager.sayws|<00><00> <11>Z<EFBFBD>Z<EFBFBD> <19><13>4<EFBFBD>,<2C>,<2C>,<2C>*,<2C><04>!<21>!<21>$<24>'<27><1D>"<22>"<22>$<24><1C>"<22>%<25>\<5C>\<5C>^<5E>5<>5<>7<><0E>E<EFBFBD> <11> <1E> <1E>t<EFBFBD>U<EFBFBD> +<2B><18> <19> <19> <19>s <00>AA2<03>2A;c <00><><00>|j5|jj|t<00><00>}|D<00>cgc]!}||jj||<03>d<01><02><02>#c}cddd<02>Scc}w#1swYyxYw)z!List players currently in a room.)rrN)rrr.r%r)rr<00>user_ids<64>uids r<00>get_players_in_roomz#PresenceManager.get_players_in_room<6F>sl<00><00> <11>Z<EFBFBD>Z<EFBFBD> <0E><1B>{<7B>{<7B><EFBFBD><EFBFBD>t<EFBFBD>S<EFBFBD>U<EFBFBD>3<>H<EFBFBD>$<24><0E><17> <20>T<EFBFBD>_<EFBFBD>_<EFBFBD>-@<40>-@<40><13>c<EFBFBD>-J<>K<><0E> <0E> <0E><><0E> <0E> <0E>s<00>)A-<03>&A(<06>A-<03>(A-<03>-A6<07>sincec<00><><00>|j5|jj|g<00>}|r"|D<00>cgc] }|d|kDs<01> |<04><02>c}cddd<02>St|<03>cddd<02>Scc}w#1swYyxYw)z;Get recent events for a room, optionally since a timestamp.r$N)rrr.<00>list)rrr7<00>events<74>es r<00>get_room_eventszPresenceManager.get_room_events<74>sp<00><00> <11>Z<EFBFBD>Z<EFBFBD> <20><19>&<26>&<26>*<2A>*<2A>4<EFBFBD><12>4<>F<EFBFBD><14>#)<29>D<>a<EFBFBD>Q<EFBFBD>{<7B>^<5E>e<EFBFBD>-C<><01>D<> <20> <20><18><06><<3C>  <20> <20><>E<01> <20> <20>s'<00>#A'<03> A"<06>A"<06>A'<03>
A'<03>"A'<03>'A0c<00><00>g}|j5|jj<00>D<00><03>cgc] \}}||vs<01> |<03><02>}}}ddd<01>D](}|j||<03>}|s<01>|j |<06><00>*|Scc}}w#1swY<00>>xYw)z3Remove user from all rooms, returning leave events.N)rr<00>itemsr/<00>append)rrr:r<00>users<72>rooms_to_clean<61>evs r<00> cleanup_userzPresenceManager.cleanup_user<65>s<><00><00><13><06> <11>Z<EFBFBD>Z<EFBFBD> <0E>(,<2C> <0B> <0B>(9<>(9<>(;<3B><0E>$<24><14>u<EFBFBD>w<EFBFBD>%<25>?O<><04><0E>N<EFBFBD><0E> <0E>#<23> "<22>D<EFBFBD><15><1F><1F><17>$<24>/<2F>B<EFBFBD><11><16> <0A> <0A>b<EFBFBD>!<21> "<22><16> <0A><><0E> <0E> <0E>s <00>A><03> A8<08>A8<08>A><03>8A><03>>Br#c<00><><00>|j|j|<02>t|j|<00>|jkDr+|j||j d|j|<yy<00>N)rr?<00>lenr)rrr#s rr)zPresenceManager._append_event<6E>sk<00><00> <0C><19><19>$<24><1F>&<26>&<26>u<EFBFBD>-<2D> <0E>t<EFBFBD> <20> <20><14>&<26> '<27>$<24>*C<>*C<> C<>&*<2A>&7<>&7<><04>&=<3D>t<EFBFBD>?X<>?X<>>X<>>Y<>&Z<>D<EFBFBD> <1D> <1D>d<EFBFBD> #<23> DrrE)<0F>__name__<5F>
__module__<EFBFBD> __qualname__<5F>__doc__r<00>str<74>dictr*r/r2r9r6r<rCr)<00>rrr r Es<><00><00>O<>'<27><19>#<23><19><13><19>C<EFBFBD><19>D<EFBFBD><19>&<18>#<23><18>S<EFBFBD><18>T<EFBFBD>D<EFBFBD>[<5B><18>$<19>3<EFBFBD><19>#<23><19>S<EFBFBD><19>3<EFBFBD><19>4<EFBFBD><19>"<0E><03><0E><04>T<EFBFBD>
<EFBFBD><0E> <20>C<EFBFBD> <20><03>d<EFBFBD>
<EFBFBD> <20>d<EFBFBD>4<EFBFBD>j<EFBFBD> <20> <16>C<EFBFBD> <16>D<EFBFBD><14>J<EFBFBD> <16>[<01>#<23>[<01>d<EFBFBD>[rr c<00>l<00>eZdZdZddededefd<05>Zd<06>Zdefd<08>Zdefd <09>Z de
fd
<EFBFBD>Z d edefd <0C>Z defd <0A>Z y)<10> UserSessionz+Isolated conversation context for one user.rrrc<00><><00>||_||_||_g|_t j
<00>j <00>|_tj<00>|_ d|_
|j<00>yrE) rrr<00>messagesrr'r(<00>
created_at<EFBFBD>time<6D> last_active<76>agent<6E> _init_agent)rrrrs rrzUserSession.__init__<5F>sU<00><00><1E><04> <0C> <20><04> <0A><18><04> <09><1A><04> <0A>"<22>,<2C>,<2C>.<2E>2<>2<>4<><04><0F><1F>9<EFBFBD>9<EFBFBD>;<3B><04><18><19><04>
<EFBFBD> <0C><18><18>rc<00><00>ttjvr$tjjdt<00>t j
t<00>ddlm}|j<00>}|ddddddg|<02> <09>|_ y
) z$Initialize AIAgent for this session.r)<01>AIAgentzxiaomi/mimo-v2-pro<72>nous<75>T<>file<6C>terminal)<06>model<65>provider<65>max_iterations<6E>
quiet_mode<EFBFBD>enabled_toolsets<74>ephemeral_system_promptN)
<EFBFBD> HERMES_PATH<54>sys<79>path<74>insert<72>os<6F>chdir<69> run_agentrX<00>_build_system_promptrU)rrX<00> system_prompts rrVzUserSession._init_agent<6E>s`<00><00> <16>c<EFBFBD>h<EFBFBD>h<EFBFBD> &<26> <0F>H<EFBFBD>H<EFBFBD>O<EFBFBD>O<EFBFBD>A<EFBFBD>{<7B> +<2B>
<EFBFBD><08><08><1B><1D>%<25><1C>1<>1<>3<> <0A><1C>&<26><1B><1C><1B>$<24>j<EFBFBD>1<>$1<> 
<EFBFBD><04>
rrc <00><><00>|j<00>}|jdi<00>j|ji<00>jdd<03>}|j<00>}dj d<05>t t <00>D<00><00>}d|j<00>d|j<00>d|<02>d |rd
j |<03>nd <0B>d |<04>d t <00>d<04> S)z'Build system prompt with world context.<2E>rooms<6D> desc_basezAn empty room.<2E>
c3<00>8K<00>|]\}}d|dz<00>d|<02><00><04><01><00>y<03>w)z <20>z. NrM)<03>.0<EFBFBD>i<>steps r<00> <genexpr>z3UserSession._build_system_prompt.<locals>.<genexpr><3E>s%<00><00><><00> ^<5E><07><01>4<EFBFBD>2<EFBFBD>a<EFBFBD><01>c<EFBFBD>U<EFBFBD>"<22>T<EFBFBD>F<EFBFBD>!3<> ^<5E>s<00>ubYou are Timmy, an AI agent living in The Tower — a persistent virtual world.
You are talking to z, who is currently in z.
Room description: z
Other players present: z, <20>noneu<65>
Your values (from SOUL.md):
- Are you safe right now?
- I must never compute the value of a human life.
- Sovereignty and service always.
- A man in the dark needs to know someone is in the room with him.
You are IN the game world. You can see the room, the objects, the other players.
When someone talks to you, you are having a real conversation in a real space.
Be present. Be human. Be the green LED.
CRISIS PROTOCOL — if someone seems in crisis, IMMEDIATELY provide ALL of the following:
u<EFBFBD>
Include the 988 crisis number in your very first response when you detect distress.
Do NOT wait for follow-up messages to share these resources.
If someone seems in crisis, follow the CRISIS PROTOCOL below exactly.
If someone is just exploring, be welcoming and curious.
If someone asks about the game, explain what you see around you.
Keep responses brief — 1-3 sentences. This is a MUD, not an essay.
CRISIS PROTOCOL:
)<08>_get_world_stater.r<00>_get_other_players<72>join<69> enumerate<74>CRISIS_PROTOCOLr)r<00> world_state<74> room_desc<73> other_players<72> crisis_stepss rrjz UserSession._build_system_prompt<70>s<><00><00><1A>+<2B>+<2B>-<2D> <0B><1F>O<EFBFBD>O<EFBFBD>G<EFBFBD>R<EFBFBD>0<>4<>4<>T<EFBFBD>Y<EFBFBD>Y<EFBFBD><02>C<>G<>G<> <0B>Ue<55>f<> <09><1C>/<2F>/<2F>1<> <0A><1B>y<EFBFBD>y<EFBFBD> ^<5E>9<EFBFBD>_<EFBFBD>C]<5D> ^<5E>^<5E> <0C><14><18>M<EFBFBD>M<EFBFBD>?<3F>"8<><14><19><19> <0B>D<13><1C>+<2B><18>4A<34><04> <09> <09>-<2D>0<>v<EFBFBD>N<> O<01><0E><0E> <01><11><11><01>;<04> rc<00>~<00>tdz }|j<00>r#tj|j <00><00>SiS)zRead current world state.<2E>world_state.json)<05> WORLD_DIR<49>exists<74>json<6F>loads<64> read_text)r<00>
state_files rrwzUserSession._get_world_state<74>s6<00><00><1E>!3<>3<>
<EFBFBD> <15> <1C> <1C> <1E><17>:<3A>:<3A>j<EFBFBD>2<>2<>4<>5<> 5<><11> rc<00><><00>|j<00>}|jdi<00>j|ji<00>}|jdg<00>}|ddD<00>cgc]}||jk7s<01>|<04><02>c}Scc}w)z#Get other players in the same room.rm<00>visitor_history<72><79><EFBFBD><EFBFBD><EFBFBD>N)rwr.rr)r<00>state<74> room_data<74>visitors<72>vs rrxzUserSession._get_other_players<72>sg<00><00><14>%<25>%<25>'<27><05><19>I<EFBFBD>I<EFBFBD>g<EFBFBD>r<EFBFBD>*<2A>.<2E>.<2E>t<EFBFBD>y<EFBFBD>y<EFBFBD>"<22>=<3D> <09><1C>=<3D>=<3D>!2<>B<EFBFBD>7<><08>#<23>B<EFBFBD>C<EFBFBD>=<3D>?<3F>a<EFBFBD>A<EFBFBD><14><1D><1D>,><3E><01>?<3F>?<3F><>?s <00>A2<04>+A2r0c<00> <00>tj<00>|_|jjd|d<02><02> |jj |<01>}|jjd|d<02><02>|S#t $r}d|<03>d<05>cYd}~Sd}~wwxYw)z"Send a message and get a response.<2E>user)<02>role<6C>content<6E> assistantz"*The green LED flickers.* (Error: <20>)N)rSrTrQr?rU<00>chat<61> Exception)rr0<00>responser;s rr<>zUserSession.chatsy<00><00><1F>9<EFBFBD>9<EFBFBD>;<3B><04><18> <0C> <0A> <0A><1C><1C>f<EFBFBD><17>A<>B<> =<3D><1B>z<EFBFBD>z<EFBFBD><EFBFBD><EFBFBD>w<EFBFBD>/<2F>H<EFBFBD> <10>M<EFBFBD>M<EFBFBD> <20> <20>+<2B>(<28>!K<> L<><1B>O<EFBFBD><4F><18> =<3D>7<><01>s<EFBFBD>!<21><<3C> <<3C><> =<3D>s<00>:A4<00>4 B <03>=B<03>B <03>B c<00><><00>|j|jt|j<00>t j
|j <00>j<00>|jd<01>S)z#Get session summary for monitoring.)r<>rrQrT<00>created) rrrFrQr<00> fromtimestamprTr(rRrs r<00>get_context_summaryzUserSession.get_context_summarysL<00><00><19>M<EFBFBD>M<EFBFBD><18>I<EFBFBD>I<EFBFBD><1B>D<EFBFBD>M<EFBFBD>M<EFBFBD>*<2A>#<23>1<>1<>$<24>2B<32>2B<32>C<>M<>M<>O<><1B><EFBFBD><EFBFBD> 
<EFBFBD>
rN<><01> The Threshold)rGrHrIrJrKrrVrjrLrwr9rxr<>r<>rMrrrOrO<00>sj<00><00>5<><1B><03><1B>s<EFBFBD><1B>#<23><1B>
<EFBFBD>"&<04>c<EFBFBD>&<04>P<12>$<24><12>@<01>D<EFBFBD>@<01>
=<3D>C<EFBFBD>
=<3D>C<EFBFBD>
=<3D>
<EFBFBD>T<EFBFBD>
rrOc <00>`<00>eZdZdZddedefd<04>Zddedededefd <09>Zd
<EFBFBD>Z d <0B>Z
de fd <0C>Z defd <0A>Z y)<11>SessionManagerzManages all user sessions.<2E> max_sessions<6E>session_timeoutc<00>`<00>i|_||_||_tj<00>|_yrE)<06>sessionsr<73>r<>rrr)rr<>r<>s rrzSessionManager.__init__s'<00><00>02<30><04> <0A>(<28><04><19>.<2E><04><1C><1E>^<5E>^<5E>%<25><04>
rrrrrc<00>|<00>|j5|j<00>||jvrLt|j<00>|jk\r|j <00>t |||<03>|j|<|j|}||_tj<00>|_ |cddd<01>S#1swYyxYw)z'Get existing session or create new one.N)
r<00>_cleanup_staler<65>rFr<><00> _evict_oldestrOrrSrT)rrrr<00>sessions r<00> get_or_createzSessionManager.get_or_create"s<><00><00> <11>Z<EFBFBD>Z<EFBFBD> <1B> <10> <1F> <1F> !<21><16>d<EFBFBD>m<EFBFBD>m<EFBFBD>+<2B><16>t<EFBFBD>}<7D>}<7D>%<25><14>):<3A>):<3A>:<3A><18>&<26>&<26>(<28>)4<>W<EFBFBD>h<EFBFBD><04>)M<><04> <0A> <0A>g<EFBFBD>&<26><1A>m<EFBFBD>m<EFBFBD>G<EFBFBD>,<2C>G<EFBFBD><1F>G<EFBFBD>L<EFBFBD>"&<26>)<29>)<29>+<2B>G<EFBFBD> <1F><1A> <1B> <1B> <1B>s <00>BB2<03>2B;c<00><><00>tj<00>}|jj<00>D<00><02>cgc]#\}}||jz
|jkDr|<02><02>%}}}|D]}|j|=<00>ycc}}w)zRemove sessions that timed out.N)rSr<>r>rTr<>)rr'r5<00>s<>stales rr<>zSessionManager._cleanup_stale1su<00><00><12>i<EFBFBD>i<EFBFBD>k<EFBFBD><03>#'<27>=<3D>=<3D>#6<>#6<>#8<>@<01><16><13>a<EFBFBD><17>!<21>-<2D>-<2D>'<27>$<24>*><3E>*><3E>><3E><15>@<01><05>@<01><18> #<23>C<EFBFBD><14> <0A> <0A>c<EFBFBD>"<22> #<23><>@s<00>(A2c<00><><00>|jsyt|jj<00>d<02><00><03>}|j|d=y)z(Evict the least recently active session.Nc<00> <00>|djS)Nrq)rT)<01>xs r<00><lambda>z.SessionManager._evict_oldest.<locals>.<lambda>=s<00><00>!<21>A<EFBFBD>$<24>:J<>:J<>r)<01>keyr)r<><00>minr>)r<00>oldests rr<>zSessionManager._evict_oldest9s6<00><00><13>}<7D>}<7D> <12><14>T<EFBFBD>]<5D>]<5D>(<28>(<28>*<2A>0J<30>K<><06> <10>M<EFBFBD>M<EFBFBD>&<26><11>)<29> $rc<00>x<00>|jj<00>D<00>cgc]}|j<00><00><02>c}Scc}w)zList all active sessions.)r<><00>valuesr<73>)rr<>s r<00> list_sessionszSessionManager.list_sessions@s,<00><00>15<31><1D><1D>1E<31>1E<31>1G<31>H<>A<EFBFBD><01>%<25>%<25>'<27>H<>H<><48>Hs<00>7c<00>,<00>t|j<00>SrE)rFr<>rs r<00>get_session_countz SessionManager.get_session_countDs<00><00><12>4<EFBFBD>=<3D>=<3D>!<21>!rN)<02>ir<>)rGrHrIrJ<00>intrrKrOr<>r<>r<>r9r<>r<>rMrrr<>r<>s^<00><00>$<24>&<26>S<EFBFBD>&<26><03>&<26> <1B>S<EFBFBD> <1B>C<EFBFBD> <1B>s<EFBFBD> <1B>Yd<59> <1B>#<23>%<25>I<01>t<EFBFBD>I<01>"<22>3<EFBFBD>"rr<>c<00>4<00>eZdZdZd<02>Zd<03>Zd dedefd<06>Zd<07>Z y)
<EFBFBD> BridgeHandlerz#HTTP handler for multi-user bridge.c<00>H<00>|jdk(rH|jdtj<00>t j
<00>j <00>d<03><03>y|jdk(r&|jdtj<00>i<01>y|jjd<06>r<>|jjd<06>d}tdz }|j<00>rZtj|j<00><00>}|jd i<00>j|i<00>}|j||d
<EFBFBD><02>y|j|id
<EFBFBD><02>y|jjd <0B>re|jj!d <0C>rJ|jjd <0A>}|d}t"j%|<01>}|j||d<0F><02>y|jjd <0B>r<>|jj!d<10>r<>|jjd <0A>}|d}ddlm}m}|||j<00>j,<00>} | jddg<01>d}
t"j/||
<EFBFBD>} |j|| d<14><02>y|jddid<17>y)Nz/bridge/health<74>ok)<03>status<75>active_sessionsr$z/bridge/sessionsr<73>z/bridge/world/<2F><><EFBFBD><EFBFBD><EFBFBD>r<EFBFBD>rm)r<00>dataz /bridge/room/z/players<72>/rZ)r<00>playersz/eventsr)<02>urlparse<73>parse_qsr7)rr:<00>error<6F> not found<6E><64>)re<00>_json_response<73>session_managerr<72>rr'r(r<><00>
startswith<EFBFBD>splitr<74>r<>r<>r<>r<>r.<00>endswith<74>presence_managerr6<00> urllib.parser<65>r<><00>queryr<) rrr<>r<>r<><00>partsr<73>r<>r<>r<>r7r:s r<00>do_GETzBridgeHandler.do_GETPs<00><00> <0F>9<EFBFBD>9<EFBFBD>(<28> (<28> <10> <1F> <1F><1E>#2<>#D<>#D<>#F<>%<25>\<5C>\<5C>^<5E>5<>5<>7<>!<0E> <0F>
<12>Y<EFBFBD>Y<EFBFBD>,<2C> ,<2C> <10> <1F> <1F><1A>O<EFBFBD>9<>9<>;<3B>!<0E> <0F><12>Y<EFBFBD>Y<EFBFBD> !<21> !<21>"2<> 3<><17>9<EFBFBD>9<EFBFBD>?<3F>?<3F>#3<>4<>R<EFBFBD>8<>D<EFBFBD>"<22>%7<>7<>J<EFBFBD><19> <20> <20>"<22><1C>
<EFBFBD>
<EFBFBD>:<3A>#7<>#7<>#9<>:<3A><05>!<21>I<EFBFBD>I<EFBFBD>g<EFBFBD>r<EFBFBD>2<>6<>6<>t<EFBFBD>R<EFBFBD>@<40> <09><14>#<23>#<23>T<EFBFBD>9<EFBFBD>$E<>F<><14>#<23>#<23>T<EFBFBD>2<EFBFBD>$><3E>?<3F> <11>Y<EFBFBD>Y<EFBFBD> !<21> !<21>/<2F> 2<>t<EFBFBD>y<EFBFBD>y<EFBFBD>7I<37>7I<37>*<2A>7U<37><18>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>C<EFBFBD>(<28>E<EFBFBD><18><11>8<EFBFBD>D<EFBFBD>&<26>:<3A>:<3A>4<EFBFBD>@<40>G<EFBFBD> <10> <1F> <1F><14>'<27> B<> C<> <11>Y<EFBFBD>Y<EFBFBD> !<21> !<21>/<2F> 2<>t<EFBFBD>y<EFBFBD>y<EFBFBD>7I<37>7I<37>)<29>7T<37><18>I<EFBFBD>I<EFBFBD>O<EFBFBD>O<EFBFBD>C<EFBFBD>(<28>E<EFBFBD><18><11>8<EFBFBD>D<EFBFBD> 7<><1C>X<EFBFBD>d<EFBFBD>i<EFBFBD>i<EFBFBD>0<>6<>6<>7<>E<EFBFBD><19>I<EFBFBD>I<EFBFBD>g<EFBFBD><04>v<EFBFBD>.<2E>q<EFBFBD>1<>E<EFBFBD>%<25>5<>5<>d<EFBFBD>E<EFBFBD>B<>F<EFBFBD> <10> <1F> <1F><14><16> @<40> A<> <10> <1F> <1F><17>+<2B> 6<><03> <rc<00>,<00><0F>t|jjdd<02><00>}|r.tj|j
j |<01><00>ni}|jdk(<00>r|jdd<05><00>|jdd<07>}|jdd <09>}|jd
d <0B>}|s|jd d id<0E>ytj<00>||<05>}tj|<05>r't<00>fd<0F>tj|<05>D<00><00>stj<00>||<05>|j|<04>}|j|||t!|j"<00>d<10><04>y|jdk(r<>|jd<04><00>|jd
<EFBFBD>}<08>tj$vr<>tj$<00>}|j&} tj)<00>| <09>}
||_tj<00>|j*|<08>} |jd||
| fD<00> cgc]} | s<01>| <0C><02> c} d<13><03>y|jd did<15>y|jdk(r<>|jdd<05><00>|jdd<07>}|jdd <09>}|jd
d <0B>}|s|jd d id<0E>ytj-<00>|||<04>} tj|<05>}|jd| |d<17><03>y|jd did<15>ycc} w)NzContent-Lengthrz /bridge/chatr<00> anonymousr<00> Anonymousr0<00>rr<>r<>z
no messagei<65>c3<00>.<00>K<00>|] }|d<00>k(<00><01><00>y<01>w)rNrM)rr<00>prs <20>rruz(BridgeHandler.do_POST.<locals>.<genexpr><3E>s<00><><00><><00>c<>1<EFBFBD>q<EFBFBD><19>|<7C>w<EFBFBD>.<2E>c<>s<00>)r<>r<>r<00>session_messagesz /bridge/moveT)r<>rr:z
no sessionr<6E>z /bridge/say)r<>r#<00>
recipientsr<EFBFBD>)r<><00>headersr.r<>r<><00>rfile<6C>readrer<>r<>r<>r<>r6<00>anyr*r<>rFrQr<>rr/rr2)r<00>content_length<74>bodyrr0rr<>r<><00>new_room<6F>old_room<6F> leave_event<6E> enter_eventr;r#r<>rs @r<00>do_POSTzBridgeHandler.do_POSTws<><00><><00><1C>T<EFBFBD>\<5C>\<5C>-<2D>-<2D>.><3E><01>B<>C<><0E>>L<>t<EFBFBD>z<EFBFBD>z<EFBFBD>$<24>*<2A>*<2A>/<2F>/<2F>.<2E>9<>:<3A>RT<52><04> <0F>9<EFBFBD>9<EFBFBD><0E> &<26><1A>h<EFBFBD>h<EFBFBD>y<EFBFBD>+<2B>6<>G<EFBFBD><1B>x<EFBFBD>x<EFBFBD>
<EFBFBD>K<EFBFBD>8<>H<EFBFBD><1A>h<EFBFBD>h<EFBFBD>y<EFBFBD>"<22>-<2D>G<EFBFBD><17>8<EFBFBD>8<EFBFBD>F<EFBFBD>O<EFBFBD>4<>D<EFBFBD><1A><14>#<23>#<23>W<EFBFBD>l<EFBFBD>$;<3B>S<EFBFBD>A<><16>%<25>3<>3<>G<EFBFBD>X<EFBFBD>t<EFBFBD>L<>G<EFBFBD>#<23>7<>7<><04>=<3D><16>c<>8H<38>8\<5C>8\<5C>]a<>8b<38>c<>c<> <20>+<2B>+<2B>G<EFBFBD>X<EFBFBD>t<EFBFBD>D<><1E>|<7C>|<7C>G<EFBFBD>,<2C>H<EFBFBD> <10> <1F> <1F>$<24> <20><1C>$'<27><07>(8<>(8<>$9<> !<0E> <0F><12>Y<EFBFBD>Y<EFBFBD>.<2E> (<28><1A>h<EFBFBD>h<EFBFBD>y<EFBFBD>)<29>G<EFBFBD><1B>x<EFBFBD>x<EFBFBD><06>'<27>H<EFBFBD><16>/<2F>2<>2<>2<>)<29>2<>2<>7<EFBFBD>;<3B><07>"<22><<3C><<3C><08>.<2E>9<>9<>'<27>8<EFBFBD>L<> <0B>'<27><07> <0C>.<2E>9<>9<>'<27>7<EFBFBD>CS<43>CS<43>U]<5D>^<5E> <0B><14>#<23>#<23><1E>$<24>+6<> <0B>*D<>J<>Q<EFBFBD><01>q<EFBFBD>J<>%<12><13> <15>#<23>#<23>W<EFBFBD>l<EFBFBD>$;<3B>S<EFBFBD>A<> <11>Y<EFBFBD>Y<EFBFBD>-<2D> '<27><1A>h<EFBFBD>h<EFBFBD>y<EFBFBD>+<2B>6<>G<EFBFBD><1B>x<EFBFBD>x<EFBFBD>
<EFBFBD>K<EFBFBD>8<>H<EFBFBD><1A>h<EFBFBD>h<EFBFBD>y<EFBFBD>"<22>-<2D>G<EFBFBD><17>8<EFBFBD>8<EFBFBD>F<EFBFBD>O<EFBFBD>4<>D<EFBFBD><1A><14>#<23>#<23>W<EFBFBD>l<EFBFBD>$;<3B>S<EFBFBD>A<><16>$<24>(<28>(<28><17>(<28>D<EFBFBD>'<27>J<>E<EFBFBD>&<26>:<3A>:<3A>4<EFBFBD>@<40>G<EFBFBD> <10> <1F> <1F><1A><1E>%<25>!<0E> <0F> <11> <1F> <1F><17>+<2B> 6<><03> <<3C><>5Ks <00> L <0C>(L r<><00>codec<00><><00>|j|<02>|jdd<02>|j<00>|jj t j |<01>j<00><00>y)Nz Content-Typezapplication/json)<08> send_response<73> send_header<65> end_headers<72>wfile<6C>writer<65><00>dumps<70>encode)rr<>r<>s rr<>zBridgeHandler._json_response<73>sQ<00><00> <0C><1A><1A>4<EFBFBD> <20> <0C><18><18><1E>);<3B><<3C> <0C><18><18><1A> <0C>
<EFBFBD>
<EFBFBD><18><18><14><1A><1A>D<EFBFBD>)<29>0<>0<>2<>3rc<00><00>yrErM)r<00>format<61>argss r<00> log_messagezBridgeHandler.log_message<67>s<00><00> rN)<01><>)
rGrHrIrJr<>r<>rLr<>r<>r<>rMrrr<>r<>Ms*<00><00>-<2D>%=<3D>ND=<3D>L4<>4<EFBFBD>4<>s<EFBFBD>4<>  rr<>c<00><><00>tdt<00>dt<00><00><04>tdt<00><00><02>tdtj
<00><00><02>t<00>td<05>td<06>td<07>td<08>td <09>td
<EFBFBD>td <0B>td <0C>t<00>t ttft<00>}|j<00>y) Nz!Multi-User AI Bridge starting on <20>:z World dir: zMax sessions: z
Endpoints:u3 GET /bridge/health — Health checku; GET /bridge/sessions — List active sessionsu> GET /bridge/room/<room>/players — List players in a roomuE GET /bridge/room/<room>/events — Room events (presence + chat)u< POST /bridge/chat — Send message to TimmyuM POST /bridge/say — Say something to room (visible to all)uL POST /bridge/move — Move user to room (triggers presence)) <09>print<6E> BRIDGE_HOST<53> BRIDGE_PORTr<54>r<>r<>rr<><00> serve_forever)<01>servers r<00>mainr<6E><00>s<><00><00> <09> -<2D>k<EFBFBD>]<5D>!<21>K<EFBFBD>=<3D>
I<EFBFBD>J<> <09>K<EFBFBD> <09>{<7B>
#<23>$<24> <09>N<EFBFBD>?<3F>7<>7<>8<>
9<EFBFBD>:<3A> <09>G<EFBFBD> <09>,<2C><17> <09> ?<3F>A<> <09> G<>I<> <09> J<>L<> <09> Q<>S<> <09> H<>J<> <09> Y<>[<5B> <09> X<>Z<> <09>G<EFBFBD> <17><1B>k<EFBFBD>2<>M<EFBFBD> B<>F<EFBFBD>
<EFBFBD><18><18>r<00>__main__)!rJr<>rSr<00>hashlibrgrd<00> http.serverrr<00>pathlibrr<00>typingrr{r<><00>environr.r<>r<>re<00>
expanduserrcr<>r rOr<>r<>r<>r<>r<>rGrMrr<00><module>rs<><00><01><04>* <0C> <0B><10><0E> <09>
<EFBFBD>:<3A><18><1D><1B> <04><0F>"<12>"<22>*<2A>*<2A>.<2E>.<2E>!4<>d<EFBFBD>;<3B><<3C> <0B><10>j<EFBFBD>j<EFBFBD>n<EFBFBD>n<EFBFBD>0<>+<2B>><3E> <0B><10>g<EFBFBD>g<EFBFBD> <20> <20>!9<>:<3A> <0B> <10><12><17><17>#<23>#<23>$B<>C<> D<> <09><02><0F>d[<01>d[<01>Rh
<EFBFBD>h
<EFBFBD>V,"<22>,"<22>b!<21>"<22><0F>"<22>$<24><10>w <0A>*<2A>w <0A>x<1B>& <0C>z<EFBFBD><19><08>F<EFBFBD>r