Skip to content

Part 4: put configuration first and make the completed code discoverable - #586

Merged
jongalloway merged 3 commits into
mainfrom
part4-configuration-first
Jul 27, 2026
Merged

Part 4: put configuration first and make the completed code discoverable#586
jongalloway merged 3 commits into
mainfrom
part4-configuration-first

Conversation

@jongalloway

Copy link
Copy Markdown
Contributor

Fixes #580.

Rehearsal feedback was that Part 4's configuration steps were unclear and came too late. An attendee scaffolded, ran the app, and hit an Azure provisioning prompt before the README had told them how to point at an existing resource — and the connection string was documented only as a CLI command, ~250 lines into the part, buried after a long code walkthrough.

Configuration now comes before the first run

The part is reordered around one idea: get it configured, get it running, then read the code.

  • New Step 2, "Configure it before you run it", sits immediately after scaffolding and opens with a table of the four changes and an explicit "do this before you press F5."
    • 2.1 packages → 2.2 AddConnectionString swap → 2.3 deployment name → 2.4 the secret → 2.5 build check
  • Step 2.2 now shows the exact AddAzureOpenAI block to delete instead of describing it.
  • Step 2.4 works for Visual Studio. Right-click GenAiLab.AppHostManage User Secrets, with the literal secrets.json to paste, alongside the CLI command and a list verification. An IMPORTANT states that the secret belongs to AppHost, not Web — putting it on the wrong project fails silently, which is a miserable thing to debug.
  • The code walkthrough moved to Step 5, after the app works, and now shows the AppHost as the attendee actually left it rather than the template's version they just deleted.
  • Step 3 gained a troubleshooting tip: an Azure provisioning prompt means 2.2 didn't take.

Docker-free path (#580)

It was a sub-bullet inside Step 1 that handed readers off to Step 3 for the gpt-4o-minigpt-5-mini edit — a step that same section also told them to skip. So they never made the edit, while the comparison table claimed the path already used gpt-5-mini.

This is the path people take because Docker wouldn't start, so it failed at the worst possible moment. It's now a standalone end-of-part section with a complete configuration of its own, showing the edit in place against what the template actually emits, and warning that skipping it means the app builds and starts fine and then 404s on the first message. The comparison table gained a Credentials row, since the two paths genuinely differ there (ConnectionStrings:openai on the AppHost vs AzureOpenAI:Endpoint + AzureOpenAI:Key on the app).

Stale Qdrant data volume

Hit while rehearsing: run the app, update packages, run again, and vectordb never starts. Two causes, both deliberate settings:

.WithDataVolume()                              // storage survives shutdown
.WithLifetime(ContainerLifetime.Persistent);   // container survives shutdown

Bumping Aspire bumps the Qdrant image, and old storage can be incompatible — but ContainerLifetime.Persistent compounds it, because the old container is reused rather than recreated, so it never picks up the new image. Deleting only the volume wouldn't have fixed it.

New "Qdrant won't start after updating packages" section explains both, gives --filter commands so attendees can find their own generated names, notes the Docker Desktop equivalent, and reassures that nothing of value is lost. Part 11 links to it, since it runs the same solution.

The completed code is now findable

Part 4 has no snapshot of its own by design — Part 11 - Deployment/GenAiLab/ is a finished Part 4 plus the single WithExternalHttpEndpoints() line. That was implicit knowledge. It's now stated in the Part 4 README, the Part 11 README, the root README, and the snapshot's own template-generated README, which previously pointed readers at Azure provisioning that the workshop version has deliberately removed.

Also: setup-workshop-credentials.ps1 now targets eShopLite-start as well as eShopLite.

Verification

Everything here was run against the live workshop resource, not just read.

Check Result
GenAiLab.sln Release build 0 warnings, 0 errors
AppHost start No provisioning prompt; vectordb + markitdown up
Aspire chat Grounded answer, 2 working citations into the sample PDF
Docker-free re-scaffold, new section only 0 warnings; same answer, same 2 citations
Volume recovery docker rm -f then docker volume rm both succeed; re-run recreates and re-ingests

Two notes from doing it:

  • The cleanup command order matters — Docker refuses to remove a volume still attached to a container, so the documented order is the working one.
  • GenAiLab.AppHost had no user secret set at all, because Align Parts 4 and 11 with the current aichatweb template #566 re-scaffolded it and changed its UserSecretsId. Re-running setup-workshop-credentials.ps1 -ApplyUserSecrets fixes it. Worth knowing whenever that project is regenerated.

Also includes docs/testing/workshop-test-report-2026-07-27.md, the report for the full end-to-end run this and the four earlier fix PRs came out of, indexed in docs/README.md.

Docs only — no snapshot code changed, so the eight CI build targets are untouched. markdownlint is clean, and all internal and cross-file anchors resolve.

Rehearsal feedback was that Part 4's configuration steps were unclear and came
too late: attendees scaffolded, ran the app, and hit an Azure provisioning
prompt before the README had told them how to point at an existing resource.

Restructure the part so configuration happens before the first run:

- New Step 2 "Configure it before you run it" collects all four changes --
  package updates, the AddConnectionString swap, the deployment-name change,
  and the connection-string secret -- immediately after scaffolding.
- Step 2.2 now shows the exact AddAzureOpenAI block to delete rather than
  describing it.
- Step 2.4 documents the secret for Visual Studio (Manage User Secrets, with
  the literal secrets.json shape) as well as the CLI, and says plainly that it
  belongs to GenAiLab.AppHost rather than GenAiLab.Web.
- The code walkthrough moves to Step 5, after the app runs, and shows the
  AppHost as the attendee actually left it.

Fix the Docker-free path (#580). It was a sub-bullet inside Step 1 that handed
readers to a step it also told them to skip, so they never got the
gpt-4o-mini -> gpt-5-mini edit, while the comparison table claimed the path
already used gpt-5-mini. It is now a standalone end-of-part section with a
complete configuration of its own, and the comparison table gained a
credentials row because the two paths genuinely differ there.

Document the stale Qdrant data volume. Updating Aspire also updates the Qdrant
image, and WithDataVolume() keeps storage written by the older version while
WithLifetime(ContainerLifetime.Persistent) keeps the old container instead of
recreating it from the new image, so vectordb can fail to start. Add a
troubleshooting section covering both causes, with cleanup commands in the
order Docker requires. Part 11 links to it because it runs the same solution.

Make the shared snapshot explicit. Part 4 has no snapshot of its own by
design -- Part 11 - Deployment/GenAiLab/ is a finished Part 4 plus the single
WithExternalHttpEndpoints() line. Say so in the Part 4 README, the Part 11
README, the root README, and the snapshot's own template-generated README,
which previously told readers to use Azure provisioning that the workshop
version has deliberately removed.

Also have setup-workshop-credentials.ps1 target eShopLite-start.

Verified against the live resource: the committed solution builds Release with
0 warnings, starts with no provisioning prompt, and answers with citations; a
fresh Docker-free scaffold following only the new section builds 0 warnings and
returns the same grounded answer; and removing the container and volume
recovers a broken vectordb, re-ingesting on the next question.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 4d6ee636-7a1e-41e5-bf5c-12863a9dd8cc
@jongalloway

Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

…irst

# Conflicts:
#	.github/copilot-instructions.md

Copilot AI commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Resolved the merge conflicts by merging origin/main into this branch and fixing the conflict in .github/copilot-instructions.md in commit 58eaee2.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Reorders and clarifies Part 4’s attendee flow so configuration happens before first run (avoiding Azure provisioning prompts), and makes the “completed” Part 4 solution discoverable by explicitly pointing to the Part 11 GenAiLab/ snapshot across the repo. Also adds a full end-to-end workshop test report and updates credential automation to cover eShopLite-start.

Changes:

  • Reworked Part 4 README structure: “configure first, run, then walkthrough,” plus a fully self-contained Docker-free path section (including the gpt-5-mini fix and credential differences).
  • Documented that Part 11’s GenAiLab/ is also the completed/answer-key code for Part 4 (root README, Part 4 README, Part 11 README, and the template-generated snapshot README).
  • Added a full workshop test report and indexed it; expanded setup-workshop-credentials.ps1 to write secrets for eShopLite-start as well.
Show a summary per file
File Description
README.md Updates Docker requirement note for Part 4 and documents that Part 11 GenAiLab/ is the completed Part 4 solution.
Part 04 - AI Web Chat Template/README.md Reorders the lab around early configuration, adds “completed code” discovery, and moves the Docker-free path into a complete end-of-part alternative section.
Part 11 - Deployment/README.md States GenAiLab/ is the Part 4 completed solution and adds a link to Part 4’s Qdrant stale-volume troubleshooting.
Part 11 - Deployment/GenAiLab/README.md Adds a workshop-specific IMPORTANT note explaining the intentional divergence from template provisioning and how to set credentials.
docs/testing/workshop-test-report-2026-07-27.md Adds an end-to-end attendee-style run report for Parts 1–11.
docs/README.md Indexes the new 2026-07-27 test report.
.github/scripts/setup-workshop-credentials.ps1 Writes secrets for eShopLite-start and broadens the local-model secret application to all */Store targets in the list.
.github/copilot-instructions.md Updates repo guidance to reflect that Part 4 shares the Part 11 GenAiLab/ snapshot and must stay consistent.

Review details

  • Files reviewed: 8/8 changed files
  • Comments generated: 2
  • Review effort level: Low

Comment on lines +504 to +506
Everything in Steps 1-4 applies, but the configuration is different enough that
the whole path is given here. Read Step 5 as an architecture comparison rather
than a description of files in your project.
Comment thread docs/testing/workshop-test-report-2026-07-27.md Outdated
@jongalloway

Copy link
Copy Markdown
Contributor Author

@copilot Fix the code for all comments in this review thread.

When a review comment includes a suggested change, apply the suggestion exactly.

Do not make changes beyond what is described in the linked review thread.

Copilot AI commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

@copilot Fix the code for all comments in this review thread.

When a review comment includes a suggested c...

Implemented the requested fixes from that review thread in commit 08eaa32.

@jongalloway
jongalloway merged commit a2005cc into main Jul 27, 2026
2 checks passed
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.

Part 4: the Docker-free path never gets the gpt-4o-minigpt-5-mini fix, and the comparison table says it already has it

3 participants