diff --git a/pkg/workflow/threat_detection_inline_engine.go b/pkg/workflow/threat_detection_inline_engine.go index 72b4c2cc588..99ba687e63a 100644 --- a/pkg/workflow/threat_detection_inline_engine.go +++ b/pkg/workflow/threat_detection_inline_engine.go @@ -34,6 +34,17 @@ func (c *Compiler) buildDetectionEngineExecutionStep(data *WorkflowData) []strin if hasThreatDetectionEngineConfig { engineConfig = data.SafeOutputs.ThreatDetection.EngineConfig } + // Preserve the original engine identity before Pi is normalized to Copilot for + // detection. Precedence matches runtime engine resolution: explicit + // threat-detection.engine.id overrides the main engine config, which overrides + // the legacy top-level AI field. + originalEngineID := data.AI + if data.EngineConfig != nil && data.EngineConfig.ID != "" { + originalEngineID = data.EngineConfig.ID + } + if hasThreatDetectionEngineConfig && data.SafeOutputs.ThreatDetection.EngineConfig.ID != "" { + originalEngineID = data.SafeOutputs.ThreatDetection.EngineConfig.ID + } // Get the engine instance engine, err := c.getAgenticEngine(engineSetting) @@ -87,6 +98,13 @@ func (c *Compiler) buildDetectionEngineExecutionStep(data *WorkflowData) []strin if detectionEngineConfig.APITarget == "" && data.EngineConfig != nil && data.EngineConfig.APITarget != "" { detectionEngineConfig.APITarget = data.EngineConfig.APITarget } + if engineSetting == "copilot" && originalEngineID == "pi" { + // Pi requires provider/model syntax (for example "copilot/gpt-5.4"), but the + // Copilot CLI expects only the model ID. extractPiModelID preserves bare model + // names unchanged, so empty or already-normalized values keep their current + // fallback behavior while provider-scoped Pi models become Copilot-compatible. + detectionEngineConfig.Model = extractPiModelID(detectionEngineConfig.Model) + } // Create minimal WorkflowData for threat detection. // SandboxConfig with AWF enabled ensures the engine runs inside the firewall. diff --git a/pkg/workflow/threat_detection_test.go b/pkg/workflow/threat_detection_test.go index d1af1a6229c..14fa42f73f4 100644 --- a/pkg/workflow/threat_detection_test.go +++ b/pkg/workflow/threat_detection_test.go @@ -1269,6 +1269,21 @@ func TestCopilotDetectionDefaultModel(t *testing.T) { shouldContainModel: true, expectedModel: "gpt-4", }, + { + name: "pi engine threat detection normalizes provider-scoped model for copilot fallback", + data: &WorkflowData{ + AI: "pi", + EngineConfig: &EngineConfig{ + ID: "pi", + Model: "copilot/gpt-5.4", + }, + SafeOutputs: &SafeOutputsConfig{ + ThreatDetection: &ThreatDetectionConfig{}, + }, + }, + shouldContainModel: true, + expectedModel: "gpt-5.4", + }, { name: "copilot engine with threat detection engine config with custom model", data: &WorkflowData{