Expose content array alongside structuredContent in workflow templates#4384
Merged
Expose content array alongside structuredContent in workflow templates#4384
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4384 +/- ##
==========================================
+ Coverage 69.43% 69.49% +0.05%
==========================================
Files 485 485
Lines 49493 49514 +21
==========================================
+ Hits 34367 34409 +42
+ Misses 12466 12443 -23
- Partials 2660 2662 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
ContentArrayToMap previously ignored EmbeddedResource content types,
making it impossible for composite tool workflows to chain on embedded
resource data (e.g., an SBOM returned by get_referrer_content).
Handle ContentTypeResource in ContentArrayToMap with "resource",
"resource_1", "resource_2" key pattern. Expose the content array as
a separate template namespace ({{.steps.X.content.*}}) alongside the
existing output namespace ({{.steps.X.output.*}}), keeping
structuredContent clean for outputSchema validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
7318079 to
4b9613e
Compare
yrobla
approved these changes
Mar 26, 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.
Summary
structuredContentandcontentas separate concerns:structuredContentmust conform tooutputSchema, while thecontentarray is the backward-compatible representation (text, images, embedded resources). The vmcp workflow engine only exposedstructuredContentto templates, so composite tools could not access embedded resource data from downstream steps.ContentArrayToMapexplicitly ignoredEmbeddedResourcecontent types, so even the fallback path (nostructuredContent) dropped resource data.This PR:
ContentTypeResourceinContentArrayToMap, mapping embedded resource text/data toresource,resource_1, etc.Contentfield toStepResultand wires it through the workflow engine, so the raw content array is preserved alongsideStructuredContent.contentnamespace in templates via{{.steps.X.content.*}}, keepingstructuredContentclean foroutputSchemavalidation.Template access after this change:
{{.steps.get_sbom.output.format}}-- structuredContent field (schema-conformant){{.steps.get_sbom.content.resource}}-- embedded resource text from content array{{.steps.get_sbom.content.text}}-- text content from content arrayType of change
Test plan
task test)task lint-fix)Changes
pkg/vmcp/conversion/content.goContentTypeResourceinContentArrayToMapwithresource,resource_1, etc. key patternpkg/vmcp/composer/composer.goContent []vmcp.Contentfield toStepResultpkg/vmcp/composer/workflow_context.goRecordStepSuccessto accept and store Content; fixClone()to copy itpkg/vmcp/composer/workflow_engine.goToolCallResultfromcallToolWithRetry; pass Content through toRecordStepSuccesspkg/vmcp/composer/template_expander.gocontentkey inbuildStepsContextviaContentArrayToMappkg/vmcp/client/client.gopkg/vmcp/session/internal/backend/mcp_session.gopkg/vmcp/conversion/conversion_test.goContentArrayToMappkg/vmcp/composer/template_expander_test.go{{.steps.X.content.resource}}and namespace independencepkg/vmcp/composer/workflow_engine_test.go.contentand structured data via.outputDoes this introduce a user-facing change?
Composite tool workflows can now access embedded resource content from downstream steps via
{{.steps.stepID.content.resource}}. Structured output remains accessible via{{.steps.stepID.output.field}}as before.Special notes for reviewers
The key design decision is keeping
outputandcontentas independent template namespaces rather than merging content array keys into structuredContent. Merging would violateoutputSchemavalidation whenadditionalProperties: falseis set, since the extra keys from the content array would fail schema checks.When a backend returns only a Content array (no StructuredContent),
outputandcontentboth resolve toContentArrayToMap(result.Content), so{{.steps.X.output.text}}and{{.steps.X.content.text}}return the same value. This is the expected fallback behavior.Generated with Claude Code