Feat: warn when a skill's resource payload exceeds the recommended size limit (adk-python parity) - #453
Open
AmaadMartin wants to merge 2 commits into
Open
Feat: warn when a skill's resource payload exceeds the recommended size limit (adk-python parity)#453AmaadMartin wants to merge 2 commits into
AmaadMartin wants to merge 2 commits into
Conversation
added 2 commits
August 5, 2026 23:02
A skill's references/, assets/ and scripts/ are shipped wholesale into a code executor by getSkillResourceFiles(). The Python SDK size-accounts that payload and warns above 16 MB; the JS SDK did not account for it at all, so a developer whose skill grew to hundreds of megabytes of assets got no signal until the executor itself failed or silently degraded far downstream. Accumulate the raw byte length of every resource that is actually shipped and log a single warning when the total exceeds MAX_SKILL_PAYLOAD_BYTES. The limit stays soft, matching the reference implementation: nothing is rejected, truncated or thrown, and the returned File[] is unchanged.
The four existing payload tests all use single-byte content, so they pass unchanged when the accumulator measures String.length instead of Buffer.byteLength. That is the exact defect this feature exists to avoid: a skill of multi-byte text is undercounted by up to 3x and never warns. Add a reference of 8,388,609 'é' characters. It is under the limit by String.length and over it by UTF-8 byte length, so it fails against a code-unit count. Add a second case that splits the payload across references and assets, so no single resource exceeds the limit but the total does.
AmaadMartin
force-pushed
the
feat/skill-payload-size-warning
branch
from
August 6, 2026 06:09
ff66d94 to
f775659
Compare
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.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
No existing issue.
Problem:
getSkillResourceFiles()ships a skill's wholereferences/,assets/andscripts/payload into a code executor on every script call. The TypeScript SDK measures none of it, so an oversized skill fails only later, inside the executor, with an opaque message.adk-pythonaccounts for the same payload and warns above a 16 MB soft limit.Solution: Sum the byte length of every resource that is actually shipped, and log one warning when the total exceeds
MAX_SKILL_PAYLOAD_BYTES. The limit stays soft, as in Python: nothing is rejected, truncated or thrown, and the returnedFile[]is unchanged. The accumulator runs after the existingfileContent === undefinedguard, so a skipped resource contributes 0 bytes.Deliberate deviations from the reference:
Buffer.byteLength, notString.prototype.length. Python'slen()over astrcounts code points, so the reference undercounts multi-byte text by up to 3x. Parity here is the behaviour, and a byte count is the correct implementation of it. Noadk-pythonchange is made._MAX_SKILL_PAYLOAD_BYTES. This repo forbids the leading underscore, so it isMAX_SKILL_PAYLOAD_BYTES. The value and the message wording are identical.Buffer.byteLengthaccepts astringand aBufferand returns the byte length of each, so one call replaces aBuffer.isBufferternary.The constant is not added to
index.tsorcommon.ts. This is not new public API.Testing Plan
Unit Tests:
Six cases in a new
describe('payload size accounting', ...)incore/test/tools/skills/run_skill_script_tool_test.ts. No existing test is modified, removed or weakened.Coverage of the new code is 100% of lines and branches, read from
coverage-final.json. The file's remaining uncovered lines (200-201, 216-217) predate this change. No coverage suppression was added.Mutation proofs. I mutated one source line per row, re-ran the targeted suite, then restored the source:
Buffer.byteLength(fileContent)->fileContent.lengthmeasures multi-byte text in UTF-8 bytes, not UTF-16 code unitsexpected "warn" to be called 1 times, but got 0 timestotalBytes >->totalBytes >=does not warn when skill resources are exactly at the limitexpected "warn" to not be called at all, but actually been called 1 timeslogger.warncallexpected "warn" to be called 1 times, but got 0 timestotalBytes +=->totalBytes =sums bytes across resource typesexpected "warn" to be called 1 times, but got 0 timesThe first mutation is why the multi-byte case exists. Every single-byte test passes against a
String.lengthcount, so those tests give no signal on the defect this feature guards against. The fixture is 8,388,609'é'characters: under the limit byString.length, over it by UTF-8 byte length.This change adds no error path.
getSkillResourceFilesdoes not throw and has noerrorCode. The negative path is "no warning", pinned by the under-limit and at-limit cases.Manual End-to-End (E2E) Tests:
No E2E test is included. The change alters neither the executor payload nor any tool response, so there is no cross-component contract to exercise. To check the log by hand, set the ADK log level to
warnand run a skill script whose resources exceed 16 MiB. The warning renders once:Repo gates on the pushed commit:
npm run buildpasses,npx eslinton both touched files is clean, andnpx prettier --checkreportsAll matched files use Prettier code style!.npm run ts:checkis already red onmain(280 errors). This diff adds zero new errors: the count is 280 before and after, and the one error in the touched test file is the pre-existingas Filecast in a test I did not change.Collision check. I listed all 697 fork PRs. Ten open PRs touch
run_skill_script_tool.ts(#634, #564, #556, #518, #517, #481, #410, #356, #353, #298), but none adds payload accounting:grep -icE 'byteLength|PAYLOAD_BYTES|payload size'over each diff returns 0. The overlap is textual only, inrunAsync, so this branches frommainrather than stacking.Checklist