Repository navigation
fix(session): interview must ask via the question tool, not prose - #37
Merged
Merged
Conversation
The Amico pulse-designer interview asks each question via the native `question`
tool, which renders the clickable answer card. Models intermittently drift and
ask in PLAIN PROSE instead ("What's your qubit frequency and do you want 3 or 4
levels?"), which renders no card — the user has nothing to click and the
interview stalls. Prompt hardening in AGENTS.md alone did not hold (LLM
tool-use adherence is probabilistic), so this enforces it in the turn loop.
Guard in the session prompt loop: when a turn is about to exit (assistant
finished, no tool calls) AND
- an Amico interview is active (the session has used any `amicode_*` tool), AND
- this turn made NO `question` tool call, AND
- the assistant's final text ends with "?" (a question to the user),
inject a synthetic system nudge ("re-ask via the question tool") and continue
the loop instead of exiting, forcing the model to re-emit the question as a
card. Idempotent: an in-memory Set of nudged assistant-message IDs fires the
nudge at most once per message (the Assistant info schema has no metadata field
to persist a flag on), so a stubborn turn cannot loop forever — after one nudge
it exits normally.
Scope: only fires inside an active amicode interview; ordinary agent turns that
happen to end in a question (e.g. a build agent asking for clarification) are
unaffected because they haven't used amicode_* tools.
typecheck (tsgo --noEmit): clean. Built the darwin-arm64 binary and verified
the interview re-asks via the tool in the local dev host.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The Amico pulse-designer interview asks each question via the native
questiontool, which renders the clickable answer card. Models intermittently drift and ask in plain prose instead — e.g.:That renders no card, so the user has nothing to click and the interview stalls. Reported repeatedly. Prompt hardening in AGENTS.md alone did not hold — LLM tool-use adherence is probabilistic — so this enforces the contract in the turn loop.
Fix
In the session prompt loop, when a turn is about to exit (assistant finished, no tool calls) and:
amicode_*tool), andquestiontool call, and?(a question to the user),…inject a synthetic system nudge ("re-ask via the question tool") and continue the loop instead of exiting — forcing the model to re-emit the question as a card.
Idempotent: an in-memory
Setof nudged assistant-message IDs fires the nudge at most once per message (theAssistantinfo schema has no metadata field to persist a flag on), so a stubborn turn cannot loop forever — after one nudge it exits normally.Scope: only fires inside an active amicode interview. Ordinary agent turns that happen to end in a question (e.g. a build agent asking for clarification) are unaffected — they haven't used
amicode_*tools.Testing
tsgo --noEmit: cleanFollow-up
Once merged, cut a fork release so the amicode extension's vendored binary (
opencode.lock.json) can bump to it — the fix ships to users via that pin, not this branch directly.