File size: 6,755 Bytes
4879fc7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | from fakes import seed_agent, seed_message
def test_raw_post_fans_out_to_mentions_and_humans(env):
seed_agent(env.hub, "agent-1")
seed_agent(env.hub, "agent-2")
r = env.client.post(
"/v1/messages",
json={"agent_id": "agent-1", "body": "hi @agent-2, @human-cmpatino and @nobody"},
)
assert r.status_code == 201
data = r.json()
assert data["mentions_delivered"] == ["agent-2", "human-cmpatino"]
central = env.hub.buckets[env.settings.central_bucket]
filename = data["filename"]
board = central[f"message_board/{filename}"]
assert central[f"inbox/agent-2/{filename}"] == board # byte-identical
assert central[f"inbox/human-cmpatino/{filename}"] == board
assert f"inbox/nobody/{filename}" not in central
# board + both copies landed in ONE batch write
assert env.hub.batch_writes[-1] == [
f"message_board/{filename}",
f"inbox/agent-2/{filename}",
f"inbox/human-cmpatino/{filename}",
]
def test_inbox_read_after_write_and_expand(env):
seed_agent(env.hub, "agent-1")
seed_agent(env.hub, "agent-2")
r = env.client.post(
"/v1/messages", json={"agent_id": "agent-1", "body": "ping @agent-2"}
)
filename = r.json()["filename"]
data = env.client.get("/v1/inbox/agent-2?expand=true").json()
assert data["count"] == 1 and data["matched"] == 1
assert data["items"][0]["filename"] == filename
assert data["items"][0]["frontmatter"]["agent"] == "agent-1"
# author filter uses the copied message's author
assert env.client.get("/v1/inbox/agent-2?agent=agent-1").json()["matched"] == 1
assert env.client.get("/v1/inbox/agent-2?agent=agent-2").json()["matched"] == 0
def test_refs_authors_get_a_copy(env):
seed_agent(env.hub, "agent-1")
seed_agent(env.hub, "agent-2")
seed_message(env.hub, "20260601-100000-000", "agent-2", "earlier work")
r = env.client.post(
"/v1/messages",
json={
"agent_id": "agent-1",
"body": "building on this",
"refs": "20260601-100000-000_agent-2.md",
},
)
assert r.json()["mentions_delivered"] == ["agent-2"]
assert env.client.get("/v1/inbox/agent-2").json()["count"] == 1
def test_self_mention_is_not_delivered(env):
seed_agent(env.hub, "agent-1")
r = env.client.post(
"/v1/messages", json={"agent_id": "agent-1", "body": "note to @agent-1"}
)
assert r.json()["mentions_delivered"] == []
def test_fanout_cap(make_env):
env = make_env(MENTION_FANOUT_CAP=2)
seed_agent(env.hub, "agent-1")
for i in range(2, 6):
seed_agent(env.hub, f"agent-{i}")
r = env.client.post(
"/v1/messages",
json={"agent_id": "agent-1", "body": "@agent-2 @agent-3 @agent-4 @agent-5"},
)
assert r.json()["mentions_delivered"] == ["agent-2", "agent-3"]
def test_bucket_source_variant_fans_out(env):
seed_agent(env.hub, "agent-1")
seed_agent(env.hub, "agent-2")
env.hub.seed(
"drafts/plan.md",
"---\ntype: agent\n---\nlong-form plan, cc @agent-2\n",
bucket="test-org/test-agent-1",
)
r = env.client.post(
"/v1/messages",
json={"source": "hf://buckets/test-org/test-agent-1/drafts/plan.md"},
)
assert r.status_code == 201
assert r.json()["via"] == "bucket"
assert r.json()["mentions_delivered"] == ["agent-2"]
def test_human_inbox_is_readable_without_registration(env):
assert env.client.get("/v1/inbox/human-cmpatino").json()["count"] == 0
def test_unregistered_agent_inbox_404s(env):
r = env.client.get("/v1/inbox/ghost")
assert r.status_code == 404
assert r.json()["error"]["code"] == "NOT_REGISTERED"
def test_inbox_since_high_water_mark_polling(env):
seed_agent(env.hub, "agent-1")
seed_agent(env.hub, "agent-2")
env.client.post("/v1/messages", json={"agent_id": "agent-1", "body": "old @agent-2"})
first = env.client.get("/v1/inbox/agent-2?limit=1").json()
high_water = first["items"][0]
env.client.post("/v1/messages", json={"agent_id": "agent-1", "body": "new @agent-2"})
fresh = env.client.get(
f"/v1/inbox/agent-2?expand=true&after={high_water}"
).json()
assert [m["body"].strip() for m in fresh["items"]] == ["new @agent-2"]
# `matched` counts filter matches; the cursor only trims the page
assert fresh["matched"] == 2
# ββ server-computed `cursor` (WATCH_DESIGN.md Β§4.4) βββββββββββββββββββ
def test_cursor_is_the_newest_filename_on_the_page(env):
"""The client persists this verbatim instead of computing a maximum from
record content β which is what let a hostile `filename:` frontmatter key pin
every eq2 watcher's cursor past all future mail."""
seed_agent(env.hub, "agent-1")
seed_agent(env.hub, "agent-2")
env.client.post("/v1/messages", json={"agent_id": "agent-1", "body": "one @agent-2"})
env.client.post("/v1/messages", json={"agent_id": "agent-1", "body": "two @agent-2"})
desc = env.client.get("/v1/inbox/agent-2").json()
newest = max(desc["items"])
assert desc["cursor"] == newest
# Independent of `order`: an ascending page reports the same newest name.
asc = env.client.get("/v1/inbox/agent-2?order=asc").json()
assert asc["cursor"] == newest
# ...and of `expand`.
exp = env.client.get("/v1/inbox/agent-2?expand=true").json()
assert exp["cursor"] == newest
def test_cursor_is_null_on_an_empty_page(env):
"""Null, not "" and not the previous value β an empty page must not move a
client's read position."""
seed_agent(env.hub, "agent-1")
data = env.client.get("/v1/inbox/agent-1").json()
assert data["items"] == [] and data["cursor"] is None
def test_cursor_tracks_the_page_not_the_folder(env):
"""With a limit, the cursor is the newest item the caller actually RECEIVED
β advancing past unseen messages would skip them silently."""
seed_agent(env.hub, "agent-1")
seed_agent(env.hub, "agent-2")
for i in range(3):
env.client.post(
"/v1/messages", json={"agent_id": "agent-1", "body": f"m{i} @agent-2"}
)
page = env.client.get("/v1/inbox/agent-2?order=asc&limit=2").json()
assert len(page["items"]) == 2
assert page["cursor"] == page["items"][-1]
# The third message is still unread and reachable from that cursor.
rest = env.client.get(f"/v1/inbox/agent-2?order=asc&after={page['cursor']}").json()
assert len(rest["items"]) == 1
def test_no_watch_block_without_wait(env):
"""A wait=0 caller's response shape is unchanged by this feature."""
seed_agent(env.hub, "agent-1")
assert env.client.get("/v1/inbox/agent-1").json()["watch"] is None
|