BYOC creation method, manylinux_2_28 dependency resolution, free-form runtime replies, list-first agent management - #128
Open
alex-sample-code wants to merge 4 commits into
Open
alex-sample-code wants to merge 4 commits into
alex-sample-code wants to merge 4 commits into
Conversation
A fourth wizard card deploys code the member's developers wrote themselves,
already wrapped with the AgentCore SDK (BedrockAgentCoreApp) or any HTTP
server satisfying the Runtime contract (ARM64, :8080, POST /invocations +
GET /ping). One spec.byoc block, three artifact kinds:
- code_zip zip of Python source staged via POST /api/agents/uploads,
resolved for linux/aarch64 and deployed as a direct-code
Runtime (codeConfiguration, member's Python version +
entrypoint)
- container_source zip carrying a Dockerfile, built by the shared
launchpad-agent-builder CodeBuild project (the platform
buildspec is injected into the zip) -> ECR -> Runtime
- container_image an existing image in this account's private ECR,
verified with DescribeImages, deployed as-is
Security model: developers need no IAM — uploads and deploys carry
perm:agents.deploy. Each agent gets its own least-privilege execution role;
bedrock:InvokeModel covers exactly spec.byoc.allowed_models (1–20 ids,
primary injected as env MODEL_ID, full list as ALLOWED_MODEL_IDS). Uploads
are workspace-scoped under byoc/{workspace_id}/{upload_id}/ with provenance
stamped server-side. The spoke role gains read-only ecr:DescribeImages on
the account's repositories for container_image.
Wizard: upload with detected entrypoints / requirements / SDK markers,
allowed-models list, BYOC provenance on the detail view. Samples under
samples/byoc (hello-http, hello-container), lab chapter 13, architecture
and API docs (en + zh-CN).
… handling, upload-time pre-resolve
The zip deploy paths (byoc code_zip + platform zip runtimes) resolved
Python dependencies for manylinux2014, the docs' conservative
recommendation. Measured from inside a deployed AgentCore Runtime
direct-code agent (2026-09-18): AL2023, aarch64, glibc 2.34 — so
packages that only ship manylinux_2_26/2_28 aarch64 wheels (google-re2,
pulled in by chromadb) were unsolvable despite running fine there.
- app/core/runtime_target.py: one definition of the resolve/install
target, default manylinux_2_28, configurable via
runtime_python_platform (LAUNCHPAD_RUNTIME_PYTHON_PLATFORM;
manylinux2014 stays the documented fallback). pip gets the full tag
ladder down to manylinux2014 because it treats --platform as exact
strings; uv widens from one tag itself. Consumed by zip_runtime,
byoc and schemas/requirements.resolve_pins — still --only-binary,
user code is never built or executed on the control plane.
- app/services/requirements_txt.py: pip-format parsing for uploaded
requirements.txt (continuations, inline comments, markers; --hash
dropped — the platform re-locks with its own hashes), supply-chain
rejections (-r/-c, -e, local paths, URL/VCS, index options, >500
entries), and a resolver-failure summarizer that names the offending
package + reason + fix hints instead of dumping uv's derivation tree.
- POST /api/agents/uploads pre-resolves the zip's requirements.txt
against the target (optional ?python_version=, 90s bound, threadpool)
and returns detected.requirements {status, package_count, error}; the
BYOC wizard shows the verdict and re-checks on Python version change.
- Docs: architecture (+zh), api (+zh), lab 13, samples/byoc README.
The Runtime HTTP contract requires JSON or SSE and names no key, but
_runtime_payload_events only read {"result"} (BedrockAgentCoreApp's
convention), the delta/tool/complete envelope and Converse events. A BYOC
agent answering its own JSON — measured 2026-09-18: a CrewAI agent
returning {"answer", "session_id", "turns", "latency_ms"} — produced
an empty chat turn with no error while CloudWatch showed the invocation
succeeding.
- Bodies with none of the known keys now take the first conventional text
key (response, answer, output, output_text, text, message, content,
completion, reply; a nested {"text"} block under one counts), and a
body with none of those is shown as compact JSON (4000-char cap) with a
warning log, never as a blank turn. {"result"} still wins; {"error"}
still raises; Converse bookkeeping events stay silent.
- Tests for each shape; docs (architecture en/zh, lab 13, samples/byoc
README) now state the response contract.
…ents/:id
The management page at /create hosted the 3-step wizard and the agent list
on one route, with discovery hidden behind ?view=discover. Split it into
routes without touching the wizard's state machine:
/agents list landing: + New Agent / Import existing Runtime,
stats strip (total / running / deploying / failed), the
agent table — name links to the detail, CHAT + DETAILS
visible, EDIT / CONVERT / DELETE in a per-row "···" menu
(portalled so the last row is never clipped), FAILED rows
carry the error as tooltip + VIEW REASON, relative
UPDATED time, empty state with a create CTA
/agents/new the wizard: four method cards (equal height), a button
to the import page, the system-preset cards beneath
/agents/import discovery of existing Runtime / Harness resources
/agents/:id the agent's detail (launch sequence, versions, BYOC
provenance; live polling while deploying; OPEN CHAT /
OBSERVABILITY / EDIT). A deploy from /agents/new hands
over here when it goes active
/agents/:id/edit the wizard preloaded for a re-publish
/create[?...] redirects (?view=discover -> /agents/import, otherwise
/agents/new with the query kept for Registry prefill)
Sidebar target, ROUTE_PATHS, every in-app navigate()/Link, the preset
settings mock script and the docs (architecture en/zh, lab 02/03/13,
studio-integration) follow. en + zh-CN keys under agents.*.
alex-sample-code
marked this pull request as ready for review
September 18, 2026 14:18
alex-sample-code
force-pushed
the
feat/byoc
branch
from
September 19, 2026 11:50
03a8061 to
3178ade
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.
Summary
Four commits, each independently reviewable:
spec.byocblock:code_zip(direct-code Runtime),container_source(Dockerfile → the sharedlaunchpad-agent-builderCodeBuild project → ECR → Runtime),container_image(an existing private-ECR image in this account, verified withDescribeImages). Developers need no IAM: uploads and deploys carryperm:agents.deploy; each agent gets its own least-privilege execution role whosebedrock:InvokeModelcovers exactlyspec.byoc.allowed_models(primary injected asMODEL_ID, list asALLOWED_MODEL_IDS). Samples undersamples/byoc/, lab chapter 13, architecture/API docs (en + zh-CN).manylinux2014(the docs' conservative example). Measured from inside a deployed direct-code Runtime (2026-09-18): AL2023, aarch64, glibc 2.34 — so packages shipping onlymanylinux_2_26/2_28aarch64 wheels (e.g.google-re2, pulled in by chromadb) were unsolvable. One resolve/install target (app/core/runtime_target.py, defaultmanylinux_2_28,LAUNCHPAD_RUNTIME_PYTHON_PLATFORMfalls back tomanylinux2014); pip gets the full tag ladder because--platformis an exact match, uv widens itself. Uploadedrequirements.txtis parsed in pip format (continuations, comments, markers;--hashdropped and re-locked), supply-chain entries refused (-r/-c,-e, local paths, URL/VCS, index options), andPOST /api/agents/uploadspre-resolves so the wizard names the offending package before a deploy is attempted.{"result"}. A BYOC agent answering{"answer", "session_id", …}produced an empty turn with no error while CloudWatch showed the invocation succeeding. Conventional text keys are now read (response,answer,output,text,message, …), anything else is shown as compact JSON,{"error"}still surfaces as a failed turn. Docs state the response contract./createsplit into/agents(list + stats),/agents/new(wizard, system presets beneath the four cards),/agents/import(discovery),/agents/:id(detail, live while deploying),/agents/:id/edit;/create[?…]redirects with the query kept. Row actions collapse into a portalled···menu; failed rows expose the reason.Verification
env -u AWS_REGION make verifyon this branch after rebase ontomain: ruff / pytest (4497) / infra ruff / infra pytest (47) / eslint / tsc / vite build / i18n_check / i18n_zh_punct — all OK.uv sync+npm ci→make verifyalso green (no dependency or lockfile changes; the only new setting has a default; no schema migration).code_zipandcontainer_sourceboth reach READY and answer through Chat; arequirements.txtwith\continuations +--hash+google-re2pre-resolves (21 packages), deploys in ~50 s, andimport re2succeeds at invocation time (glibc 2.34); a--index-urlentry is refused at upload with the reason. A probe agent answering{"answer": …}renders in Chat after (3). The/agents*routes and redirects were exercised in a browser.Notes for reviewers
container_imageneeds the spoke role toecr:DescribeImageson repositories other thanlaunchpad-agents; the template gains a read-only statement for that (the agent's own execution role still receives the pull grant scoped to its repository)./create; they resolve through the redirect.