Skip to content

[dotnet-port] Port skill script_schemas block for file-based skills #249

Description

@github-actions

Summary

Aligns the Go fsskills package with the upstream .NET PR microsoft/agent-framework#6343, which restructured how script schema information is included in skill content.

Before this change, the Go SDK returned only the raw SKILL.md content when loading a file-based skill via load_skill. The LLM had no schema information about available scripts or their argument format.

After this change, when a file-based skill has scripts, a <script_schemas> XML block is appended to the skill body:

<script_schemas>
  <schema script="scripts/convert.py">{"type":"array","items":{"type":"string"}}</schema>
</script_schemas>

This tells the LLM how to format arguments when calling run_skill_script for that skill.

Changes

  • agent/skills/skills.go: Added ParametersSchema *string to Script. When set, its value is embedded in the <schema> element. This field is optional so code-defined skills can provide custom schemas.
  • agent/skills/fsskills/source.go:
    • newScript now sets ParametersSchema to the default {"type":"array","items":{"type":"string"}}, matching .NET's AgentFileSkillScript.ParametersSchema.
    • parseSkillDirectory appends buildScriptSchemasBlock() to the raw SKILL.md content when the skill has scripts.
    • New buildScriptSchemasBlock, xmlEscapeAttr, and xmlEscapeContent helpers. Quotes in embedded JSON are intentionally preserved (not &quot;-escaped) so the schema stays readable to the model.

Ported .NET PRs

Upstream commit: bb9ed63a347b3e437106b27ff7547bd388fd5bbe

Breaking Changes

Yes — for file-based skills that have scripts, GetContent now returns content that includes an appended <script_schemas> block. Any code that compares the exact output of GetContent against the raw SKILL.md bytes will see a difference.

Old behavior: GetContent returned the exact SKILL.md file bytes.
New behavior: GetContent returns SKILL.md bytes + appended <script_schemas> block when scripts are present.

This is acceptable for a beta SDK and directly aligns with the upstream .NET behavior.

Tests and Examples

New tests added in agent/skills/fsskills/source_script_test.go:

  • TestFileScript_HasDefaultParametersSchema — verifies file scripts get the default {"type":"array","items":{"type":"string"}} schema
  • TestFileSkill_WithScripts_ContentIncludesScriptSchemasBlock — verifies <script_schemas> block is appended with <schema script="name"> entries
  • TestFileSkill_WithScripts_ContentStartsWithOriginalSkillMd — verifies original SKILL.md content is preserved
  • TestFileSkill_WithoutScripts_ContentDoesNotIncludeScriptSchemasBlock — verifies no block appended when skill has no scripts
  • TestFileSkill_ScriptContent_IncludesDefaultArraySchema — verifies schema JSON appears in content and quotes are not escaped

Ran: go test ./agent/skills/... -count=1 (all pass) and go test ./... -count=1 (full suite, all pass).

Notes

Skipped from the same upstream PR:

  • The .NET-only change removing resources from inline/class skill bodies — Go's code-defined skills never auto-included resources in body content, so this was already aligned.
  • The .NET-only AgentInlineSkillContentBuilder changes — Go does not have an equivalent builder class; code-defined skill authors provide their own GetContent function.

Generated by .NET to Go Porting Agent · ● 33.4M ·


Note

This was originally intended as a pull request, but GitHub Actions is not permitted to create or approve pull requests in this repository.
The changes have been pushed to branch dotnet-port/skill-script-schemas-ea03fccbfe757fd3.

Click here to create the pull request

To fix the permissions issue, go to SettingsActionsGeneral and enable Allow GitHub Actions to create and approve pull requests. See also: gh-aw FAQ

Show patch preview (287 of 287 lines)
From fa2bec11a322cc96841885d13eacae1a37c70ba2 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]" <github-actions[bot]@users.noreply.github.com>
Date: Fri, 5 Jun 2026 10:27:01 +0000
Subject: [PATCH] Port script_schemas block for file-based skills from .NET PR
 #6343

Align fsskills with upstream .NET change: file-based skills now append
a <script_schemas> XML block to their content when they have scripts.
Previously Go returned only the raw SKILL.md without any script schema
information; .NET (AgentFileSkill) appended a <scripts> block.

Changes:
- Add ParametersSchema *string field to skills.Script. When non-nil, its
  value is included inside the <schema script="..."> element so the LLM
  knows the argument format for each script.
- In fsskills.newScript, set ParametersSchema to the default array schema
  {"type":"array","items":{"type":"string"}} matching the .NET
  AgentFileSkillScript.ParametersSchema default.
- In fsskills.parseSkillDirectory, append buildScriptSchemasBlock() to the
  raw SKILL.md content when the skill has scripts.
- buildScriptSchemasBlock emits:
    <script_schemas>
      <schema script="name">JSON_SCHEMA</schema>
    </script_schemas>
  Quotes in embedded JSON are preserved (not XML-escaped) so the schema
  remains readable to the model, matching .NET preserveQuotes: true behavior.
- Add xmlEscapeAttr/xmlEscapeContent helpers (no xml package dependency).
- Add six new tests covering: default ParametersSchema presence, block
  appended when scripts exist, original content preserved, no block when
  no scripts, schema content includes array schema, quotes not escaped.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---
 agent/skills/fsskills/source.go             |  55 ++++++++-
 agent/skills/fsskills/source_script_test.go | 126 ++++++++++++++++++++
 agent/skills/skills.go                      |   8 +-
 3 files changed, 185 insertions(+), 4 deletions(-)

diff --git a/agent/skills/fsskills/source.go b/agent/skills/fsski
... (truncated)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions