feat: inject the human conversation into every agent prompt #22
No reviewers
Labels
No labels
agent
coordinate
agent
dev
agent
plan
agent
reflect
agent
test
agent
triage
ai/off
blocked
night
blocked
usage
loop
1
loop
2
loop
3
needs/approval
needs/human
needs/input
needs/review
plan/approved
run/night
state
blocked
state
building
state
passed
state
planning
state
testing
tier
fable
tier
haiku
tier
local
tier
opus
tier
sonnet
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
valssi-public/agent-workflows!22
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/comment-context-injection"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #21.
The bug
No agent route read a single human-authored comment.
.title+.body— nothing else (plan.yaml:61-75)dev.yaml:94-134)git diff --stat(test.yaml:73-102).title+.body(coordinate.yaml:60-75)So re-triggering an agent re-ran a byte-identical prompt. The comment written to redirect it was never in context, and it produced the same answer again. On valssi-ai/development-container#15 that gave three near-identical plans and made course correction impossible.
The fix
New
lib/threadcomposite action renders the human side of an issue or PR thread to a file the route pastes into its prompt:<!-- agent-state -->/<!-- agent-digest -->dropped entirelyWired into all four model-using routes, with the thread last in the prompt and an explicit instruction that later comments override earlier ones, the approved plan, and the test findings — a human asking for something different outranks all of them.
Two extras that fall out of the same problem:
**What changed:**line — rather than a fresh derivation. This is what stops the duplicate-plan pile-up on #15.Safety
Fails safe throughout. An API error, an empty thread, or a bot-only thread all yield an empty file and
has-human=false; the route omits the block and runs exactly as before. The action never fails the job.Bot logins are matched exactly (
claude-plan,claude-dev) — an early draft used jq'sinside, which does substring matching and would have misclassified a human whose login is a substring of a bot's as an agent.No new triggers, no new permissions, no cost change: the same label re-trigger, now with the conversation in context.
Testing
Ran against a fixture reproducing the real #15 thread (3 plan comments, 1 state comment, 2 human comments, 1 bot notice, plus a human login that is a substring of a bot login):
bash -nclean across all 16run:blocks; all touched YAML parseshas_human=falsewithout crashing…[truncated]markerNot yet exercised against the live Forgejo API — the first real run will be the planner on #15 or on this repo.
Follow-ups (not in this PR)
@mentionre-fire a route directly, so steering does not need a label round-trip. The plumbing is already half-built —caller-agent.yaml:15forwardsissue_commentevents today anddispatch.yamlhas no job that matches them.needs/inputlabel.🤖 Generated with Claude Code