redis-agent-kit 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 (176) hide show
  1. redis_agent_kit-0.1.0/.autorc +90 -0
  2. redis_agent_kit-0.1.0/.github/workflows/auto-release.yml +235 -0
  3. redis_agent_kit-0.1.0/.github/workflows/lint.yml +60 -0
  4. redis_agent_kit-0.1.0/.github/workflows/test.yml +49 -0
  5. redis_agent_kit-0.1.0/.gitignore +64 -0
  6. redis_agent_kit-0.1.0/.pre-commit-config.yaml +17 -0
  7. redis_agent_kit-0.1.0/AGENTS.md +313 -0
  8. redis_agent_kit-0.1.0/Makefile +71 -0
  9. redis_agent_kit-0.1.0/PKG-INFO +198 -0
  10. redis_agent_kit-0.1.0/README.md +130 -0
  11. redis_agent_kit-0.1.0/docs/guide/api.md +220 -0
  12. redis_agent_kit-0.1.0/docs/guide/cli.md +122 -0
  13. redis_agent_kit-0.1.0/docs/guide/input.md +235 -0
  14. redis_agent_kit-0.1.0/docs/guide/memory.md +142 -0
  15. redis_agent_kit-0.1.0/docs/guide/middleware.md +158 -0
  16. redis_agent_kit-0.1.0/docs/guide/pipelines.md +161 -0
  17. redis_agent_kit-0.1.0/docs/guide/protocols.md +158 -0
  18. redis_agent_kit-0.1.0/docs/guide/streaming.md +153 -0
  19. redis_agent_kit-0.1.0/docs/guide/tasks.md +145 -0
  20. redis_agent_kit-0.1.0/docs/guide/threads.md +109 -0
  21. redis_agent_kit-0.1.0/docs/index.md +117 -0
  22. redis_agent_kit-0.1.0/docs/tutorial.md +286 -0
  23. redis_agent_kit-0.1.0/examples/README.md +189 -0
  24. redis_agent_kit-0.1.0/examples/basic_llm/__init__.py +2 -0
  25. redis_agent_kit-0.1.0/examples/basic_llm/agent.py +108 -0
  26. redis_agent_kit-0.1.0/examples/docs/caching-patterns.md +81 -0
  27. redis_agent_kit-0.1.0/examples/docs/redis-basics.md +70 -0
  28. redis_agent_kit-0.1.0/examples/docs/vector-search.md +91 -0
  29. redis_agent_kit-0.1.0/examples/langgraph_agent/__init__.py +1 -0
  30. redis_agent_kit-0.1.0/examples/langgraph_agent/agent.py +209 -0
  31. redis_agent_kit-0.1.0/examples/langgraph_interrupt/__init__.py +2 -0
  32. redis_agent_kit-0.1.0/examples/langgraph_interrupt/agent.py +223 -0
  33. redis_agent_kit-0.1.0/examples/langgraph_rag/__init__.py +2 -0
  34. redis_agent_kit-0.1.0/examples/langgraph_rag/agent.py +137 -0
  35. redis_agent_kit-0.1.0/examples/multi_protocol_agent/__init__.py +2 -0
  36. redis_agent_kit-0.1.0/examples/multi_protocol_agent/agent.py +132 -0
  37. redis_agent_kit-0.1.0/examples/openai_agent/__init__.py +1 -0
  38. redis_agent_kit-0.1.0/examples/openai_agent/agent.py +177 -0
  39. redis_agent_kit-0.1.0/examples/rag_agent/__init__.py +2 -0
  40. redis_agent_kit-0.1.0/examples/rag_agent/agent.py +156 -0
  41. redis_agent_kit-0.1.0/examples/rag_with_memory/__init__.py +2 -0
  42. redis_agent_kit-0.1.0/examples/rag_with_memory/agent.py +154 -0
  43. redis_agent_kit-0.1.0/examples/sse_streaming/__init__.py +2 -0
  44. redis_agent_kit-0.1.0/examples/sse_streaming/agent.py +161 -0
  45. redis_agent_kit-0.1.0/examples/tool_agent/__init__.py +2 -0
  46. redis_agent_kit-0.1.0/examples/tool_agent/agent.py +175 -0
  47. redis_agent_kit-0.1.0/pyproject.toml +132 -0
  48. redis_agent_kit-0.1.0/redis_agent_kit/__init__.py +222 -0
  49. redis_agent_kit-0.1.0/redis_agent_kit/agent.py +265 -0
  50. redis_agent_kit-0.1.0/redis_agent_kit/api/__init__.py +21 -0
  51. redis_agent_kit-0.1.0/redis_agent_kit/api/app.py +163 -0
  52. redis_agent_kit-0.1.0/redis_agent_kit/api/auth.py +97 -0
  53. redis_agent_kit-0.1.0/redis_agent_kit/api/pipelines.py +240 -0
  54. redis_agent_kit-0.1.0/redis_agent_kit/api/tasks.py +511 -0
  55. redis_agent_kit-0.1.0/redis_agent_kit/api/v1.py +386 -0
  56. redis_agent_kit-0.1.0/redis_agent_kit/attachments.py +225 -0
  57. redis_agent_kit-0.1.0/redis_agent_kit/cli/__init__.py +5 -0
  58. redis_agent_kit-0.1.0/redis_agent_kit/cli/agent.py +54 -0
  59. redis_agent_kit-0.1.0/redis_agent_kit/cli/api_common.py +130 -0
  60. redis_agent_kit-0.1.0/redis_agent_kit/cli/chat.py +434 -0
  61. redis_agent_kit-0.1.0/redis_agent_kit/cli/health.py +21 -0
  62. redis_agent_kit-0.1.0/redis_agent_kit/cli/main.py +173 -0
  63. redis_agent_kit-0.1.0/redis_agent_kit/cli/pipelines.py +327 -0
  64. redis_agent_kit-0.1.0/redis_agent_kit/cli/task.py +298 -0
  65. redis_agent_kit-0.1.0/redis_agent_kit/cli/up.py +67 -0
  66. redis_agent_kit-0.1.0/redis_agent_kit/cli/worker.py +103 -0
  67. redis_agent_kit-0.1.0/redis_agent_kit/config.py +209 -0
  68. redis_agent_kit-0.1.0/redis_agent_kit/core.py +575 -0
  69. redis_agent_kit-0.1.0/redis_agent_kit/emitter.py +126 -0
  70. redis_agent_kit-0.1.0/redis_agent_kit/keys.py +119 -0
  71. redis_agent_kit-0.1.0/redis_agent_kit/knowledge.py +188 -0
  72. redis_agent_kit-0.1.0/redis_agent_kit/mcp/__init__.py +5 -0
  73. redis_agent_kit-0.1.0/redis_agent_kit/mcp/server.py +340 -0
  74. redis_agent_kit-0.1.0/redis_agent_kit/memory.py +700 -0
  75. redis_agent_kit-0.1.0/redis_agent_kit/middleware.py +481 -0
  76. redis_agent_kit-0.1.0/redis_agent_kit/models.py +329 -0
  77. redis_agent_kit-0.1.0/redis_agent_kit/pipelines/__init__.py +64 -0
  78. redis_agent_kit-0.1.0/redis_agent_kit/pipelines/artifact_storage.py +189 -0
  79. redis_agent_kit-0.1.0/redis_agent_kit/pipelines/config_loader.py +113 -0
  80. redis_agent_kit-0.1.0/redis_agent_kit/pipelines/deduplicator.py +114 -0
  81. redis_agent_kit-0.1.0/redis_agent_kit/pipelines/frontmatter.py +109 -0
  82. redis_agent_kit-0.1.0/redis_agent_kit/pipelines/ingest_stage.py +100 -0
  83. redis_agent_kit-0.1.0/redis_agent_kit/pipelines/models.py +209 -0
  84. redis_agent_kit-0.1.0/redis_agent_kit/pipelines/orchestrator.py +285 -0
  85. redis_agent_kit-0.1.0/redis_agent_kit/pipelines/pipeline.py +309 -0
  86. redis_agent_kit-0.1.0/redis_agent_kit/pipelines/prepare_stage.py +160 -0
  87. redis_agent_kit-0.1.0/redis_agent_kit/pipelines/processor.py +120 -0
  88. redis_agent_kit-0.1.0/redis_agent_kit/pipelines/scraper.py +96 -0
  89. redis_agent_kit-0.1.0/redis_agent_kit/pipelines/vector_store.py +386 -0
  90. redis_agent_kit-0.1.0/redis_agent_kit/protocols/__init__.py +23 -0
  91. redis_agent_kit-0.1.0/redis_agent_kit/protocols/a2a/__init__.py +35 -0
  92. redis_agent_kit-0.1.0/redis_agent_kit/protocols/a2a/adapter.py +148 -0
  93. redis_agent_kit-0.1.0/redis_agent_kit/protocols/a2a/models.py +101 -0
  94. redis_agent_kit-0.1.0/redis_agent_kit/protocols/a2a/router.py +196 -0
  95. redis_agent_kit-0.1.0/redis_agent_kit/protocols/acp/__init__.py +28 -0
  96. redis_agent_kit-0.1.0/redis_agent_kit/protocols/acp/adapter.py +160 -0
  97. redis_agent_kit-0.1.0/redis_agent_kit/protocols/acp/models.py +65 -0
  98. redis_agent_kit-0.1.0/redis_agent_kit/protocols/acp/router.py +108 -0
  99. redis_agent_kit-0.1.0/redis_agent_kit/protocols/base.py +134 -0
  100. redis_agent_kit-0.1.0/redis_agent_kit/protocols/unified.py +111 -0
  101. redis_agent_kit-0.1.0/redis_agent_kit/side_effects.py +381 -0
  102. redis_agent_kit-0.1.0/redis_agent_kit/streaming.py +148 -0
  103. redis_agent_kit-0.1.0/redis_agent_kit/task_manager.py +601 -0
  104. redis_agent_kit-0.1.0/redis_agent_kit/thread_manager.py +176 -0
  105. redis_agent_kit-0.1.0/redis_agent_kit/tools/__init__.py +33 -0
  106. redis_agent_kit-0.1.0/redis_agent_kit/tools/decorator.py +553 -0
  107. redis_agent_kit-0.1.0/redis_agent_kit/tools/knowledge_provider.py +82 -0
  108. redis_agent_kit-0.1.0/redis_agent_kit/tools/manager.py +141 -0
  109. redis_agent_kit-0.1.0/redis_agent_kit/tools/models.py +67 -0
  110. redis_agent_kit-0.1.0/redis_agent_kit/tools/provider.py +106 -0
  111. redis_agent_kit-0.1.0/redis_agent_kit/vectorizer.py +197 -0
  112. redis_agent_kit-0.1.0/tests/__init__.py +1 -0
  113. redis_agent_kit-0.1.0/tests/api/__init__.py +2 -0
  114. redis_agent_kit-0.1.0/tests/api/test_app.py +175 -0
  115. redis_agent_kit-0.1.0/tests/api/test_auth.py +141 -0
  116. redis_agent_kit-0.1.0/tests/api/test_pipelines.py +371 -0
  117. redis_agent_kit-0.1.0/tests/api/test_tasks.py +919 -0
  118. redis_agent_kit-0.1.0/tests/api/test_v1.py +105 -0
  119. redis_agent_kit-0.1.0/tests/api/test_v1_extended.py +254 -0
  120. redis_agent_kit-0.1.0/tests/cli/__init__.py +2 -0
  121. redis_agent_kit-0.1.0/tests/cli/test_api_common.py +135 -0
  122. redis_agent_kit-0.1.0/tests/cli/test_chat.py +97 -0
  123. redis_agent_kit-0.1.0/tests/cli/test_main.py +90 -0
  124. redis_agent_kit-0.1.0/tests/cli/test_operator_commands.py +57 -0
  125. redis_agent_kit-0.1.0/tests/cli/test_pipelines.py +457 -0
  126. redis_agent_kit-0.1.0/tests/cli/test_tasks.py +107 -0
  127. redis_agent_kit-0.1.0/tests/cli/test_unified_commands_extended.py +232 -0
  128. redis_agent_kit-0.1.0/tests/cli/test_worker.py +249 -0
  129. redis_agent_kit-0.1.0/tests/conftest.py +125 -0
  130. redis_agent_kit-0.1.0/tests/mcp/__init__.py +2 -0
  131. redis_agent_kit-0.1.0/tests/mcp/test_pipelines.py +305 -0
  132. redis_agent_kit-0.1.0/tests/mcp/test_server.py +274 -0
  133. redis_agent_kit-0.1.0/tests/mcp/test_tasks.py +64 -0
  134. redis_agent_kit-0.1.0/tests/pipelines/__init__.py +2 -0
  135. redis_agent_kit-0.1.0/tests/pipelines/test_artifact_storage.py +251 -0
  136. redis_agent_kit-0.1.0/tests/pipelines/test_config_loader.py +171 -0
  137. redis_agent_kit-0.1.0/tests/pipelines/test_deduplicator.py +148 -0
  138. redis_agent_kit-0.1.0/tests/pipelines/test_frontmatter.py +219 -0
  139. redis_agent_kit-0.1.0/tests/pipelines/test_ingest_stage.py +186 -0
  140. redis_agent_kit-0.1.0/tests/pipelines/test_models.py +677 -0
  141. redis_agent_kit-0.1.0/tests/pipelines/test_orchestrator.py +284 -0
  142. redis_agent_kit-0.1.0/tests/pipelines/test_pipeline.py +477 -0
  143. redis_agent_kit-0.1.0/tests/pipelines/test_prepare_stage.py +165 -0
  144. redis_agent_kit-0.1.0/tests/pipelines/test_processor.py +198 -0
  145. redis_agent_kit-0.1.0/tests/pipelines/test_scraper.py +171 -0
  146. redis_agent_kit-0.1.0/tests/pipelines/test_vector_store.py +419 -0
  147. redis_agent_kit-0.1.0/tests/protocols/__init__.py +1 -0
  148. redis_agent_kit-0.1.0/tests/protocols/a2a/__init__.py +1 -0
  149. redis_agent_kit-0.1.0/tests/protocols/a2a/test_adapter.py +155 -0
  150. redis_agent_kit-0.1.0/tests/protocols/a2a/test_models.py +166 -0
  151. redis_agent_kit-0.1.0/tests/protocols/a2a/test_router.py +305 -0
  152. redis_agent_kit-0.1.0/tests/protocols/acp/__init__.py +1 -0
  153. redis_agent_kit-0.1.0/tests/protocols/acp/test_adapter.py +121 -0
  154. redis_agent_kit-0.1.0/tests/protocols/acp/test_models.py +118 -0
  155. redis_agent_kit-0.1.0/tests/protocols/acp/test_router.py +216 -0
  156. redis_agent_kit-0.1.0/tests/protocols/test_base.py +123 -0
  157. redis_agent_kit-0.1.0/tests/protocols/test_unified.py +148 -0
  158. redis_agent_kit-0.1.0/tests/test_agent.py +382 -0
  159. redis_agent_kit-0.1.0/tests/test_agentkit_docket.py +764 -0
  160. redis_agent_kit-0.1.0/tests/test_attachments.py +192 -0
  161. redis_agent_kit-0.1.0/tests/test_config.py +241 -0
  162. redis_agent_kit-0.1.0/tests/test_docket.py +79 -0
  163. redis_agent_kit-0.1.0/tests/test_docs_examples.py +331 -0
  164. redis_agent_kit-0.1.0/tests/test_emitter.py +119 -0
  165. redis_agent_kit-0.1.0/tests/test_integration.py +149 -0
  166. redis_agent_kit-0.1.0/tests/test_keys.py +104 -0
  167. redis_agent_kit-0.1.0/tests/test_knowledge.py +149 -0
  168. redis_agent_kit-0.1.0/tests/test_memory.py +1309 -0
  169. redis_agent_kit-0.1.0/tests/test_middleware.py +1097 -0
  170. redis_agent_kit-0.1.0/tests/test_models.py +562 -0
  171. redis_agent_kit-0.1.0/tests/test_side_effects.py +722 -0
  172. redis_agent_kit-0.1.0/tests/test_task_manager.py +562 -0
  173. redis_agent_kit-0.1.0/tests/test_thread_manager.py +184 -0
  174. redis_agent_kit-0.1.0/tests/test_tools.py +1018 -0
  175. redis_agent_kit-0.1.0/tests/test_vectorizer.py +288 -0
  176. redis_agent_kit-0.1.0/uv.lock +4309 -0
@@ -0,0 +1,90 @@
1
+ {
2
+ "plugins": [
3
+ "git-tag",
4
+ "conventional-commits",
5
+ "released"
6
+ ],
7
+ "owner": "redis-developer",
8
+ "repo": "redis-agent-kit",
9
+ "onlyPublishWithReleaseLabel": true,
10
+ "labels": [
11
+ {
12
+ "name": "auto:major",
13
+ "changelogTitle": "💥 Breaking Change",
14
+ "description": "Increment the major version when merged",
15
+ "releaseType": "major",
16
+ "color": "#C5000B",
17
+ "overwrite": true
18
+ },
19
+ {
20
+ "name": "auto:minor",
21
+ "changelogTitle": "🚀 Enhancement",
22
+ "description": "Increment the minor version when merged",
23
+ "releaseType": "minor",
24
+ "color": "#F1A60E",
25
+ "overwrite": true
26
+ },
27
+ {
28
+ "name": "auto:patch",
29
+ "changelogTitle": "🐛 Bug Fix",
30
+ "description": "Increment the patch version when merged",
31
+ "releaseType": "patch",
32
+ "color": "#870048",
33
+ "overwrite": true
34
+ },
35
+ {
36
+ "name": "auto:skip-release",
37
+ "description": "Preserve the current version when merged",
38
+ "releaseType": "skip",
39
+ "color": "#bf5416",
40
+ "overwrite": true
41
+ },
42
+ {
43
+ "name": "auto:release",
44
+ "description": "Create a release when this PR is merged",
45
+ "releaseType": "release",
46
+ "color": "#007f70",
47
+ "overwrite": true
48
+ },
49
+ {
50
+ "name": "auto:internal",
51
+ "changelogTitle": "🏠 Internal",
52
+ "description": "Changes only affect the internal API",
53
+ "releaseType": "none",
54
+ "color": "#696969",
55
+ "overwrite": true
56
+ },
57
+ {
58
+ "name": "auto:documentation",
59
+ "changelogTitle": "📝 Documentation",
60
+ "description": "Changes only affect the documentation",
61
+ "releaseType": "none",
62
+ "color": "#cfd3d7",
63
+ "overwrite": true
64
+ },
65
+ {
66
+ "name": "auto:tests",
67
+ "changelogTitle": "🧪 Tests",
68
+ "description": "Add or improve existing tests",
69
+ "releaseType": "none",
70
+ "color": "#ffd3cc",
71
+ "overwrite": true
72
+ },
73
+ {
74
+ "name": "auto:dependencies",
75
+ "changelogTitle": "🔩 Dependency Updates",
76
+ "description": "Update one or more dependencies version",
77
+ "releaseType": "none",
78
+ "color": "#8732bc",
79
+ "overwrite": true
80
+ },
81
+ {
82
+ "name": "auto:ci",
83
+ "changelogTitle": "CI/CD Changes",
84
+ "description": "Updates to CI/CD workflows and processes",
85
+ "releaseType": "none",
86
+ "color": "#E5A3DD",
87
+ "overwrite": true
88
+ }
89
+ ]
90
+ }
@@ -0,0 +1,235 @@
1
+ name: Auto Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ workflow_dispatch:
7
+ inputs:
8
+ first_release:
9
+ description: "Bootstrap: publish the version currently in pyproject.toml. Bypasses the auto:release label gate and skips version bumping. Use only for the first release or manual recovery."
10
+ type: boolean
11
+ default: false
12
+
13
+ permissions:
14
+ contents: write
15
+ issues: write
16
+ pull-requests: write
17
+
18
+ concurrency:
19
+ group: auto-release-${{ github.ref }}
20
+ cancel-in-progress: false
21
+
22
+ env:
23
+ PYTHON_VERSION: "3.11"
24
+ UV_VERSION: "0.7.13"
25
+ AUTO_VERSION: "11.3.6"
26
+ RELEASE_BOT_NAME: "github-actions[bot]"
27
+ RELEASE_BOT_EMAIL: "41898282+github-actions[bot]@users.noreply.github.com"
28
+
29
+ jobs:
30
+ gate:
31
+ name: Gate on merged PR label
32
+ runs-on: ubuntu-latest
33
+ # Prevent infinite loops from the bot's "chore(release)" commit.
34
+ if: github.actor != 'github-actions[bot]'
35
+ outputs:
36
+ should_release: ${{ steps.find_pr.outputs.should_release }}
37
+ pr_number: ${{ steps.find_pr.outputs.pr_number }}
38
+ steps:
39
+ - name: Find merged PR and check labels
40
+ id: find_pr
41
+ uses: actions/github-script@v7
42
+ env:
43
+ FIRST_RELEASE: ${{ github.event.inputs.first_release }}
44
+ with:
45
+ script: |
46
+ // Manual bootstrap: bypass the PR label check entirely.
47
+ if (context.eventName === 'workflow_dispatch' && process.env.FIRST_RELEASE === 'true') {
48
+ core.notice('Manual first_release=true; bypassing PR label check.');
49
+ core.setOutput('should_release', 'true');
50
+ core.setOutput('pr_number', '');
51
+ return;
52
+ }
53
+ const { owner, repo } = context.repo;
54
+ const sha = context.sha;
55
+ const maxAttempts = 6;
56
+ let pulls;
57
+ // GitHub can briefly lag in associating a merge commit with its PR, so retry.
58
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
59
+ pulls = await github.rest.repos.listPullRequestsAssociatedWithCommit({
60
+ owner, repo, commit_sha: sha,
61
+ });
62
+ if (pulls.data.length) break;
63
+ if (attempt < maxAttempts) {
64
+ await new Promise((r) => setTimeout(r, 10000));
65
+ }
66
+ }
67
+ if (!pulls.data || !pulls.data.length) {
68
+ core.notice(`No PR associated with ${sha}. Not releasing.`);
69
+ core.setOutput('should_release', 'false');
70
+ core.setOutput('pr_number', '');
71
+ return;
72
+ }
73
+ const pr = pulls.data.find((p) => p.merged_at && p.base?.ref === 'main') ?? pulls.data[0];
74
+ const labels = (pr.labels || []).map((l) => l.name);
75
+ const should = labels.includes('auto:release');
76
+ core.setOutput('pr_number', String(pr.number));
77
+ core.setOutput('should_release', should ? 'true' : 'false');
78
+ core.notice(`PR #${pr.number} labels: ${labels.join(', ')}`);
79
+ core.notice(`should_release=${should}`);
80
+
81
+ release:
82
+ name: Tag, release, and publish
83
+ runs-on: ubuntu-latest
84
+ needs: gate
85
+ if: needs.gate.outputs.should_release == 'true'
86
+ env:
87
+ # 'true' for manual bootstrap runs; 'false' or empty otherwise.
88
+ FIRST_RELEASE: ${{ github.event.inputs.first_release || 'false' }}
89
+ steps:
90
+ - name: Checkout
91
+ uses: actions/checkout@v6
92
+ with:
93
+ ref: main
94
+ fetch-depth: 0
95
+ fetch-tags: true
96
+ # RELEASE_PAT (a PAT with repo + workflow scopes) lets the bot push to
97
+ # protected branches and trigger other workflows. Falls back to
98
+ # GITHUB_TOKEN for repos without branch protection.
99
+ token: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
100
+
101
+ - name: Install Python
102
+ uses: actions/setup-python@v6
103
+ with:
104
+ python-version: ${{ env.PYTHON_VERSION }}
105
+
106
+ - name: Install uv
107
+ uses: astral-sh/setup-uv@v6
108
+ with:
109
+ version: ${{ env.UV_VERSION }}
110
+ enable-cache: true
111
+ python-version: ${{ env.PYTHON_VERSION }}
112
+ cache-dependency-glob: |
113
+ pyproject.toml
114
+ uv.lock
115
+
116
+ - name: Install auto
117
+ run: |
118
+ set -euo pipefail
119
+ curl -L "https://github.com/intuit/auto/releases/download/v${AUTO_VERSION}/auto-linux.gz" -o auto-linux.gz
120
+ gunzip auto-linux.gz
121
+ chmod +x auto-linux
122
+ sudo mv auto-linux /usr/local/bin/auto
123
+ auto --version
124
+
125
+ - name: Sanity build (pre-tag)
126
+ run: uv build
127
+
128
+ - name: Capture previous tag
129
+ id: previous_tag
130
+ run: |
131
+ set -euo pipefail
132
+ echo "tag=$(git describe --tags --abbrev=0 2>/dev/null || echo '')" >> "$GITHUB_OUTPUT"
133
+
134
+ - name: Resolve next version (auto)
135
+ id: resolve_version
136
+ if: env.FIRST_RELEASE != 'true'
137
+ env:
138
+ GH_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
139
+ run: |
140
+ set -euo pipefail
141
+ RAW_VERSION="$(auto shipit --name "${RELEASE_BOT_NAME}" --email "${RELEASE_BOT_EMAIL}" --dry-run --quiet | tail -n1 | tr -d '\r')"
142
+ VERSION="${RAW_VERSION#v}"
143
+ if [ -z "$VERSION" ]; then
144
+ echo "Could not resolve release version from auto."
145
+ exit 1
146
+ fi
147
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
148
+ echo "Resolved version: $VERSION"
149
+
150
+ - name: Apply version to pyproject.toml
151
+ if: env.FIRST_RELEASE != 'true'
152
+ run: |
153
+ set -euo pipefail
154
+ VERSION="${{ steps.resolve_version.outputs.version }}"
155
+ sed -i "s/^version = \".*\"$/version = \"${VERSION}\"/" pyproject.toml
156
+ grep '^version = ' pyproject.toml
157
+
158
+ - name: Commit version bump
159
+ if: env.FIRST_RELEASE != 'true'
160
+ env:
161
+ GH_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
162
+ run: |
163
+ set -euo pipefail
164
+ if git diff --quiet -- pyproject.toml; then
165
+ echo "No pyproject version change to commit."
166
+ else
167
+ git config user.name "${RELEASE_BOT_NAME}"
168
+ git config user.email "${RELEASE_BOT_EMAIL}"
169
+ git add pyproject.toml
170
+ # [skip ci] avoids re-running this workflow on the bot's own commit.
171
+ git commit -m "chore(release): v${{ steps.resolve_version.outputs.version }} [skip ci]"
172
+ git push origin HEAD:main
173
+ fi
174
+
175
+ - name: Read final version from pyproject.toml
176
+ id: final_version
177
+ run: |
178
+ set -euo pipefail
179
+ VERSION="$(grep -E '^version = ' pyproject.toml | head -1 | sed -E 's/version = "([^"]+)"/\1/')"
180
+ if [ -z "$VERSION" ]; then
181
+ echo "Could not read version from pyproject.toml"
182
+ exit 1
183
+ fi
184
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
185
+ echo "Final version: $VERSION"
186
+
187
+ - name: Capture release commit SHA
188
+ id: release_commit
189
+ run: |
190
+ set -euo pipefail
191
+ echo "sha=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
192
+
193
+ - name: Create labels (idempotent)
194
+ env:
195
+ GH_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
196
+ run: auto create-labels
197
+
198
+ - name: Create and push tag
199
+ run: |
200
+ set -euo pipefail
201
+ TAG="v${{ steps.final_version.outputs.version }}"
202
+ TARGET_SHA="${{ steps.release_commit.outputs.sha }}"
203
+ if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then
204
+ EXISTING_SHA="$(git rev-list -n1 "$TAG")"
205
+ if [ "$EXISTING_SHA" = "$TARGET_SHA" ]; then
206
+ echo "Tag $TAG already exists at $TARGET_SHA. Skipping."
207
+ exit 0
208
+ fi
209
+ echo "Tag $TAG exists at $EXISTING_SHA but expected $TARGET_SHA."
210
+ exit 1
211
+ fi
212
+ git tag "$TAG" "$TARGET_SHA"
213
+ git push origin "$TAG"
214
+
215
+ - name: Create GitHub release with auto notes
216
+ env:
217
+ GH_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }}
218
+ run: |
219
+ set -euo pipefail
220
+ args=(--to "${{ steps.release_commit.outputs.sha }}" --use-version "v${{ steps.final_version.outputs.version }}")
221
+ if [ -n "${{ steps.previous_tag.outputs.tag }}" ]; then
222
+ args=(--from "${{ steps.previous_tag.outputs.tag }}" "${args[@]}")
223
+ fi
224
+ auto release "${args[@]}"
225
+
226
+ - name: Build final artifacts
227
+ run: |
228
+ set -euo pipefail
229
+ rm -rf dist
230
+ uv build
231
+
232
+ - name: Publish to PyPI
233
+ env:
234
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI }}
235
+ run: uv publish
@@ -0,0 +1,60 @@
1
+ name: Lint
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - main
8
+
9
+ env:
10
+ UV_VERSION: "0.7.13"
11
+
12
+ jobs:
13
+ check:
14
+ name: Style-check ${{ matrix.python-version }}
15
+ runs-on: ubuntu-latest
16
+ strategy:
17
+ fail-fast: false
18
+ matrix:
19
+ python-version:
20
+ - "3.11"
21
+ - "3.12"
22
+
23
+ steps:
24
+ - name: Check out repository
25
+ uses: actions/checkout@v6
26
+
27
+ - name: Install Python
28
+ uses: actions/setup-python@v6
29
+ with:
30
+ python-version: ${{ matrix.python-version }}
31
+
32
+ - name: Install uv
33
+ uses: astral-sh/setup-uv@v6
34
+ with:
35
+ version: ${{ env.UV_VERSION }}
36
+ enable-cache: true
37
+ python-version: ${{ matrix.python-version }}
38
+ cache-dependency-glob: |
39
+ pyproject.toml
40
+ uv.lock
41
+
42
+ - name: Install dependencies
43
+ run: |
44
+ uv sync --frozen --extra dev --extra api --extra cli --extra mcp
45
+
46
+ - name: check-sort-imports
47
+ run: |
48
+ make check-sort-imports
49
+
50
+ - name: check-format
51
+ run: |
52
+ make check-format
53
+
54
+ - name: check-ruff
55
+ run: |
56
+ make check-ruff
57
+
58
+ - name: check-types
59
+ run: |
60
+ make check-types
@@ -0,0 +1,49 @@
1
+ name: Test Suite
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - main
8
+ workflow_dispatch:
9
+
10
+ env:
11
+ UV_VERSION: "0.7.13"
12
+
13
+ jobs:
14
+ test:
15
+ name: Python ${{ matrix.python-version }}
16
+ runs-on: ubuntu-latest
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ python-version:
21
+ - "3.11"
22
+ - "3.12"
23
+
24
+ steps:
25
+ - name: Check out repository
26
+ uses: actions/checkout@v6
27
+
28
+ - name: Install Python
29
+ uses: actions/setup-python@v6
30
+ with:
31
+ python-version: ${{ matrix.python-version }}
32
+
33
+ - name: Install uv
34
+ uses: astral-sh/setup-uv@v6
35
+ with:
36
+ version: ${{ env.UV_VERSION }}
37
+ enable-cache: true
38
+ python-version: ${{ matrix.python-version }}
39
+ cache-dependency-glob: |
40
+ pyproject.toml
41
+ uv.lock
42
+
43
+ - name: Install dependencies
44
+ run: |
45
+ uv sync --frozen --extra dev --extra api --extra cli --extra mcp
46
+
47
+ - name: Run tests
48
+ run: |
49
+ make test
@@ -0,0 +1,64 @@
1
+ # Environment
2
+ .env
3
+ .env.*
4
+ !.env.example
5
+
6
+ # Python
7
+ __pycache__/
8
+ *.py[cod]
9
+ *$py.class
10
+ *.so
11
+ .Python
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+
28
+ # Virtual environments
29
+ .venv/
30
+ venv/
31
+ ENV/
32
+ env/
33
+
34
+ # IDE
35
+ .idea/
36
+ .vscode/
37
+ *.swp
38
+ *.swo
39
+ *~
40
+
41
+ # Testing
42
+ .coverage
43
+ .pytest_cache/
44
+ htmlcov/
45
+ .tox/
46
+ .nox/
47
+
48
+ # mypy
49
+ .mypy_cache/
50
+ .dmypy.json
51
+ dmypy.json
52
+
53
+ # Jupyter
54
+ .ipynb_checkpoints/
55
+
56
+ # OS
57
+ .DS_Store
58
+ Thumbs.db
59
+
60
+ # Project specific
61
+ *.log
62
+
63
+ artifacts/
64
+ reference/
@@ -0,0 +1,17 @@
1
+ repos:
2
+ - repo: local
3
+ hooks:
4
+ - id: code-quality-checks
5
+ name: Run pre-commit checks (format, sort-imports, check-mypy)
6
+ entry: bash -c 'make format && make check-sort-imports && make check-types'
7
+ language: system
8
+ pass_filenames: false
9
+ - repo: https://github.com/codespell-project/codespell
10
+ rev: v2.2.6
11
+ hooks:
12
+ - id: codespell
13
+ name: Check spelling
14
+ args:
15
+ - --write-changes
16
+ - --skip=*.pyc,*.pyo,*.lock,*.git,*.mypy_cache,__pycache__,*.egg-info,.pytest_cache,docs/_build,env,venv,.venv,artifacts
17
+ - --ignore-words-list=enginee