"""TemplateExtractionService — propose a parameter schema from a rendered script. Phase 5 of the FlowPilot migration. Called when an engineer chooses "Run now, templatize after resolve" on a suggested fix with no existing library match. The service looks at the concrete script (with the values the engineer is about to run with) and session/ticket context, then proposes a parameterization that future engineers could use from the Script Library. Design choices (per FLOWPILOT-MIGRATION.md Section 6.4): - **Conservative by default.** Prefer fewer parameters. Environment-agnostic values (like a command name) should not be parameterized. The prompt calls that out explicitly. - **Round-trip check.** After the LLM proposes parameters, we validate that the templated body renders back to the original script when given the extracted parameter values. Failures log a warning and the caller falls back to a single-parameter "raw script" proposal. - **Model:** Sonnet (`template_extraction` tier). Creates a persistent library artifact — quality matters more than latency. Output shape mirrors the Script Generator's parameter schema: { "parameters": [ {"key": "", "label": "", "type": "text|password|select|...", "inferred_from": ""} ], "templated_body": "