Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
221 commits
Select commit Hold shift + click to select a range
dd76000
Use strands logo that looks good in dark & light mode (#505)
zastrowm Jul 21, 2025
24ccb00
deps(a2a): address interface changes and bump min version (#515)
jer96 Jul 22, 2025
6905342
ci: expose STRANDS_TEST_API_KEYS_SECRET_NAME to integration tests (#513)
dbschmigelski Jul 22, 2025
5a7076b
Don't re-run workflows on un/approvals (#516)
zastrowm Jul 22, 2025
9aba018
Fixing some typos in various texts (#487)
didier-durand Jul 22, 2025
040ba21
docs(readme): add hot reloading documentation for load_tools_from_dir…
cagataycali Jul 22, 2025
022ec55
ci: enable integ tests for anthropic, cohere, mistral, openai, writer…
dbschmigelski Jul 22, 2025
e597e07
Automatically flatten nested tool collections (#508)
zastrowm Jul 23, 2025
4f4e5ef
feat(a2a): support mounts for containerized deployments (#524)
jer96 Jul 23, 2025
b30e7e6
fix: include agent trace into tool for agent as tools (#526)
poshinchen Jul 23, 2025
8c55625
Support for Amazon SageMaker AI endpoints as Model Provider (#176)
dgallitelli Jul 28, 2025
3f4c3a3
fix: Remove leftover print statement from sagemaker model provider (#…
mehtarac Jul 28, 2025
bdc893b
[Feat] Update structured output error message (#563)
Unshure Jul 29, 2025
4e0e0a6
feat(mcp): retain structured content in the AgentTool response (#528)
dbschmigelski Jul 29, 2025
b13c5c5
feat(mcp): Add list_prompts, get_prompt methods (#160)
Ketansuhaas Jul 30, 2025
3d526f2
fix(deps): pin a2a-sdk>=0.2.16 to resolve #572 (#581)
minorun365 Jul 31, 2025
b56a4ff
chore: pin a2a to a minor version while it is still in beta (#586)
dbschmigelski Aug 1, 2025
8b1de4d
fix: uses new a2a snake_case for lints to pass (#591)
theagenticguy Aug 1, 2025
c85464c
fix(event_loop): raise dedicated exception when encountering max toke…
dbschmigelski Aug 1, 2025
34d499a
fix(telemetry): added mcp tracing context propagation (#569)
poshinchen Aug 5, 2025
09ca806
Change max_tokens type to int to match Anthropic API (#588)
vinc3m1 Aug 5, 2025
bf24ebf
feat: Add additional intructions for contributors to find issues that…
mehtarac Aug 6, 2025
297ec5c
feat(a2a): configurable request handler (#601)
jer96 Aug 6, 2025
ec5304c
chore(a2a): update host per AppSec recommendation (#619)
jer96 Aug 6, 2025
29b2127
fix(event_loop): ensure tool_use content blocks are valid after max_t…
dbschmigelski Aug 8, 2025
adac26f
fix(structured_output): do not modify conversation_history when promp…
dbschmigelski Aug 8, 2025
99963b6
feature(graph): Allow cyclic graphs (#497)
mkmeral Aug 11, 2025
72709cf
chore: request to include code snippet section (#654)
poshinchen Aug 11, 2025
8434409
feat: Add configuration option to MCP Client for server init timeout …
fhwilton55 Aug 12, 2025
49ff226
fix: Bedrock hang when exception occurs during message conversion (#643)
zastrowm Aug 13, 2025
0455756
feat: add structured_output_span (#655)
poshinchen Aug 13, 2025
1c7257b
litellm - set 1.73.1 as minimum version (#668)
pgrayy Aug 14, 2025
606f657
feat: expose tool_use and agent through ToolContext to decorated tool…
dbschmigelski Aug 14, 2025
8c63d75
session manager - prevent file path injection (#680)
pgrayy Aug 15, 2025
fbd598a
fix: only set signature in message if signature was provided by the m…
clareliguori Aug 18, 2025
ae74aa3
fix: Add openai dependency to sagemaker dependency group (#678)
zastrowm Aug 18, 2025
980a988
Have [all] group reference the other optional dependency groups by na…
zastrowm Aug 18, 2025
b1df148
fix: append blank text content if assistant content is empty (#677)
poshinchen Aug 18, 2025
cfcf93d
feat: add cached token metrics support for Amazon Bedrock (#531)
oaltagar-aws Aug 18, 2025
c087f18
fix: fix non-serializable parameter of agent from toolUse block (#568)
JackYPCOnline Aug 19, 2025
17ccdd2
chore: add .DS_Store to .gitignore (#681)
vawsgit Aug 19, 2025
ef18a25
feat(a2a): support A2A FileParts and DataParts (#596)
jer96 Aug 20, 2025
60dcb45
ci: update pre-commit requirement from <4.2.0,>=3.2.0 to >=3.2.0,<4.4…
dependabot[bot] Aug 20, 2025
b61a064
ci: update ruff requirement from <0.5.0,>=0.4.4 to >=0.4.4,<0.13.0 (#…
dependabot[bot] Aug 21, 2025
93d3ac8
ci: update pytest-asyncio requirement from <0.27.0,>=0.26.0 to >=0.26…
dependabot[bot] Aug 21, 2025
9397f58
fix: add system_prompt to structured_output_span before adding input_…
chengweitsai Aug 21, 2025
6ef6447
feat(multiagent): Add __call__ implementation to MultiAgentBase (#645)
mkmeral Aug 25, 2025
e4879e1
chore: Update pydantic minimum version (#723)
mehtarac Aug 25, 2025
c18ef93
tool executors (#658)
pgrayy Aug 25, 2025
dbe0fea
feat: Add support for agent invoke with no input, or Message input (#…
Unshure Aug 25, 2025
b156ea6
ci: bump actions/checkout from 4 to 5 (#711)
dependabot[bot] Aug 25, 2025
0283169
ci: bump actions/download-artifact from 4 to 5 (#712)
dependabot[bot] Aug 25, 2025
e5e308f
ci: update pytest-cov requirement from <5.0.0,>=4.1.0 to >=4.1.0,<7.0…
dependabot[bot] Aug 25, 2025
918f094
fix: prevent path traversal for message_id in file_session_manager (#…
mehtarac Aug 25, 2025
f028dc9
fix: Add AgentInput TypeAlias (#738)
Unshure Aug 25, 2025
0fac648
fix: Move AgentInput to types submodule (#746)
Unshure Aug 26, 2025
aa03b3d
feat: Implement typed events internally (#745)
zastrowm Aug 27, 2025
d9f8d8a
summarization manager - add summary prompt to messages (#698)
pgrayy Aug 28, 2025
6dadbce
feat: Use TypedEvent inheritance for callback behavior (#755)
zastrowm Aug 28, 2025
47faba0
feat: claude citation support with BedrockModel (#631)
theagenticguy Aug 28, 2025
94b41b4
feat: Enable hooks for MultiAgents (#760)
zastrowm Aug 28, 2025
b008cf5
Add invocation_state to ToolContext (#761)
zastrowm Aug 28, 2025
ae9d5ad
feat(models): Add VPC endpoint support to BedrockModel class (#502)
dbavro19 Aug 29, 2025
7a5caad
fix: fix stop reason for bedrock model when stop_reason (#767)
JackYPCOnline Aug 29, 2025
cb4b7fb
fix: Fix tool result message event (#771)
zastrowm Aug 29, 2025
e7d95d6
fix: fix loading tools with same tool name (#772)
JackYPCOnline Aug 29, 2025
237e188
fix: don't emit ToolStream events for non generator functions (#773)
zastrowm Sep 3, 2025
4dee33b
fix(tests): adjust test_bedrock_guardrails to account for async behav…
dbschmigelski Sep 3, 2025
2db5226
fix(doc): replace invalid Hook names in doc comment with BeforeInvoca…
deepyes02 Sep 3, 2025
1e6d12d
fix: Remove status field from toolResult for non-claude 3 models in B…
mehtarac Sep 4, 2025
ed33868
fix: filter 'SDK_UNKNOWN_MEMBER' from response content (#798)
JackYPCOnline Sep 4, 2025
d07629f
feat: Implement async generator tools (#788)
zastrowm Sep 4, 2025
ec000b8
ci: update openai requirement from <1.100.0 to <1.102.0 (#722)
dependabot[bot] Sep 5, 2025
d77f08b
fix: only add signature to reasoning blocks if signature is provided …
zastrowm Sep 5, 2025
faeb21a
fix: Moved tool_spec retrieval to after the before model invocation c…
pghazanfari Sep 8, 2025
b568864
fix(graph): fix cyclic graph behavior (#768)
mkmeral Sep 8, 2025
8cb53d3
fix(models): filter reasoningContent in Bedrock requests using DeepSe…
aryan835-datainflexion Sep 8, 2025
c142e7a
docs: cleanup docs so the yields section renders correctly (#820)
afarntrog Sep 8, 2025
f185c52
feat: Warn on unknown model configuration properties (#819)
zastrowm Sep 8, 2025
1f27488
fix: do not block asyncio event loop between retries (#805)
osdemah Sep 8, 2025
5420679
feat: improve structured output tool circular reference handling (#817)
afarntrog Sep 8, 2025
6ab1aca
fix(tools/loader): load and register all decorated @tool functions fr…
Ratish1 Sep 9, 2025
d66fcdb
fix(models): patch litellm bug to honor passing in use_litellm_proxy …
dbschmigelski Sep 9, 2025
9213bc5
feat: add default read timeout to Bedrock model (#829)
afarntrog Sep 9, 2025
001aa93
feat: add support for Bedrock/Anthropic ToolChoice to structured_outp…
liushang1997 Sep 10, 2025
7f58ce9
feat(multiagent): allow callers of swarm and graph to pass kwargs to …
dbschmigelski Sep 10, 2025
64d61e0
feat: add region-aware default model ID for Bedrock (#835)
afarntrog Sep 10, 2025
ab125f5
llama.cpp model provider support (#585)
westonbrown Sep 10, 2025
4fbe46a
fix(llama.cpp) - add ToolChoice and validation of model config values…
awsarron Sep 10, 2025
bf4e3e4
feat(telemetry): add cache usage metrics to OpenTelemetry spans (#825)
vamgan Sep 11, 2025
7f77a59
docs: improve docstring formatting for `invoke_async` function in `A…
waitasecant Sep 11, 2025
7d1bdbf
ci: bump actions/setup-python from 5 to 6 (#796)
dependabot[bot] Sep 11, 2025
eace0ec
ci: bump actions/github-script from 7 to 8 (#801)
dependabot[bot] Sep 11, 2025
fe7a700
ci: bump aws-actions/configure-aws-credentials from 4 to 5 (#795)
dependabot[bot] Sep 11, 2025
f12fee8
fix: Add type to tool_input (#854)
Unshure Sep 12, 2025
cbdab32
feat(swarm): Make entry point configurable (#851)
mkmeral Sep 12, 2025
5790a9c
ci: update ruff requirement from <0.13.0,>=0.12.0 to >=0.12.0,<0.14.0…
dependabot[bot] Sep 12, 2025
6a1b2d4
ci: update openai requirement (#827)
dependabot[bot] Sep 12, 2025
066a427
feat: add automated issue auto-close workflows with dry-run testing (…
yonib05 Sep 12, 2025
500d01a
fix: Clean up pyproject.toml (#844)
Unshure Sep 12, 2025
69d3910
Fixing documentation in decorator.py (#852)
prabhuteja12 Sep 12, 2025
6ccc8e7
models - openai - use client context (#856)
pgrayy Sep 15, 2025
8122453
Feature: Handle Bedrock redactedContent (#848)
afarntrog Sep 15, 2025
7226025
fix(telemetry): correctly label tool result messages in OpenTelemetry…
vamgan Sep 15, 2025
4b29edc
models - openai - client context comment (#864)
pgrayy Sep 16, 2025
8805021
fix(test): litellm structured_output test with more descriptive model…
dbschmigelski Sep 16, 2025
03c62f7
fix(mcp): auto cleanup on exceptions occurring in __enter__ (#833)
dbschmigelski Sep 16, 2025
2a5f0f1
fix(mcp): do not verify _background_session is present in stop() (#876)
dbschmigelski Sep 16, 2025
1f25512
docs(readme): fix links and imports, document all model providers (#837)
awsarron Sep 16, 2025
406458d
feat: decouple Strands ContentBlock and BedrockModel (#836)
dbschmigelski Sep 18, 2025
a36255d
fix: Invoke callback handler for structured_output (#857)
zastrowm Sep 18, 2025
4b10c93
fix: Update prepare to use format instead of test-format (#858)
zastrowm Sep 18, 2025
68103f6
fix: add explicit permissions to auto-close workflow (#893)
Unshure Sep 18, 2025
337c43e
fix: make mcp_instrumentation idempotent to prevent recursion errors …
Unshure Sep 18, 2025
98f7cde
fix: Fix github workflow to use fmt instead of hatch run (#898)
Unshure Sep 19, 2025
00a1f28
fix(models): make tool_choice an optional keyword arg instead positio…
dbschmigelski Sep 19, 2025
6ea8f72
feat: add optional outputSchema support for tool specifications (#818)
vamgan Sep 19, 2025
54bc162
feat: add Gemini model provider (#725)
notgitika Sep 20, 2025
f5e2070
Improve OpenAI error handling (#918)
mkmeral Sep 25, 2025
d1536b9
ci: update sphinx-autodoc-typehints requirement (#903)
dependabot[bot] Sep 26, 2025
fac0757
ci: update sphinx requirement from <6.0.0,>=5.0.0 to >=5.0.0,<9.0.0 (…
dependabot[bot] Sep 26, 2025
c857970
ci: update openai requirement (#916)
dependabot[bot] Sep 26, 2025
01d8fac
ci: update pytest-asyncio requirement (#861)
dependabot[bot] Sep 26, 2025
439653d
fix(gemini): Fix event loop closed error from Gemini asyncio (#932)
mkmeral Sep 26, 2025
04669d8
fix: Fix mcp timeout issue (#922)
Unshure Sep 26, 2025
ecd9eab
feat: add supports_hot_reload property to PythonAgentTool (#928)
cagataycali Sep 26, 2025
99cd49b
feat(hooks): Mark ModelCall and ToolCall events as non-experimental (…
zastrowm Sep 26, 2025
eef11cc
feat: Create a new HookEvent for Multiagent (#925)
JackYPCOnline Sep 26, 2025
921ca89
fix: GeminiModel argument (#955)
tosi29 Oct 1, 2025
81c00e4
tool - executors - concurrent - remove no-op gather (#954)
pgrayy Oct 2, 2025
2493545
feat(telemetry): updated traces to match OTEL v1.37 semantic conventi…
poshinchen Oct 2, 2025
428750b
event loop - handle model execution (#958)
pgrayy Oct 2, 2025
08dc4ae
feat: implement concurrent message reading for session managers (#897)
vamgan Oct 2, 2025
bab1270
hooks - before tool call event - cancel tool (#964)
pgrayy Oct 3, 2025
776fd93
fix(telemetry): removed double serialization for events (#977)
poshinchen Oct 4, 2025
2a26ffa
fix(litellm): map LiteLLM context-window errors to ContextWindowOverf…
Ratish1 Oct 7, 2025
171779a
feat: Refactor and update tool loading to support modules (#989)
Unshure Oct 8, 2025
1790b2d
Adding Development Tenets to CONTRIBUTING.md (#1009)
Unshure Oct 8, 2025
92da544
Revert "feat: implement concurrent message reading for session manage…
pgrayy Oct 9, 2025
2f04758
feat(models): use tool for litellm structured_output when supports_re…
dbschmigelski Oct 9, 2025
aada326
feat(mcp): Add EmbeddedResource support to mcp (#726)
KyMidd Oct 9, 2025
9632ed5
conversation manager - summarization - noop tool (#1003)
pgrayy Oct 9, 2025
419de19
Fix additional_args passing in SageMakerAIModel (#983)
athewsey Oct 10, 2025
7fbc9dc
feat: replace kwargs with invocation_state in agent APIs (#966)
JackYPCOnline Oct 10, 2025
355b3bb
feat(telemetry): updated semantic conventions, added timeToFirstByteM…
poshinchen Oct 14, 2025
c3e5f6b
chore(telemetry): added gen_ai.tool.description and gen_ai.tool.json_…
poshinchen Oct 14, 2025
6cf4f7e
fix(tool/decorator): validate ToolContext parameter name and raise cl…
Ratish1 Oct 14, 2025
f7931c5
integ tests - fix flaky structured output test (#1030)
pgrayy Oct 14, 2025
dbf6200
hooks - before tool call event - interrupt (#987)
pgrayy Oct 15, 2025
61e41da
multiagents - temporarily raise exception when interrupted (#1038)
pgrayy Oct 16, 2025
7cd10b9
feat: Support adding exception notes for Python 3.10 (#1034)
zastrowm Oct 16, 2025
26862e4
interrupts - decorated tools (#1041)
pgrayy Oct 17, 2025
3a7af77
models - litellm - start and stop reasoning (#947)
pgrayy Oct 21, 2025
b69478b
feat: add experimental AgentConfig with comprehensive tool management…
mr-lee Oct 21, 2025
78c59b9
fix(telemetry): make strands agent invoke_agent span as INTERNAL span…
poshinchen Oct 21, 2025
8a89d91
feat: add multiagent hooks, add serialize & deserialize function to m…
JackYPCOnline Oct 22, 2025
648af22
feat: Add Structured Output as part of the agent loop (#943)
afarntrog Oct 22, 2025
de802fb
integ tests - interrupts - remove asyncio marker (#1045)
pgrayy Oct 23, 2025
d4ef8bf
interrupt - docstring - fix formatting (#1074)
pgrayy Oct 24, 2025
1544384
ci: add pr size labeler (#1082)
dbschmigelski Oct 24, 2025
999e654
fix: Don't bail out if there are no tool_uses (#1087)
zastrowm Oct 24, 2025
3446938
feat(mcp): add experimental agent managed connection via ToolProvider…
dbschmigelski Oct 27, 2025
73865d3
fix (bug): retry on varying Bedrock throttlingexception cases (#1096)
mehtarac Oct 27, 2025
2147920
feat: skip model invocation when latest message contains ToolUse (#1068)
Unshure Oct 27, 2025
071f89f
direct tool call - interrupt not allowed (#1097)
pgrayy Oct 27, 2025
49e432d
mcp elicitation (#1094)
pgrayy Oct 28, 2025
104ecb5
fix(litellm): enhance structured output handling (#1021)
Arindam200 Oct 28, 2025
c2ba0f7
Transform invalid tool usages on sending, not on initial detection (#…
zastrowm Oct 28, 2025
4e49d9a
fix: (bug): Drop reasoningContent from request (#1099)
mehtarac Oct 29, 2025
c302a8a
fix: Dont initialize an agent on swarm init (#1107)
Unshure Oct 29, 2025
95906fa
feat: add multiagent session/repository management. (#1071)
JackYPCOnline Oct 29, 2025
111e77c
feat(multiagent): Add stream_async (#961)
mkmeral Oct 31, 2025
ce5c662
fix: properly redact toolResult blocks (#1080)
leotac Oct 31, 2025
3b00110
linting (#1120)
pgrayy Oct 31, 2025
db671ba
Fix input/output message not redacted when guardrails_trace="enabled_…
leotac Oct 31, 2025
bed1b68
fix: Allow none structured output context in tool executors (#1128)
mkmeral Nov 3, 2025
417ebea
fix: Fix broken converstaion with orphaned toolUse (#1123)
Unshure Nov 3, 2025
5981d36
feat: Enable multiagent session persistent in Graph/Swarm (#1110)
JackYPCOnline Nov 4, 2025
9f10595
feat(models): add SystemContentBlock support for provider-agnostic ca…
dbschmigelski Nov 4, 2025
89bab98
fix(models/gemini): handle non-JSON error messages from Gemini API (#…
Ratish1 Nov 4, 2025
e844b30
fix: Handle "prompt is too long" from Anthropic (#1137)
zastrowm Nov 5, 2025
1df45be
feat(telemetry): Add tool definitions to traces via semconv opt-in (#…
Ratish1 Nov 6, 2025
28fea41
fix: Strip argument sections out of inputSpec top-level description (…
zastrowm Nov 7, 2025
c250fc0
share thread context (#1146)
pgrayy Nov 7, 2025
2b0c6e6
async hooks (#1119)
pgrayy Nov 7, 2025
3061116
feat(tools): Support string descriptions in Annotated parameters (#1089)
Ratish1 Nov 10, 2025
e930243
chore(telemetry): updated opt-in attributes to internal (#1152)
poshinchen Nov 11, 2025
bbe765d
feat(models): allow SystemContentBlocks in LiteLLMModel (#1141)
dbschmigelski Nov 11, 2025
ccc3a8b
share interrupt state (#1148)
pgrayy Nov 11, 2025
57e2081
fix: Don't hang when MCP server returns 5xx (#1169)
zastrowm Nov 12, 2025
8cae18c
fix(models): allow setter on system_prompt and system_prompt_content …
dbschmigelski Nov 12, 2025
cee5145
feat: allow setting a timeout when creating MCPAgentTool (#1184)
AnirudhKonduru Nov 14, 2025
ded0934
fix(litellm): add validation for stream parameter in LiteLLM (#1183)
dbschmigelski Nov 17, 2025
77cb23f
fix(event_loop): handle MetadataEvents without optional usage and met…
dbschmigelski Nov 17, 2025
b4efc9d
swarm - switch to handoff node only after current node stops (#1147)
pgrayy Nov 17, 2025
95ac650
fix(a2a): base64 decode byte data before placing in ContentBlocks (#1…
dbschmigelski Nov 18, 2025
ab5f8ee
multi agent input (#1196)
pgrayy Nov 19, 2025
432d269
interrupt - activate - set context separately (#1194)
pgrayy Nov 19, 2025
fb8a861
feat(callback_handler): optional verbose output for PrintingCallbackH…
marcbrooker Nov 20, 2025
f554cca
fix: fix swarm session management integ test. (#1155)
JackYPCOnline Nov 20, 2025
a4837d4
move tool caller definition out of agent module (#1215)
pgrayy Nov 20, 2025
93997f0
interrupt - interruptible multi agent hook interface (#1207)
pgrayy Nov 20, 2025
87e0f34
security(tool_loader): prevent tool name and sys modules collisions i…
dbschmigelski Nov 21, 2025
efeba7b
fix(mcp): protect connection on non-fatal client side timeout error (…
dbschmigelski Nov 21, 2025
3efc9c0
fix(litellm): populate cacheWriteInputTokens from cache_creation_inpu…
dbschmigelski Nov 21, 2025
eaa6efb
fix: fix integ test for mcp eclicitation_server (#1234)
JackYPCOnline Nov 21, 2025
aaf9715
fix(tools): avoid KeyError in direct tool calls with ToolContext (#1213)
qmays-phdata Nov 24, 2025
8e6f48a
fix: attached custom attributes to all spans (#1235)
poshinchen Nov 25, 2025
f3cee8c
hooks - before node call - cancel node (#1203)
pgrayy Nov 26, 2025
f8c3008
interrupts - support falsey responses (#1256)
pgrayy Nov 26, 2025
01b821c
Bidirectional Streaming Agent (#1276)
mehtarac Dec 3, 2025
9fa818e
mcp - elicitation - fix server request (#1281)
pgrayy Dec 3, 2025
50969a4
feat(steering): add experimental steering for modular prompting (#1280)
dbschmigelski Dec 3, 2025
62534de
test(steering): adjust integ test system prompts to reduce flakiness …
dbschmigelski Dec 3, 2025
5ea97f9
Remove toolUse message when its missing due to pagination in session …
afarntrog Dec 4, 2025
25f1ce6
interrupts - swarm (#1193)
pgrayy Dec 5, 2025
911a1c7
fix(agent): Return structured output JSON when AgentResult has no tex…
afarntrog Dec 5, 2025
d1b523c
bidi - fix record direct tool call (#1300)
pgrayy Dec 5, 2025
2944abf
Update doc strings for the doc build (#1284)
zastrowm Dec 6, 2025
45dd597
fix: fix broken tool spec with composition keywords (#1301)
mkmeral Dec 8, 2025
17a2839
ci: add workflow for lambda layer publish and yank
dbschmigelski Dec 9, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 11 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
coverage:
status:
project:
default:
target: 90% # overall coverage threshold
patch:
default:
target: 90% # patch coverage threshold
base: auto
# Only post patch coverage on decreases
only_pulls: true
7 changes: 4 additions & 3 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ body:
label: Steps to Reproduce
description: Detailed steps to reproduce the behavior
placeholder: |
1. Install Strands using...
2. Run the command...
3. See error...
1. Code Snippet (Minimal reproducible example)
2. Install Strands using...
3. Run the command...
4. See error...
validations:
required: true
- type: textarea
Expand Down
43 changes: 43 additions & 0 deletions .github/workflows/LAMDBA_LAYERS_SOP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Lambda Layers Standard Operating Procedures (SOP)

## Overview

This document defines the standard operating procedures for managing Strands Agents Lambda layers across all AWS regions, Python versions, and architectures.

**Total: 136 individual Lambda layers** (17 regions × 2 architectures × 4 Python versions). All variants must maintain the same layer version number for each PyPI package version, with only one row per PyPI version appearing in documentation.

## Deployment Process

### 1. Initial Deployment
1. Run workflow with ALL options selected (default)
2. Specify PyPI package version
3. Type "Create Lambda Layer {package_version}" to confirm
4. All 136 individual layers deploy in parallel (4 Python × 2 arch × 17 regions)
5. Each layer gets its own unique name: `strands-agents-py{PYTHON_VERSION}-{ARCH}`

### 2. Version Buffering for New Variants
When adding new variants (new Python version, architecture, or region):

1. **Determine target layer version**: Check existing variants to find the highest layer version
2. **Buffer deployment**: Deploy new variants multiple times until layer version matches existing variants
3. **Example**: If existing variants are at layer version 5, deploy new variant 5 times to reach version 5

### 3. Handling Transient Failures
When some regions fail during deployment:

1. **Identify failed regions**: Check which combinations didn't complete successfully
2. **Targeted redeployment**: Use specific region/arch/Python inputs to redeploy failed combinations
3. **Version alignment**: Continue deploying until all variants reach the same layer version
4. **Verification**: Confirm all combinations have identical layer versions before updating docs

## Yank Process

### Yank Procedure
1. Use the `yank_lambda_layer` GitHub action workflow
2. Specify the layer version to yank
3. Type "Yank Lambda Layer {layer_version}" to confirm
4. **Full yank**: Run with ALL options selected (default) to yank all 136 variants OR **Partial yank**: Specify Python versions, architectures, and regions for targeted yanking
6. Update documentation
7. **Communication**: Notify users through appropriate channels

**Note**: Yanking deletes layer versions completely. Existing Lambda functions using the layer continue to work, but new functions cannot use the yanked version.
242 changes: 242 additions & 0 deletions .github/workflows/auto-close.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
name: Auto Close Issues

on:
schedule:
- cron: '0 14 * * 1-5' # 9 AM EST (2 PM UTC) Monday through Friday
workflow_dispatch:
inputs:
dry_run:
description: 'Run in dry-run mode (no actions taken, only logging)'
required: false
default: 'false'
type: boolean

permissions:
contents: read
issues: write
pull-requests: write

jobs:
auto-close:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- label: 'autoclose in 3 days'
days: 3
issue_types: 'issues' #issues/pulls/both
replacement_label: ''
closure_message: 'This issue has been automatically closed as it was marked for auto-closure by the team and no additional responses was received within 3 days.'
dry_run: 'false'
- label: 'autoclose in 7 days'
days: 7
issue_types: 'issues' # issues/pulls/both
replacement_label: ''
closure_message: 'This issue has been automatically closed as it was marked for auto-closure by the team and no additional responses was received within 7 days.'
dry_run: 'false'
steps:
- name: Validate and process ${{ matrix.label }}
uses: actions/github-script@v8
env:
LABEL_NAME: ${{ matrix.label }}
DAYS_TO_WAIT: ${{ matrix.days }}
AUTHORIZED_USERS: ''
AUTH_MODE: 'write-access'
ISSUE_TYPES: ${{ matrix.issue_types }}
DRY_RUN: ${{ matrix.dry_run }}
REPLACEMENT_LABEL: ${{ matrix.replacement_label }}
CLOSE_MESSAGE: ${{matrix.closure_message}}
with:
script: |
const REQUIRED_PERMISSIONS = ['write', 'admin'];
const CLOSE_MESSAGE = process.env.CLOSE_MESSAGE;
const isDryRun = '${{ inputs.dry_run }}' === 'true' || process.env.DRY_RUN === 'true';

const config = {
labelName: process.env.LABEL_NAME,
daysToWait: parseInt(process.env.DAYS_TO_WAIT),
authMode: process.env.AUTH_MODE,
authorizedUsers: process.env.AUTHORIZED_USERS?.split(',').map(u => u.trim()).filter(u => u) || [],
issueTypes: process.env.ISSUE_TYPES,
replacementLabel: process.env.REPLACEMENT_LABEL?.trim() || null
};

console.log(`🏷️ Processing label: "${config.labelName}" (${config.daysToWait} days)`);
if (isDryRun) console.log('🧪 DRY-RUN MODE: No actions will be taken');

const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - config.daysToWait);

async function isAuthorizedUser(username) {
try {
if (config.authMode === 'users') {
return config.authorizedUsers.includes(username);
} else if (config.authMode === 'write-access') {
const { data } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: username
});
return REQUIRED_PERMISSIONS.includes(data.permission);
}
} catch (error) {
console.log(`⚠️ Failed to check authorization for ${username}: ${error.message}`);
return false;
}
return false;
}

let allIssues = [];
let page = 1;

while (true) {
const { data: issues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: config.labelName,
sort: 'updated',
direction: 'desc',
per_page: 100,
page: page
});

if (issues.length === 0) break;
allIssues = allIssues.concat(issues);
if (issues.length < 100) break;
page++;
}

const targetIssues = allIssues.filter(issue => {
if (config.issueTypes === 'issues' && issue.pull_request) return false;
if (config.issueTypes === 'pulls' && !issue.pull_request) return false;
return true;
});

console.log(`🔍 Found ${targetIssues.length} items with label "${config.labelName}"`);

if (targetIssues.length === 0) {
console.log('✅ No items to process');
return;
}

let closedCount = 0;
let labelRemovedCount = 0;
let skippedCount = 0;

for (const issue of targetIssues) {
console.log(`\n📋 Processing #${issue.number}: ${issue.title}`);

try {
const { data: events } = await github.rest.issues.listEvents({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number
});

const labelEvents = events
.filter(e => e.event === 'labeled' && e.label?.name === config.labelName)
.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));

if (labelEvents.length === 0) {
console.log(`⚠️ No label events found for #${issue.number}`);
skippedCount++;
continue;
}

const lastLabelAdded = new Date(labelEvents[0].created_at);
const labelAdder = labelEvents[0].actor.login;

const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
since: lastLabelAdded.toISOString()
});

let hasUnauthorizedComment = false;

for (const comment of comments) {
if (comment.user.login === labelAdder) continue;

const isAuthorized = await isAuthorizedUser(comment.user.login);
if (!isAuthorized) {
console.log(`❌ New comment from ${comment.user.login}`);
hasUnauthorizedComment = true;
break;
}
}

if (hasUnauthorizedComment) {
if (isDryRun) {
console.log(`🧪 DRY-RUN: Would remove ${config.labelName} label from #${issue.number}`);
if (config.replacementLabel) {
console.log(`🧪 DRY-RUN: Would add ${config.replacementLabel} label to #${issue.number}`);
}
} else {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
name: config.labelName
});
console.log(`🏷️ Removed ${config.labelName} label from #${issue.number}`);

if (config.replacementLabel) {
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
labels: [config.replacementLabel]
});
console.log(`🏷️ Added ${config.replacementLabel} label to #${issue.number}`);
}
}
labelRemovedCount++;
continue;
}

if (lastLabelAdded > cutoffDate) {
const daysRemaining = Math.ceil((lastLabelAdded - cutoffDate) / (1000 * 60 * 60 * 24));
console.log(`⏳ Label added too recently (${daysRemaining} days remaining)`);
skippedCount++;
continue;
}

if (isDryRun) {
console.log(`🧪 DRY-RUN: Would close #${issue.number} with comment`);
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: CLOSE_MESSAGE
});

await github.rest.issues.update({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
state: 'closed'
});

console.log(`🔒 Closed #${issue.number}`);
}
closedCount++;
} catch (error) {
console.log(`❌ Error processing #${issue.number}: ${error.message}`);
skippedCount++;
}
}

console.log(`\n📊 Summary for "${config.labelName}":`);
if (isDryRun) {
console.log(` 🧪 DRY-RUN MODE - No actual changes made:`);
console.log(` • Issues that would be closed: ${closedCount}`);
console.log(` • Labels that would be removed: ${labelRemovedCount}`);
} else {
console.log(` • Issues closed: ${closedCount}`);
console.log(` • Labels removed: ${labelRemovedCount}`);
}
console.log(` • Issues skipped: ${skippedCount}`);
console.log(` • Total processed: ${targetIssues.length}`);
9 changes: 5 additions & 4 deletions .github/workflows/integration-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
approval-env: ${{ steps.collab-check.outputs.result }}
steps:
- name: Collaborator Check
uses: actions/github-script@v7
uses: actions/github-script@v8
id: collab-check
with:
result-encoding: string
Expand Down Expand Up @@ -46,18 +46,18 @@ jobs:
contents: read
steps:
- name: Configure Credentials
uses: aws-actions/configure-aws-credentials@v4
uses: aws-actions/configure-aws-credentials@v5
with:
role-to-assume: ${{ secrets.STRANDS_INTEG_TEST_ROLE }}
aws-region: us-east-1
mask-aws-account-id: true
- name: Checkout head commit
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
ref: ${{ github.event.pull_request.head.sha }} # Pull the commit from the forked repo
persist-credentials: false # Don't persist credentials for subsequent actions
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: '3.10'
- name: Install dependencies
Expand All @@ -67,6 +67,7 @@ jobs:
env:
AWS_REGION: us-east-1
AWS_REGION_NAME: us-east-1 # Needed for LiteLLM
STRANDS_TEST_API_KEYS_SECRET_NAME: ${{ secrets.STRANDS_TEST_API_KEYS_SECRET_NAME }}
id: tests
run: |
hatch test tests_integ
2 changes: 1 addition & 1 deletion .github/workflows/pr-and-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Pull Request and Push Action
on:
pull_request: # Safer than pull_request_target for untrusted code
branches: [ main ]
types: [opened, synchronize, reopened, ready_for_review, review_requested, review_request_removed]
types: [opened, synchronize, reopened, ready_for_review]
push:
branches: [ main ] # Also run on direct pushes to main
concurrency:
Expand Down
Loading
Loading