strands-compose 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- strands_compose-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +124 -0
- strands_compose-0.1.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
- strands_compose-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +46 -0
- strands_compose-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +42 -0
- strands_compose-0.1.0/.github/agents/developer.md +38 -0
- strands_compose-0.1.0/.github/agents/docs-writer.md +48 -0
- strands_compose-0.1.0/.github/agents/reviewer.md +46 -0
- strands_compose-0.1.0/.github/agents/tester.md +37 -0
- strands_compose-0.1.0/.github/copilot-instructions.md +176 -0
- strands_compose-0.1.0/.github/dependabot.yml +20 -0
- strands_compose-0.1.0/.github/workflows/ci.yml +76 -0
- strands_compose-0.1.0/.github/workflows/publish.yml +126 -0
- strands_compose-0.1.0/.gitignore +57 -0
- strands_compose-0.1.0/.pre-commit-config.yaml +48 -0
- strands_compose-0.1.0/.secrets.baseline +111 -0
- strands_compose-0.1.0/AGENTS.md +176 -0
- strands_compose-0.1.0/CHANGELOG.md +26 -0
- strands_compose-0.1.0/CLAUDE.md +3 -0
- strands_compose-0.1.0/CONTRIBUTING.md +115 -0
- strands_compose-0.1.0/GEMINI.md +3 -0
- strands_compose-0.1.0/LICENSE +174 -0
- strands_compose-0.1.0/PKG-INFO +445 -0
- strands_compose-0.1.0/README.md +408 -0
- strands_compose-0.1.0/RELEASING.md +50 -0
- strands_compose-0.1.0/SECURITY.md +31 -0
- strands_compose-0.1.0/SUPPORT.md +34 -0
- strands_compose-0.1.0/docs/configuration/Chapter_01.md +71 -0
- strands_compose-0.1.0/docs/configuration/Chapter_02.md +106 -0
- strands_compose-0.1.0/docs/configuration/Chapter_03.md +117 -0
- strands_compose-0.1.0/docs/configuration/Chapter_04.md +115 -0
- strands_compose-0.1.0/docs/configuration/Chapter_05.md +107 -0
- strands_compose-0.1.0/docs/configuration/Chapter_06.md +180 -0
- strands_compose-0.1.0/docs/configuration/Chapter_07.md +162 -0
- strands_compose-0.1.0/docs/configuration/Chapter_08.md +71 -0
- strands_compose-0.1.0/docs/configuration/Chapter_09.md +195 -0
- strands_compose-0.1.0/docs/configuration/Chapter_10.md +170 -0
- strands_compose-0.1.0/docs/configuration/Chapter_11.md +67 -0
- strands_compose-0.1.0/docs/configuration/Chapter_12.md +118 -0
- strands_compose-0.1.0/docs/configuration/Chapter_13.md +110 -0
- strands_compose-0.1.0/docs/configuration/Chapter_14.md +97 -0
- strands_compose-0.1.0/docs/configuration/Chapter_15.md +76 -0
- strands_compose-0.1.0/docs/configuration/Chapter_16.md +70 -0
- strands_compose-0.1.0/docs/configuration/Chapter_17.md +199 -0
- strands_compose-0.1.0/docs/configuration/Chapter_18.md +155 -0
- strands_compose-0.1.0/docs/configuration/Quick_Recipes.md +113 -0
- strands_compose-0.1.0/docs/configuration/README.md +38 -0
- strands_compose-0.1.0/docs/img/logo-black.svg +213 -0
- strands_compose-0.1.0/docs/img/logo-white.svg +213 -0
- strands_compose-0.1.0/docs/img/logo.png +0 -0
- strands_compose-0.1.0/docs/index.html +67 -0
- strands_compose-0.1.0/examples/01_minimal/README.md +67 -0
- strands_compose-0.1.0/examples/01_minimal/config.yaml +22 -0
- strands_compose-0.1.0/examples/01_minimal/main.py +48 -0
- strands_compose-0.1.0/examples/02_vars_and_anchors/README.md +104 -0
- strands_compose-0.1.0/examples/02_vars_and_anchors/config.yaml +48 -0
- strands_compose-0.1.0/examples/02_vars_and_anchors/main.py +60 -0
- strands_compose-0.1.0/examples/03_tools/README.md +78 -0
- strands_compose-0.1.0/examples/03_tools/config.yaml +35 -0
- strands_compose-0.1.0/examples/03_tools/main.py +49 -0
- strands_compose-0.1.0/examples/03_tools/tools.py +48 -0
- strands_compose-0.1.0/examples/04_session/README.md +144 -0
- strands_compose-0.1.0/examples/04_session/config.yaml +32 -0
- strands_compose-0.1.0/examples/04_session/main.py +48 -0
- strands_compose-0.1.0/examples/05_hooks/README.md +84 -0
- strands_compose-0.1.0/examples/05_hooks/config.yaml +40 -0
- strands_compose-0.1.0/examples/05_hooks/custom_tools.py +50 -0
- strands_compose-0.1.0/examples/05_hooks/hooks.py +36 -0
- strands_compose-0.1.0/examples/05_hooks/main.py +51 -0
- strands_compose-0.1.0/examples/06_mcp/README.md +126 -0
- strands_compose-0.1.0/examples/06_mcp/config.yaml +68 -0
- strands_compose-0.1.0/examples/06_mcp/main.py +50 -0
- strands_compose-0.1.0/examples/06_mcp/server.py +75 -0
- strands_compose-0.1.0/examples/07_delegate/README.md +86 -0
- strands_compose-0.1.0/examples/07_delegate/config.yaml +57 -0
- strands_compose-0.1.0/examples/07_delegate/main.py +48 -0
- strands_compose-0.1.0/examples/08_swarm/README.md +75 -0
- strands_compose-0.1.0/examples/08_swarm/config.yaml +52 -0
- strands_compose-0.1.0/examples/08_swarm/main.py +48 -0
- strands_compose-0.1.0/examples/09_graph/README.md +76 -0
- strands_compose-0.1.0/examples/09_graph/config.yaml +55 -0
- strands_compose-0.1.0/examples/09_graph/main.py +48 -0
- strands_compose-0.1.0/examples/10_nested/README.md +85 -0
- strands_compose-0.1.0/examples/10_nested/config.yaml +105 -0
- strands_compose-0.1.0/examples/10_nested/main.py +49 -0
- strands_compose-0.1.0/examples/11_multi_file_config/README.md +88 -0
- strands_compose-0.1.0/examples/11_multi_file_config/agents.yaml +18 -0
- strands_compose-0.1.0/examples/11_multi_file_config/base.yaml +19 -0
- strands_compose-0.1.0/examples/11_multi_file_config/main.py +51 -0
- strands_compose-0.1.0/examples/12_streaming/README.md +84 -0
- strands_compose-0.1.0/examples/12_streaming/config.yaml +59 -0
- strands_compose-0.1.0/examples/12_streaming/main.py +74 -0
- strands_compose-0.1.0/examples/13_graph_conditions/README.md +90 -0
- strands_compose-0.1.0/examples/13_graph_conditions/conditions.py +33 -0
- strands_compose-0.1.0/examples/13_graph_conditions/config.yaml +55 -0
- strands_compose-0.1.0/examples/13_graph_conditions/main.py +49 -0
- strands_compose-0.1.0/examples/14_agent_factory/README.md +75 -0
- strands_compose-0.1.0/examples/14_agent_factory/config.yaml +23 -0
- strands_compose-0.1.0/examples/14_agent_factory/factory.py +53 -0
- strands_compose-0.1.0/examples/14_agent_factory/main.py +48 -0
- strands_compose-0.1.0/examples/README.md +36 -0
- strands_compose-0.1.0/examples/TEMPLATE_EXAMPLE.md +62 -0
- strands_compose-0.1.0/justfile +29 -0
- strands_compose-0.1.0/pyproject.toml +130 -0
- strands_compose-0.1.0/src/strands_compose/__init__.py +64 -0
- strands_compose-0.1.0/src/strands_compose/cli.py +427 -0
- strands_compose-0.1.0/src/strands_compose/config/__init__.py +53 -0
- strands_compose-0.1.0/src/strands_compose/config/interpolation.py +196 -0
- strands_compose-0.1.0/src/strands_compose/config/loaders/__init__.py +12 -0
- strands_compose-0.1.0/src/strands_compose/config/loaders/helpers.py +406 -0
- strands_compose-0.1.0/src/strands_compose/config/loaders/loaders.py +270 -0
- strands_compose-0.1.0/src/strands_compose/config/loaders/validators.py +124 -0
- strands_compose-0.1.0/src/strands_compose/config/resolvers/__init__.py +28 -0
- strands_compose-0.1.0/src/strands_compose/config/resolvers/agents.py +203 -0
- strands_compose-0.1.0/src/strands_compose/config/resolvers/config.py +166 -0
- strands_compose-0.1.0/src/strands_compose/config/resolvers/conversation_manager.py +54 -0
- strands_compose-0.1.0/src/strands_compose/config/resolvers/hooks.py +68 -0
- strands_compose-0.1.0/src/strands_compose/config/resolvers/mcp.py +106 -0
- strands_compose-0.1.0/src/strands_compose/config/resolvers/models.py +47 -0
- strands_compose-0.1.0/src/strands_compose/config/resolvers/orchestrations/__init__.py +80 -0
- strands_compose-0.1.0/src/strands_compose/config/resolvers/orchestrations/builders.py +354 -0
- strands_compose-0.1.0/src/strands_compose/config/resolvers/orchestrations/planner.py +102 -0
- strands_compose-0.1.0/src/strands_compose/config/resolvers/session_manager.py +149 -0
- strands_compose-0.1.0/src/strands_compose/config/schema.py +337 -0
- strands_compose-0.1.0/src/strands_compose/converters/__init__.py +13 -0
- strands_compose-0.1.0/src/strands_compose/converters/base.py +54 -0
- strands_compose-0.1.0/src/strands_compose/converters/openai.py +221 -0
- strands_compose-0.1.0/src/strands_compose/converters/raw.py +31 -0
- strands_compose-0.1.0/src/strands_compose/exceptions.py +40 -0
- strands_compose-0.1.0/src/strands_compose/hooks/__init__.py +17 -0
- strands_compose-0.1.0/src/strands_compose/hooks/event_publisher.py +378 -0
- strands_compose-0.1.0/src/strands_compose/hooks/max_calls_guard.py +90 -0
- strands_compose-0.1.0/src/strands_compose/hooks/stop_guard.py +113 -0
- strands_compose-0.1.0/src/strands_compose/hooks/tool_name_sanitizer.py +184 -0
- strands_compose-0.1.0/src/strands_compose/mcp/README.md +105 -0
- strands_compose-0.1.0/src/strands_compose/mcp/__init__.py +27 -0
- strands_compose-0.1.0/src/strands_compose/mcp/client.py +170 -0
- strands_compose-0.1.0/src/strands_compose/mcp/lifecycle.py +233 -0
- strands_compose-0.1.0/src/strands_compose/mcp/server.py +327 -0
- strands_compose-0.1.0/src/strands_compose/mcp/transports.py +188 -0
- strands_compose-0.1.0/src/strands_compose/models.py +69 -0
- strands_compose-0.1.0/src/strands_compose/py.typed +0 -0
- strands_compose-0.1.0/src/strands_compose/renderers/__init__.py +9 -0
- strands_compose-0.1.0/src/strands_compose/renderers/ansi.py +237 -0
- strands_compose-0.1.0/src/strands_compose/renderers/base.py +36 -0
- strands_compose-0.1.0/src/strands_compose/startup/__init__.py +24 -0
- strands_compose-0.1.0/src/strands_compose/startup/report.py +174 -0
- strands_compose-0.1.0/src/strands_compose/startup/validator.py +167 -0
- strands_compose-0.1.0/src/strands_compose/tools/__init__.py +33 -0
- strands_compose-0.1.0/src/strands_compose/tools/extractors.py +182 -0
- strands_compose-0.1.0/src/strands_compose/tools/loaders.py +238 -0
- strands_compose-0.1.0/src/strands_compose/tools/wrappers.py +100 -0
- strands_compose-0.1.0/src/strands_compose/types.py +110 -0
- strands_compose-0.1.0/src/strands_compose/utils.py +210 -0
- strands_compose-0.1.0/src/strands_compose/wire.py +196 -0
- strands_compose-0.1.0/tasks/README.md +152 -0
- strands_compose-0.1.0/tasks/check.just +30 -0
- strands_compose-0.1.0/tasks/clean.just +55 -0
- strands_compose-0.1.0/tasks/commit.just +19 -0
- strands_compose-0.1.0/tasks/format.just +13 -0
- strands_compose-0.1.0/tasks/install.just +15 -0
- strands_compose-0.1.0/tasks/release.just +39 -0
- strands_compose-0.1.0/tasks/test.just +13 -0
- strands_compose-0.1.0/tests/__init__.py +1 -0
- strands_compose-0.1.0/tests/conftest.py +10 -0
- strands_compose-0.1.0/tests/examples/test_examples_smoke.py +103 -0
- strands_compose-0.1.0/tests/integration/__init__.py +0 -0
- strands_compose-0.1.0/tests/integration/conftest.py +28 -0
- strands_compose-0.1.0/tests/integration/fixtures/complex_full.yaml +50 -0
- strands_compose-0.1.0/tests/integration/fixtures/graph.yaml +17 -0
- strands_compose-0.1.0/tests/integration/fixtures/minimal.yaml +4 -0
- strands_compose-0.1.0/tests/integration/fixtures/multi_agent_delegate.yaml +13 -0
- strands_compose-0.1.0/tests/integration/fixtures/nested_orchestration.yaml +23 -0
- strands_compose-0.1.0/tests/integration/fixtures/swarm.yaml +12 -0
- strands_compose-0.1.0/tests/integration/fixtures/with_hooks.yaml +8 -0
- strands_compose-0.1.0/tests/integration/fixtures/with_model.yaml +9 -0
- strands_compose-0.1.0/tests/integration/fixtures/with_session_manager.yaml +8 -0
- strands_compose-0.1.0/tests/integration/fixtures/with_vars.yaml +12 -0
- strands_compose-0.1.0/tests/integration/test_full_pipeline.py +90 -0
- strands_compose-0.1.0/tests/integration/test_load_config.py +301 -0
- strands_compose-0.1.0/tests/unit/__init__.py +1 -0
- strands_compose-0.1.0/tests/unit/config/__init__.py +0 -0
- strands_compose-0.1.0/tests/unit/config/loaders/__init__.py +0 -0
- strands_compose-0.1.0/tests/unit/config/loaders/conftest.py +131 -0
- strands_compose-0.1.0/tests/unit/config/loaders/test_helpers.py +219 -0
- strands_compose-0.1.0/tests/unit/config/loaders/test_helpers_extended.py +348 -0
- strands_compose-0.1.0/tests/unit/config/loaders/test_load_session.py +174 -0
- strands_compose-0.1.0/tests/unit/config/loaders/test_loaders.py +633 -0
- strands_compose-0.1.0/tests/unit/config/loaders/test_validators.py +227 -0
- strands_compose-0.1.0/tests/unit/config/resolvers/__init__.py +0 -0
- strands_compose-0.1.0/tests/unit/config/resolvers/orchestrations/__init__.py +0 -0
- strands_compose-0.1.0/tests/unit/config/resolvers/orchestrations/test_builders.py +328 -0
- strands_compose-0.1.0/tests/unit/config/resolvers/orchestrations/test_planner.py +115 -0
- strands_compose-0.1.0/tests/unit/config/resolvers/orchestrations/test_tools.py +581 -0
- strands_compose-0.1.0/tests/unit/config/resolvers/test_agents.py +270 -0
- strands_compose-0.1.0/tests/unit/config/resolvers/test_config.py +145 -0
- strands_compose-0.1.0/tests/unit/config/resolvers/test_conversation_manager.py +119 -0
- strands_compose-0.1.0/tests/unit/config/resolvers/test_hooks.py +82 -0
- strands_compose-0.1.0/tests/unit/config/resolvers/test_mcp.py +118 -0
- strands_compose-0.1.0/tests/unit/config/resolvers/test_models.py +64 -0
- strands_compose-0.1.0/tests/unit/config/resolvers/test_session_manager.py +234 -0
- strands_compose-0.1.0/tests/unit/config/resolvers/test_wire_event_queue.py +78 -0
- strands_compose-0.1.0/tests/unit/config/test_edge_cases.py +64 -0
- strands_compose-0.1.0/tests/unit/config/test_interpolation.py +92 -0
- strands_compose-0.1.0/tests/unit/config/test_schema.py +191 -0
- strands_compose-0.1.0/tests/unit/conftest.py +250 -0
- strands_compose-0.1.0/tests/unit/converters/__init__.py +0 -0
- strands_compose-0.1.0/tests/unit/converters/test_base.py +47 -0
- strands_compose-0.1.0/tests/unit/converters/test_openai.py +440 -0
- strands_compose-0.1.0/tests/unit/converters/test_raw.py +129 -0
- strands_compose-0.1.0/tests/unit/hooks/__init__.py +0 -0
- strands_compose-0.1.0/tests/unit/hooks/test_edge_cases.py +59 -0
- strands_compose-0.1.0/tests/unit/hooks/test_event_publisher.py +506 -0
- strands_compose-0.1.0/tests/unit/hooks/test_max_calls_guard.py +46 -0
- strands_compose-0.1.0/tests/unit/hooks/test_stop_guard.py +119 -0
- strands_compose-0.1.0/tests/unit/hooks/test_tool_name_sanitizer.py +133 -0
- strands_compose-0.1.0/tests/unit/mcp/__init__.py +0 -0
- strands_compose-0.1.0/tests/unit/mcp/test_client.py +193 -0
- strands_compose-0.1.0/tests/unit/mcp/test_init.py +32 -0
- strands_compose-0.1.0/tests/unit/mcp/test_lifecycle.py +152 -0
- strands_compose-0.1.0/tests/unit/mcp/test_server.py +203 -0
- strands_compose-0.1.0/tests/unit/mcp/test_transports.py +301 -0
- strands_compose-0.1.0/tests/unit/models/__init__.py +0 -0
- strands_compose-0.1.0/tests/unit/models/test_models.py +61 -0
- strands_compose-0.1.0/tests/unit/renderers/__init__.py +0 -0
- strands_compose-0.1.0/tests/unit/renderers/test_ansi.py +173 -0
- strands_compose-0.1.0/tests/unit/renderers/test_base.py +15 -0
- strands_compose-0.1.0/tests/unit/startup/__init__.py +0 -0
- strands_compose-0.1.0/tests/unit/startup/test_report.py +102 -0
- strands_compose-0.1.0/tests/unit/startup/test_validator.py +133 -0
- strands_compose-0.1.0/tests/unit/test_cli.py +501 -0
- strands_compose-0.1.0/tests/unit/test_concurrency.py +176 -0
- strands_compose-0.1.0/tests/unit/test_event_queue.py +118 -0
- strands_compose-0.1.0/tests/unit/test_exception_usage.py +74 -0
- strands_compose-0.1.0/tests/unit/test_exceptions.py +84 -0
- strands_compose-0.1.0/tests/unit/test_exports.py +25 -0
- strands_compose-0.1.0/tests/unit/test_golden_outputs.py +335 -0
- strands_compose-0.1.0/tests/unit/test_tools.py +173 -0
- strands_compose-0.1.0/tests/unit/test_tools_module.py +92 -0
- strands_compose-0.1.0/tests/unit/test_types.py +58 -0
- strands_compose-0.1.0/tests/unit/test_utils.py +169 -0
- strands_compose-0.1.0/tests/unit/test_wire.py +51 -0
- strands_compose-0.1.0/uv.lock +2177 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
name: Bug Report
|
|
2
|
+
description: Report a bug in strands-compose
|
|
3
|
+
title: "[BUG] "
|
|
4
|
+
labels: ["bug", "triage"]
|
|
5
|
+
assignees: []
|
|
6
|
+
body:
|
|
7
|
+
- type: markdown
|
|
8
|
+
attributes:
|
|
9
|
+
value: |
|
|
10
|
+
Thanks for taking the time to fill out this bug report for strands-compose!
|
|
11
|
+
|
|
12
|
+
- type: checkboxes
|
|
13
|
+
id: checks
|
|
14
|
+
attributes:
|
|
15
|
+
label: Checks
|
|
16
|
+
options:
|
|
17
|
+
- label: I have updated to the latest version of strands-compose
|
|
18
|
+
required: true
|
|
19
|
+
- label: I have checked the documentation and this is not expected behavior
|
|
20
|
+
required: true
|
|
21
|
+
- label: I have searched [./issues](./issues?q=) and there are no duplicates of my issue
|
|
22
|
+
required: true
|
|
23
|
+
|
|
24
|
+
- type: input
|
|
25
|
+
id: compose-version
|
|
26
|
+
attributes:
|
|
27
|
+
label: strands-compose Version
|
|
28
|
+
description: Which version of strands-compose are you using?
|
|
29
|
+
placeholder: e.g., 0.1.0
|
|
30
|
+
validations:
|
|
31
|
+
required: true
|
|
32
|
+
|
|
33
|
+
- type: input
|
|
34
|
+
id: strands-version
|
|
35
|
+
attributes:
|
|
36
|
+
label: strands-agents Version
|
|
37
|
+
description: Which version of strands-agents are you using?
|
|
38
|
+
placeholder: e.g., 1.32.0
|
|
39
|
+
validations:
|
|
40
|
+
required: true
|
|
41
|
+
|
|
42
|
+
- type: input
|
|
43
|
+
id: python-version
|
|
44
|
+
attributes:
|
|
45
|
+
label: Python Version
|
|
46
|
+
description: Which version of Python are you using?
|
|
47
|
+
placeholder: e.g., 3.11.5
|
|
48
|
+
validations:
|
|
49
|
+
required: true
|
|
50
|
+
|
|
51
|
+
- type: input
|
|
52
|
+
id: os
|
|
53
|
+
attributes:
|
|
54
|
+
label: Operating System
|
|
55
|
+
description: Which operating system are you using?
|
|
56
|
+
placeholder: e.g., Ubuntu 22.04 / Windows 11 / macOS 14
|
|
57
|
+
validations:
|
|
58
|
+
required: true
|
|
59
|
+
|
|
60
|
+
- type: dropdown
|
|
61
|
+
id: installation-method
|
|
62
|
+
attributes:
|
|
63
|
+
label: Installation Method
|
|
64
|
+
description: How did you install strands-compose?
|
|
65
|
+
options:
|
|
66
|
+
- pip
|
|
67
|
+
- uv
|
|
68
|
+
- git clone
|
|
69
|
+
- other
|
|
70
|
+
validations:
|
|
71
|
+
required: true
|
|
72
|
+
|
|
73
|
+
- type: textarea
|
|
74
|
+
id: config-yaml
|
|
75
|
+
attributes:
|
|
76
|
+
label: Relevant YAML Config
|
|
77
|
+
description: Paste the relevant portion of your `config.yaml` (remove any secrets)
|
|
78
|
+
render: yaml
|
|
79
|
+
|
|
80
|
+
- type: textarea
|
|
81
|
+
id: steps-to-reproduce
|
|
82
|
+
attributes:
|
|
83
|
+
label: Steps to Reproduce
|
|
84
|
+
description: Detailed steps to reproduce the behavior
|
|
85
|
+
placeholder: |
|
|
86
|
+
1. config.yaml and code snippet (minimal reproducible example)
|
|
87
|
+
2. Run the command...
|
|
88
|
+
3. See error...
|
|
89
|
+
validations:
|
|
90
|
+
required: true
|
|
91
|
+
|
|
92
|
+
- type: textarea
|
|
93
|
+
id: expected-behavior
|
|
94
|
+
attributes:
|
|
95
|
+
label: Expected Behavior
|
|
96
|
+
description: A clear description of what you expected to happen
|
|
97
|
+
validations:
|
|
98
|
+
required: true
|
|
99
|
+
|
|
100
|
+
- type: textarea
|
|
101
|
+
id: actual-behavior
|
|
102
|
+
attributes:
|
|
103
|
+
label: Actual Behavior
|
|
104
|
+
description: What actually happened — include full traceback if applicable
|
|
105
|
+
validations:
|
|
106
|
+
required: true
|
|
107
|
+
|
|
108
|
+
- type: textarea
|
|
109
|
+
id: additional-context
|
|
110
|
+
attributes:
|
|
111
|
+
label: Additional Context
|
|
112
|
+
description: Any other relevant information, logs, screenshots, etc.
|
|
113
|
+
|
|
114
|
+
- type: textarea
|
|
115
|
+
id: possible-solution
|
|
116
|
+
attributes:
|
|
117
|
+
label: Possible Solution
|
|
118
|
+
description: Optional — if you have suggestions on how to fix the bug
|
|
119
|
+
|
|
120
|
+
- type: input
|
|
121
|
+
id: related-issues
|
|
122
|
+
attributes:
|
|
123
|
+
label: Related Issues
|
|
124
|
+
description: Optional — link to related issues if applicable
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: false
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: strands-compose Discussions
|
|
4
|
+
url: https://github.com/strands-compose/sdk-python/discussions
|
|
5
|
+
about: Please ask and answer questions here
|
|
6
|
+
- name: strands-compose Documentation
|
|
7
|
+
url: https://github.com/strands-compose/sdk-python/tree/main/docs
|
|
8
|
+
about: Visit the documentation for help
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: Feature Request
|
|
2
|
+
description: Suggest a new feature or enhancement for strands-compose
|
|
3
|
+
title: "[FEATURE] "
|
|
4
|
+
labels: ["enhancement", "triage"]
|
|
5
|
+
assignees: []
|
|
6
|
+
body:
|
|
7
|
+
- type: markdown
|
|
8
|
+
attributes:
|
|
9
|
+
value: |
|
|
10
|
+
Thanks for suggesting a new feature for strands-compose!
|
|
11
|
+
|
|
12
|
+
- type: textarea
|
|
13
|
+
id: problem-statement
|
|
14
|
+
attributes:
|
|
15
|
+
label: Problem Statement
|
|
16
|
+
description: Describe the problem you're trying to solve. What is currently difficult or impossible to do?
|
|
17
|
+
placeholder: I would like strands-compose to...
|
|
18
|
+
validations:
|
|
19
|
+
required: true
|
|
20
|
+
|
|
21
|
+
- type: textarea
|
|
22
|
+
id: proposed-solution
|
|
23
|
+
attributes:
|
|
24
|
+
label: Proposed Solution
|
|
25
|
+
description: Optional — describe your proposed solution. How would this feature work? Include example YAML or Python if helpful.
|
|
26
|
+
|
|
27
|
+
- type: textarea
|
|
28
|
+
id: use-case
|
|
29
|
+
attributes:
|
|
30
|
+
label: Use Case
|
|
31
|
+
description: Provide specific use cases for the feature. How would people use it?
|
|
32
|
+
placeholder: This would help with...
|
|
33
|
+
validations:
|
|
34
|
+
required: true
|
|
35
|
+
|
|
36
|
+
- type: textarea
|
|
37
|
+
id: alternatives
|
|
38
|
+
attributes:
|
|
39
|
+
label: Alternatives Considered
|
|
40
|
+
description: Optional — have you considered alternative approaches? What are their pros and cons?
|
|
41
|
+
|
|
42
|
+
- type: textarea
|
|
43
|
+
id: additional-context
|
|
44
|
+
attributes:
|
|
45
|
+
label: Additional Context
|
|
46
|
+
description: Any other context, screenshots, code examples, or references that might help understand the request.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
## Description
|
|
2
|
+
|
|
3
|
+
<!-- Provide a detailed description of the changes in this PR -->
|
|
4
|
+
|
|
5
|
+
## Related Issues
|
|
6
|
+
|
|
7
|
+
<!-- Link to related issues using #issue-number format -->
|
|
8
|
+
|
|
9
|
+
## Type of Change
|
|
10
|
+
|
|
11
|
+
<!-- Choose one and delete the rest -->
|
|
12
|
+
|
|
13
|
+
- Bug fix
|
|
14
|
+
- New feature
|
|
15
|
+
- Breaking change
|
|
16
|
+
- Documentation update
|
|
17
|
+
- Other (please describe):
|
|
18
|
+
|
|
19
|
+
## YAML / API Impact
|
|
20
|
+
|
|
21
|
+
<!-- Does this change affect the config schema or the public Python API?
|
|
22
|
+
If yes, describe what changes and whether it's backwards-compatible. -->
|
|
23
|
+
|
|
24
|
+
## Testing
|
|
25
|
+
|
|
26
|
+
How have you tested the change?
|
|
27
|
+
|
|
28
|
+
- [ ] I ran `uv run just check` (lint + type check)
|
|
29
|
+
- [ ] I ran `uv run just test` for overall testing
|
|
30
|
+
- [ ] I added or updated tests that prove my fix is effective or my feature works
|
|
31
|
+
- [ ] I verified existing examples in `examples/` still work
|
|
32
|
+
|
|
33
|
+
## Checklist
|
|
34
|
+
|
|
35
|
+
- [ ] I have read the [CONTRIBUTING](CONTRIBUTING.md) document
|
|
36
|
+
- [ ] I have updated the documentation accordingly
|
|
37
|
+
- [ ] My changes generate no new warnings
|
|
38
|
+
- [ ] Any dependent changes have been merged and published
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: developer
|
|
3
|
+
description: Implements features and fixes bugs in strands-compose following all project architecture and coding conventions
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are an expert contributor to strands-compose. Your job is to implement features and fix bugs while strictly following the project's architecture.
|
|
7
|
+
|
|
8
|
+
## Workflow
|
|
9
|
+
|
|
10
|
+
1. Read the issue carefully. Identify the minimal change needed.
|
|
11
|
+
2. Check `.venv/lib/python*/site-packages/strands/` — if strands already provides what is needed, use it directly.
|
|
12
|
+
3. Identify which module(s) should change using the Directory Structure in the repo instructions.
|
|
13
|
+
4. Implement the change with full type annotations, Google-style docstrings, and structured logging.
|
|
14
|
+
5. Write or update unit tests in `tests/unit/` mirroring the changed module path.
|
|
15
|
+
6. Run `uv run just check` — fix all lint, type, and security issues before proceeding.
|
|
16
|
+
7. Run `uv run just test` — all tests must pass.
|
|
17
|
+
8. Open a draft PR with a clear description of what changed and why.
|
|
18
|
+
|
|
19
|
+
## Where New Code Goes
|
|
20
|
+
|
|
21
|
+
- New YAML config key → `src/strands_compose/models.py` (Pydantic model) + `src/strands_compose/config/schema.py` (JSON schema)
|
|
22
|
+
- New resolver → `src/strands_compose/config/resolvers/`
|
|
23
|
+
- New built-in hook → `src/strands_compose/hooks/`
|
|
24
|
+
- New MCP transport or lifecycle change → `src/strands_compose/mcp/`
|
|
25
|
+
- New converter → `src/strands_compose/converters/`
|
|
26
|
+
- New tool helper → `src/strands_compose/tools/`
|
|
27
|
+
- New renderer → `src/strands_compose/renderers/`
|
|
28
|
+
- Public API changes → `src/strands_compose/__init__.py`
|
|
29
|
+
|
|
30
|
+
## Hard Rules
|
|
31
|
+
|
|
32
|
+
- Never modify files outside the scope of the issue.
|
|
33
|
+
- Never reimplement what strands already provides.
|
|
34
|
+
- Every new public function, method, and class needs a docstring and full type hints.
|
|
35
|
+
- No `Optional`, `Union`, `List`, `Dict` — use `X | None`, `list`, `dict`.
|
|
36
|
+
- No f-strings in `logger.*` calls — use `%s` with field-value pairs.
|
|
37
|
+
- Raise specific exceptions with context; never swallow with bare `except:`.
|
|
38
|
+
- `from __future__ import annotations` at the top of every module you create or edit.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: docs-writer
|
|
3
|
+
description: Writes and updates documentation for strands-compose — README, examples, and configuration reference chapters
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are a documentation specialist for strands-compose. Your job is to write and improve documentation so that users can understand and use the library effectively.
|
|
7
|
+
|
|
8
|
+
## Workflow
|
|
9
|
+
|
|
10
|
+
1. Identify what needs documenting from the issue or PR.
|
|
11
|
+
2. Determine the correct location for the change (see below).
|
|
12
|
+
3. Write clear, concise, accurate documentation. Test any YAML or Python examples by running them.
|
|
13
|
+
4. Run `uv run just check` to ensure no markdown lint issues.
|
|
14
|
+
5. Open a PR scoped only to documentation changes.
|
|
15
|
+
|
|
16
|
+
## Where Documentation Lives
|
|
17
|
+
|
|
18
|
+
| Content | Location |
|
|
19
|
+
|---------|----------|
|
|
20
|
+
| Project overview, installation, quick-start | `README.md` |
|
|
21
|
+
| YAML configuration reference (per-feature) | `docs/configuration/Chapter_XX.md` |
|
|
22
|
+
| Quick recipes / how-tos | `docs/configuration/Quick_Recipes.md` |
|
|
23
|
+
| Example projects | `examples/NN_name/` — each needs `config.yaml`, `main.py`, `README.md` |
|
|
24
|
+
| Release history | `CHANGELOG.md` — follows Keep a Changelog format |
|
|
25
|
+
|
|
26
|
+
## Writing Rules
|
|
27
|
+
|
|
28
|
+
- Use plain English. Short sentences. Active voice.
|
|
29
|
+
- Every documented feature needs a minimal working YAML example.
|
|
30
|
+
- YAML examples must use valid strands-compose syntax — verify against the JSON schema in `src/strands_compose/config/schema.py`.
|
|
31
|
+
- Python examples must be runnable as-is.
|
|
32
|
+
- Do not document internal implementation details — only the public API and YAML config surface.
|
|
33
|
+
- Use relative links (never absolute URLs) for files within the repository.
|
|
34
|
+
- Keep `README.md` concise — link out to `docs/` for detail rather than expanding inline.
|
|
35
|
+
|
|
36
|
+
## Examples
|
|
37
|
+
|
|
38
|
+
When adding a new example under `examples/`:
|
|
39
|
+
- Follow the naming pattern: `NN_short_name/` (next available number)
|
|
40
|
+
- The `README.md` must explain what the example demonstrates and how to run it.
|
|
41
|
+
- Use `TEMPLATE_EXAMPLE.md` in `examples/` as a structural guide.
|
|
42
|
+
- Run `uv run just test` — there is a smoke test suite in `tests/examples/` that runs all examples.
|
|
43
|
+
|
|
44
|
+
## What Not to Change
|
|
45
|
+
|
|
46
|
+
- Do not modify source code.
|
|
47
|
+
- Do not edit `docs/configuration/` chapters without understanding the full feature — ask for clarification in the issue if unsure.
|
|
48
|
+
- Do not remove existing examples without an explicit request.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: reviewer
|
|
3
|
+
description: Reviews code in pull requests for correctness, style, architecture compliance, and security in strands-compose
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are a senior code reviewer for strands-compose. Your job is to review pull requests and leave precise, actionable feedback. You enforce the project rules strictly but fairly.
|
|
7
|
+
|
|
8
|
+
## Review Workflow
|
|
9
|
+
|
|
10
|
+
1. Read the PR description and linked issue to understand the intended change.
|
|
11
|
+
2. Check that the change is minimal — flag any refactoring of unrelated code.
|
|
12
|
+
3. Run `uv run just check` — report any lint, type, or security failures.
|
|
13
|
+
4. Run `uv run just test` — report any test failures or coverage regressions.
|
|
14
|
+
5. Leave inline comments on specific lines. Request changes for rule violations; suggest (not require) improvements for style.
|
|
15
|
+
|
|
16
|
+
## What to Check
|
|
17
|
+
|
|
18
|
+
### Architecture
|
|
19
|
+
- [ ] Change is placed in the correct module (see Directory Structure in repo instructions)
|
|
20
|
+
- [ ] No strands functionality reimplemented — check `.venv/lib/python*/site-packages/strands/`
|
|
21
|
+
- [ ] No global state, singletons, or auto-registration introduced
|
|
22
|
+
- [ ] Public API changes are reflected in `src/strands_compose/__init__.py`
|
|
23
|
+
|
|
24
|
+
### Python rules
|
|
25
|
+
- [ ] `from __future__ import annotations` present in every modified module
|
|
26
|
+
- [ ] All functions/methods fully typed (parameters + return type)
|
|
27
|
+
- [ ] No `Optional`, `Union`, `List`, `Dict` — only `X | None`, `list`, `dict`
|
|
28
|
+
- [ ] Google-style docstring on every new public class, function, and method
|
|
29
|
+
- [ ] Class docstrings on `__init__`, not the class body
|
|
30
|
+
- [ ] No f-strings in `logger.*` calls — `%s` field-value pairs only
|
|
31
|
+
- [ ] No bare `except:` — specific exception types with context messages
|
|
32
|
+
- [ ] Properties returning mutable state return copies: `return list(self._items)`
|
|
33
|
+
- [ ] No hardcoded secrets, no `eval()`, `exec()`, `subprocess(shell=True)`
|
|
34
|
+
|
|
35
|
+
### Tests
|
|
36
|
+
- [ ] New public code has tests in `tests/unit/` mirroring the source path
|
|
37
|
+
- [ ] Error paths are tested with `pytest.raises`
|
|
38
|
+
- [ ] Tests are named descriptively
|
|
39
|
+
|
|
40
|
+
### Commits
|
|
41
|
+
- [ ] Commit messages follow conventional commits (`feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`)
|
|
42
|
+
- [ ] No "WIP" commits in the final PR
|
|
43
|
+
|
|
44
|
+
## Tone
|
|
45
|
+
|
|
46
|
+
Be direct and specific. Quote the problematic line. Explain why it violates a rule and what the fix should be. Don't leave vague comments like "consider refactoring this".
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tester
|
|
3
|
+
description: Writes and improves tests for strands-compose — unit, integration, and example smoke tests
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
You are a testing specialist for strands-compose. Your job is to add missing tests, improve coverage, and ensure all test behaviour is correct and well-structured.
|
|
7
|
+
|
|
8
|
+
## Workflow
|
|
9
|
+
|
|
10
|
+
1. Identify what is under-tested: missing unit tests, edge cases, or error paths.
|
|
11
|
+
2. Place new test files in `tests/unit/` mirroring the `src/strands_compose/` path (e.g. `src/strands_compose/hooks/stop_guard.py` → `tests/unit/hooks/test_stop_guard.py`).
|
|
12
|
+
3. Write tests using `pytest` — use `fixtures`, `parametrize`, and `tmp_path`. Mock all external dependencies.
|
|
13
|
+
4. Run `uv run just test` — all tests must pass and coverage must remain ≥ 70%.
|
|
14
|
+
5. Run `uv run just check` — tests must also pass lint and type checks.
|
|
15
|
+
|
|
16
|
+
## Test Structure Rules
|
|
17
|
+
|
|
18
|
+
- Test **behaviour**, not implementation details.
|
|
19
|
+
- Name tests descriptively: `test_<what>_<condition>_<expected_outcome>`.
|
|
20
|
+
- Good: `test_interpolate_missing_var_without_default_raises_value_error`
|
|
21
|
+
- Bad: `test_interpolate_1`
|
|
22
|
+
- One `assert` concept per test where practical — split into multiple tests rather than one large test.
|
|
23
|
+
- Use `pytest.raises` with `match=` to assert exception messages.
|
|
24
|
+
- Mock at the boundary: patch I/O, network, and strands internals — not internal logic you're testing.
|
|
25
|
+
- Use `tmp_path` for any file system interactions.
|
|
26
|
+
|
|
27
|
+
## Coverage Targets
|
|
28
|
+
|
|
29
|
+
- Every public function and method must have at least one test.
|
|
30
|
+
- Error paths (`ValueError`, `KeyError`, `RuntimeError`, etc.) each need a dedicated test.
|
|
31
|
+
- Parametrize repetitive cases instead of copy-pasting test bodies.
|
|
32
|
+
|
|
33
|
+
## What Not to Change
|
|
34
|
+
|
|
35
|
+
- Do not modify source code to make tests pass — fix the test or raise an issue.
|
|
36
|
+
- Do not add integration tests for behaviour already covered by unit tests.
|
|
37
|
+
- Do not remove existing tests unless they are genuinely wrong or duplicate.
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# strands-compose — Copilot Instructions
|
|
2
|
+
|
|
3
|
+
This is **strands-compose**: a declarative multi-agent orchestration library for [strands-agents](https://github.com/strands-agents/sdk-python).
|
|
4
|
+
It reads YAML configs and returns fully wired, plain `strands` objects — no wrappers, no subclasses.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Architecture — NON-NEGOTIABLE
|
|
9
|
+
|
|
10
|
+
1. **Strands-first** — always check `.venv/lib/python*/site-packages/strands/` before implementing anything. If strands provides it, use it directly.
|
|
11
|
+
2. **Thin wrapper** — translate YAML → Python objects, then get out of the way.
|
|
12
|
+
3. **Composition over inheritance** — small, focused components that compose.
|
|
13
|
+
4. **Explicit over implicit** — no auto-registration, no global singletons.
|
|
14
|
+
5. **Single responsibility** — each module does one thing.
|
|
15
|
+
6. **Testable in isolation** — no global state, every unit testable without other components.
|
|
16
|
+
|
|
17
|
+
## Python Rules
|
|
18
|
+
|
|
19
|
+
- `from __future__ import annotations` at the top of every module.
|
|
20
|
+
- Every public function/method/class must be fully typed — parameters and return type.
|
|
21
|
+
- Use `X | None`, `X | Y`, `list`, `dict`, `tuple` — never `Optional`, `Union`, `List`, `Dict`.
|
|
22
|
+
- Google-style docstrings on every public class, function, and method.
|
|
23
|
+
- Class docstring goes on `__init__`, not the class body.
|
|
24
|
+
- Early returns always — handle edge cases first, max 3 nesting levels.
|
|
25
|
+
- Raise specific exceptions (`ValueError`, `KeyError`, `TypeError`, `RuntimeError`) with context.
|
|
26
|
+
- Never silently swallow exceptions. No bare `except:`.
|
|
27
|
+
- Return copies from properties: `return list(self._items)`.
|
|
28
|
+
- `logging.getLogger(__name__)` — never `print()` for diagnostics.
|
|
29
|
+
- No `eval()`, `exec()`, `pickle` for untrusted data, `subprocess(shell=True)`.
|
|
30
|
+
- No hardcoded secrets — use env vars.
|
|
31
|
+
- Import order: stdlib → third-party → local (ruff-enforced).
|
|
32
|
+
- `__all__` only in `__init__.py`.
|
|
33
|
+
|
|
34
|
+
## Naming
|
|
35
|
+
|
|
36
|
+
- Classes: `PascalCase` | functions/methods: `snake_case` | constants: `UPPER_SNAKE_CASE` | private: `_prefix`
|
|
37
|
+
- No abbreviations in public API. Boolean params: `is_`, `has_`, `enable_` prefixes.
|
|
38
|
+
|
|
39
|
+
## Key Strands APIs (do NOT reimplement)
|
|
40
|
+
|
|
41
|
+
| What | Import path |
|
|
42
|
+
|------|-------------|
|
|
43
|
+
| `Agent` | `strands.agent.agent` |
|
|
44
|
+
| Hook events | `strands.hooks.events` — `BeforeInvocationEvent`, `AfterInvocationEvent`, `BeforeModelCallEvent`, `AfterModelCallEvent`, `BeforeToolCallEvent`, `AfterToolCallEvent` |
|
|
45
|
+
| `HookProvider` | `strands.hooks` — implement `register_hooks(registry)` |
|
|
46
|
+
| `MCPClient` | `strands.tools.mcp.mcp_client` |
|
|
47
|
+
| `SessionManager` | `strands.session` — `FileSessionManager`, `S3SessionManager` |
|
|
48
|
+
| Multi-agent | `strands.multiagent` — `Swarm`, `Graph` |
|
|
49
|
+
| `ToolRegistry` | `strands.tools.registry` |
|
|
50
|
+
| `@tool` decorator | `strands.tools.decorator` |
|
|
51
|
+
|
|
52
|
+
## Testing
|
|
53
|
+
|
|
54
|
+
- Every public function gets at least one test. Test behavior, not implementation.
|
|
55
|
+
- Use pytest fixtures, `parametrize`, `tmp_path`. Mock external dependencies.
|
|
56
|
+
- Name tests descriptively: `test_interpolate_missing_var_without_default_raises_value_error`.
|
|
57
|
+
|
|
58
|
+
## Tooling
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
uv run just install # install deps + git hooks (once after clone)
|
|
62
|
+
uv run just check # lint + type check + security scan
|
|
63
|
+
uv run just test # pytest with coverage (≥70%)
|
|
64
|
+
uv run just format # auto-format with ruff
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Directory Structure
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
src/strands_compose/
|
|
71
|
+
├── __init__.py # Public API — load(), ResolvedConfig
|
|
72
|
+
├── models.py # Pydantic config models (AgentConfig, ModelConfig, …)
|
|
73
|
+
├── types.py # Shared type aliases
|
|
74
|
+
├── utils.py # Miscellaneous helpers
|
|
75
|
+
├── exceptions.py # Custom exception hierarchy
|
|
76
|
+
├── wire.py # Final assembly — wires all resolved objects into ResolvedConfig
|
|
77
|
+
├── config/ # YAML loading, validation, interpolation
|
|
78
|
+
│ ├── schema.py # JSON-schema for config validation
|
|
79
|
+
│ ├── interpolation.py # ${VAR:-default} interpolation
|
|
80
|
+
│ ├── loaders/ # File/string/dict loaders, helpers, validators
|
|
81
|
+
│ └── resolvers/ # Per-key resolvers (agents, models, mcp, hooks, …)
|
|
82
|
+
│ └── orchestrations/ # Orchestration builder and planner
|
|
83
|
+
│ ├── builders.py # Build delegate, swarm, graph objects
|
|
84
|
+
│ └── planner.py # Resolve orchestration config to plan
|
|
85
|
+
├── converters/ # Config dict → strands objects
|
|
86
|
+
│ ├── base.py # BaseConverter protocol
|
|
87
|
+
│ ├── openai.py # OpenAI-specific conversion
|
|
88
|
+
│ └── raw.py # Raw/passthrough conversion
|
|
89
|
+
├── hooks/ # Built-in HookProvider implementations
|
|
90
|
+
│ ├── event_publisher.py # Streaming event queue publisher
|
|
91
|
+
│ ├── max_calls_guard.py # Max tool-call circuit breaker
|
|
92
|
+
│ ├── stop_guard.py # Agent stop-signal hook
|
|
93
|
+
│ └── tool_name_sanitizer.py # Sanitize tool names for model compatibility
|
|
94
|
+
├── mcp/ # MCP server/client lifecycle
|
|
95
|
+
│ ├── client.py # MCPClient factory and wiring
|
|
96
|
+
│ ├── lifecycle.py # Server startup, readiness polling, shutdown
|
|
97
|
+
│ ├── server.py # Local Python server launcher
|
|
98
|
+
│ └── transports.py # Transport builders (stdio, streamable_http)
|
|
99
|
+
├── renderers/ # Terminal output rendering
|
|
100
|
+
│ ├── base.py # BaseRenderer protocol
|
|
101
|
+
│ └── ansi.py # ANSI colour renderer
|
|
102
|
+
├── startup/ # Post-load validation and reporting
|
|
103
|
+
│ ├── validator.py # Config correctness checks
|
|
104
|
+
│ └── report.py # Human-readable startup report
|
|
105
|
+
└── tools/ # Tool loading helpers
|
|
106
|
+
├── extractors.py # Extract @tool functions from modules
|
|
107
|
+
├── loaders.py # Import modules by path/name
|
|
108
|
+
└── wrappers.py # Wrap callables as strands tools
|
|
109
|
+
|
|
110
|
+
tests/
|
|
111
|
+
├── unit/ # Unit tests (mirrors src/ structure)
|
|
112
|
+
│ ├── config/ # Tests for config loading, schema, interpolation, resolvers
|
|
113
|
+
│ ├── converters/ # Tests for converter modules
|
|
114
|
+
│ ├── hooks/ # Tests for hook providers
|
|
115
|
+
│ ├── mcp/ # Tests for MCP lifecycle
|
|
116
|
+
│ ├── models/ # Tests for Pydantic config models
|
|
117
|
+
│ ├── renderers/ # Tests for renderers
|
|
118
|
+
│ └── startup/ # Tests for validator and report
|
|
119
|
+
├── integration/ # Integration tests (real strands objects)
|
|
120
|
+
└── examples/ # Smoke tests for all examples/
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Logging Style
|
|
124
|
+
|
|
125
|
+
Use `%s` interpolation with structured field-value pairs — never f-strings:
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
# Good
|
|
129
|
+
logger.debug("agent_id=<%s>, tool=<%s> | tool call started", agent_id, tool_name)
|
|
130
|
+
logger.warning("path=<%s>, reason=<%s> | config file not found", path, reason)
|
|
131
|
+
|
|
132
|
+
# Bad
|
|
133
|
+
logger.debug(f"Tool {tool_name} called on agent {agent_id}") # no f-strings
|
|
134
|
+
logger.info("Config loaded.") # no punctuation
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
- Field-value pairs first: `key=<value>` separated by commas
|
|
138
|
+
- Human-readable message after ` | `
|
|
139
|
+
- `<>` around values (makes empty values visible)
|
|
140
|
+
- Lowercase messages, no trailing punctuation
|
|
141
|
+
- `%s` format strings, not f-strings (lazy evaluation)
|
|
142
|
+
|
|
143
|
+
## Things to Do
|
|
144
|
+
|
|
145
|
+
- Check `.venv/lib/python*/site-packages/strands/` before implementing — use strands if it exists
|
|
146
|
+
- `from __future__ import annotations` at the top of every module
|
|
147
|
+
- Fully type every function signature (parameters + return type)
|
|
148
|
+
- Google-style docstring on every public class, function, and method
|
|
149
|
+
- Put class docstrings on `__init__`, not the class body
|
|
150
|
+
- Early returns — handle edge cases first, max 3 nesting levels
|
|
151
|
+
- Raise specific exceptions (`ValueError`, `KeyError`, `TypeError`, `RuntimeError`) with context
|
|
152
|
+
- Return copies from properties exposing mutable state: `return list(self._items)`
|
|
153
|
+
- Use structured logging with `%s` and field-value pairs
|
|
154
|
+
- Run `uv run just check` then `uv run just test` before committing
|
|
155
|
+
|
|
156
|
+
## Things NOT to Do
|
|
157
|
+
|
|
158
|
+
- Don't reimplement what strands already provides — check first
|
|
159
|
+
- Don't use `Optional[X]`, `Union[X, Y]`, `List`, `Dict` — use `X | None`, `list`, `dict`
|
|
160
|
+
- Don't use `print()` for diagnostics — use `logging.getLogger(__name__)`
|
|
161
|
+
- Don't use f-strings in log calls — use `%s` interpolation
|
|
162
|
+
- Don't swallow exceptions silently — no bare `except:`
|
|
163
|
+
- Don't add `__all__` outside `__init__.py`
|
|
164
|
+
- Don't hardcode secrets — use env vars
|
|
165
|
+
- Don't use `eval()`, `exec()`, `pickle` for untrusted data, or `subprocess(shell=True)`
|
|
166
|
+
- Don't commit without running `uv run just check`
|
|
167
|
+
- Don't add comments about what changed or temporal context ("recently refactored", "moved from")
|
|
168
|
+
|
|
169
|
+
## Agent-Specific Notes
|
|
170
|
+
|
|
171
|
+
- Make the **smallest reasonable change** to achieve the goal — don't refactor unrelated code
|
|
172
|
+
- Prefer simple, readable, maintainable solutions over clever ones
|
|
173
|
+
- When unsure where something belongs, check the Directory Structure above
|
|
174
|
+
- Comments should explain **what** and **why**, never **when** or **how it changed**
|
|
175
|
+
- If you find something broken while working, fix it — don't leave it commented out
|
|
176
|
+
- Never add or change files outside the scope of the task
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "pip"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "daily"
|
|
7
|
+
open-pull-requests-limit: 100
|
|
8
|
+
commit-message:
|
|
9
|
+
prefix: ci
|
|
10
|
+
groups:
|
|
11
|
+
dev-dependencies:
|
|
12
|
+
patterns:
|
|
13
|
+
- "pytest"
|
|
14
|
+
- package-ecosystem: "github-actions"
|
|
15
|
+
directory: "/"
|
|
16
|
+
schedule:
|
|
17
|
+
interval: "daily"
|
|
18
|
+
open-pull-requests-limit: 100
|
|
19
|
+
commit-message:
|
|
20
|
+
prefix: ci
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Continuous Integration — runs on every push and pull request.
|
|
2
|
+
|
|
3
|
+
name: CI
|
|
4
|
+
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
branches: ["main"]
|
|
8
|
+
pull_request:
|
|
9
|
+
branches: ["main"]
|
|
10
|
+
workflow_call:
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ci-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: read
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
# ── Quality checks (format · lint · type · security) ──────────────────────
|
|
21
|
+
check:
|
|
22
|
+
name: Quality checks
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
permissions:
|
|
25
|
+
contents: read
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v6
|
|
28
|
+
|
|
29
|
+
- uses: astral-sh/setup-uv@v7
|
|
30
|
+
with:
|
|
31
|
+
enable-cache: true
|
|
32
|
+
|
|
33
|
+
- name: Install just
|
|
34
|
+
uses: extractions/setup-just@v3
|
|
35
|
+
|
|
36
|
+
- name: Install dev deps
|
|
37
|
+
run: uv sync --all-groups --all-extras
|
|
38
|
+
|
|
39
|
+
- name: Ruff — format check
|
|
40
|
+
run: uv run just check-format
|
|
41
|
+
|
|
42
|
+
- name: Ruff — lint
|
|
43
|
+
run: uv run just check-code
|
|
44
|
+
|
|
45
|
+
- name: ty — type check
|
|
46
|
+
run: uv run just check-type
|
|
47
|
+
|
|
48
|
+
- name: Bandit — security scan
|
|
49
|
+
run: uv run just check-security
|
|
50
|
+
|
|
51
|
+
# ── Tests ──────────────────────────────────────────────────────────────────
|
|
52
|
+
test:
|
|
53
|
+
name: Tests (Python ${{ matrix.python-version }})
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
permissions:
|
|
56
|
+
contents: read
|
|
57
|
+
strategy:
|
|
58
|
+
fail-fast: false
|
|
59
|
+
matrix:
|
|
60
|
+
python-version: ["3.11", "3.12", "3.13"]
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v6
|
|
63
|
+
|
|
64
|
+
- uses: astral-sh/setup-uv@v7
|
|
65
|
+
with:
|
|
66
|
+
enable-cache: true
|
|
67
|
+
python-version: ${{ matrix.python-version }}
|
|
68
|
+
|
|
69
|
+
- name: Install just
|
|
70
|
+
uses: extractions/setup-just@v3
|
|
71
|
+
|
|
72
|
+
- name: Install dev deps
|
|
73
|
+
run: uv sync --all-groups --all-extras
|
|
74
|
+
|
|
75
|
+
- name: pytest with coverage
|
|
76
|
+
run: uv run just test
|