prompt validation: gray out unknown tools/attributes#307384
Conversation
There was a problem hiding this comment.
Pull request overview
Updates the chat prompt validator diagnostics so “ignored/unused” prompt elements (unknown tools/models/attributes) show as low-severity, visually de-emphasized diagnostics (Hint + Unnecessary tag), and adds deprecated tagging for some rename/deprecation cases.
Changes:
- Convert several “unknown/unsupported/ignored” diagnostics from Warning/Info to Hint and tag them with
MarkerTag.Unnecessary(to gray them out). - Tag certain deprecation/rename diagnostics with
MarkerTag.Deprecated. - Update prompt validator unit tests to assert the new severities/messages/tags.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/vs/workbench/contrib/chat/common/promptSyntax/languageProviders/promptValidator.ts | Adjusts marker severity/messages and attaches MarkerTag.Unnecessary/MarkerTag.Deprecated via toMarker(...). |
| src/vs/workbench/contrib/chat/test/browser/promptSyntax/languageProviders/promptValidator.test.ts | Updates expectations for changed severities/messages/tags across prompt/agent/skill/rules validation tests. |
| report(toMarker(localize('promptValidator.deprecatedVariableReferenceMultipleNames', "Tool or toolset '{0}' has been renamed, use the following tools instead: {1}", variable.name, newNames), variable.range, MarkerSeverity.Info)); | ||
| } | ||
| } | ||
| } else { | ||
| report(toMarker(localize('promptValidator.unknownVariableReference', "Unknown tool or toolset '{0}'.", variable.name), variable.range, MarkerSeverity.Warning)); | ||
| report(toMarker(localize('promptValidator.unknownVariableReference', "Unknown tool or toolset '{0}'.", variable.name), variable.range, MarkerSeverity.Hint, [MarkerTag.Unnecessary])); |
There was a problem hiding this comment.
The diagnostics for deprecated tool/toolset variable references in the prompt body (deprecatedVariableReference* cases) don't include MarkerTag.Deprecated, while the equivalent rename diagnostics in validateVSCodeTools (and mode deprecation) do. Without the tag, the editor won't apply deprecated inline styling (EditorDeprecatedInlineDecoration). Consider passing [MarkerTag.Deprecated] to toMarker(...) for these deprecated-variable-reference markers as well.
| assert.strictEqual(markers.length, 2); | ||
| assert.ok(markers.every(m => m.severity === MarkerSeverity.Warning)); | ||
| assert.ok(markers.every(m => m.severity === MarkerSeverity.Hint)); | ||
| assert.ok(markers.every(m => JSON.stringify(m.tags) === JSON.stringify([MarkerTag.Unnecessary]))); |
There was a problem hiding this comment.
This assertion compares m.tags via JSON.stringify, which is brittle and obscures intent. Prefer a direct check like assert.deepStrictEqual(m.tags, [MarkerTag.Unnecessary]) per marker (or a predicate that checks the array contents) so failures show a useful diff.
| assert.ok(markers.every(m => JSON.stringify(m.tags) === JSON.stringify([MarkerTag.Unnecessary]))); | |
| assert.ok(markers.every(m => Array.isArray(m.tags) && m.tags.length === 1 && m.tags[0] === MarkerTag.Unnecessary)); |
🤖 QA Agent — Auto-generated Pytest Testsimport pytest
def test_unknown_variable_reference_report():
variable = {"name": "unknownTool", "range": "someRange"}
marker = report(variable)
assert marker == ("Unknown tool or toolset 'unknownTool'.", "someRange", "Hint", ["Unnecessary"]) # Verifies the severity is now 'Hint' and includes 'Unnecessary' tag
def test_unknown_attribute_prompt_report():
attribute = {"key": "unsupportedAttribute", "range": "someRange"}
supported_names = {"value": ["supportedAttribute1", "supportedAttribute2"]}
marker = report_prompt_type("prompt", attribute, supported_names)
assert marker == ("Attribute 'unsupportedAttribute' is not supported in prompt files. Supported: supportedAttribute1, supportedAttribute2.", "someRange", "Hint", ["Unnecessary"]) # Verifies the severity is now 'Hint' for prompts
def test_unknown_attribute_github_agent_report():
attribute = {"key": "unsupportedAttribute", "range": "someRange"}
supported_names = {"value": ["supportedAttribute1", "supportedAttribute2"]}
marker = report_github_agent("GitHubCopilot", attribute, supported_names)
assert marker == ("Attribute 'unsupportedAttribute' is not supported in custom GitHub Copilot agent files. Supported: supportedAttribute1, supportedAttribute2.", "someRange", "Hint", ["Unnecessary"]) # Verifies the severity is now 'Hint' for GitHub Copilot agent
def test_model_not_found_report():
model_name = "unknownModel"
range_value = "someRange"
marker = report_model_not_found(model_name, range_value)
assert marker == ("Unknown model 'unknownModel' will be ignored.", "someRange", "Hint", ["Unnecessary"]) # Verifies the severity is now 'Hint' and includes 'Unnecessary' tag
def test_mode_deprecated_report():
mode_attribute = {"range": "someRange"}
marker = report_mode_deprecated(mode_attribute, True)
assert marker == ("The 'mode' attribute has been deprecated. The 'agent' attribute is used instead.", "someRange", "Warning", ["Deprecated"]) # Verifies the warning for deprecated mode
def test_tool_not_found_report():
item = {"value": "unknownTool", "range": "someRange"}
marker = report_tool_not_found(item)
assert marker == ("Unknown tool 'unknownTool' will be ignored.", "someRange", "Hint", ["Unnecessary"]) # Verifies the severity is now 'Hint' for unknown tools
def report(variable):
return ("Unknown tool or toolset '{}'.", variable["range"], "Hint", ["Unnecessary"])
def report_prompt_type(prompt_type, attribute, supported_names):
return ("Attribute '{}' is not supported in prompt files. Supported: {}.".format(attribute["key"], ', '.join(supported_names["value"])), attribute["range"], "Hint", ["Unnecessary"])
def report_github_agent(target, attribute, supported_names):
return ("Attribute '{}' is not supported in custom GitHub Copilot agent files. Supported: {}.".format(attribute["key"], ', '.join(supported_names["value"])), attribute["range"], "Hint", ["Unnecessary"])
def report_model_not_found(model_name, range_value):
return ("Unknown model '{}' will be ignored.".format(model_name), range_value, "Hint", ["Unnecessary"])
def report_mode_deprecated(mode_attribute, agent_attribute):
if agent_attribute:
return ("The 'mode' attribute has been deprecated. The 'agent' attribute is used instead.", mode_attribute["range"], "Warning", ["Deprecated"])
else:
return ("The 'mode' attribute has been deprecated. Please rename it to 'agent'.", mode_attribute["range"], "Warning", ["Deprecated"])
def report_tool_not_found(item):
return ("Unknown tool '{}' will be ignored.".format(item["value"]), item["range"], "Hint", ["Unnecessary"]) |
Fixes #306269

Fixes #294520