Skip to content

v1.1.1

Latest

Choose a tag to compare

@Lancetnik Lancetnik released this 29 Sep 20:49
72dcc9d

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 an aiobotocore.session.AioSession. A boto3.Session fails on the first call with AttributeError: 'Session' object has no attribute 'create_client'.
  • The bedrock extra installs aiobotocore>=3.9.1,<4 instead of boto3. If your application also installs boto3, pick a version whose botocore fits aiobotocore's pin.
  • Explicit keys and region_name passed together with session= 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=True only allows commands that cannot write files or run other programs. find, file, sort, uniq and git … are no longer in the built-in set; list the ones you need in allowed.
  • 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's deploy.
  • 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's resume.
  • MCP conversations survive long turns. SessionStore idle 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 Authorization header. MCPToolkit and MCPServerTool send exactly one Authorization header on every provider, whatever the casing of an explicit header next to authorization_token.
  • Network fixes. delegate() closes its channel when the first message fails to send, and the context() tool rejects non-positive limit / 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