Spaces:
Running on Zero
Running on Zero
File size: 5,777 Bytes
ba6dd5f 0b0d9be ba6dd5f f6566bb ba6dd5f | 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 | """ContextBuilder — the shared blackboard reaches the prompt (ADR-0023).
Before this, an agent saw only the world text and its own past lines, so small
models looped on one clue and never reacted to anyone. The builder now surfaces
``projection.agent_notes`` (peers' public lines) so the table is actually shared.
"""
from __future__ import annotations
from src.core.context import ContextBuilder
from src.core.projections import StageProjection
def test_blackboard_surfaces_peer_lines():
proj = StageProjection(goal="g", current_scene="scene")
proj.agent_notes = ["spy-cara: a morning fuel", "spy-nil: warm and comforting"]
prompt = ContextBuilder().build(agent_name="spy-bex", persona="(bex)", projection=proj, all_events=())
assert "WHAT'S BEEN SAID" in prompt
assert "a morning fuel" in prompt
assert "warm and comforting" in prompt
# nudges toward a fresh contribution, not an echo
assert "new angle" in prompt.lower() and "echo" in prompt.lower()
def test_blackboard_prompts_the_first_speaker_to_open():
proj = StageProjection(goal="g", current_scene="scene") # no notes yet
prompt = ContextBuilder().build(agent_name="spy-cara", persona="(cara)", projection=proj, all_events=())
assert "WHAT'S BEEN SAID" in prompt
assert "you go first" in prompt.lower()
def test_persona_and_goal_still_lead():
proj = StageProjection(goal="catch the spy", current_scene="scene")
prompt = ContextBuilder().build(agent_name="a", persona="I am A.", projection=proj, all_events=())
# IDENTITY and SHARED GOAL must still come before the blackboard.
assert prompt.index("I am A.") < prompt.index("catch the spy") < prompt.index("WHAT'S BEEN SAID")
def _spoke(actor, text, turn=1, kind="agent.spoke"):
from src.core.events import Event
return Event(run_id="r", turn=turn, kind=kind, actor=actor, payload={"text": text})
def test_judge_gets_the_full_ordered_transcript_not_just_the_tail():
# A judge rules on the WHOLE discussion — every spoken line, in order — not the
# recency-biased blackboard tail a worker reacts to (ADR-0023 follow-up).
events = tuple(_spoke("debater-a" if i % 2 == 0 else "debater-b", f"point number {i}", turn=i) for i in range(12))
proj = StageProjection(goal="g", current_scene="scene")
prompt = ContextBuilder().build(
agent_name="debate-judge", persona="(judge)", projection=proj, all_events=events, role="judge"
)
assert "THE EXCHANGE TO JUDGE" in prompt and "WHAT'S BEEN SAID" not in prompt
# every line is present, oldest first
assert "point number 0" in prompt and "point number 11" in prompt
assert prompt.index("point number 0") < prompt.index("point number 11")
def test_judge_transcript_excludes_private_thoughts():
# Thoughts are the mind-reader's alone; a judge rules on what was SAID.
events = (_spoke("a", "said aloud"), _spoke("b", "secret scheming", kind="agent.thought"))
prompt = ContextBuilder().build(
agent_name="j",
persona="(judge)",
projection=StageProjection(current_scene="s"),
all_events=events,
role="judge",
)
assert "said aloud" in prompt
assert "secret scheming" not in prompt
def test_worker_gets_blackboard_not_transcript():
proj = StageProjection(current_scene="scene")
proj.agent_notes = ["a: hello there"]
prompt = ContextBuilder().build(
agent_name="w", persona="(w)", projection=proj, all_events=(_spoke("a", "hello there"),), role="worker"
)
assert "WHAT'S BEEN SAID" in prompt and "THE EXCHANGE TO JUDGE" not in prompt
def test_memory_does_not_repeat_a_line_already_in_the_discussion():
# A spoken line shown in the blackboard must not be printed again in YOUR MEMORY:
# the union is unchanged, we just don't duplicate (blackboard=recent, memory=earlier).
proj = StageProjection(current_scene="scene")
proj.agent_notes = ["a: the bench needs shade"]
memory_text = "[turn 003][agent.spoke] the bench needs shade\n[turn 001][world.observed] an older beat"
prompt = ContextBuilder().build(
agent_name="w", persona="(w)", projection=proj, all_events=(), memory_text=memory_text, role="worker"
)
# the duplicated line appears once (in the blackboard), the unique earlier beat survives in memory
assert prompt.count("the bench needs shade") == 1
assert "an older beat" in prompt
def test_memory_shows_a_pointer_when_fully_covered_by_the_discussion():
proj = StageProjection(current_scene="scene")
proj.agent_notes = ["a: only line"]
prompt = ContextBuilder().build(
agent_name="w",
persona="(w)",
projection=proj,
all_events=(),
memory_text="[turn 003][agent.spoke] only line",
role="worker",
)
assert "nothing beyond the exchange above" in prompt
def test_a_peer_thought_never_reaches_another_agent():
# A spoken event carries a private `thought` (the mind-reader content). It must
# ride only on its own payload — peers see the public `text`, never the thought.
from src.core.events import Event
proj = StageProjection(goal="g", current_scene="scene")
proj.apply(
Event(
run_id="r",
turn=1,
kind="agent.spoke",
actor="spy-nil",
payload={"text": "warm and comforting", "thought": "I'm the spy — keep it vague!"},
)
)
assert any("warm and comforting" in n for n in proj.agent_notes)
assert not any("spy" in n.lower() and "vague" in n.lower() for n in proj.agent_notes)
prompt = ContextBuilder().build(agent_name="spy-bex", persona="(bex)", projection=proj, all_events=())
assert "warm and comforting" in prompt
assert "keep it vague" not in prompt
|