Files
nisse/nisse-dev/src/nisse_dev/loop/tools.py
T
dongarandClaude Opus 5.5 ecff719f1a
CI / checks (push) Skipped
CI / checks (pull_request) Successful in 2m5s
CI / e2e (pull_request) Successful in 3m30s
M7.4: nisse-dev answers a peer
Anyone's comment on an item's PR but an operator's (and its own) is a
peer's point (D5, L11): kept on the item with an id, in the transcript as
a `peer` message labelled with its author, and never an instruction. The
driver answers each with answer_peer, inline on its line or quoting it,
or skips it with skip_peer and a recorded reason. A run going back to
waiting with points open is reminded once; then the harness lists them
on the PR. A peer's comment wakes the item; a wake by peers alone goes
back to the same wait quietly, with one line in the thread. The
operator's inline comments are now answered inline too.

Also corrects ci.yml's header: a push to main runs no end-to-end tests.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01J5Utyfzw7gF7UhjRDEtjTk
2026-10-16 19:42:19 +00:00

141 lines
5.5 KiB
Python

"""nisse-dev's control tools (L13), beside the ones any agent offers
(``nisse_core.loop.tools``): handled in the harness, acting only on the agent's
own state, conversation and records. A *waiting* tool ends the driver's run:
the item then waits on the operator."""
from nisse_core.loop.tools import tool as _tool
RESTATE = _tool(
"restate",
"Put your understanding of the request to the operator, in their item's "
"thread: what you take it to mean, how it fits the project, your first "
"step, and why that way (and the main alternative you considered). Ends "
"your turn; work starts when they agree.",
text="Your restatement, in plain language.",
changed="What changed from your previous restatement, and why; leave it "
"empty for the first.",
)
ASK_HUMAN = _tool(
"ask_human",
"Ask the operator a question in the item's thread. Ends your turn; you "
"continue when they answer.",
question="The question.",
)
CLOSE_ITEM = _tool(
"close_item",
"The work is done: close the work item with a summary of what was done, "
"what was verified, and what is left open.",
summary="What was done, verified, and left open.",
)
START_MILESTONE = _tool(
"start_milestone",
"Start a milestone before changing code: the harness cuts its branch. "
"Never create or switch branches yourself.",
name="A short name for the milestone.",
)
FINISH_MILESTONE = _tool(
"finish_milestone",
"The milestone's work is done and its tests pass: the harness commits "
"the work, pushes it and opens a PR, or, after review comments, pushes "
"your fix to the PR. Ends your turn; you continue when the PR is "
"reviewed or merged.",
summary="What the milestone did and how it was verified, for the PR.",
title="A short title for the PR (ignored when pushing a review fix).",
final="yes if this milestone completes the issue, no if more milestones follow it.",
)
WAIT_FOR_REVIEW = _tool(
"wait_for_review",
"Nothing more to do until the operator reviews or merges the PR (you "
"can't merge it yourself): say so and wait. You continue when there's a "
"new comment, or when it merges or closes.",
note="What you're waiting on, for the operator.",
)
# A peer's points on the PR (D5): anyone's comment but an operator's. Not
# waiting tools: the run goes on.
ANSWER_PEER = _tool(
"answer_peer",
"Answer one of a peer's points on the PR, where it was made: what you "
"changed (or will change in this push), or why you disagree. Posted at "
"once.",
point="The point's id, like P2.",
reply="Your answer, in plain language.",
)
SKIP_PEER = _tool(
"skip_peer",
"A peer's point needs no reply (an automated notice, say): mark it "
"answered without posting anything. The reason is recorded for the "
"operator.",
point="The point's id, like P2.",
reason="Why it needs no reply.",
)
TOOLCHAIN_STEP = _tool(
"toolchain_step",
"The work needs a toolchain change (a new tool, library or version): a "
"step that installs it on the build VM and brings the project's pins, "
"setup docs and CI configuration in step. Its edits are part of the "
"current work. Returns its report.",
reason="What the work needs, and why.",
)
REQUEST_REIMAGE = _tool(
"request_reimage",
"The build VM seems broken beyond the usual fixes (reinstalling "
"dependencies, a toolchain_step): ask for it to be reimaged from its "
"template rather than diagnosing it further. Anything not pushed on it is "
"lost. Ends your turn; the project waits until the operator says the VM "
"is ready, and it is set up again from the repository first.",
reason="What is broken, and what you tried.",
)
# A conversation's tools (L1, L5): it talks, and may propose work.
REPLY = _tool(
"reply",
"Answer the operator in the conversation's thread. Ends your turn; you "
"continue when they say more.",
text="Your answer, in plain language.",
)
PROPOSE_WORK = _tool(
"propose_work",
"The conversation has turned into work on one of the projects: propose "
"an issue for it. The operator agrees to it as to a restatement; then the "
"issue is opened, and work on it starts as its own item. Ends your turn.",
project="The project's name, from the list in your instructions.",
title="A short title for the issue.",
summary="What was decided, distilled: the request, what it means, and the "
"first step. Not the conversation; it is the issue's body and the work's "
"whole brief.",
)
PROPOSE_PROJECT = _tool(
"propose_project",
"The conversation has become a new project: propose it. The operator "
"agrees to it as to a restatement; then you list what it needs set up "
"(a repository, a build VM, the project's entry), and once it is ready "
"and checked, the project's architecture is your first piece of work. "
"Ends your turn.",
name="The project's name: lowercase letters, digits and -.",
purpose="What it is for, in a paragraph.",
decisions="The decisions setting it up depends on: language and toolchain "
"(which pick the build VM), services, secrets, network access beyond the "
"default; and anything else agreed so far.",
)
WAITING_TOOLS = frozenset(
{
"restate",
"ask_human",
"close_item",
"finish_milestone",
"wait_for_review",
"reply",
"propose_work",
"propose_project",
"toolchain_ready",
"request_reimage",
"memory_done",
}
)