Skip to content

Display ingredient table in fleet campaign sessions#2203

Merged
Trecek merged 1 commit into
developfrom
fleet-campaign-in-session-ingredient-table-not-displayed-to/2198
May 7, 2026
Merged

Display ingredient table in fleet campaign sessions#2203
Trecek merged 1 commit into
developfrom
fleet-campaign-in-session-ingredient-table-not-displayed-to/2198

Conversation

@Trecek
Copy link
Copy Markdown
Collaborator

@Trecek Trecek commented May 7, 2026

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 via AutoSkillit

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
review_pr claude-sonnet-4-6 1 84 13.8k 374.4k 52.6k 31 41.0k 3m 48s
Total 925.0k 66.6k 3.1M 77.7k 241.7k 26m 13s

* 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
review_pr 0
Total 91 34466.0 2656.0 732.0

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

…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>
Copy link
Copy Markdown
Collaborator Author

@Trecek Trecek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AutoSkillit PR Review — Verdict: approved_with_comments

"via AskUserQuestion. Do not dispatch until all required values are confirmed.\n"
)

_first_action_section = ""
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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:
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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(
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[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.

Copy link
Copy Markdown
Collaborator Author

@Trecek Trecek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AutoSkillit review: warning-only findings detected. See inline comments — no blocking changes required.

@Trecek Trecek added this pull request to the merge queue May 7, 2026
Merged via the queue into develop with commit dd91bfc May 7, 2026
2 checks passed
@Trecek Trecek deleted the fleet-campaign-in-session-ingredient-table-not-displayed-to/2198 branch May 7, 2026 23:32
Trecek added a commit that referenced this pull request May 8, 2026
## 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant