strands-compose-chat 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.
Files changed (162) hide show
  1. strands_compose_chat-0.1.0/.dockerignore +30 -0
  2. strands_compose_chat-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +117 -0
  3. strands_compose_chat-0.1.0/.github/ISSUE_TEMPLATE/config.yml +8 -0
  4. strands_compose_chat-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +46 -0
  5. strands_compose_chat-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +37 -0
  6. strands_compose_chat-0.1.0/.github/dependabot.yml +20 -0
  7. strands_compose_chat-0.1.0/.github/workflows/ci.yml +123 -0
  8. strands_compose_chat-0.1.0/.github/workflows/publish.yml +134 -0
  9. strands_compose_chat-0.1.0/.gitignore +30 -0
  10. strands_compose_chat-0.1.0/.kiro/skills/backend-development/SKILL.md +324 -0
  11. strands_compose_chat-0.1.0/.kiro/skills/backend-development/references/project-map.md +133 -0
  12. strands_compose_chat-0.1.0/.kiro/skills/backend-testing/SKILL.md +278 -0
  13. strands_compose_chat-0.1.0/.kiro/skills/backend-testing/references/test-patterns.md +250 -0
  14. strands_compose_chat-0.1.0/.kiro/skills/frontend-development/SKILL.md +355 -0
  15. strands_compose_chat-0.1.0/.kiro/skills/frontend-development/references/project-map.md +127 -0
  16. strands_compose_chat-0.1.0/.kiroignore +1 -0
  17. strands_compose_chat-0.1.0/.pre-commit-config.yaml +48 -0
  18. strands_compose_chat-0.1.0/.secrets.baseline +127 -0
  19. strands_compose_chat-0.1.0/AGENTS.md +69 -0
  20. strands_compose_chat-0.1.0/CHANGELOG.md +25 -0
  21. strands_compose_chat-0.1.0/CONTRIBUTING.md +126 -0
  22. strands_compose_chat-0.1.0/Dockerfile +54 -0
  23. strands_compose_chat-0.1.0/LICENSE +174 -0
  24. strands_compose_chat-0.1.0/PKG-INFO +25 -0
  25. strands_compose_chat-0.1.0/README.md +128 -0
  26. strands_compose_chat-0.1.0/RELEASING.md +50 -0
  27. strands_compose_chat-0.1.0/SECURITY.md +30 -0
  28. strands_compose_chat-0.1.0/SUPPORT.md +34 -0
  29. strands_compose_chat-0.1.0/docker-compose.yaml +29 -0
  30. strands_compose_chat-0.1.0/example.env +13 -0
  31. strands_compose_chat-0.1.0/examples/01-local-dev/README.md +65 -0
  32. strands_compose_chat-0.1.0/examples/01-local-dev/pyproject.toml +17 -0
  33. strands_compose_chat-0.1.0/examples/02-docker/Dockerfile +43 -0
  34. strands_compose_chat-0.1.0/examples/02-docker/README.md +61 -0
  35. strands_compose_chat-0.1.0/examples/02-docker/docker-compose.yaml +37 -0
  36. strands_compose_chat-0.1.0/examples/README.md +49 -0
  37. strands_compose_chat-0.1.0/justfile +29 -0
  38. strands_compose_chat-0.1.0/pyproject.toml +163 -0
  39. strands_compose_chat-0.1.0/src/strands_compose_chat/__init__.py +1 -0
  40. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/__init__.py +1 -0
  41. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/auth.py +132 -0
  42. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/templates/dashboard.html +18 -0
  43. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/templates/sqladmin/index.html +45 -0
  44. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/templates/sqladmin/layout.html +132 -0
  45. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/views/__init__.py +23 -0
  46. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/views/agent.py +234 -0
  47. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/views/api_key.py +134 -0
  48. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/views/base.py +84 -0
  49. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/views/chat_message.py +161 -0
  50. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/views/chat_session.py +148 -0
  51. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/views/dashboard.py +44 -0
  52. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/views/group.py +49 -0
  53. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/views/model_pricing.py +51 -0
  54. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/views/token_usage.py +215 -0
  55. strands_compose_chat-0.1.0/src/strands_compose_chat/admin/views/user.py +250 -0
  56. strands_compose_chat-0.1.0/src/strands_compose_chat/agents/__init__.py +5 -0
  57. strands_compose_chat-0.1.0/src/strands_compose_chat/agents/client.py +52 -0
  58. strands_compose_chat-0.1.0/src/strands_compose_chat/agents/invocation.py +195 -0
  59. strands_compose_chat-0.1.0/src/strands_compose_chat/agents/payload.py +169 -0
  60. strands_compose_chat-0.1.0/src/strands_compose_chat/agents/routes.py +45 -0
  61. strands_compose_chat-0.1.0/src/strands_compose_chat/agents/service.py +117 -0
  62. strands_compose_chat-0.1.0/src/strands_compose_chat/agents/streaming.py +428 -0
  63. strands_compose_chat-0.1.0/src/strands_compose_chat/alembic.ini +46 -0
  64. strands_compose_chat-0.1.0/src/strands_compose_chat/analytics/__init__.py +3 -0
  65. strands_compose_chat-0.1.0/src/strands_compose_chat/analytics/routes_admin.py +135 -0
  66. strands_compose_chat-0.1.0/src/strands_compose_chat/analytics/routes_me.py +42 -0
  67. strands_compose_chat-0.1.0/src/strands_compose_chat/analytics/service.py +1428 -0
  68. strands_compose_chat-0.1.0/src/strands_compose_chat/app.py +160 -0
  69. strands_compose_chat-0.1.0/src/strands_compose_chat/auth/__init__.py +1 -0
  70. strands_compose_chat-0.1.0/src/strands_compose_chat/auth/api_key.py +167 -0
  71. strands_compose_chat-0.1.0/src/strands_compose_chat/auth/current_user.py +190 -0
  72. strands_compose_chat-0.1.0/src/strands_compose_chat/auth/jit.py +165 -0
  73. strands_compose_chat-0.1.0/src/strands_compose_chat/auth/oidc.py +211 -0
  74. strands_compose_chat-0.1.0/src/strands_compose_chat/auth/passwords.py +70 -0
  75. strands_compose_chat-0.1.0/src/strands_compose_chat/auth/routes.py +377 -0
  76. strands_compose_chat-0.1.0/src/strands_compose_chat/auth/service.py +194 -0
  77. strands_compose_chat-0.1.0/src/strands_compose_chat/bootstrap.py +55 -0
  78. strands_compose_chat-0.1.0/src/strands_compose_chat/cli.py +95 -0
  79. strands_compose_chat-0.1.0/src/strands_compose_chat/config.py +222 -0
  80. strands_compose_chat-0.1.0/src/strands_compose_chat/db/__init__.py +1 -0
  81. strands_compose_chat-0.1.0/src/strands_compose_chat/db/base.py +65 -0
  82. strands_compose_chat-0.1.0/src/strands_compose_chat/db/migrations/env.py +68 -0
  83. strands_compose_chat-0.1.0/src/strands_compose_chat/db/migrations/script.py.mako +27 -0
  84. strands_compose_chat-0.1.0/src/strands_compose_chat/db/migrations/versions/0001_initial_schema.py +256 -0
  85. strands_compose_chat-0.1.0/src/strands_compose_chat/db/models/__init__.py +24 -0
  86. strands_compose_chat-0.1.0/src/strands_compose_chat/db/models/agent.py +69 -0
  87. strands_compose_chat-0.1.0/src/strands_compose_chat/db/models/api_key.py +53 -0
  88. strands_compose_chat-0.1.0/src/strands_compose_chat/db/models/associations.py +63 -0
  89. strands_compose_chat-0.1.0/src/strands_compose_chat/db/models/chat_message.py +79 -0
  90. strands_compose_chat-0.1.0/src/strands_compose_chat/db/models/chat_session.py +80 -0
  91. strands_compose_chat-0.1.0/src/strands_compose_chat/db/models/group.py +39 -0
  92. strands_compose_chat-0.1.0/src/strands_compose_chat/db/models/model_pricing.py +33 -0
  93. strands_compose_chat-0.1.0/src/strands_compose_chat/db/models/token_usage.py +65 -0
  94. strands_compose_chat-0.1.0/src/strands_compose_chat/db/models/user.py +69 -0
  95. strands_compose_chat-0.1.0/src/strands_compose_chat/deps.py +37 -0
  96. strands_compose_chat-0.1.0/src/strands_compose_chat/errors.py +161 -0
  97. strands_compose_chat-0.1.0/src/strands_compose_chat/frontend.py +169 -0
  98. strands_compose_chat-0.1.0/src/strands_compose_chat/logging.py +109 -0
  99. strands_compose_chat-0.1.0/src/strands_compose_chat/media/__init__.py +6 -0
  100. strands_compose_chat-0.1.0/src/strands_compose_chat/media/blocks.py +117 -0
  101. strands_compose_chat-0.1.0/src/strands_compose_chat/media/routes.py +26 -0
  102. strands_compose_chat-0.1.0/src/strands_compose_chat/media/service.py +44 -0
  103. strands_compose_chat-0.1.0/src/strands_compose_chat/middleware/__init__.py +7 -0
  104. strands_compose_chat-0.1.0/src/strands_compose_chat/middleware/security_headers.py +45 -0
  105. strands_compose_chat-0.1.0/src/strands_compose_chat/schemas/__init__.py +9 -0
  106. strands_compose_chat-0.1.0/src/strands_compose_chat/schemas/agents.py +43 -0
  107. strands_compose_chat-0.1.0/src/strands_compose_chat/schemas/analytics.py +330 -0
  108. strands_compose_chat-0.1.0/src/strands_compose_chat/schemas/auth.py +71 -0
  109. strands_compose_chat-0.1.0/src/strands_compose_chat/schemas/invocations.py +44 -0
  110. strands_compose_chat-0.1.0/src/strands_compose_chat/schemas/media.py +46 -0
  111. strands_compose_chat-0.1.0/src/strands_compose_chat/schemas/sessions.py +138 -0
  112. strands_compose_chat-0.1.0/src/strands_compose_chat/sessions/__init__.py +1 -0
  113. strands_compose_chat-0.1.0/src/strands_compose_chat/sessions/routes.py +156 -0
  114. strands_compose_chat-0.1.0/src/strands_compose_chat/sessions/service.py +227 -0
  115. strands_compose_chat-0.1.0/src/strands_compose_chat/templates/app.html +16 -0
  116. strands_compose_chat-0.1.0/src/strands_compose_chat/templates/login.html +16 -0
  117. strands_compose_chat-0.1.0/tasks/README.md +152 -0
  118. strands_compose_chat-0.1.0/tasks/check.just +30 -0
  119. strands_compose_chat-0.1.0/tasks/clean.just +55 -0
  120. strands_compose_chat-0.1.0/tasks/commit.just +19 -0
  121. strands_compose_chat-0.1.0/tasks/db.just +12 -0
  122. strands_compose_chat-0.1.0/tasks/format.just +13 -0
  123. strands_compose_chat-0.1.0/tasks/install.just +15 -0
  124. strands_compose_chat-0.1.0/tasks/release.just +39 -0
  125. strands_compose_chat-0.1.0/tasks/test.just +29 -0
  126. strands_compose_chat-0.1.0/tasks/ui.just +4 -0
  127. strands_compose_chat-0.1.0/tests/__init__.py +0 -0
  128. strands_compose_chat-0.1.0/tests/agents/__init__.py +0 -0
  129. strands_compose_chat-0.1.0/tests/agents/test_routes.py +167 -0
  130. strands_compose_chat-0.1.0/tests/agents/test_service.py +313 -0
  131. strands_compose_chat-0.1.0/tests/agents/test_streaming.py +224 -0
  132. strands_compose_chat-0.1.0/tests/analytics/__init__.py +0 -0
  133. strands_compose_chat-0.1.0/tests/analytics/test_routes.py +240 -0
  134. strands_compose_chat-0.1.0/tests/analytics/test_service.py +495 -0
  135. strands_compose_chat-0.1.0/tests/auth/__init__.py +0 -0
  136. strands_compose_chat-0.1.0/tests/auth/test_routes.py +162 -0
  137. strands_compose_chat-0.1.0/tests/auth/test_service.py +392 -0
  138. strands_compose_chat-0.1.0/tests/conftest.py +139 -0
  139. strands_compose_chat-0.1.0/tests/contract/__init__.py +0 -0
  140. strands_compose_chat-0.1.0/tests/contract/openapi.snapshot.json +2423 -0
  141. strands_compose_chat-0.1.0/tests/contract/test_openapi_snapshot.py +150 -0
  142. strands_compose_chat-0.1.0/tests/db/__init__.py +0 -0
  143. strands_compose_chat-0.1.0/tests/db/conftest.py +30 -0
  144. strands_compose_chat-0.1.0/tests/db/test_migrations.py +89 -0
  145. strands_compose_chat-0.1.0/tests/factories.py +186 -0
  146. strands_compose_chat-0.1.0/tests/fakes/__init__.py +5 -0
  147. strands_compose_chat-0.1.0/tests/fakes/agent_client.py +68 -0
  148. strands_compose_chat-0.1.0/tests/fakes/oidc.py +113 -0
  149. strands_compose_chat-0.1.0/tests/media/__init__.py +0 -0
  150. strands_compose_chat-0.1.0/tests/media/test_routes.py +28 -0
  151. strands_compose_chat-0.1.0/tests/media/test_service.py +78 -0
  152. strands_compose_chat-0.1.0/tests/sessions/__init__.py +0 -0
  153. strands_compose_chat-0.1.0/tests/sessions/test_routes.py +321 -0
  154. strands_compose_chat-0.1.0/tests/sessions/test_service.py +348 -0
  155. strands_compose_chat-0.1.0/tests/unit/__init__.py +0 -0
  156. strands_compose_chat-0.1.0/tests/unit/conftest.py +13 -0
  157. strands_compose_chat-0.1.0/tests/unit/test_auth_invariants.py +30 -0
  158. strands_compose_chat-0.1.0/tests/unit/test_content_blocks.py +227 -0
  159. strands_compose_chat-0.1.0/tests/unit/test_pricing.py +163 -0
  160. strands_compose_chat-0.1.0/tests/unit/test_redirect_validation.py +118 -0
  161. strands_compose_chat-0.1.0/tests/unit/test_token_accounting.py +260 -0
  162. strands_compose_chat-0.1.0/uv.lock +2538 -0
@@ -0,0 +1,30 @@
1
+ # Python
2
+ .venv/
3
+ __pycache__/
4
+ *.pyc
5
+ *.pyo
6
+ .ruff_cache/
7
+ .coverage
8
+ *.egg-info/
9
+ dist/
10
+ build/
11
+ *cache
12
+
13
+ # Node
14
+ */node_modules/
15
+ */dist/
16
+
17
+ # Dev / tooling
18
+ .git/
19
+ .kiro/
20
+ .env
21
+ *.sqlite
22
+ *.db
23
+ tasks
24
+
25
+ # Tests
26
+ tests/
27
+ .pytest_cache/
28
+
29
+ # Docs / misc
30
+ *.md
@@ -0,0 +1,117 @@
1
+ name: Bug Report
2
+ description: Report a bug in strands-compose-chat
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-chat!
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-chat
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: chat-version
26
+ attributes:
27
+ label: strands-compose-chat Version
28
+ description: Which version of strands-compose-chat are you using?
29
+ placeholder: e.g., 0.1.0
30
+ validations:
31
+ required: true
32
+
33
+ - type: input
34
+ id: strands-compose-agentcore-version
35
+ attributes:
36
+ label: strands-compose-agentcore Version
37
+ description: Which version of strands-compose-agentcore are you using?
38
+ placeholder: e.g., 0.9.1
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-chay?
65
+ options:
66
+ - pip
67
+ - uv
68
+ - git clone
69
+ - other
70
+ validations:
71
+ required: true
72
+
73
+ - type: textarea
74
+ id: steps-to-reproduce
75
+ attributes:
76
+ label: Steps to Reproduce
77
+ description: Detailed steps to reproduce the behavior
78
+ placeholder: |
79
+ 1. config.yaml and code snippet (minimal reproducible example)
80
+ 2. Run the command...
81
+ 3. See error...
82
+ validations:
83
+ required: true
84
+
85
+ - type: textarea
86
+ id: expected-behavior
87
+ attributes:
88
+ label: Expected Behavior
89
+ description: A clear description of what you expected to happen
90
+ validations:
91
+ required: true
92
+
93
+ - type: textarea
94
+ id: actual-behavior
95
+ attributes:
96
+ label: Actual Behavior
97
+ description: What actually happened — include full traceback if applicable
98
+ validations:
99
+ required: true
100
+
101
+ - type: textarea
102
+ id: additional-context
103
+ attributes:
104
+ label: Additional Context
105
+ description: Any other relevant information, logs, screenshots, etc.
106
+
107
+ - type: textarea
108
+ id: possible-solution
109
+ attributes:
110
+ label: Possible Solution
111
+ description: Optional — if you have suggestions on how to fix the bug
112
+
113
+ - type: input
114
+ id: related-issues
115
+ attributes:
116
+ label: Related Issues
117
+ description: Optional — link to related issues if applicable
@@ -0,0 +1,8 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: strands-compose-chat Discussions
4
+ url: https://github.com/strands-compose/chat/discussions
5
+ about: Please ask and answer questions here
6
+ - name: strands-compose-chat Documentation
7
+ url: https://github.com/strands-compose/chat/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-chat
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-chat!
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-chat 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?
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,37 @@
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
+ ## Testing
20
+
21
+ How have you tested the change?
22
+
23
+ - [ ] I ran `uv run just check` (lint + type check)
24
+ - [ ] I ran `uv run just test` for overall testing
25
+ - [ ] I added or updated tests that prove my fix is effective or my feature works
26
+ - [ ] I verified existing examples in `examples/` still work
27
+
28
+ ## Checklist
29
+
30
+ - [ ] I have read the [CONTRIBUTING](CONTRIBUTING.md) document
31
+ - [ ] I have updated the documentation accordingly
32
+ - [ ] My changes generate no new warnings
33
+ - [ ] Any dependent changes have been merged and published
34
+
35
+ ---
36
+
37
+ 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,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,123 @@
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
21
+ check:
22
+ name: Quality checks
23
+ runs-on: ubuntu-latest
24
+ permissions:
25
+ contents: read
26
+ steps:
27
+ - uses: actions/checkout@v7
28
+
29
+ - uses: astral-sh/setup-uv@v8.2.0
30
+ with:
31
+ enable-cache: true
32
+
33
+ - name: Install dev deps
34
+ run: uv sync --all-groups --all-extras
35
+
36
+ - name: Ruff — format check
37
+ run: uv run just check-format
38
+
39
+ - name: Ruff — lint
40
+ run: uv run just check-code
41
+
42
+ - name: ty — type check
43
+ run: uv run just check-type
44
+
45
+ - name: Bandit — security scan
46
+ run: uv run just check-security
47
+
48
+ # Fast tier: unit + SQLite-backed
49
+ test-fast:
50
+ name: Fast tier (Python ${{ matrix.python-version }}, ${{ matrix.os }})
51
+ runs-on: ${{ matrix.os }}
52
+ permissions:
53
+ contents: read
54
+ strategy:
55
+ fail-fast: false
56
+ matrix:
57
+ os: [ubuntu-latest, windows-latest]
58
+ python-version: ["3.11", "3.12", "3.13"]
59
+ steps:
60
+ - uses: actions/checkout@v7
61
+
62
+ - uses: astral-sh/setup-uv@v8.2.0
63
+ with:
64
+ enable-cache: true
65
+ python-version: ${{ matrix.python-version }}
66
+
67
+ - name: Install dev deps
68
+ run: uv sync --all-groups --all-extras
69
+
70
+ - name: Run tests
71
+ run: uv run just test-fast
72
+
73
+ # Postgres tier: dialect-sensitive tests + migration guard
74
+ test-postgres:
75
+ name: Postgres tier
76
+ runs-on: ubuntu-latest
77
+ permissions:
78
+ contents: read
79
+ services:
80
+ postgres:
81
+ image: postgres:17
82
+ env:
83
+ POSTGRES_USER: testuser
84
+ POSTGRES_PASSWORD: testpassword # pragma: allowlist secret
85
+ POSTGRES_DB: testdb
86
+ ports:
87
+ - 5432:5432
88
+ options: >-
89
+ --health-cmd "pg_isready -U testuser -d testdb"
90
+ --health-interval 5s
91
+ --health-timeout 5s
92
+ --health-retries 5
93
+ env:
94
+ DATABASE_URL: "postgresql+psycopg://testuser:testpassword@localhost:5432/testdb" # pragma: allowlist secret
95
+ steps:
96
+ - uses: actions/checkout@v7
97
+
98
+ - uses: astral-sh/setup-uv@v8.2.0
99
+ with:
100
+ enable-cache: true
101
+
102
+ - name: Install dev deps
103
+ run: uv sync --all-groups --all-extras
104
+
105
+ - name: Verify Postgres is reachable
106
+ run: |
107
+ uv run python - <<'EOF'
108
+ import sys
109
+ import psycopg
110
+
111
+ try:
112
+ with psycopg.connect(
113
+ "postgresql://testuser:testpassword@localhost:5432/testdb",
114
+ connect_timeout=10,
115
+ ) as conn:
116
+ conn.execute("SELECT 1")
117
+ except Exception as exc:
118
+ print(f"ERROR: database connection failed — {exc}", file=sys.stderr)
119
+ sys.exit(1)
120
+ EOF
121
+
122
+ - name: Run tests
123
+ run: uv run just test-postgres db_host=localhost
@@ -0,0 +1,134 @@
1
+ # Publish to PyPI — triggered by pushing a version tag (v*.*.*).
2
+ # Uses Trusted Publishing (OIDC — no API tokens required).
3
+ #
4
+ # One-time setup on PyPI:
5
+ # 1. Create a project for "strands-compose" at https://pypi.org/manage/account/publishing/
6
+ # 2. Configure Trusted Publisher:
7
+ # - Owner: strands-compose
8
+ # - Repository: chat
9
+ # - Workflow: publish.yml
10
+ # - Environment: release
11
+
12
+ name: Publish
13
+
14
+ on:
15
+ push:
16
+ tags:
17
+ - "v[0-9]+.[0-9]+.[0-9]+"
18
+ - "v[0-9]+.[0-9]+.[0-9]+.post*"
19
+ - "v[0-9]+.[0-9]+.[0-9]+rc*"
20
+
21
+ permissions:
22
+ contents: read
23
+
24
+ jobs:
25
+ # Gate: run CI checks before publishing
26
+ ci:
27
+ uses: ./.github/workflows/ci.yml
28
+ permissions:
29
+ contents: read
30
+
31
+ # Build distribution package
32
+ build:
33
+ name: Build
34
+ needs: ci
35
+ runs-on: ubuntu-latest
36
+ permissions:
37
+ contents: read
38
+ steps:
39
+ - uses: actions/checkout@v7
40
+
41
+ - uses: astral-sh/setup-uv@v8.2.0
42
+ with:
43
+ enable-cache: true
44
+
45
+ - name: Set up Node.js
46
+ uses: actions/setup-node@v6
47
+ with:
48
+ node-version: "22"
49
+ cache: "npm"
50
+ cache-dependency-path: ui/package-lock.json
51
+
52
+ - name: Build frontend
53
+ run: |
54
+ cd ui
55
+ npm ci
56
+ npm run build:backend
57
+
58
+ - name: Build wheel + sdist
59
+ run: uv build --out-dir dist/
60
+
61
+ - name: Upload build artifacts
62
+ uses: actions/upload-artifact@v7
63
+ with:
64
+ name: dist
65
+ path: dist/
66
+ if-no-files-found: error
67
+
68
+ # Publish to PyPI
69
+ publish:
70
+ name: Publish to PyPI
71
+ needs: build
72
+ runs-on: ubuntu-latest
73
+ environment: release
74
+ permissions:
75
+ id-token: write
76
+ steps:
77
+ - name: Download build artifacts
78
+ uses: actions/download-artifact@v8
79
+ with:
80
+ name: dist
81
+ path: dist/
82
+
83
+ - name: Publish to PyPI
84
+ uses: pypa/gh-action-pypi-publish@release/v1
85
+ with:
86
+ packages-dir: dist/
87
+
88
+ # Create GitHub Release with CHANGELOG notes
89
+ github-release:
90
+ name: GitHub Release
91
+ needs: publish
92
+ runs-on: ubuntu-latest
93
+ permissions:
94
+ contents: write
95
+ steps:
96
+ - uses: actions/checkout@v7
97
+ with:
98
+ fetch-depth: 0
99
+
100
+ - uses: actions/setup-python@v6
101
+ with:
102
+ python-version: "3.x"
103
+
104
+ - name: Extract changelog for this version
105
+ id: changelog
106
+ run: |
107
+ VERSION="${GITHUB_REF_NAME#v}"
108
+ NOTES=$(python -c "
109
+ import re, pathlib
110
+ text = pathlib.Path('CHANGELOG.md').read_text()
111
+ match = re.search(
112
+ r'(?:^|\n)(## v?' + re.escape('$VERSION') + r'[^\n]*\n.*?)(?=\n## |\Z)',
113
+ text, re.DOTALL
114
+ )
115
+ print(match.group(1).strip() if match else 'See CHANGELOG.md for details.')
116
+ " VERSION="$VERSION")
117
+ {
118
+ echo 'notes<<EOF'
119
+ echo "$NOTES"
120
+ echo EOF
121
+ } >> "$GITHUB_OUTPUT"
122
+
123
+ - name: Download all artifacts
124
+ uses: actions/download-artifact@v8
125
+ with:
126
+ path: dist-all/
127
+ merge-multiple: true
128
+
129
+ - name: Create GitHub Release
130
+ uses: softprops/action-gh-release@v3
131
+ with:
132
+ body: ${{ steps.changelog.outputs.notes }}
133
+ files: dist-all/**/*
134
+ prerelease: ${{ contains(github.ref_name, 'rc') || contains(github.ref_name, 'alpha') || contains(github.ref_name, 'beta') }}
@@ -0,0 +1,30 @@
1
+ .claude
2
+ .kiro/specs
3
+
4
+ .venv/
5
+ venv/
6
+ *.pyc
7
+ *.pyo
8
+ */__pycache__/
9
+ *.sqlite3
10
+ .*_cache
11
+ .hypothesis
12
+
13
+ .coverage*
14
+ .req.txt
15
+
16
+ *.log
17
+ *.ipynb
18
+
19
+ .env*
20
+
21
+ # IDE
22
+ .idea/
23
+ .vscode/
24
+
25
+ proxy.py
26
+ *.sqlite
27
+ seed_dummy_db.py
28
+
29
+ # Built frontend artifacts — populated by `just build-ui` or Docker build stage.
30
+ src/strands_compose_chat/static/