Display ingredient table in fleet campaign sessions#2203
Conversation
…in fleet campaign sessions The ingredient table was injected into the system prompt but Claude was never instructed to display it to the user. A shared helper `_ingredient_table_display_instruction(source)` in _prompts.py encapsulates the display-verbatim instruction. The campaign path (_prompts_campaign.py) now uses it in a FIRST ACTION block; the orchestrator path (_prompts_orchestrator.py) refactors inline step 2 text to use the helper for wording sync. K-16 tests added to test_l3_orchestrator_prompt.py. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Trecek
left a comment
There was a problem hiding this comment.
AutoSkillit PR Review — Verdict: approved_with_comments
| "via AskUserQuestion. Do not dispatch until all required values are confirmed.\n" | ||
| ) | ||
|
|
||
| _first_action_section = "" |
There was a problem hiding this comment.
[warning] cohesion: Local variable _display at L208 is a one-shot intermediate with no reuse but follows the private-underscore convention inconsistently — other section variables like _first_action_section and _ing_section are multi-line builders, while _display is a single-call result. Inline it into _first_action_section to remove the unnecessary intermediate and make the structure symmetric.
| assert overview_pos < ingredients_pos < manifest_pos | ||
|
|
||
|
|
||
| class TestK16IngredientDisplayFirstAction: |
There was a problem hiding this comment.
[info] cohesion: TestK16IngredientDisplayFirstAction tests the fleet campaign prompt (checks DISPATCH MANIFEST, calls _build with ingredients_table), but lives in test_l3_orchestrator_prompt.py. This is a feature locality issue — campaign-specific tests belong in a campaign test file.
| "- Passing ingredients to pipeline steps via `with:` arguments\n\n" | ||
| ) | ||
|
|
||
| _display_step = _ingredient_table_display_instruction( |
There was a problem hiding this comment.
[info] cohesion: _display_step is computed unconditionally outside any ingredients_table guard, but in _prompts_campaign.py the equivalent _display is computed only when ingredients_table is truthy. Asymmetric guard pattern — either both should guard or neither should.
Trecek
left a comment
There was a problem hiding this comment.
AutoSkillit review: warning-only findings detected. See inline comments — no blocking changes required.
## Summary When `autoskillit fleet campaign` launches a session, the ingredient table is injected into the system prompt but Claude is never instructed to display it to the user. The user sees no ingredient names, required flags, or defaults — Claude just asks questions into the void. The fix adds a FIRST ACTION block to `_build_fleet_campaign_prompt` that instructs Claude to display the table verbatim before collecting values. A shared helper function in `_prompts.py` encapsulates the "display verbatim from [source]" instruction, used by both the campaign path (source = system prompt section) and the orchestrator path (source = `open_kitchen` response). Two files change: `_prompts.py` (new helper + export) and `_prompts_campaign.py` (FIRST ACTION block using the helper). `_prompts_orchestrator.py` is refactored to use the helper's display instruction so the wording stays in sync. ## Requirements ## Problem When `autoskillit order` launches a Claude Code session, the user sees the ingredient table in Claude's first response. This works via a two-step mechanism: 1. The system prompt (`_prompts_orchestrator.py:97-108`) mandates calling `open_kitchen(name=recipe)` as the FIRST ACTION 2. `open_kitchen` returns the ingredient table in its MCP response; the PostToolUse formatter (`_fmt_recipe.py:104-108`) wraps it with `--- INGREDIENTS TABLE ---` markers 3. The system prompt instructs: "Display it verbatim in your response — do not reformat or re-render it" 4. The user sees the formatted ingredient table in Claude's first assistant message When `autoskillit fleet campaign` launches a Claude Code session, the user sees **nothing** about ingredients. Claude just starts asking questions without showing what's available. The ingredient table is injected into the system prompt (`_prompts_campaign.py:199-206`) but is invisible to the user — and `open_kitchen` is explicitly **forbidden** (`_prompts_campaign.py:247`) because campaigns operate at L3 and use `dispatch_food_truck` instead of kitchen tools. There is no replacement mechanism for displaying the table to the user inside the session. ## Solution The `order` and `fleet campaign` flows should share an abstraction layer for the in-session ingredient table display instruction. The campaign system prompt already contains the full ingredient table in `_ing_section` — it just needs a FIRST ACTION block (analogous to `_prompts_orchestrator.py:97-108`) that instructs Claude to: 1. Display the ingredient table from its system prompt context verbatim as its first response 2. Then ask for required fields (marked with `*`) 3. Collect values via AskUserQuestion before dispatching The shared abstraction should generate this FIRST ACTION instruction block, differing only in the source of the table: `open_kitchen` response for `order`, system prompt content for `campaign`. ## Implementation Plan Plan file: `/home/talon/projects/autoskillit-runs/impl-20260507-152551-548485/.autoskillit/temp/make-plan/fleet_campaign_ingredient_table_display_plan_2026-05-07_152551.md` 🤖 Generated with [Claude Code](https://claude.com/claude-code) via AutoSkillit <!-- autoskillit:pipeline-signature steps=prepare_pr,run_arch_lenses,compose_pr,annotate_pr_diff,review_pr --> ## Token Usage Summary | Step | Model | count | uncached | output | cache_read | peak_ctx | turns | cache_write | time | |------|-------|-------|----------|--------|------------|----------|-------|-------------|------| | plan | claude-sonnet-4-6 | 1 | 3.1k | 25.3k | 713.6k | 77.7k | 69 | 65.9k | 13m 17s | | verify | claude-sonnet-4-6 | 1 | 100 | 11.8k | 590.1k | 73.2k | 35 | 60.6k | 3m 5s | | implement* | MiniMax-M2.7-highspeed | 1 | 821.0k | 10.4k | 1.1M | 54.1k | 86 | 36.7k | 4m 8s | | prepare_pr* | MiniMax-M2.7-highspeed | 1 | 61.0k | 3.3k | 232.0k | 34.0k | 23 | 22.4k | 1m 12s | | compose_pr* | MiniMax-M2.7-highspeed | 1 | 39.7k | 2.0k | 169.3k | 28.7k | 15 | 15.1k | 40s | | **Total** | | | 924.9k | 52.8k | 2.8M | 77.7k | | 200.7k | 22m 24s | \* *Step used a non-Anthropic provider; caching behavior may differ.* ## Token Efficiency | Step | LoC Changed | cache_read/LoC | cache_write/LoC | output/LoC | |------|-------------|----------------|-----------------|------------| | plan | 0 | — | — | — | | verify | 0 | — | — | — | | implement | 91 | 11615.3 | 402.9 | 113.8 | | prepare_pr | 0 | — | — | — | | compose_pr | 0 | — | — | — | | **Total** | **91** | 30351.7 | 2205.1 | 580.3 | ## Model Usage Breakdown | Model | steps | uncached | output | cache_read | cache_write | time | |-------|-------|----------|--------|------------|-------------|------| | claude-sonnet-4-6 | 2 | 3.2k | 37.1k | 1.3M | 126.5k | 16m 23s | | MiniMax-M2.7-highspeed | 3 | 921.7k | 15.7k | 1.5M | 74.2k | 6m 0s | Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Summary
When
autoskillit fleet campaignlaunches a session, the ingredient table is injected into the system prompt but Claude is never instructed to display it to the user. The user sees no ingredient names, required flags, or defaults — Claude just asks questions into the void.The fix adds a FIRST ACTION block to
_build_fleet_campaign_promptthat instructs Claude to display the table verbatim before collecting values. A shared helper function in_prompts.pyencapsulates the "display verbatim from [source]" instruction, used by both the campaign path (source = system prompt section) and the orchestrator path (source =open_kitchenresponse).Two files change:
_prompts.py(new helper + export) and_prompts_campaign.py(FIRST ACTION block using the helper)._prompts_orchestrator.pyis refactored to use the helper's display instruction so the wording stays in sync.Requirements
Problem
When
autoskillit orderlaunches a Claude Code session, the user sees the ingredient table in Claude's first response. This works via a two-step mechanism:_prompts_orchestrator.py:97-108) mandates callingopen_kitchen(name=recipe)as the FIRST ACTIONopen_kitchenreturns the ingredient table in its MCP response; the PostToolUse formatter (_fmt_recipe.py:104-108) wraps it with--- INGREDIENTS TABLE ---markersWhen
autoskillit fleet campaignlaunches a Claude Code session, the user sees nothing about ingredients. Claude just starts asking questions without showing what's available. The ingredient table is injected into the system prompt (_prompts_campaign.py:199-206) but is invisible to the user — andopen_kitchenis explicitly forbidden (_prompts_campaign.py:247) because campaigns operate at L3 and usedispatch_food_truckinstead of kitchen tools.There is no replacement mechanism for displaying the table to the user inside the session.
Solution
The
orderandfleet campaignflows should share an abstraction layer for the in-session ingredient table display instruction. The campaign system prompt already contains the full ingredient table in_ing_section— it just needs a FIRST ACTION block (analogous to_prompts_orchestrator.py:97-108) that instructs Claude to:*)The shared abstraction should generate this FIRST ACTION instruction block, differing only in the source of the table:
open_kitchenresponse fororder, system prompt content forcampaign.Implementation Plan
Plan file:
/home/talon/projects/autoskillit-runs/impl-20260507-152551-548485/.autoskillit/temp/make-plan/fleet_campaign_ingredient_table_display_plan_2026-05-07_152551.md🤖 Generated with Claude Code via AutoSkillit
Token Usage Summary
* Step used a non-Anthropic provider; caching behavior may differ.
Token Efficiency
Model Usage Breakdown