Skip to content

prompt validation: gray out unknown tools/attributes#307384

Merged
aeschli merged 1 commit intomainfrom
aeschli/roasted-reptile-998
Apr 2, 2026
Merged

prompt validation: gray out unknown tools/attributes#307384
aeschli merged 1 commit intomainfrom
aeschli/roasted-reptile-998

Conversation

@aeschli
Copy link
Copy Markdown
Contributor

@aeschli aeschli commented Apr 2, 2026

Fixes #306269
Fixes #294520
image

Copilot AI review requested due to automatic review settings April 2, 2026 10:09
@aeschli aeschli enabled auto-merge (squash) April 2, 2026 10:09
@aeschli aeschli self-assigned this Apr 2, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

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.

Comment on lines 163 to +167
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]));
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

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.

Copilot uses AI. Check for mistakes.
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])));
Copy link

Copilot AI Apr 2, 2026

Choose a reason for hiding this comment

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

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.

Suggested change
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));

Copilot uses AI. Check for mistakes.
@aeschli aeschli changed the title prompt validation: gray unused tools, severity hint prompt validation: gray out unknown tools/attributes, severity hint Apr 2, 2026
@aeschli aeschli changed the title prompt validation: gray out unknown tools/attributes, severity hint prompt validation: gray out unknown tools/attributes Apr 2, 2026
@ideedestiny
Copy link
Copy Markdown

🤖 QA Agent — Auto-generated Pytest Tests

import 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"])

@aeschli aeschli merged commit 9040997 into main Apr 2, 2026
23 checks passed
@aeschli aeschli deleted the aeschli/roasted-reptile-998 branch April 2, 2026 12:32
@vs-code-engineering vs-code-engineering bot added this to the 1.115.0 milestone Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

4 participants