Python: Allow custom argument parsing for skill scripts#6817
Merged
Conversation
Add an optional argument_marshaler hook so callers can plug in their own argument conversion logic for inline skill scripts. Supplied at the InlineSkillScript, InlineSkill, and ClassSkill levels; when omitted, behavior is unchanged. This supports backends (e.g. vLLM) that send tool-call arguments in a non-conforming shape such as a JSON string. Port of .NET PR microsoft#6498. Closes microsoft#6543. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
Python Test Coverage Report •
Python Unit Test Overview
|
||||||||||||||||||||||||||||||
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds an opt-in customization hook in the Python skills runtime to convert (“marshal”) raw tool-call args into the shape expected by inline skill scripts, enabling compatibility with OpenAI-compatible backends that send arguments in non-object forms (e.g., JSON strings).
Changes:
- Introduces
SkillScriptArgumentMarshalerand wires it throughInlineSkillScript,InlineSkill(decorator-added scripts), andClassSkill(discovered scripts). - Applies the marshaler in
InlineSkillScript.run()prior to the existing list-args guard. - Exports the new alias publicly, adds documentation, and adds unit tests covering the propagation + end-to-end provider flow.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| python/packages/core/agent_framework/_skills.py | Adds the marshaler alias and plumbs it through inline/class skill script creation and execution. |
| python/packages/core/agent_framework/init.py | Exports SkillScriptArgumentMarshaler as part of the public package API. |
| python/packages/core/AGENTS.md | Documents the new marshaling hook and where it can be configured. |
| python/packages/core/tests/core/test_skills.py | Adds tests for marshaling behavior and propagation at script/skill/provider levels. |
- Widen InlineSkillScript.run args to accept a raw str (the one place a marshaler-converted value is valid), and drop the now-unneeded type: ignore markers in tests. - Constrain the SkillScriptArgumentMarshaler output type to dict | None so the type enforces the inline-script contract instead of a docstring note. - Add a clear TypeError when a str reaches an inline script with no marshaler configured. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SergeyMenshykh
approved these changes
Jun 30, 2026
In Python 'marshalling' specifically connotes the stdlib marshal module, so the term is misleading here. Rename the type alias, the argument_parser parameter/attribute, docstrings, exports, and tests accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
TaoChenOSU
approved these changes
Jun 30, 2026
The skill constructors are fully keyword-only, so name/description/function are already documented under Args. Singling out argument_parser into its own Keyword Args section was inconsistent; merge it into Args for InlineSkillScript, InlineSkill, and ClassSkill. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
TaoChenOSU
approved these changes
Jun 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation & Context
vLLM and some other OpenAI-compatible backends send tool-call arguments in a non-conforming shape (for example, as a JSON string
"{\"query\":\"hello\"}"instead of a JSON object). Inline skill scripts bind arguments by keyword name and expect a JSON object (adict), so arguments arriving in another shape cannot be handled and the call fails.This mirrors the scenario fixed on the .NET side, letting callers plug in their own argument conversion logic so skill scripts work against these backends.
Description & Review Guide
What are the major changes?
SkillScriptArgumentParsertype alias: an optional callable(raw args: dict | list[str] | str | None) -> dict | Nonethat converts the rawargsvalue into named keyword arguments before an inline script runs.InlineSkillScriptconstructor — per script.InlineSkillconstructor — default for scripts added via@skill.script.ClassSkillconstructor — default for scripts discovered via@ClassSkill.script.InlineSkillScript.run(), the parser is applied first, before the existing inline list-args guard. A rawstrreaching an inline script with no parser configured raises a clearTypeError.agent_frameworkand documents it in the core packageAGENTS.md.What is the impact of these changes?
None, leaving existing behavior unchanged (arguments are used as-is, expecting adictorNone).dict | None, so the type system enforces the inline-script contract (inline scripts bind by keyword name).SkillScriptRunneralready owns argument handling, matching the .NET scoping to inline scripts.What do you want reviewers to focus on?
Related Issue
Closes #6543
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.