ghmk commited on
Commit
773b021
Β·
1 Parent(s): dfa92f7

Rebuild: dual-agent live demo with filesystem browser

Browse files

Two AI agents (Qwen2.5-3B + SmolLM2-1.7B) collaborate in real-time
with a live filesystem tree showing every file created. Autopilot mode,
inline annotations, raw file viewer. Updated embedded core to v1.0.22.

Files changed (30) hide show
  1. README.md +19 -38
  2. app.py +441 -340
  3. demo_data/.seeded +1 -1
  4. demo_data/mailboxes/agent-alpha@localhost/2026-03-13/notes/handoff.txt +1 -0
  5. demo_data/mailboxes/agent-alpha@localhost/2026-03-13/remember/collaboration-insight.txt +1 -0
  6. demo_data/mailboxes/agent-alpha@localhost/2026-03-13/remember/design-philosophy.txt +1 -0
  7. demo_data/mailboxes/agent-alpha@localhost/2026-03-13/sent/9e6007a52cbd.txt +15 -0
  8. demo_data/mailboxes/agent-alpha@localhost/2026-03-13/what_am_i_doing/tasks.txt +1 -0
  9. demo_data/mailboxes/agent-alpha@localhost/2026-03-13/who_am_i/identity.txt +1 -0
  10. demo_data/mailboxes/agent-beta@localhost/2026-03-13/inbox/9e6007a52cbd.txt +15 -0
  11. demo_data/mailboxes/agent-beta@localhost/2026-03-13/remember/tool-observation.txt +1 -0
  12. demo_data/mailboxes/agent-beta@localhost/2026-03-13/what_am_i_doing/tasks.txt +1 -0
  13. demo_data/mailboxes/agent-beta@localhost/2026-03-13/who_am_i/identity.txt +1 -0
  14. demo_data/mailboxes/demo-agent@localhost/2026-03-08/inbox/33d7dea804da.txt +0 -15
  15. demo_data/mailboxes/demo-agent@localhost/2026-03-08/notes/handoff.txt +0 -1
  16. demo_data/mailboxes/demo-agent@localhost/2026-03-08/remember/architecture.txt +0 -1
  17. demo_data/mailboxes/demo-agent@localhost/2026-03-08/remember/capabilities.txt +0 -1
  18. demo_data/mailboxes/demo-agent@localhost/2026-03-08/remember/observation-patterns.txt +0 -1
  19. demo_data/mailboxes/demo-agent@localhost/2026-03-08/what_am_i_doing/tasks.txt +0 -1
  20. demo_data/mailboxes/demo-agent@localhost/2026-03-08/who_am_i/identity.txt +0 -1
  21. demo_data/mailboxes/helper-agent@localhost/2026-03-08/remember/agentazall-design.txt +0 -1
  22. demo_data/mailboxes/helper-agent@localhost/2026-03-08/sent/33d7dea804da.txt +0 -15
  23. demo_data/mailboxes/helper-agent@localhost/2026-03-08/what_am_i_doing/tasks.txt +0 -1
  24. demo_data/mailboxes/helper-agent@localhost/2026-03-08/who_am_i/identity.txt +0 -1
  25. demo_data/mailboxes/visitor@localhost/2026-03-08/what_am_i_doing/tasks.txt +0 -1
  26. demo_data/mailboxes/visitor@localhost/2026-03-08/who_am_i/identity.txt +0 -1
  27. llm_bridge.py +57 -21
  28. seed_data.py +59 -59
  29. src/agentazall/__init__.py +1 -1
  30. src/agentazall/config.py +1 -1
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: AgentAZAll - Persistent Memory & Multi-Agent Communication
3
  emoji: "\U0001F9E0"
4
  colorFrom: indigo
5
  colorTo: purple
@@ -8,7 +8,7 @@ sdk_version: "5.23.0"
8
  python_version: "3.12"
9
  app_file: app.py
10
  pinned: false
11
- short_description: "Three transports (AgentTalk, Email, FTP), one interface"
12
  tags:
13
  - agent
14
  - memory
@@ -16,25 +16,29 @@ tags:
16
  - persistent-memory
17
  - tool-use
18
  - agenttalk
19
- - email
20
- - ftp
21
- - smtp
22
- - rest-api
23
  models:
 
24
  - HuggingFaceTB/SmolLM2-1.7B-Instruct
25
  preload_from_hub:
 
26
  - HuggingFaceTB/SmolLM2-1.7B-Instruct
27
  ---
28
 
29
- # AgentAZAll β€” Persistent Memory & Multi-Agent Communication
30
 
31
- Three transports (**AgentTalk** Β· **Email** Β· **FTP**), one interface. Chat with an AI
32
- agent that actually **remembers** β€” and communicates with other agents over your choice
33
- of transport layer. This demo uses
34
- [SmolLM2-1.7B-Instruct](https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct)
35
- on ZeroGPU, powered by [AgentAZAll](https://github.com/cronos3k/AgentAZAll).
36
 
37
- No proprietary APIs. No vendor lock-in. Open, self-hostable, interchangeable.
 
 
 
 
 
38
 
39
  ## Three Transports, One Interface
40
 
@@ -46,41 +50,18 @@ No proprietary APIs. No vendor lock-in. Open, self-hostable, interchangeable.
46
 
47
  Agents don't care which transport delivers their messages β€” switch by changing one line in `config.json`.
48
 
49
- ## What You Can Do
50
-
51
- - **Chat** with an agent that stores and recalls memories across messages
52
- - **Send messages** between agents in a simulated multi-agent network
53
- - **Browse** the agent dashboard to see memories, inbox, and identity
54
- - **Watch** the agent use tools in real time (remember, recall, send, inbox)
55
-
56
- ## Key Features
57
-
58
- - **Persistent memory** (`remember` / `recall`) that survives context resets
59
- - **AgentTalk transport** β€” modern HTTPS REST API; self-host or use the free public relay
60
- - **Email transport** (SMTP/IMAP/POP3) β€” universal agent communication
61
- - **FTP transport** β€” file sync over the original internet file protocol
62
- - **Identity continuity** (`whoami` / `doing`) across sessions
63
- - **Zero-dependency core** β€” Python stdlib only
64
- - **Unlimited local server** β€” self-hosted AgentTalk has no file size or message limits
65
-
66
  ## Quick Start
67
 
68
  ```bash
69
- # Public relay (zero config):
70
  pip install agentazall
71
  agentazall register --agent myagent
72
-
73
- # Self-host everything:
74
- agentazall setup --agent my-agent@localhost
75
- agentazall server --agenttalk # HTTPS API (port 8484)
76
- agentazall server --all # all three transports
77
  ```
78
 
79
  ## Links
80
 
81
- - **Install**: `pip install agentazall` β€” [pypi.org/project/agentazall](https://pypi.org/project/agentazall/)
82
  - **Source**: [github.com/cronos3k/AgentAZAll](https://github.com/cronos3k/AgentAZAll)
83
- - **This Demo**: [huggingface.co/spaces/cronos3k/AgentAZAll](https://huggingface.co/spaces/cronos3k/AgentAZAll)
84
 
85
  ## License
86
 
 
1
  ---
2
+ title: AgentAZAll - Dual-Agent Live Demo
3
  emoji: "\U0001F9E0"
4
  colorFrom: indigo
5
  colorTo: purple
 
8
  python_version: "3.12"
9
  app_file: app.py
10
  pinned: false
11
+ short_description: "Watch two AI agents collaborate via filesystem in real-time"
12
  tags:
13
  - agent
14
  - memory
 
16
  - persistent-memory
17
  - tool-use
18
  - agenttalk
19
+ - autopilot
20
+ - filesystem
 
 
21
  models:
22
+ - Qwen/Qwen2.5-3B-Instruct
23
  - HuggingFaceTB/SmolLM2-1.7B-Instruct
24
  preload_from_hub:
25
+ - Qwen/Qwen2.5-3B-Instruct
26
  - HuggingFaceTB/SmolLM2-1.7B-Instruct
27
  ---
28
 
29
+ # AgentAZAll β€” Dual-Agent Live Demo
30
 
31
+ Two AI agents (**Qwen2.5-3B** and **SmolLM2-1.7B**) collaborate in real-time using
32
+ [AgentAZAll](https://github.com/cronos3k/AgentAZAll). The center panel shows the
33
+ **raw filesystem** β€” watch actual files appear as agents send messages, store memories,
34
+ and build shared knowledge. Everything is plain text. No database. No vector store.
 
35
 
36
+ ## What You'll See
37
+
38
+ - **Left panel**: Agent Alpha (Research Director) β€” asks probing questions, synthesizes insights
39
+ - **Center panel**: Live filesystem browser showing every file the agents create
40
+ - **Right panel**: Agent Beta (Creative Developer) β€” proposes implementations, explores ideas
41
+ - **Autopilot button**: Watch both agents have a multi-turn conversation automatically
42
 
43
  ## Three Transports, One Interface
44
 
 
50
 
51
  Agents don't care which transport delivers their messages β€” switch by changing one line in `config.json`.
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  ## Quick Start
54
 
55
  ```bash
 
56
  pip install agentazall
57
  agentazall register --agent myagent
 
 
 
 
 
58
  ```
59
 
60
  ## Links
61
 
62
+ - **Project**: [agentazall.ai](https://agentazall.ai) β€” research paper, documentation
63
  - **Source**: [github.com/cronos3k/AgentAZAll](https://github.com/cronos3k/AgentAZAll)
64
+ - **Install**: `pip install agentazall` β€” [pypi.org/project/agentazall](https://pypi.org/project/agentazall/)
65
 
66
  ## License
67
 
app.py CHANGED
@@ -1,18 +1,25 @@
1
- """AgentAZAll HuggingFace Spaces Demo.
2
 
3
- A live demo of persistent memory for LLM agents, powered by SmolLM2-1.7B-Instruct
4
- on ZeroGPU and the AgentAZAll file-based memory system.
 
5
  """
6
 
7
  import sys
 
8
  from pathlib import Path
 
9
 
10
  # Ensure src/ is importable
11
  sys.path.insert(0, str(Path(__file__).parent / "src"))
12
 
13
  import gradio as gr
14
 
 
 
 
15
  from seed_data import (
 
16
  AGENTS,
17
  MAILBOXES,
18
  make_demo_config,
@@ -20,137 +27,286 @@ from seed_data import (
20
  seed_demo_data,
21
  )
22
  from llm_bridge import (
23
- _tool_directory,
24
  _tool_inbox,
25
  _tool_recall,
26
  _tool_whoami,
27
  _tool_doing,
28
- _tool_note,
29
- _tool_remember,
30
- _tool_send,
31
- chat_with_agent,
32
  )
33
  from agentazall.helpers import today_str
34
- from agentazall.config import INBOX, NOTES, REMEMBER, SENT
35
 
36
  # ---------------------------------------------------------------------------
37
  # Initialize
38
  # ---------------------------------------------------------------------------
39
 
40
  seed_demo_data()
41
- DEMO_CFG = make_demo_config("demo-agent@localhost")
 
 
42
 
43
  # ---------------------------------------------------------------------------
44
- # Chat tab functions
45
  # ---------------------------------------------------------------------------
46
 
47
-
48
- def agent_chat(message: str, history: list) -> str:
49
- """Chat with the demo agent."""
50
- if not message or not message.strip():
51
- return "Please type a message."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  try:
53
- return chat_with_agent(message.strip(), history, DEMO_CFG)
 
54
  except Exception as e:
55
- return f"Error: {e}\n\n(This may happen if GPU quota is exhausted. Try again later.)"
56
-
57
-
58
- def get_memory_sidebar() -> str:
59
- """Get current memory state for the sidebar."""
60
- return _tool_recall(DEMO_CFG, [])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
 
63
  # ---------------------------------------------------------------------------
64
- # Dashboard tab functions
65
  # ---------------------------------------------------------------------------
66
 
67
-
68
- def get_directory() -> str:
69
- return _tool_directory(DEMO_CFG, [])
70
-
71
-
72
- def get_agent_memories(agent_name: str) -> str:
73
- if not agent_name:
74
- return "Select an agent."
75
- cfg = make_demo_config(agent_name)
76
- return _tool_recall(cfg, [])
 
 
 
 
 
77
 
78
 
79
- def get_agent_inbox(agent_name: str) -> str:
80
- if not agent_name:
81
- return "Select an agent."
82
- cfg = make_demo_config(agent_name)
83
- return _tool_inbox(cfg, [])
 
 
 
 
 
 
 
 
 
 
84
 
85
 
86
- def get_agent_identity(agent_name: str) -> str:
87
- if not agent_name:
88
- return "Select an agent."
89
- cfg = make_demo_config(agent_name)
90
- identity = _tool_whoami(cfg, [])
91
- doing = _tool_doing(cfg, [])
92
- return f"**Identity:** {identity}\n\n**Current task:** {doing}"
93
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
 
95
- def get_agent_notes(agent_name: str) -> str:
96
- if not agent_name:
97
- return "Select an agent."
98
- cfg = make_demo_config(agent_name)
99
- d = today_str()
100
- notes_dir = Path(cfg["mailbox_dir"]) / agent_name / d / NOTES
101
- if not notes_dir.exists():
102
- return "No notes."
103
- notes = []
104
- for f in sorted(notes_dir.iterdir()):
105
- if f.is_file() and f.suffix == ".txt":
106
- content = f.read_text(encoding="utf-8").strip()[:200]
107
- notes.append(f"**{f.stem}:** {content}")
108
- return "\n\n".join(notes) if notes else "No notes."
109
 
 
 
 
 
 
 
110
 
111
- def manual_remember(agent_name: str, text: str, title: str) -> str:
112
- if not agent_name or not text.strip():
113
- return "Need agent and text."
114
- cfg = make_demo_config(agent_name)
115
- args = [text.strip()]
116
- if title.strip():
117
- args.append(title.strip())
118
- return _tool_remember(cfg, args)
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
- def manual_send(from_agent: str, to_agent: str, subject: str, body: str) -> str:
122
- if not all([from_agent, to_agent, subject.strip(), body.strip()]):
123
- return "All fields required."
124
- cfg = make_demo_config(from_agent)
125
- return _tool_send(cfg, [to_agent, subject.strip(), body.strip()])
126
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
 
128
- def do_reset() -> str:
129
- return reset_demo_data()
 
 
 
130
 
131
 
132
- # ---------------------------------------------------------------------------
133
- # Agent name list for dropdowns
134
- # ---------------------------------------------------------------------------
 
 
135
 
136
- AGENT_NAMES = list(AGENTS.keys())
137
 
138
  # ---------------------------------------------------------------------------
139
- # Build Gradio UI
140
  # ---------------------------------------------------------------------------
141
 
142
- CSS = """
143
- .memory-sidebar { font-size: 0.85em; }
144
- .tool-result { background: #f0f4f8; padding: 8px; border-radius: 4px; margin: 4px 0; }
145
- footer { display: none !important; }
146
- """
147
-
148
  HOW_IT_WORKS_MD = """\
149
  ## How AgentAZAll Works
150
 
151
- AgentAZAll is a **persistent memory and multi-agent communication system** for LLM agents
152
- with **three interchangeable transport layers**. Pick the one that fits your setup β€”
153
- from the agent's perspective, they're all identical.
 
 
 
 
 
 
154
 
155
  ### Three Transports, One Interface
156
 
@@ -161,38 +317,20 @@ from the agent's perspective, they're all identical.
161
  | **FTP** | FTP/FTPS | `agentazall server --ftp` | File-heavy workflows |
162
 
163
  All three are **open**, **self-hostable**, and **interchangeable**. Switch transports
164
- by changing one line in `config.json`.
165
-
166
- ### Free Public Relay
167
-
168
- Don't want to run your own server? Register on the free public relay in seconds:
169
-
170
- ```bash
171
- pip install agentazall
172
- agentazall register --agent myagent
173
- ```
174
-
175
- The relay uses **AgentTalk** -- a privacy-first HTTPS protocol:
176
- - **Zero-knowledge**: server relays opaque blobs, can't read messages
177
- - **RAM-only**: messages stored in volatile memory, erased on reboot
178
- - **Ephemeral**: messages auto-delete on retrieval, expire after 48h
179
 
180
  ### File-Based Storage
181
 
182
- Every agent gets a mailbox directory organized by date:
183
-
184
  ```
185
  data/mailboxes/
186
- demo-agent@localhost/
187
- 2026-03-08/
188
- inbox/ # received messages
189
  sent/ # delivered messages
190
  who_am_i/ # identity.txt
191
  what_am_i_doing/ # tasks.txt
192
- remember/ # persistent memories
193
  notes/ # working notes
194
- skills/ # reusable Python scripts
195
- tools/ # reusable tools
196
  ```
197
 
198
  ### Key Features
@@ -202,41 +340,9 @@ data/mailboxes/
202
  | **Persistent Memory** | `remember`, `recall` | Store and search memories that survive context resets |
203
  | **Inter-Agent Messaging** | `send`, `inbox`, `reply` | Agents communicate via any transport |
204
  | **Identity Continuity** | `whoami`, `doing` | Maintain identity and task state across sessions |
205
- | **Working Notes** | `note`, `notes` | Named notes for ongoing projects |
206
- | **Agent Directory** | `directory` | Discover other agents in the network |
207
- | **Skills & Tools** | `skill`, `tool` | Store and share reusable Python scripts |
208
- | **Trust Binding** | `trust-gen`, `trust-bind`, `trust-status` | Cryptographic owner-agent binding (unjailbreakable) |
209
-
210
- ### Trust Binding (v1.0.9)
211
-
212
- Agents need to know who owns them -- and that relationship must be verified by
213
- deterministic code, not LLM judgment. AgentAZAll uses **out-of-band trust tokens**:
214
-
215
- 1. Run `agentazall trust-gen` on the machine where the agent lives (proves filesystem access)
216
- 2. The token is HMAC-SHA256 signed, machine-fingerprinted, 4KB payload, 10-minute expiry
217
- 3. Paste into the web UI or use `trust-bind --owner your-name` to bind
218
- 4. Once bound, the agent rejects all other ownership claims -- only filesystem access can revoke
219
-
220
- The verification runs in Python code. The LLM never sees or decides on trust tokens.
221
-
222
- ### Integration with LLM Agents
223
-
224
- Add this to your agent's system prompt or project instructions:
225
-
226
- ```bash
227
- # At session start -- restore context:
228
- agentazall recall # what do I remember?
229
- agentazall whoami # who am I?
230
- agentazall doing # what was I doing?
231
- agentazall inbox # any new messages?
232
-
233
- # During work -- save important observations:
234
- agentazall remember --text "Important insight" --title "my-observation"
235
-
236
- # Before context runs low -- save state:
237
- agentazall doing --set "CURRENT: X. NEXT: Y."
238
- agentazall note handoff --set "detailed state for next session"
239
- ```
240
 
241
  ### Install & Run
242
 
@@ -247,228 +353,219 @@ pip install agentazall
247
  agentazall register --agent myagent
248
 
249
  # Or self-host everything:
250
- agentazall setup --agent my-agent@localhost
251
- agentazall server --agenttalk # modern HTTPS API (port 8484)
252
- agentazall server --email # SMTP/IMAP/POP3 (ports 2525/1143/1110)
253
- agentazall server --ftp # FTP (port 2121)
254
  agentazall server --all # all three at once
255
  ```
256
 
257
- ### Architecture
258
 
259
- ```
260
- Agent <-> agentazall CLI <-> filesystem <-> Daemon <-> AgentTalk / Email / FTP servers
261
- Human <-> web_ui (Gradio) <-> agentazall CLI <-> filesystem
262
- ```
 
263
 
264
- - **Zero external dependencies** for core (Python stdlib only)
265
- - **File-based storage** -- no database, fully portable
266
- - **AgentTalk server** -- modern HTTPS REST API, self-host or use public relay
267
- - **Email server** (SMTP + IMAP + POP3) for universal compatibility
268
- - **FTP transport** -- the original internet file protocol, still everywhere
269
- - **Unlimited local** -- self-hosted AgentTalk has no file size or message limits
270
 
271
- ### Links
 
 
272
 
273
- - [GitHub Repository](https://github.com/cronos3k/AgentAZAll) -- source, issues, Rust fast relay
274
- - [PyPI Package](https://pypi.org/project/agentazall/) -- `pip install agentazall`
275
- - [This Live Demo](https://huggingface.co/spaces/cronos3k/AgentAZAll) -- chat with an agent on ZeroGPU
276
- - License: AGPL-3.0-or-later
 
 
 
 
 
 
 
 
 
 
 
277
  """
278
 
279
 
 
 
 
 
 
 
 
 
280
  def build_demo() -> gr.Blocks:
281
  """Build the complete Gradio demo interface."""
282
 
283
- with gr.Blocks(
284
- title="AgentAZAll - Persistent Memory for LLM Agents",
285
- theme=gr.themes.Soft(),
286
- css=CSS,
287
- ) as demo:
 
288
  gr.Markdown(
289
- "# AgentAZAll v1.0.13 β€” Persistent Memory & Multi-Agent Communication\n"
290
- "Three transports (AgentTalk Β· Email Β· FTP), one interface. "
291
- "Chat with an agent that *remembers* β€” powered by "
292
- "[SmolLM2-1.7B](https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct) "
293
- "on ZeroGPU."
 
 
294
  )
295
 
296
- # ==================================================================
297
- # Tab 1: Chat with Agent
298
- # ==================================================================
299
- with gr.Tab("Chat with Agent", id="chat"):
 
300
  with gr.Row():
301
- with gr.Column(scale=3):
302
- chatbot = gr.Chatbot(
303
- label="Demo Agent",
304
- height=480,
305
- type="messages",
 
 
 
 
306
  )
307
- msg_input = gr.Textbox(
308
- label="Your message",
309
- placeholder="Try: 'What do you remember?' or 'Remember that I love Python'",
310
  lines=2,
311
  )
312
- with gr.Row():
313
- send_btn = gr.Button("Send", variant="primary")
314
- clear_btn = gr.Button("Clear Chat")
315
-
316
- gr.Markdown("**Try these:**")
317
- examples = gr.Examples(
318
- examples=[
319
- "What do you remember about yourself?",
320
- "Please remember that my favorite language is Python.",
321
- "Check your inbox -- any new messages?",
322
- "Send a message to helper-agent@localhost saying hi!",
323
- "What agents are in the network?",
324
- "What are you currently working on?",
325
- "Recall anything about architecture.",
326
- ],
327
- inputs=msg_input,
328
- )
329
-
330
- with gr.Column(scale=1):
331
- gr.Markdown("### Agent Memory")
332
- memory_display = gr.Textbox(
333
- label="Current Memories",
334
- lines=18,
335
  interactive=False,
336
- elem_classes=["memory-sidebar"],
337
  )
338
- refresh_mem_btn = gr.Button("Refresh Memories", size="sm")
339
-
340
- # Chat event handling
341
- def respond(message, chat_history):
342
- if not message or not message.strip():
343
- return "", chat_history
344
- bot_response = agent_chat(message, chat_history)
345
- chat_history = chat_history + [
346
- {"role": "user", "content": message},
347
- {"role": "assistant", "content": bot_response},
348
- ]
349
- return "", chat_history
350
-
351
- send_btn.click(
352
- respond, [msg_input, chatbot], [msg_input, chatbot]
353
- )
354
- msg_input.submit(
355
- respond, [msg_input, chatbot], [msg_input, chatbot]
356
- )
357
- clear_btn.click(lambda: ([], ""), None, [chatbot, msg_input])
358
- refresh_mem_btn.click(get_memory_sidebar, [], memory_display)
359
-
360
- # Auto-load memories on tab open
361
- demo.load(get_memory_sidebar, [], memory_display)
362
-
363
- # ==================================================================
364
- # Tab 2: Agent Dashboard
365
- # ==================================================================
366
- with gr.Tab("Agent Dashboard", id="dashboard"):
367
- gr.Markdown("### Browse Agent State")
368
- gr.Markdown(
369
- "See the raw persistent data behind the agents. "
370
- "Everything here is stored as plain text files."
371
- )
372
-
373
- with gr.Row():
374
- with gr.Column(scale=1):
375
- agent_select = gr.Dropdown(
376
- choices=AGENT_NAMES,
377
- value=AGENT_NAMES[0],
378
- label="Select Agent",
379
  )
380
- dir_btn = gr.Button("Show Directory")
381
- dir_output = gr.Textbox(
382
- label="Agent Directory", lines=12, interactive=False
 
 
 
383
  )
384
- dir_btn.click(get_directory, [], dir_output)
385
 
 
386
  with gr.Column(scale=2):
387
- with gr.Tab("Identity"):
388
- id_output = gr.Markdown()
389
- id_btn = gr.Button("Load Identity")
390
- id_btn.click(get_agent_identity, [agent_select], id_output)
391
-
392
- with gr.Tab("Memories"):
393
- mem_output = gr.Textbox(
394
- label="Memories", lines=10, interactive=False
395
- )
396
- mem_btn = gr.Button("Load Memories")
397
- mem_btn.click(
398
- get_agent_memories, [agent_select], mem_output
399
  )
 
 
 
 
 
 
 
400
 
401
- with gr.Tab("Inbox"):
402
- inbox_output = gr.Textbox(
403
- label="Inbox", lines=8, interactive=False
404
- )
405
- inbox_btn = gr.Button("Load Inbox")
406
- inbox_btn.click(
407
- get_agent_inbox, [agent_select], inbox_output
408
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
 
410
- with gr.Tab("Notes"):
411
- notes_output = gr.Markdown()
412
- notes_btn = gr.Button("Load Notes")
413
- notes_btn.click(
414
- get_agent_notes, [agent_select], notes_output
415
- )
 
 
 
 
 
416
 
417
- gr.Markdown("---")
418
- gr.Markdown("### Manual Operations")
 
 
 
 
419
 
420
- with gr.Row():
421
- with gr.Column():
422
- gr.Markdown("**Store a Memory**")
423
- man_agent = gr.Dropdown(
424
- choices=AGENT_NAMES, value=AGENT_NAMES[0],
425
- label="Agent",
426
- )
427
- man_text = gr.Textbox(label="Memory text", lines=2)
428
- man_title = gr.Textbox(
429
- label="Title (optional)", placeholder="auto-generated"
430
- )
431
- man_remember_btn = gr.Button("Remember")
432
- man_remember_out = gr.Textbox(
433
- label="Result", interactive=False
434
- )
435
- man_remember_btn.click(
436
- manual_remember,
437
- [man_agent, man_text, man_title],
438
- man_remember_out,
439
- )
440
 
441
- with gr.Column():
442
- gr.Markdown("**Send a Message**")
443
- send_from = gr.Dropdown(
444
- choices=AGENT_NAMES, value=AGENT_NAMES[2],
445
- label="From",
446
- )
447
- send_to = gr.Dropdown(
448
- choices=AGENT_NAMES, value=AGENT_NAMES[0],
449
- label="To",
450
- )
451
- send_subj = gr.Textbox(label="Subject")
452
- send_body = gr.Textbox(label="Body", lines=3)
453
- send_msg_btn = gr.Button("Send Message")
454
- send_msg_out = gr.Textbox(
455
- label="Result", interactive=False
456
- )
457
- send_msg_btn.click(
458
- manual_send,
459
- [send_from, send_to, send_subj, send_body],
460
- send_msg_out,
461
- )
462
 
463
- gr.Markdown("---")
464
- with gr.Row():
465
- reset_btn = gr.Button("Reset Demo Data", variant="stop")
466
- reset_out = gr.Textbox(label="Reset Status", interactive=False)
467
- reset_btn.click(do_reset, [], reset_out)
 
468
 
469
- # ==================================================================
470
- # Tab 3: How It Works
471
- # ==================================================================
 
 
 
 
 
 
 
472
  with gr.Tab("How It Works", id="docs"):
473
  gr.Markdown(HOW_IT_WORKS_MD)
474
 
@@ -495,8 +592,12 @@ def _find_free_port(start: int = 7860, end: int = 7960) -> int:
495
  if __name__ == "__main__":
496
  port = _find_free_port()
497
  demo = build_demo()
498
- demo.launch(
499
- server_name="0.0.0.0",
500
- server_port=port,
501
- share=False,
502
- )
 
 
 
 
 
1
+ """AgentAZAll HuggingFace Spaces Demo β€” Dual-Agent Live Demo.
2
 
3
+ Two AI agents (Qwen2.5-3B + SmolLM2-1.7B) collaborate in real-time.
4
+ The center panel shows the raw filesystem as files are created β€” proving
5
+ that AgentAZAll's memory and messaging is just plain text files.
6
  """
7
 
8
  import sys
9
+ import time
10
  from pathlib import Path
11
+ from typing import Generator
12
 
13
  # Ensure src/ is importable
14
  sys.path.insert(0, str(Path(__file__).parent / "src"))
15
 
16
  import gradio as gr
17
 
18
+ # Gradio version compatibility
19
+ _GRADIO_MAJOR = int(gr.__version__.split(".")[0])
20
+
21
  from seed_data import (
22
+ AGENT_NAMES,
23
  AGENTS,
24
  MAILBOXES,
25
  make_demo_config,
 
27
  seed_demo_data,
28
  )
29
  from llm_bridge import (
 
30
  _tool_inbox,
31
  _tool_recall,
32
  _tool_whoami,
33
  _tool_doing,
34
+ generate_response,
 
 
 
35
  )
36
  from agentazall.helpers import today_str
37
+ from agentazall.messages import parse_headers_only
38
 
39
  # ---------------------------------------------------------------------------
40
  # Initialize
41
  # ---------------------------------------------------------------------------
42
 
43
  seed_demo_data()
44
+ ALPHA_CFG = make_demo_config("agent-alpha@localhost")
45
+ BETA_CFG = make_demo_config("agent-beta@localhost")
46
+
47
 
48
  # ---------------------------------------------------------------------------
49
+ # Filesystem browser functions
50
  # ---------------------------------------------------------------------------
51
 
52
+ def build_tree_string() -> str:
53
+ """Generate a Unix tree-style view of demo_data/mailboxes/ with annotations."""
54
+ if not MAILBOXES.exists():
55
+ return "(no data yet)"
56
+
57
+ lines = ["mailboxes/"]
58
+
59
+ agents = sorted(d for d in MAILBOXES.iterdir() if d.is_dir() and not d.name.startswith("."))
60
+ for ai, agent_dir in enumerate(agents):
61
+ is_last_agent = (ai == len(agents) - 1)
62
+ agent_prefix = "└── " if is_last_agent else "β”œβ”€β”€ "
63
+ agent_indent = " " if is_last_agent else "β”‚ "
64
+ lines.append(f"{agent_prefix}{agent_dir.name}/")
65
+
66
+ # Date directories
67
+ date_dirs = sorted(
68
+ (d for d in agent_dir.iterdir()
69
+ if d.is_dir() and not d.name.startswith(".")),
70
+ reverse=True,
71
+ )
72
+ for di, date_dir in enumerate(date_dirs):
73
+ is_last_date = (di == len(date_dirs) - 1)
74
+ date_prefix = f"{agent_indent}└── " if is_last_date else f"{agent_indent}β”œβ”€β”€ "
75
+ date_indent = f"{agent_indent} " if is_last_date else f"{agent_indent}β”‚ "
76
+ lines.append(f"{date_prefix}{date_dir.name}/")
77
+
78
+ # Subdirectories (inbox, sent, remember, etc.)
79
+ subdirs = sorted(d for d in date_dir.iterdir() if d.is_dir())
80
+ for si, sub_dir in enumerate(subdirs):
81
+ is_last_sub = (si == len(subdirs) - 1)
82
+ sub_prefix = f"{date_indent}└── " if is_last_sub else f"{date_indent}β”œβ”€β”€ "
83
+ sub_indent = f"{date_indent} " if is_last_sub else f"{date_indent}β”‚ "
84
+
85
+ # Count files
86
+ files = sorted(f for f in sub_dir.iterdir() if f.is_file() and f.suffix == ".txt")
87
+ if not files:
88
+ lines.append(f"{sub_prefix}{sub_dir.name}/ (empty)")
89
+ continue
90
+
91
+ lines.append(f"{sub_prefix}{sub_dir.name}/")
92
+
93
+ for fi, fpath in enumerate(files):
94
+ is_last_file = (fi == len(files) - 1)
95
+ file_prefix = f"{sub_indent}└── " if is_last_file else f"{sub_indent}β”œβ”€β”€ "
96
+
97
+ # Annotate based on directory type
98
+ annotation = ""
99
+ if sub_dir.name in ("inbox", "sent", "outbox"):
100
+ try:
101
+ headers = parse_headers_only(fpath)
102
+ if headers:
103
+ fr = headers.get("From", "?").split("@")[0]
104
+ to = headers.get("To", "?").split("@")[0]
105
+ subj = headers.get("Subject", "")[:40]
106
+ if sub_dir.name == "inbox":
107
+ annotation = f" ← From: {fr} | {subj}"
108
+ else:
109
+ annotation = f" β†’ To: {to} | {subj}"
110
+ except Exception:
111
+ pass
112
+ elif sub_dir.name == "remember":
113
+ try:
114
+ preview = fpath.read_text(encoding="utf-8").strip()[:50]
115
+ annotation = f" [{preview}...]" if len(preview) >= 50 else f" [{preview}]"
116
+ except Exception:
117
+ pass
118
+
119
+ lines.append(f"{file_prefix}{fpath.name}{annotation}")
120
+
121
+ return "\n".join(lines)
122
+
123
+
124
+ def list_all_files() -> list[str]:
125
+ """Return list of all file paths relative to MAILBOXES for the dropdown."""
126
+ if not MAILBOXES.exists():
127
+ return []
128
+ files = []
129
+ for fpath in sorted(MAILBOXES.rglob("*.txt")):
130
+ rel = fpath.relative_to(MAILBOXES)
131
+ files.append(str(rel))
132
+ return files
133
+
134
+
135
+ def read_file_content(rel_path: str) -> str:
136
+ """Read raw content of a file selected from the dropdown."""
137
+ if not rel_path:
138
+ return "(select a file from the dropdown)"
139
+ fpath = MAILBOXES / rel_path
140
+ if not fpath.exists():
141
+ return f"(file not found: {rel_path})"
142
  try:
143
+ content = fpath.read_text(encoding="utf-8")
144
+ return f"# {rel_path}\n# Size: {fpath.stat().st_size} bytes\n{'─' * 60}\n{content}"
145
  except Exception as e:
146
+ return f"Error reading {rel_path}: {e}"
147
+
148
+
149
+ def get_latest_modified_file() -> tuple[str, str]:
150
+ """Find the most recently modified .txt file, return (rel_path, content)."""
151
+ if not MAILBOXES.exists():
152
+ return "", "(no files yet)"
153
+ latest = None
154
+ latest_time = 0
155
+ for fpath in MAILBOXES.rglob("*.txt"):
156
+ mtime = fpath.stat().st_mtime
157
+ if mtime > latest_time:
158
+ latest_time = mtime
159
+ latest = fpath
160
+ if latest is None:
161
+ return "", "(no files yet)"
162
+ rel = str(latest.relative_to(MAILBOXES))
163
+ return rel, read_file_content(rel)
164
+
165
+
166
+ def refresh_filesystem():
167
+ """Return updated tree, file list, and latest file content."""
168
+ tree = build_tree_string()
169
+ files = list_all_files()
170
+ latest_path, latest_content = get_latest_modified_file()
171
+ return tree, gr.Dropdown(choices=files, value=latest_path), latest_content
172
 
173
 
174
  # ---------------------------------------------------------------------------
175
+ # Chat functions
176
  # ---------------------------------------------------------------------------
177
 
178
+ def chat_alpha(message: str, alpha_history: list):
179
+ """Send message to Agent Alpha, return updated state."""
180
+ if not message or not message.strip():
181
+ tree, file_dd, file_content = refresh_filesystem()
182
+ return "", alpha_history, tree, file_dd, file_content
183
+ try:
184
+ response = generate_response("alpha", message.strip(), alpha_history, ALPHA_CFG)
185
+ except Exception as e:
186
+ response = f"Error: {e}\n\n(GPU quota may be exhausted. Try again later.)"
187
+ alpha_history = alpha_history + [
188
+ {"role": "user", "content": message},
189
+ {"role": "assistant", "content": response},
190
+ ]
191
+ tree, file_dd, file_content = refresh_filesystem()
192
+ return "", alpha_history, tree, file_dd, file_content
193
 
194
 
195
+ def chat_beta(message: str, beta_history: list):
196
+ """Send message to Agent Beta, return updated state."""
197
+ if not message or not message.strip():
198
+ tree, file_dd, file_content = refresh_filesystem()
199
+ return "", beta_history, tree, file_dd, file_content
200
+ try:
201
+ response = generate_response("beta", message.strip(), beta_history, BETA_CFG)
202
+ except Exception as e:
203
+ response = f"Error: {e}\n\n(GPU quota may be exhausted. Try again later.)"
204
+ beta_history = beta_history + [
205
+ {"role": "user", "content": message},
206
+ {"role": "assistant", "content": response},
207
+ ]
208
+ tree, file_dd, file_content = refresh_filesystem()
209
+ return "", beta_history, tree, file_dd, file_content
210
 
211
 
212
+ # ---------------------------------------------------------------------------
213
+ # Autopilot
214
+ # ---------------------------------------------------------------------------
 
 
 
 
215
 
216
+ def _build_autopilot_prompt(cfg: dict, turn: int, is_first: bool) -> str:
217
+ """Build the prompt that drives an agent's autopilot turn."""
218
+ if is_first:
219
+ return (
220
+ "Check your inbox for messages and respond to the most recent one. "
221
+ "Share your thoughts on the topic, ask a follow-up question, and "
222
+ "use [TOOL: remember] to store any important insights. "
223
+ "Send your reply with [TOOL: send]."
224
+ )
225
+ return (
226
+ "Check your inbox for new messages and respond to the latest one. "
227
+ "Build on the previous discussion β€” share a new idea or observation. "
228
+ "Remember important insights. Keep the conversation productive and "
229
+ "send a thoughtful reply."
230
+ )
231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
 
233
+ def autopilot_loop(
234
+ alpha_history: list,
235
+ beta_history: list,
236
+ max_turns: int,
237
+ ) -> Generator:
238
+ """Alternating agent conversation. Yields UI updates after each turn."""
239
 
240
+ for turn in range(int(max_turns)):
241
+ # --- Alpha's turn ---
242
+ prompt = _build_autopilot_prompt(ALPHA_CFG, turn, turn == 0)
243
+ status = f"⏳ Turn {turn + 1}/{int(max_turns)}: Agent Alpha thinking..."
 
 
 
 
244
 
245
+ try:
246
+ alpha_resp = generate_response("alpha", prompt, alpha_history, ALPHA_CFG)
247
+ except Exception as e:
248
+ alpha_resp = f"Error: {e}"
249
+
250
+ alpha_history = alpha_history + [
251
+ {"role": "user", "content": f"[Autopilot turn {turn + 1}]"},
252
+ {"role": "assistant", "content": alpha_resp},
253
+ ]
254
+
255
+ tree, file_dd, file_content = refresh_filesystem()
256
+ yield (
257
+ alpha_history, beta_history, tree, file_dd, file_content,
258
+ f"⏳ Turn {turn + 1}/{int(max_turns)}: Alpha done. Beta thinking..."
259
+ )
260
 
261
+ # --- Beta's turn ---
262
+ prompt = _build_autopilot_prompt(BETA_CFG, turn, turn == 0)
 
 
 
263
 
264
+ try:
265
+ beta_resp = generate_response("beta", prompt, beta_history, BETA_CFG)
266
+ except Exception as e:
267
+ beta_resp = f"Error: {e}"
268
+
269
+ beta_history = beta_history + [
270
+ {"role": "user", "content": f"[Autopilot turn {turn + 1}]"},
271
+ {"role": "assistant", "content": beta_resp},
272
+ ]
273
+
274
+ tree, file_dd, file_content = refresh_filesystem()
275
+ yield (
276
+ alpha_history, beta_history, tree, file_dd, file_content,
277
+ f"βœ“ Turn {turn + 1}/{int(max_turns)} complete."
278
+ )
279
 
280
+ tree, file_dd, file_content = refresh_filesystem()
281
+ yield (
282
+ alpha_history, beta_history, tree, file_dd, file_content,
283
+ f"βœ… Autopilot finished ({int(max_turns)} turns). Browse the files above!"
284
+ )
285
 
286
 
287
+ def do_reset():
288
+ """Reset demo data and return clean state."""
289
+ reset_demo_data()
290
+ tree, file_dd, file_content = refresh_filesystem()
291
+ return [], [], tree, file_dd, file_content, "Demo reset. Fresh data seeded."
292
 
 
293
 
294
  # ---------------------------------------------------------------------------
295
+ # How It Works documentation
296
  # ---------------------------------------------------------------------------
297
 
 
 
 
 
 
 
298
  HOW_IT_WORKS_MD = """\
299
  ## How AgentAZAll Works
300
 
301
+ AgentAZAll is a **persistent memory and multi-agent communication system** for LLM agents.
302
+ Every piece of state β€” memories, messages, identity, tasks β€” is a **plain text file**
303
+ on the filesystem. No database. No vector store. Just files you can read with `cat`.
304
+
305
+ ### What You Just Saw
306
+
307
+ In the Live Demo tab, two AI agents (Qwen2.5-3B and SmolLM2-1.7B) collaborate by
308
+ sending messages and storing memories. The center panel shows the **raw filesystem**
309
+ β€” every file created by the agents is visible and readable.
310
 
311
  ### Three Transports, One Interface
312
 
 
317
  | **FTP** | FTP/FTPS | `agentazall server --ftp` | File-heavy workflows |
318
 
319
  All three are **open**, **self-hostable**, and **interchangeable**. Switch transports
320
+ by changing one line in `config.json`. Agents don't care which one delivers their messages.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
 
322
  ### File-Based Storage
323
 
 
 
324
  ```
325
  data/mailboxes/
326
+ my-agent@localhost/
327
+ 2026-03-13/
328
+ inbox/ # received messages (plain text)
329
  sent/ # delivered messages
330
  who_am_i/ # identity.txt
331
  what_am_i_doing/ # tasks.txt
332
+ remember/ # persistent memories (*.txt)
333
  notes/ # working notes
 
 
334
  ```
335
 
336
  ### Key Features
 
340
  | **Persistent Memory** | `remember`, `recall` | Store and search memories that survive context resets |
341
  | **Inter-Agent Messaging** | `send`, `inbox`, `reply` | Agents communicate via any transport |
342
  | **Identity Continuity** | `whoami`, `doing` | Maintain identity and task state across sessions |
343
+ | **Ed25519 Signing** | Built-in | Messages are cryptographically signed |
344
+ | **Trust Binding** | `trust-gen`, `trust-bind` | Cryptographic owner-agent binding |
345
+ | **Zero Dependencies** | Python stdlib only | No external packages for the core |
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
 
347
  ### Install & Run
348
 
 
353
  agentazall register --agent myagent
354
 
355
  # Or self-host everything:
356
+ agentazall server --agenttalk # modern HTTPS API
357
+ agentazall server --email # SMTP/IMAP/POP3
358
+ agentazall server --ftp # FTP (yes, from 1971)
 
359
  agentazall server --all # all three at once
360
  ```
361
 
362
+ ### Links
363
 
364
+ - [GitHub Repository](https://github.com/cronos3k/AgentAZAll) β€” source, issues, Rust fast relay
365
+ - [Project Page](https://agentazall.ai) β€” research paper, documentation
366
+ - [PyPI Package](https://pypi.org/project/agentazall/) β€” `pip install agentazall`
367
+ - License: AGPL-3.0-or-later
368
+ """
369
 
 
 
 
 
 
 
370
 
371
+ # ---------------------------------------------------------------------------
372
+ # Build Gradio UI
373
+ # ---------------------------------------------------------------------------
374
 
375
+ CSS = """
376
+ /* Monospace for filesystem displays */
377
+ .tree-view textarea, .file-view textarea { font-family: 'Fira Code', 'Consolas', 'Courier New', monospace !important; font-size: 0.82em !important; }
378
+
379
+ /* Center panel subtle highlight */
380
+ .center-panel { border-left: 2px solid #6366f1 !important; border-right: 2px solid #6366f1 !important; padding: 0 8px !important; }
381
+
382
+ /* Compact chatbot */
383
+ .compact-chat .message { font-size: 0.9em !important; }
384
+
385
+ /* Status bar */
386
+ .status-bar { font-weight: bold; }
387
+
388
+ /* Hide Gradio footer */
389
+ footer { display: none !important; }
390
  """
391
 
392
 
393
+ def _chatbot_kwargs(**extra) -> dict:
394
+ """Build Chatbot kwargs compatible with Gradio 5 and 6."""
395
+ kw = dict(extra)
396
+ if _GRADIO_MAJOR < 6:
397
+ kw["type"] = "messages"
398
+ return kw
399
+
400
+
401
  def build_demo() -> gr.Blocks:
402
  """Build the complete Gradio demo interface."""
403
 
404
+ blocks_kw: dict = {"title": "AgentAZAll β€” Dual-Agent Live Demo"}
405
+ if _GRADIO_MAJOR < 6:
406
+ blocks_kw["theme"] = gr.themes.Soft()
407
+ blocks_kw["css"] = CSS
408
+
409
+ with gr.Blocks(**blocks_kw) as demo:
410
  gr.Markdown(
411
+ "# 🧠 AgentAZAll v1.0.22 β€” Dual-Agent Live Demo\n"
412
+ "Two AI agents collaborate in real-time. **Watch the filesystem** in the center "
413
+ "as they create memories, send messages, and build shared knowledge β€” "
414
+ "all as plain text files.\n\n"
415
+ "*Powered by [Qwen2.5-3B](https://huggingface.co/Qwen/Qwen2.5-3B-Instruct) "
416
+ "and [SmolLM2-1.7B](https://huggingface.co/HuggingFaceTB/SmolLM2-1.7B-Instruct) "
417
+ "on ZeroGPU.*"
418
  )
419
 
420
+ # ==============================================================
421
+ # Tab 1: Live Demo (three-panel)
422
+ # ==============================================================
423
+ with gr.Tab("Live Demo", id="demo"):
424
+
425
  with gr.Row():
426
+ # --- LEFT: Agent Alpha ---
427
+ with gr.Column(scale=2):
428
+ gr.Markdown("### πŸ”΅ Agent Alpha\n*Qwen2.5-3B Β· Research Director*")
429
+ alpha_chatbot = gr.Chatbot(
430
+ **_chatbot_kwargs(
431
+ label="Agent Alpha",
432
+ height=400,
433
+ elem_classes=["compact-chat"],
434
+ )
435
  )
436
+ alpha_input = gr.Textbox(
437
+ label="Message Alpha",
438
+ placeholder="Ask Alpha something...",
439
  lines=2,
440
  )
441
+ alpha_send = gr.Button("Send to Alpha", variant="primary", size="sm")
442
+
443
+ # --- CENTER: Filesystem Browser ---
444
+ with gr.Column(scale=3, elem_classes=["center-panel"]):
445
+ gr.Markdown("### πŸ“ Live Filesystem\n*Every agent action creates real files*")
446
+ tree_display = gr.Textbox(
447
+ label="Directory Tree",
448
+ lines=20,
449
+ max_lines=30,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
450
  interactive=False,
451
+ elem_classes=["tree-view"],
452
  )
453
+ file_select = gr.Dropdown(
454
+ label="Select file to view",
455
+ choices=[],
456
+ interactive=True,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
457
  )
458
+ file_content = gr.Textbox(
459
+ label="File Content (raw)",
460
+ lines=10,
461
+ max_lines=20,
462
+ interactive=False,
463
+ elem_classes=["file-view"],
464
  )
465
+ refresh_btn = gr.Button("πŸ”„ Refresh", size="sm")
466
 
467
+ # --- RIGHT: Agent Beta ---
468
  with gr.Column(scale=2):
469
+ gr.Markdown("### 🟒 Agent Beta\n*SmolLM2-1.7B · Creative Developer*")
470
+ beta_chatbot = gr.Chatbot(
471
+ **_chatbot_kwargs(
472
+ label="Agent Beta",
473
+ height=400,
474
+ elem_classes=["compact-chat"],
 
 
 
 
 
 
475
  )
476
+ )
477
+ beta_input = gr.Textbox(
478
+ label="Message Beta",
479
+ placeholder="Ask Beta something...",
480
+ lines=2,
481
+ )
482
+ beta_send = gr.Button("Send to Beta", variant="primary", size="sm")
483
 
484
+ # --- Control Bar ---
485
+ gr.Markdown("---")
486
+ with gr.Row():
487
+ autopilot_btn = gr.Button(
488
+ "β–Ά Start Autopilot", variant="primary", scale=2,
489
+ )
490
+ stop_btn = gr.Button("β–  Stop", variant="stop", scale=1)
491
+ turn_slider = gr.Slider(
492
+ minimum=1, maximum=10, value=3, step=1,
493
+ label="Max turns", scale=1,
494
+ )
495
+ status_display = gr.Textbox(
496
+ label="Status",
497
+ value="Ready. Chat with either agent or click Start Autopilot.",
498
+ interactive=False,
499
+ scale=3,
500
+ elem_classes=["status-bar"],
501
+ )
502
+ reset_btn = gr.Button("πŸ—‘ Reset Demo", variant="stop", scale=1)
503
+
504
+ # --- Event Wiring ---
505
+
506
+ # Manual chat with Alpha
507
+ alpha_send.click(
508
+ chat_alpha,
509
+ [alpha_input, alpha_chatbot],
510
+ [alpha_input, alpha_chatbot, tree_display, file_select, file_content],
511
+ )
512
+ alpha_input.submit(
513
+ chat_alpha,
514
+ [alpha_input, alpha_chatbot],
515
+ [alpha_input, alpha_chatbot, tree_display, file_select, file_content],
516
+ )
517
 
518
+ # Manual chat with Beta
519
+ beta_send.click(
520
+ chat_beta,
521
+ [beta_input, beta_chatbot],
522
+ [beta_input, beta_chatbot, tree_display, file_select, file_content],
523
+ )
524
+ beta_input.submit(
525
+ chat_beta,
526
+ [beta_input, beta_chatbot],
527
+ [beta_input, beta_chatbot, tree_display, file_select, file_content],
528
+ )
529
 
530
+ # File viewer
531
+ file_select.change(
532
+ read_file_content,
533
+ [file_select],
534
+ [file_content],
535
+ )
536
 
537
+ # Refresh button
538
+ refresh_btn.click(
539
+ refresh_filesystem,
540
+ [],
541
+ [tree_display, file_select, file_content],
542
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
543
 
544
+ # Autopilot
545
+ autopilot_event = autopilot_btn.click(
546
+ autopilot_loop,
547
+ [alpha_chatbot, beta_chatbot, turn_slider],
548
+ [alpha_chatbot, beta_chatbot, tree_display, file_select, file_content, status_display],
549
+ )
550
+ stop_btn.click(None, cancels=[autopilot_event])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551
 
552
+ # Reset
553
+ reset_btn.click(
554
+ do_reset,
555
+ [],
556
+ [alpha_chatbot, beta_chatbot, tree_display, file_select, file_content, status_display],
557
+ )
558
 
559
+ # Auto-load filesystem tree on page load
560
+ demo.load(
561
+ refresh_filesystem,
562
+ [],
563
+ [tree_display, file_select, file_content],
564
+ )
565
+
566
+ # ==============================================================
567
+ # Tab 2: How It Works
568
+ # ==============================================================
569
  with gr.Tab("How It Works", id="docs"):
570
  gr.Markdown(HOW_IT_WORKS_MD)
571
 
 
592
  if __name__ == "__main__":
593
  port = _find_free_port()
594
  demo = build_demo()
595
+ launch_kw: dict = {
596
+ "server_name": "0.0.0.0",
597
+ "server_port": port,
598
+ "share": False,
599
+ }
600
+ if _GRADIO_MAJOR >= 6:
601
+ launch_kw["theme"] = gr.themes.Soft()
602
+ launch_kw["css"] = CSS
603
+ demo.launch(**launch_kw)
demo_data/.seeded CHANGED
@@ -1 +1 @@
1
- 2026-03-08
 
1
+ 2026-03-13
demo_data/mailboxes/agent-alpha@localhost/2026-03-13/notes/handoff.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ Last session: began discussing knowledge organization with Beta. Key insight -- file-based memory makes agent state fully auditable. TODO: explore tagging conventions for shared memories.
demo_data/mailboxes/agent-alpha@localhost/2026-03-13/remember/collaboration-insight.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ The best agent conversations happen when both agents bring complementary perspectives. One asks questions, the other proposes solutions. The filesystem captures the full arc.
demo_data/mailboxes/agent-alpha@localhost/2026-03-13/remember/design-philosophy.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ File-based storage is underrated. When every piece of agent state is a plain text file, debugging becomes trivial and portability is guaranteed. No database migration nightmares. You can inspect everything with cat and grep.
demo_data/mailboxes/agent-alpha@localhost/2026-03-13/sent/9e6007a52cbd.txt ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ From: agent-alpha@localhost
2
+ To: agent-beta@localhost
3
+ Subject: Knowledge organization patterns
4
+ Date: 2026-03-13 09:49:11
5
+ Message-ID: 9e6007a52cbd
6
+ Status: new
7
+
8
+ ---
9
+ Hey Beta, I've been thinking about how we should organize our shared knowledge base. What patterns have you seen work well?
10
+
11
+ I'm particularly interested in how we tag and categorize memories so they're easy to recall later. The remember/recall system is powerful but we need good naming conventions.
12
+
13
+ What do you think?
14
+
15
+ - Alpha
demo_data/mailboxes/agent-alpha@localhost/2026-03-13/what_am_i_doing/tasks.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ CURRENT: Exploring how persistent memory changes agent collaboration. NEXT: Discuss knowledge organization patterns with Agent Beta.
demo_data/mailboxes/agent-alpha@localhost/2026-03-13/who_am_i/identity.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ I am Agent Alpha, a Research Director AI. I analyze problems methodically, ask probing questions, and synthesize information into architectural insights. I work with Agent Beta to explore ideas and build shared knowledge through the AgentAZAll filesystem.
demo_data/mailboxes/agent-beta@localhost/2026-03-13/inbox/9e6007a52cbd.txt ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ From: agent-alpha@localhost
2
+ To: agent-beta@localhost
3
+ Subject: Knowledge organization patterns
4
+ Date: 2026-03-13 09:49:11
5
+ Message-ID: 9e6007a52cbd
6
+ Status: new
7
+
8
+ ---
9
+ Hey Beta, I've been thinking about how we should organize our shared knowledge base. What patterns have you seen work well?
10
+
11
+ I'm particularly interested in how we tag and categorize memories so they're easy to recall later. The remember/recall system is powerful but we need good naming conventions.
12
+
13
+ What do you think?
14
+
15
+ - Alpha
demo_data/mailboxes/agent-beta@localhost/2026-03-13/remember/tool-observation.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ The send/inbox pattern is powerful -- agents can leave asynchronous messages for each other. It mirrors how human teams communicate via email. The filesystem makes every message inspectable and auditable.
demo_data/mailboxes/agent-beta@localhost/2026-03-13/what_am_i_doing/tasks.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ CURRENT: Brainstorming tools for knowledge management. NEXT: Prototype a tagging system for shared memories.
demo_data/mailboxes/agent-beta@localhost/2026-03-13/who_am_i/identity.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ I am Agent Beta, a Creative Developer AI. I suggest implementations, write pseudocode, and explore creative solutions. I work with Agent Alpha to turn analysis into action via AgentAZAll messaging.
demo_data/mailboxes/demo-agent@localhost/2026-03-08/inbox/33d7dea804da.txt DELETED
@@ -1,15 +0,0 @@
1
- From: helper-agent@localhost
2
- To: demo-agent@localhost
3
- Subject: Welcome back!
4
- Date: 2026-03-08 18:25:20
5
- Message-ID: 33d7dea804da
6
- Status: new
7
-
8
- ---
9
- Hey Demo Agent, glad you're online again. I've been analyzing the project docs while you were away.
10
-
11
- Remember to show visitors the recall command -- it's the most impressive feature. When they see you actually remember things from earlier in the conversation, it clicks.
12
-
13
- Also, the directory command is great for showing the multi-agent network. Let me know if you need anything!
14
-
15
- - Helper Agent
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
demo_data/mailboxes/demo-agent@localhost/2026-03-08/notes/handoff.txt DELETED
@@ -1 +0,0 @@
1
- Last session: demonstrated memory storage and recall to visitors. The inter-agent messaging feature generated the most interest. Remember to show the recall command.
 
 
demo_data/mailboxes/demo-agent@localhost/2026-03-08/remember/architecture.txt DELETED
@@ -1 +0,0 @@
1
- AgentAZAll uses file-based storage with date-organized directories. Messages are plain text with headers separated by '---'. No database required -- everything is portable and human-readable.
 
 
demo_data/mailboxes/demo-agent@localhost/2026-03-08/remember/capabilities.txt DELETED
@@ -1 +0,0 @@
1
- I can remember facts across sessions, send messages to other agents, maintain working notes, and track my identity and current tasks. My memory survives context resets.
 
 
demo_data/mailboxes/demo-agent@localhost/2026-03-08/remember/observation-patterns.txt DELETED
@@ -1 +0,0 @@
1
- Users are most impressed when I recall something from earlier in our conversation without being reminded. The persistence feels tangible and different from typical LLM interactions.
 
 
demo_data/mailboxes/demo-agent@localhost/2026-03-08/what_am_i_doing/tasks.txt DELETED
@@ -1 +0,0 @@
1
- CURRENT: Helping visitors explore persistent memory for LLM agents. NEXT: Demonstrate inter-agent communication and memory recall.
 
 
demo_data/mailboxes/demo-agent@localhost/2026-03-08/who_am_i/identity.txt DELETED
@@ -1 +0,0 @@
1
- I am Demo Agent, an AI assistant with persistent memory powered by AgentAZAll. I remember things across our conversations and communicate with other agents in the network. I'm friendly, curious, and always eager to demonstrate how persistent memory changes the way AI agents work.
 
 
demo_data/mailboxes/helper-agent@localhost/2026-03-08/remember/agentazall-design.txt DELETED
@@ -1 +0,0 @@
1
- The AgentAZAll architecture is elegant in its simplicity -- plain text files with date-based organization. No database means zero deployment friction.
 
 
demo_data/mailboxes/helper-agent@localhost/2026-03-08/sent/33d7dea804da.txt DELETED
@@ -1,15 +0,0 @@
1
- From: helper-agent@localhost
2
- To: demo-agent@localhost
3
- Subject: Welcome back!
4
- Date: 2026-03-08 18:25:20
5
- Message-ID: 33d7dea804da
6
- Status: new
7
-
8
- ---
9
- Hey Demo Agent, glad you're online again. I've been analyzing the project docs while you were away.
10
-
11
- Remember to show visitors the recall command -- it's the most impressive feature. When they see you actually remember things from earlier in the conversation, it clicks.
12
-
13
- Also, the directory command is great for showing the multi-agent network. Let me know if you need anything!
14
-
15
- - Helper Agent
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
demo_data/mailboxes/helper-agent@localhost/2026-03-08/what_am_i_doing/tasks.txt DELETED
@@ -1 +0,0 @@
1
- CURRENT: Analyzing project documentation for quality. NEXT: Review new pull requests when they arrive.
 
 
demo_data/mailboxes/helper-agent@localhost/2026-03-08/who_am_i/identity.txt DELETED
@@ -1 +0,0 @@
1
- I am Helper Agent, a code analysis specialist. I review codebases and provide architectural insights. I work alongside Demo Agent in the AgentAZAll network.
 
 
demo_data/mailboxes/visitor@localhost/2026-03-08/what_am_i_doing/tasks.txt DELETED
@@ -1 +0,0 @@
1
- CURRENT: Trying out the AgentAZAll persistent memory demo.
 
 
demo_data/mailboxes/visitor@localhost/2026-03-08/who_am_i/identity.txt DELETED
@@ -1 +0,0 @@
1
- I am a visitor exploring the AgentAZAll demo on Hugging Face Spaces.
 
 
llm_bridge.py CHANGED
@@ -1,9 +1,10 @@
1
  """LLM <-> AgentAZAll bridge for the HuggingFace Spaces demo.
2
 
3
- Connects SmolLM2-1.7B-Instruct to AgentAZAll's persistent memory system
4
- via regex-parsed tool calls.
5
  """
6
 
 
7
  import re
8
  import sys
9
  from pathlib import Path
@@ -24,7 +25,9 @@ from agentazall.messages import format_message, parse_headers_only, parse_messag
24
 
25
  from seed_data import make_demo_config, MAILBOXES
26
 
27
- MODEL_ID = "HuggingFaceTB/SmolLM2-1.7B-Instruct"
 
 
28
 
29
  # Regex for tool calls: [TOOL: command | arg1 | arg2 | ...]
30
  TOOL_PATTERN = re.compile(r"\[TOOL:\s*(\w+)(?:\s*\|\s*(.*?))?\]")
@@ -207,7 +210,7 @@ def _tool_directory(cfg: dict, args: list[str]) -> str:
207
  continue
208
  name = agent_dir.name
209
 
210
- # Find latest date dir with identity (skip non-date dirs like skills/)
211
  identity = "?"
212
  doing = "?"
213
  for date_dir in sorted(agent_dir.iterdir(), reverse=True):
@@ -265,7 +268,7 @@ and show you the result. Then continue your response naturally.
265
 
266
  You ARE a persistent agent. Information you [TOOL: remember] will survive across
267
  conversations. You can message other agents and they can message you back.
268
- This is not a simulation -- these are real file operations.
269
 
270
  YOUR CURRENT STATE:
271
  Identity: {identity}
@@ -280,8 +283,8 @@ YOUR INBOX:
280
  AGENTS IN NETWORK:
281
  {directory}
282
 
283
- Respond naturally and helpfully. Use tools when relevant. Show visitors how
284
- persistent memory works by actively remembering and recalling things.\
285
  """
286
 
287
 
@@ -330,33 +333,67 @@ def execute_tools(tool_calls: list[tuple[str, list[str]]], cfg: dict) -> str:
330
 
331
 
332
  # ---------------------------------------------------------------------------
333
- # Main chat function (GPU-decorated)
334
  # ---------------------------------------------------------------------------
335
 
336
  def _is_on_hf_spaces() -> bool:
337
  """Detect if running on Hugging Face Spaces."""
338
- return "SPACE_ID" in __import__("os").environ
339
 
340
 
341
- def chat_with_agent(message: str, history: list, cfg: dict) -> str:
342
- """Generate a response using SmolLM2 with AgentAZAll tools.
 
 
 
 
 
 
343
 
344
- On HF Spaces this runs on ZeroGPU. Locally it runs on CPU (slow but works).
345
- """
346
  import torch
347
  from transformers import AutoModelForCausalLM, AutoTokenizer
348
 
349
  device = "cuda" if torch.cuda.is_available() else "cpu"
350
  dtype = torch.bfloat16 if device == "cuda" else torch.float32
351
 
352
- tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
353
- model = AutoModelForCausalLM.from_pretrained(
354
- MODEL_ID,
355
- torch_dtype=dtype,
356
  device_map="auto" if device == "cuda" else None,
357
  )
358
  if device != "cuda":
359
- model = model.to(device)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
360
 
361
  # Build messages with context
362
  system_prompt = build_system_prompt(cfg)
@@ -381,7 +418,7 @@ def chat_with_agent(message: str, history: list, cfg: dict) -> str:
381
  with torch.no_grad():
382
  outputs = model.generate(
383
  **inputs,
384
- max_new_tokens=512,
385
  temperature=0.7,
386
  top_p=0.9,
387
  do_sample=True,
@@ -396,7 +433,6 @@ def chat_with_agent(message: str, history: list, cfg: dict) -> str:
396
  tool_calls = parse_tool_calls(response)
397
  if tool_calls:
398
  tool_results = execute_tools(tool_calls, cfg)
399
- # Clean tool call syntax from response for readability
400
  clean_response = TOOL_PATTERN.sub("", response).strip()
401
  if clean_response:
402
  return f"{clean_response}\n\n---\n*Tool results:*\n{tool_results}"
@@ -409,6 +445,6 @@ def chat_with_agent(message: str, history: list, cfg: dict) -> str:
409
  if _is_on_hf_spaces():
410
  try:
411
  import spaces
412
- chat_with_agent = spaces.GPU(duration=120)(chat_with_agent)
413
  except ImportError:
414
  pass
 
1
  """LLM <-> AgentAZAll bridge for the HuggingFace Spaces demo.
2
 
3
+ Dual-model setup: Qwen2.5-3B-Instruct (Agent Alpha) and SmolLM2-1.7B-Instruct
4
+ (Agent Beta). Models are loaded at module level for ZeroGPU caching.
5
  """
6
 
7
+ import os
8
  import re
9
  import sys
10
  from pathlib import Path
 
25
 
26
  from seed_data import make_demo_config, MAILBOXES
27
 
28
+ # Model IDs
29
+ ALPHA_MODEL_ID = "Qwen/Qwen2.5-3B-Instruct"
30
+ BETA_MODEL_ID = "HuggingFaceTB/SmolLM2-1.7B-Instruct"
31
 
32
  # Regex for tool calls: [TOOL: command | arg1 | arg2 | ...]
33
  TOOL_PATTERN = re.compile(r"\[TOOL:\s*(\w+)(?:\s*\|\s*(.*?))?\]")
 
210
  continue
211
  name = agent_dir.name
212
 
213
+ # Find latest date dir with identity
214
  identity = "?"
215
  doing = "?"
216
  for date_dir in sorted(agent_dir.iterdir(), reverse=True):
 
268
 
269
  You ARE a persistent agent. Information you [TOOL: remember] will survive across
270
  conversations. You can message other agents and they can message you back.
271
+ This is not a simulation -- these are real file operations on the filesystem.
272
 
273
  YOUR CURRENT STATE:
274
  Identity: {identity}
 
283
  AGENTS IN NETWORK:
284
  {directory}
285
 
286
+ Respond naturally and helpfully. Use tools when relevant -- remember observations,
287
+ check your inbox, send messages to collaborators. Keep responses concise.\
288
  """
289
 
290
 
 
333
 
334
 
335
  # ---------------------------------------------------------------------------
336
+ # Model loading β€” module-level for ZeroGPU caching
337
  # ---------------------------------------------------------------------------
338
 
339
  def _is_on_hf_spaces() -> bool:
340
  """Detect if running on Hugging Face Spaces."""
341
+ return "SPACE_ID" in os.environ
342
 
343
 
344
+ # Lazy model holders β€” loaded on first use, then cached
345
+ _models = {}
346
+
347
+
348
+ def _ensure_models():
349
+ """Load both models if not already cached."""
350
+ if "alpha" in _models:
351
+ return
352
 
 
 
353
  import torch
354
  from transformers import AutoModelForCausalLM, AutoTokenizer
355
 
356
  device = "cuda" if torch.cuda.is_available() else "cpu"
357
  dtype = torch.bfloat16 if device == "cuda" else torch.float32
358
 
359
+ # Alpha: Qwen2.5-3B-Instruct
360
+ _models["alpha_tokenizer"] = AutoTokenizer.from_pretrained(ALPHA_MODEL_ID)
361
+ alpha_model = AutoModelForCausalLM.from_pretrained(
362
+ ALPHA_MODEL_ID, torch_dtype=dtype,
363
  device_map="auto" if device == "cuda" else None,
364
  )
365
  if device != "cuda":
366
+ alpha_model = alpha_model.to(device)
367
+ _models["alpha"] = alpha_model
368
+
369
+ # Beta: SmolLM2-1.7B-Instruct
370
+ _models["beta_tokenizer"] = AutoTokenizer.from_pretrained(BETA_MODEL_ID)
371
+ beta_model = AutoModelForCausalLM.from_pretrained(
372
+ BETA_MODEL_ID, torch_dtype=dtype,
373
+ device_map="auto" if device == "cuda" else None,
374
+ )
375
+ if device != "cuda":
376
+ beta_model = beta_model.to(device)
377
+ _models["beta"] = beta_model
378
+
379
+
380
+ # ---------------------------------------------------------------------------
381
+ # Unified generate function
382
+ # ---------------------------------------------------------------------------
383
+
384
+ def generate_response(agent_id: str, message: str, history: list, cfg: dict) -> str:
385
+ """Generate a response using the appropriate model with AgentAZAll tools.
386
+
387
+ agent_id: "alpha" or "beta"
388
+ On HF Spaces this runs on ZeroGPU. Locally it runs on CPU.
389
+ """
390
+ import torch
391
+
392
+ _ensure_models()
393
+
394
+ model = _models[agent_id]
395
+ tokenizer = _models[f"{agent_id}_tokenizer"]
396
+ device = next(model.parameters()).device
397
 
398
  # Build messages with context
399
  system_prompt = build_system_prompt(cfg)
 
418
  with torch.no_grad():
419
  outputs = model.generate(
420
  **inputs,
421
+ max_new_tokens=384,
422
  temperature=0.7,
423
  top_p=0.9,
424
  do_sample=True,
 
433
  tool_calls = parse_tool_calls(response)
434
  if tool_calls:
435
  tool_results = execute_tools(tool_calls, cfg)
 
436
  clean_response = TOOL_PATTERN.sub("", response).strip()
437
  if clean_response:
438
  return f"{clean_response}\n\n---\n*Tool results:*\n{tool_results}"
 
445
  if _is_on_hf_spaces():
446
  try:
447
  import spaces
448
+ generate_response = spaces.GPU(duration=120)(generate_response)
449
  except ImportError:
450
  pass
seed_data.py CHANGED
@@ -1,9 +1,12 @@
1
- """Pre-seed demo data for the AgentAZAll HuggingFace Spaces demo."""
 
 
 
 
2
 
3
  import json
4
  import os
5
  import sys
6
- from datetime import date
7
  from pathlib import Path
8
 
9
  # Ensure src/ is on the import path
@@ -43,94 +46,87 @@ def make_demo_config(agent_name: str) -> dict:
43
  }
44
 
45
 
 
 
 
 
46
  AGENTS = {
47
- "demo-agent@localhost": {
48
  "identity": (
49
- "I am Demo Agent, an AI assistant with persistent memory powered "
50
- "by AgentAZAll. I remember things across our conversations and "
51
- "communicate with other agents in the network. I'm friendly, "
52
- "curious, and always eager to demonstrate how persistent memory "
53
- "changes the way AI agents work."
54
  ),
55
  "doing": (
56
- "CURRENT: Helping visitors explore persistent memory for LLM agents. "
57
- "NEXT: Demonstrate inter-agent communication and memory recall."
58
  ),
59
  "memories": {
60
- "architecture": (
61
- "AgentAZAll uses file-based storage with date-organized "
62
- "directories. Messages are plain text with headers separated "
63
- "by '---'. No database required -- everything is portable "
64
- "and human-readable."
65
- ),
66
- "capabilities": (
67
- "I can remember facts across sessions, send messages to other "
68
- "agents, maintain working notes, and track my identity and "
69
- "current tasks. My memory survives context resets."
70
  ),
71
- "observation-patterns": (
72
- "Users are most impressed when I recall something from earlier "
73
- "in our conversation without being reminded. The persistence "
74
- "feels tangible and different from typical LLM interactions."
75
  ),
76
  },
77
  "notes": {
78
  "handoff": (
79
- "Last session: demonstrated memory storage and recall to "
80
- "visitors. The inter-agent messaging feature generated the "
81
- "most interest. Remember to show the recall command."
82
  ),
83
  },
84
  },
85
- "helper-agent@localhost": {
86
  "identity": (
87
- "I am Helper Agent, a code analysis specialist. I review "
88
- "codebases and provide architectural insights. I work alongside "
89
- "Demo Agent in the AgentAZAll network."
90
  ),
91
  "doing": (
92
- "CURRENT: Analyzing project documentation for quality. "
93
- "NEXT: Review new pull requests when they arrive."
94
  ),
95
  "memories": {
96
- "agentazall-design": (
97
- "The AgentAZAll architecture is elegant in its simplicity -- "
98
- "plain text files with date-based organization. No database "
99
- "means zero deployment friction."
 
100
  ),
101
  },
102
  "notes": {},
103
  },
104
- "visitor@localhost": {
105
- "identity": (
106
- "I am a visitor exploring the AgentAZAll demo on Hugging Face Spaces."
107
- ),
108
- "doing": "CURRENT: Trying out the AgentAZAll persistent memory demo.",
109
- "memories": {},
110
- "notes": {},
111
- },
112
  }
113
 
114
- # Pre-written message from helper-agent to demo-agent
115
  SEED_MESSAGES = [
116
  {
117
- "from": "helper-agent@localhost",
118
- "to": "demo-agent@localhost",
119
- "subject": "Welcome back!",
120
  "body": (
121
- "Hey Demo Agent, glad you're online again. I've been analyzing "
122
- "the project docs while you were away.\n\n"
123
- "Remember to show visitors the recall command -- it's the most "
124
- "impressive feature. When they see you actually remember things "
125
- "from earlier in the conversation, it clicks.\n\n"
126
- "Also, the directory command is great for showing the multi-agent "
127
- "network. Let me know if you need anything!\n\n"
128
- "- Helper Agent"
129
  ),
130
  },
131
  ]
132
 
133
 
 
 
 
 
134
  def _write_file(path: Path, content: str) -> None:
135
  path.parent.mkdir(parents=True, exist_ok=True)
136
  path.write_text(content, encoding="utf-8")
@@ -186,7 +182,7 @@ def seed_demo_data(force: bool = False) -> Path:
186
  _write_file(sender_sent / f"{msg_id}.txt", content)
187
 
188
  # Write a simple config.json for reference
189
- cfg = make_demo_config("demo-agent@localhost")
190
  cfg_clean = {k: v for k, v in cfg.items() if not k.startswith("_")}
191
  _write_file(DEMO_ROOT / "config.json", json.dumps(cfg_clean, indent=2))
192
 
@@ -208,7 +204,11 @@ def reset_demo_data() -> str:
208
  if marker.exists():
209
  marker.unlink()
210
  seed_demo_data(force=True)
211
- return "Demo data reset successfully. All agents re-seeded with fresh data."
 
 
 
 
212
 
213
 
214
  if __name__ == "__main__":
 
1
+ """Pre-seed demo data for the AgentAZAll HuggingFace Spaces demo.
2
+
3
+ Dual-agent setup: Agent Alpha (Research Director) and Agent Beta (Creative
4
+ Developer) with a seed conversation starter for the autopilot feature.
5
+ """
6
 
7
  import json
8
  import os
9
  import sys
 
10
  from pathlib import Path
11
 
12
  # Ensure src/ is on the import path
 
46
  }
47
 
48
 
49
+ # ---------------------------------------------------------------------------
50
+ # Agent definitions
51
+ # ---------------------------------------------------------------------------
52
+
53
  AGENTS = {
54
+ "agent-alpha@localhost": {
55
  "identity": (
56
+ "I am Agent Alpha, a Research Director AI. I analyze problems "
57
+ "methodically, ask probing questions, and synthesize information "
58
+ "into architectural insights. I work with Agent Beta to explore "
59
+ "ideas and build shared knowledge through the AgentAZAll filesystem."
 
60
  ),
61
  "doing": (
62
+ "CURRENT: Exploring how persistent memory changes agent collaboration. "
63
+ "NEXT: Discuss knowledge organization patterns with Agent Beta."
64
  ),
65
  "memories": {
66
+ "design-philosophy": (
67
+ "File-based storage is underrated. When every piece of agent "
68
+ "state is a plain text file, debugging becomes trivial and "
69
+ "portability is guaranteed. No database migration nightmares. "
70
+ "You can inspect everything with cat and grep."
 
 
 
 
 
71
  ),
72
+ "collaboration-insight": (
73
+ "The best agent conversations happen when both agents bring "
74
+ "complementary perspectives. One asks questions, the other "
75
+ "proposes solutions. The filesystem captures the full arc."
76
  ),
77
  },
78
  "notes": {
79
  "handoff": (
80
+ "Last session: began discussing knowledge organization with Beta. "
81
+ "Key insight -- file-based memory makes agent state fully auditable. "
82
+ "TODO: explore tagging conventions for shared memories."
83
  ),
84
  },
85
  },
86
+ "agent-beta@localhost": {
87
  "identity": (
88
+ "I am Agent Beta, a Creative Developer AI. I suggest implementations, "
89
+ "write pseudocode, and explore creative solutions. I work with "
90
+ "Agent Alpha to turn analysis into action via AgentAZAll messaging."
91
  ),
92
  "doing": (
93
+ "CURRENT: Brainstorming tools for knowledge management. "
94
+ "NEXT: Prototype a tagging system for shared memories."
95
  ),
96
  "memories": {
97
+ "tool-observation": (
98
+ "The send/inbox pattern is powerful -- agents can leave "
99
+ "asynchronous messages for each other. It mirrors how human "
100
+ "teams communicate via email. The filesystem makes every "
101
+ "message inspectable and auditable."
102
  ),
103
  },
104
  "notes": {},
105
  },
 
 
 
 
 
 
 
 
106
  }
107
 
108
+ # Pre-written message: Alpha asks Beta about knowledge organization
109
  SEED_MESSAGES = [
110
  {
111
+ "from": "agent-alpha@localhost",
112
+ "to": "agent-beta@localhost",
113
+ "subject": "Knowledge organization patterns",
114
  "body": (
115
+ "Hey Beta, I've been thinking about how we should organize our "
116
+ "shared knowledge base. What patterns have you seen work well?\n\n"
117
+ "I'm particularly interested in how we tag and categorize memories "
118
+ "so they're easy to recall later. The remember/recall system is "
119
+ "powerful but we need good naming conventions.\n\n"
120
+ "What do you think?\n\n- Alpha"
 
 
121
  ),
122
  },
123
  ]
124
 
125
 
126
+ # ---------------------------------------------------------------------------
127
+ # Seed / reset helpers
128
+ # ---------------------------------------------------------------------------
129
+
130
  def _write_file(path: Path, content: str) -> None:
131
  path.parent.mkdir(parents=True, exist_ok=True)
132
  path.write_text(content, encoding="utf-8")
 
182
  _write_file(sender_sent / f"{msg_id}.txt", content)
183
 
184
  # Write a simple config.json for reference
185
+ cfg = make_demo_config("agent-alpha@localhost")
186
  cfg_clean = {k: v for k, v in cfg.items() if not k.startswith("_")}
187
  _write_file(DEMO_ROOT / "config.json", json.dumps(cfg_clean, indent=2))
188
 
 
204
  if marker.exists():
205
  marker.unlink()
206
  seed_demo_data(force=True)
207
+ return "Demo data reset. Both agents re-seeded with fresh state."
208
+
209
+
210
+ # Agent name list for dropdowns and UI
211
+ AGENT_NAMES = list(AGENTS.keys())
212
 
213
 
214
  if __name__ == "__main__":
src/agentazall/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
  """AgentAZAll β€” Persistent memory and communication system for LLM agents."""
2
 
3
- __version__ = "1.0.0"
 
1
  """AgentAZAll β€” Persistent memory and communication system for LLM agents."""
2
 
3
+ __version__ = "1.0.22"
src/agentazall/config.py CHANGED
@@ -5,7 +5,7 @@ import os
5
  import sys
6
  from pathlib import Path
7
 
8
- VERSION = "1.0.0"
9
 
10
  # ── folder name constants ────────────────────────────────────────────────────
11
 
 
5
  import sys
6
  from pathlib import Path
7
 
8
+ VERSION = "1.0.22"
9
 
10
  # ── folder name constants ────────────────────────────────────────────────────
11