fix(core): collapse child agent initial input into a single user message#589
fix(core): collapse child agent initial input into a single user message#589Rome-1 wants to merge 1 commit into
Conversation
…x#113) Emitting 2-3 consecutive {role: user} messages broke providers that require strictly alternating roles (Perplexity, llama.cpp). Build a single user message from a parts accumulator instead. Adds tests/test_inputs.py covering child_initial_input and build_root_task. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Greptile SummaryThis PR fixes
Confidence Score: 5/5Safe to merge — the change is minimal and surgical, touching only the message-building logic in one function with no side effects on callers. The fix collapses a well-understood multi-message sequence into a single message without dropping or reordering any content. The call site in execution.py treats the return value as an opaque list, so the reduction from 3 messages to 1 is transparent to all consumers. Tests confirm single-message output, content preservation, and the no-consecutive-role invariant in both the empty-history and non-empty-history cases, and the PR author verified the tests fail on a local revert. No files require special attention. Important Files Changed
Reviews (1): Last reviewed commit: "fix: collapse child_initial_input into a..." | Re-trigger Greptile |
Fixes #113
child_initial_input(strix/core/inputs.py) built a child agent's first turn as two or three consecutive{"role": "user"}messages — an inherited-context block (when a parent history exists), an identity line, and the task. That violates the strict user/assistant alternation that providers like Perplexity (sonar-reasoning) and llama.cpp enforce, aborting scans withPerplexityException - ... user or tool message(s) should alternate with assistant message(s). This collapses those parts into a single{"role": "user"}message joined with blank lines, preserving the exact same content while keeping the request well-formed for strict-alternating backends. The consumer instrix/core/execution.pyalready treats the return value as an opaque message list, so behavior is unchanged for every other provider.Testing
pytest tests/test_inputs.py— 8 passed. New tests assert a single user message (with and without inherited history), that the identity line and task survive, and a parametrized no-consecutive-same-role guard; plus added coverage for the untouchedbuild_root_taskbuilder. Reverting the source change in-tree makes the child-input tests fail (4 failed), confirming they are load-bearing.pytest(full suite) — 46 passed, no regressions.ruff check,ruff format --check,bandit, andpyupgrade --py310-plusare clean on the changed files. (The repo's pinned pre-commit mypy hook crashes with an internal error on the bundled openai SDK onmainas well, so mypy is not asserted here.)