Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion docs/syntax/agent-skill.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,43 @@
# Agent skill

The `{agent-skill}` directive renders a standardized callout that points readers to an [Elastic AI agent skill](https://github.com/elastic/agent-skills). It uses a fixed title and description, and includes a "Get the skill" button linking to the skill's URL.
The `{agent-skill}` directive renders a standardized callout that points readers to an [Elastic AI agent skill](https://github.com/elastic/agent-skills). It includes a "Get the skill" button linking to the skill's URL.

## Usage

By default, the directive renders a standard description:

:::::{tab-set}

::::{tab-item} Output

:::{agent-skill}
:url: https://github.com/elastic/agent-skills@elasticsearch-esql
:::

::::

::::{tab-item} Markdown

```markdown
:::{agent-skill}
:url: https://github.com/elastic/agent-skills@elasticsearch-esql
:::
```

::::

:::::

You can also provide custom body text to clarify the scope of the skill:

:::::{tab-set}

::::{tab-item} Output

:::{agent-skill}
:url: https://github.com/elastic/agent-skills@elasticsearch-esql

This skill helps agents write and optimize ES|QL queries.
:::

::::
Expand All @@ -19,6 +47,8 @@ The `{agent-skill}` directive renders a standardized callout that points readers
```markdown
:::{agent-skill}
:url: https://github.com/elastic/agent-skills@elasticsearch-esql

This skill helps agents write and optimize ES|QL queries.
:::
```

Expand Down
12 changes: 4 additions & 8 deletions src/Elastic.Documentation.Site/Assets/markdown/agent-skill.css
Original file line number Diff line number Diff line change
@@ -1,31 +1,27 @@
@layer components {
.agent-skill {
@apply border-teal-40 bg-teal-10 mt-4 rounded-sm border-1 pb-4;
@apply border-grey-40 bg-grey-10 mt-4 rounded-sm border-1 pb-4;

.agent-skill-header {
@apply bg-teal-20 text-teal-110 flex items-center gap-2 rounded-t-sm px-4 py-2 font-bold;
@apply bg-grey-20 text-grey-110 flex items-center gap-2 rounded-t-sm px-4 py-2 font-bold;
}

.agent-skill-icon {
@apply size-5 shrink-0;
}

.agent-skill-content {
@apply flex items-center justify-between gap-4 px-4 pt-3;
@apply flex flex-col items-start gap-3 px-4 pt-3 md:flex-row md:items-end md:justify-between md:gap-4;
}

.agent-skill-text {
p {
@apply m-0 text-base;
}

.agent-skill-learn-more {
@apply mt-1 text-sm;
}
}

.agent-skill-button {
@apply bg-blue-elastic hover:bg-blue-elastic-110 focus:ring-blue-elastic-50 flex shrink-0 cursor-pointer items-center gap-1.5 rounded-sm px-6 py-2 font-sans text-sm font-semibold text-nowrap text-white! no-underline! select-none hover:text-white! focus:ring-4 focus:outline-none;
@apply bg-blue-elastic hover:bg-blue-elastic-110 focus:ring-blue-elastic-50 flex w-full cursor-pointer items-center justify-center gap-1.5 rounded-sm px-6 py-2 font-sans text-sm font-semibold text-nowrap text-white! no-underline! select-none hover:text-white! focus:ring-4 focus:outline-none md:w-auto md:shrink-0;
}

.agent-skill-button::after {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
<div class="agent-skill-content">
<div class="agent-skill-text">
<p>A skill is available to help AI agents with this topic.</p>
<p class="agent-skill-learn-more">To learn more about Elastic agent skills, refer to the <a href="/explore-analyze/ai-features/agent-skills">documentation</a>.</p>
@if (Model.HasBody)
{
@Model.RenderBlock()
}
<p><a href="/explore-analyze/ai-features/agent-skills">Learn more about agent skills for Elastic</a></p>
</div>
<a href="@Model.Url" target="_blank" rel="noopener noreferrer" class="agent-skill-button">
Get the skill
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ namespace Elastic.Markdown.Myst.Directives.AgentSkill;
public class AgentSkillViewModel : DirectiveViewModel
{
public required string Url { get; init; }
public bool HasBody { get; init; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ private static void WriteAgentSkill(HtmlRenderer renderer, AgentSkillBlock block
var slice = AgentSkillView.Create(new AgentSkillViewModel
{
DirectiveBlock = block,
Url = block.Url
Url = block.Url,
HasBody = block.Count > 0
});
RenderRazorSlice(slice, renderer);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,8 @@ private static void WriteAgentSkillBlock(LlmMarkdownRenderer renderer, AgentSkil
renderer.Writer.Write($" url=\"{block.Url}\"");
renderer.Writer.WriteLine(">");
renderer.WriteLine(" A skill is available to help AI agents with this topic.");
if (block.Count > 0)
WriteChildrenWithIndentation(renderer, block, " ");
renderer.Writer.WriteLine("</agent-skill>");
renderer.EnsureLine();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@ protected override void Write(PlainTextRenderer renderer, DirectiveBlock obj)
renderer.EnsureBlockSpacing();
renderer.WriteLine("Agent skill available");
renderer.WriteLine("A skill is available to help AI agents with this topic.");
if (agentSkillBlock.Count > 0)
renderer.WriteChildren(agentSkillBlock);
if (!string.IsNullOrEmpty(agentSkillBlock.Url))
renderer.WriteLine(agentSkillBlock.Url);
renderer.EnsureLine();
Expand Down
32 changes: 30 additions & 2 deletions tests/Elastic.Markdown.Tests/Directives/AgentSkillTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ public void RendersTitle() =>
Html.Should().Contain("Agent skill available");

[Fact]
public void RendersFixedText() =>
public void RendersDefaultText() =>
Html.Should().Contain("A skill is available to help AI agents with this topic.");

[Fact]
public void RendersLearnMoreLink()
{
Html.Should().Contain("refer to the");
Html.Should().Contain("Learn more about agent skills for Elastic");
Html.Should().Contain("href=\"/explore-analyze/ai-features/agent-skills\"");
}

Expand All @@ -59,6 +59,34 @@ public void RendersButton()
}
}

public class AgentSkillWithBodyTests(ITestOutputHelper output) : DirectiveTest<AgentSkillBlock>(output,
"""
:::{agent-skill}
:url: https://github.com/elastic/agent-skills@elasticsearch-esql

This skill helps agents write and optimize ES|QL queries.
:::
A regular paragraph.
"""
)
{
[Fact]
public void RendersCustomBody() =>
Html.Should().Contain("This skill helps agents write and optimize ES|QL queries.");

[Fact]
public void StillRendersDefaultText() =>
Html.Should().Contain("A skill is available to help AI agents with this topic.");

[Fact]
public void StillRendersLearnMoreLink() =>
Html.Should().Contain("Learn more about agent skills for Elastic");

[Fact]
public void StillRendersButton() =>
Html.Should().Contain("Get the skill");
}

public class AgentSkillMissingUrlTests(ITestOutputHelper output) : DirectiveTest<AgentSkillBlock>(output,
"""
:::{agent-skill}
Expand Down
40 changes: 39 additions & 1 deletion tests/authoring/Blocks/AgentSkill.fs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,45 @@ type ``agent skill with url`` () =
<div class="agent-skill-content">
<div class="agent-skill-text">
<p>A skill is available to help AI agents with this topic.</p>
<p class="agent-skill-learn-more">To learn more about Elastic agent skills, refer to the <a href="/explore-analyze/ai-features/agent-skills">documentation</a>.</p>
<p><a href="/explore-analyze/ai-features/agent-skills">Learn more about agent skills for Elastic</a></p>
</div>
<a href="https://github.com/elastic/agent-skills@elasticsearch-esql" target="_blank" rel="noopener noreferrer" class="agent-skill-button">
Get the skill
<svg class="agent-skill-button-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"></path>
</svg>
</a>
</div>
</div>
"""

[<Fact>]
let ``has no errors`` () = markdown |> hasNoErrors

type ``agent skill with body content`` () =
static let markdown = Setup.Markdown """
:::{agent-skill}
:url: https://github.com/elastic/agent-skills@elasticsearch-esql

This skill helps agents write and optimize ES|QL queries.
:::
"""

[<Fact>]
let ``renders custom body`` () =
markdown |> convertsToHtml """
<div class="agent-skill">
<div class="agent-skill-header">
<svg class="agent-skill-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M9.813 15.904 9 18.75l-.813-2.846a4.5 4.5 0 0 0-3.09-3.09L2.25 12l2.846-.813a4.5 4.5 0 0 0 3.09-3.09L9 5.25l.813 2.846a4.5 4.5 0 0 0 3.09 3.09L15.75 12l-2.846.813a4.5 4.5 0 0 0-3.09 3.09ZM18.259 8.715 18 9.75l-.259-1.035a3.375 3.375 0 0 0-2.455-2.456L14.25 6l1.036-.259a3.375 3.375 0 0 0 2.455-2.456L18 2.25l.259 1.035a3.375 3.375 0 0 0 2.455 2.456L21.75 6l-1.036.259a3.375 3.375 0 0 0-2.455 2.456ZM16.894 20.567 16.5 21.75l-.394-1.183a2.25 2.25 0 0 0-1.423-1.423L13.5 18.75l1.183-.394a2.25 2.25 0 0 0 1.423-1.423l.394-1.183.394 1.183a2.25 2.25 0 0 0 1.423 1.423l1.183.394-1.183.394a2.25 2.25 0 0 0-1.423 1.423Z"></path>
</svg>
<span class="agent-skill-title">Agent skill available</span>
</div>
<div class="agent-skill-content">
<div class="agent-skill-text">
<p>A skill is available to help AI agents with this topic.</p>
<p>This skill helps agents write and optimize ES|QL queries.</p>
<p><a href="/explore-analyze/ai-features/agent-skills">Learn more about agent skills for Elastic</a></p>
</div>
<a href="https://github.com/elastic/agent-skills@elasticsearch-esql" target="_blank" rel="noopener noreferrer" class="agent-skill-button">
Get the skill
Expand Down
Loading