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)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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