Conversation on the new loop (M2.7)
- Questions never change state (L5, #77): a message ending in "?" to a waiting project item starts a question run (reply and look-only tools, an instruction to change nothing), and the item goes back to the very wait it was in: a restatement up stays up and a go binds to it; the agent's own question stays open. - Explanations: a restatement gives its reasons and the main alternative; a revision says what changed (restate(changed), sent back without it); a milestone's summary says what was done, verified and left open. - Progress in prose (#42): the driver's and a helper's own words for a turn are posted, trimmed, at most once a minute per item; `details` shows the last tool calls; a message arriving mid-run is acknowledged at once ("Noted; ..."). - CI: the e2e job's comments and the plan no longer claim a newer push cancels the run it supersedes (Gitea here doesn't); the concurrency block goes. Tests: conversation unit tests (questions in a go-ahead and an answer wait, an unanswerable question, revisions, progress rate and trimming, details, mid-run notes), the helper's progress, the walk asking questions in every state with a questions_change_nothing property (routing questions the old way fails 32 of 48 seeds), and an e2e question while a restatement is up. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPQ14L3LikyefCMFBqEbKE
This commit is contained in:
1 parent
5967d022b6
commit
8994b3fb4b
14 files changed
+456
-30
No files matched your search
@@ -634,3 +634,35 @@ def test_a_conversation_becomes_a_new_project(
|
||||
]
|
||||
assert "ARCHITECTURE.md" in files, files
|
||||
assert any(f.startswith("docs/plans/") for f in files), files
|
||||
|
||||
|
||||
def test_a_question_leaves_the_restatement_up(
|
||||
running: tuple[RunningLoop, InMemoryTransport, str],
|
||||
) -> None:
|
||||
"""M2.7: a question while a restatement is up is answered, and changes
|
||||
nothing: the same revision stays up, and a go binds to it."""
|
||||
agent, transport, run = running
|
||||
operator = Operator(agent, transport)
|
||||
repo = agent.config.gitea_repo
|
||||
as_operator = operator_gitea(agent.config.gitea_url)
|
||||
issues: list[int] = []
|
||||
try:
|
||||
issues.append(as_operator.create_issue(repo, f"vowels_{run}", task(run)))
|
||||
as_operator._request(
|
||||
"PATCH",
|
||||
f"/repos/{repo}/issues/{issues[0]}",
|
||||
json={"assignees": [agent.account]},
|
||||
)
|
||||
operator.tick()
|
||||
item = operator.drive_until(GO_AHEAD, issues[0])
|
||||
rev = loop_of(item).rev
|
||||
said = len(transport.outbound)
|
||||
operator.say("Why put it in that module rather than a new one?", issues[0])
|
||||
answer = [m.text for m in transport.outbound[said:]]
|
||||
assert answer and not answer[-1].startswith("rev-"), answer
|
||||
loop = loop_of(operator.item(issues[0]))
|
||||
assert (loop.wait, loop.rev) == (GO_AHEAD, rev), loop
|
||||
operator.say("go", issues[0])
|
||||
assert loop_of(operator.item(issues[0])).started
|
||||
finally:
|
||||
operator.tidy(issues, [])
|
||||
Reference in new issue
Block a user