v1.1.1
Breaking: Bedrock runs on aiobotocore
BedrockConfig now uses a native async client (aiobotocore) instead of wrapping synchronous boto3 in a thread per call and per streamed event. Every Converse request is also type-checked against the service's own stubs.
BedrockConfig(session=...)takes anaiobotocore.session.AioSession. Aboto3.Sessionfails on the first call withAttributeError: 'Session' object has no attribute 'create_client'.- The
bedrockextra installsaiobotocore>=3.9.1,<4instead ofboto3. If your application also installs boto3, pick a version whose botocore fits aiobotocore's pin. - Explicit keys and
region_namepassed together withsession=now apply. They used to be silently ignored.
from aiobotocore.session import AioSession
config = BedrockConfig(model=MODEL_ID, session=AioSession(profile="prod"))Security
Restricted shell mode runs commands without a shell. With allowed=[...] or readonly=True, SandboxShellTool / ShellAdapter split the command into argv once, check that argv, and run exactly it. Nothing can expand after the check, so separators, substitutions and brace expansion can no longer smuggle a second command past the allow-list. Consequences:
- Pipes, redirects, chaining, globs,
~and variables are not available in restricted mode. Shell syntax is refused with a clear error, and globs reach the program literally. readonly=Trueonly allows commands that cannot write files or run other programs.find,file,sort,uniqandgit …are no longer in the built-in set; list the ones you need inallowed.blocked=[...]is unchanged and remains best-effort. It is not a security boundary.
shell = SandboxShellTool(LocalEnvironment("/repo"), allowed=["cat", "ls", "grep", "git log"])Tools that share a name resolve to exactly one tool. A model call used to reach every tool with that name, so an approval decision on one did not bind its twin. Now each turn exposes one tool per name:
- Tools declared in code override each other by order, and the later one wins.
Agent(tools=[toolkit, my_deploy])replaces the toolkit'sdeploy. - Tools discovered at runtime (MCP) and client tools rank below code-declared ones. An MCP server can no longer shadow a local tool; a colliding MCP tool is dropped with a warning suggesting
tool_name_prefix. - Approval grants are keyed by tool implementation.
Redis pickle serializer. The docs now state that Serializer.PICKLE gives code execution to anyone who can write to the stream's Redis, so use it only with a fully trusted Redis instance. JSON remains the default.
Also in this release
- Human input over AG-UI. A tool in a served agent can call
context.input(). The question reaches the AG-UI client as the run's interrupt outcome, and the answer comes back in the next run'sresume. - MCP conversations survive long turns.
SessionStoreidle expiry and LRU overflow no longer drop a conversation while a turn is running on it. Thanks to @simpleqt for finding and first fixing this. - One
Authorizationheader.MCPToolkitandMCPServerToolsend exactly oneAuthorizationheader on every provider, whatever the casing of an explicit header next toauthorization_token. - Network fixes.
delegate()closes its channel when the first message fails to send, and thecontext()tool rejects non-positivelimit/recent_n.
What's Changed
- refactor(bedrock)!: type the Converse request and run the client on aiobotocore by @vvlrff in #3271
- fix(mcp): preserve explicit authorization headers regardless of casing by @asts-top in #3297
- fix(mcp): send one Authorization header from MCPServerTool on every provider by @Lancetnik in #3299
- docs(streams): warn that the Redis pickle serializer trusts everything in Redis by @Lancetnik in #3294
- feat(ag-ui): ask the human a question mid-run, and be answered by @vvlrff in #3248
- chore(deps): bump the github-actions group with 3 updates by @dependabot[bot] in #3301
- chore(deps): bump the uv group across 1 directory with 12 updates by @dependabot[bot] in #3307
- fix(network): close delegate channel when prompt send fails by @elCaptnCode in #3304
- fix(network): validate context result counts by @elCaptnCode in #3305
- ci: report license/cla on merge-group commits by @Lancetnik in #3312
- fix(mcp): never evict a session store entry with a turn in flight by @simpleqt in #3288
- fix(mcp): keep a conversation alive while any turn runs on it by @vvlrff in #3311
- chore: bump version to 1.1.1 by @Lancetnik in #3318
- chore(deps): bump pyjwt from 2.13.0 to 2.14.0 by @dependabot[bot] in #3319
Full Changelog: v1.1.0...v1.1.1