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.
- redis_agent_kit-0.1.0/.autorc +90 -0
- redis_agent_kit-0.1.0/.github/workflows/auto-release.yml +235 -0
- redis_agent_kit-0.1.0/.github/workflows/lint.yml +60 -0
- redis_agent_kit-0.1.0/.github/workflows/test.yml +49 -0
- redis_agent_kit-0.1.0/.gitignore +64 -0
- redis_agent_kit-0.1.0/.pre-commit-config.yaml +17 -0
- redis_agent_kit-0.1.0/AGENTS.md +313 -0
- redis_agent_kit-0.1.0/Makefile +71 -0
- redis_agent_kit-0.1.0/PKG-INFO +198 -0
- redis_agent_kit-0.1.0/README.md +130 -0
- redis_agent_kit-0.1.0/docs/guide/api.md +220 -0
- redis_agent_kit-0.1.0/docs/guide/cli.md +122 -0
- redis_agent_kit-0.1.0/docs/guide/input.md +235 -0
- redis_agent_kit-0.1.0/docs/guide/memory.md +142 -0
- redis_agent_kit-0.1.0/docs/guide/middleware.md +158 -0
- redis_agent_kit-0.1.0/docs/guide/pipelines.md +161 -0
- redis_agent_kit-0.1.0/docs/guide/protocols.md +158 -0
- redis_agent_kit-0.1.0/docs/guide/streaming.md +153 -0
- redis_agent_kit-0.1.0/docs/guide/tasks.md +145 -0
- redis_agent_kit-0.1.0/docs/guide/threads.md +109 -0
- redis_agent_kit-0.1.0/docs/index.md +117 -0
- redis_agent_kit-0.1.0/docs/tutorial.md +286 -0
- redis_agent_kit-0.1.0/examples/README.md +189 -0
- redis_agent_kit-0.1.0/examples/basic_llm/__init__.py +2 -0
- redis_agent_kit-0.1.0/examples/basic_llm/agent.py +108 -0
- redis_agent_kit-0.1.0/examples/docs/caching-patterns.md +81 -0
- redis_agent_kit-0.1.0/examples/docs/redis-basics.md +70 -0
- redis_agent_kit-0.1.0/examples/docs/vector-search.md +91 -0
- redis_agent_kit-0.1.0/examples/langgraph_agent/__init__.py +1 -0
- redis_agent_kit-0.1.0/examples/langgraph_agent/agent.py +209 -0
- redis_agent_kit-0.1.0/examples/langgraph_interrupt/__init__.py +2 -0
- redis_agent_kit-0.1.0/examples/langgraph_interrupt/agent.py +223 -0
- redis_agent_kit-0.1.0/examples/langgraph_rag/__init__.py +2 -0
- redis_agent_kit-0.1.0/examples/langgraph_rag/agent.py +137 -0
- redis_agent_kit-0.1.0/examples/multi_protocol_agent/__init__.py +2 -0
- redis_agent_kit-0.1.0/examples/multi_protocol_agent/agent.py +132 -0
- redis_agent_kit-0.1.0/examples/openai_agent/__init__.py +1 -0
- redis_agent_kit-0.1.0/examples/openai_agent/agent.py +177 -0
- redis_agent_kit-0.1.0/examples/rag_agent/__init__.py +2 -0
- redis_agent_kit-0.1.0/examples/rag_agent/agent.py +156 -0
- redis_agent_kit-0.1.0/examples/rag_with_memory/__init__.py +2 -0
- redis_agent_kit-0.1.0/examples/rag_with_memory/agent.py +154 -0
- redis_agent_kit-0.1.0/examples/sse_streaming/__init__.py +2 -0
- redis_agent_kit-0.1.0/examples/sse_streaming/agent.py +161 -0
- redis_agent_kit-0.1.0/examples/tool_agent/__init__.py +2 -0
- redis_agent_kit-0.1.0/examples/tool_agent/agent.py +175 -0
- redis_agent_kit-0.1.0/pyproject.toml +132 -0
- redis_agent_kit-0.1.0/redis_agent_kit/__init__.py +222 -0
- redis_agent_kit-0.1.0/redis_agent_kit/agent.py +265 -0
- redis_agent_kit-0.1.0/redis_agent_kit/api/__init__.py +21 -0
- redis_agent_kit-0.1.0/redis_agent_kit/api/app.py +163 -0
- redis_agent_kit-0.1.0/redis_agent_kit/api/auth.py +97 -0
- redis_agent_kit-0.1.0/redis_agent_kit/api/pipelines.py +240 -0
- redis_agent_kit-0.1.0/redis_agent_kit/api/tasks.py +511 -0
- redis_agent_kit-0.1.0/redis_agent_kit/api/v1.py +386 -0
- redis_agent_kit-0.1.0/redis_agent_kit/attachments.py +225 -0
- redis_agent_kit-0.1.0/redis_agent_kit/cli/__init__.py +5 -0
- redis_agent_kit-0.1.0/redis_agent_kit/cli/agent.py +54 -0
- redis_agent_kit-0.1.0/redis_agent_kit/cli/api_common.py +130 -0
- redis_agent_kit-0.1.0/redis_agent_kit/cli/chat.py +434 -0
- redis_agent_kit-0.1.0/redis_agent_kit/cli/health.py +21 -0
- redis_agent_kit-0.1.0/redis_agent_kit/cli/main.py +173 -0
- redis_agent_kit-0.1.0/redis_agent_kit/cli/pipelines.py +327 -0
- redis_agent_kit-0.1.0/redis_agent_kit/cli/task.py +298 -0
- redis_agent_kit-0.1.0/redis_agent_kit/cli/up.py +67 -0
- redis_agent_kit-0.1.0/redis_agent_kit/cli/worker.py +103 -0
- redis_agent_kit-0.1.0/redis_agent_kit/config.py +209 -0
- redis_agent_kit-0.1.0/redis_agent_kit/core.py +575 -0
- redis_agent_kit-0.1.0/redis_agent_kit/emitter.py +126 -0
- redis_agent_kit-0.1.0/redis_agent_kit/keys.py +119 -0
- redis_agent_kit-0.1.0/redis_agent_kit/knowledge.py +188 -0
- redis_agent_kit-0.1.0/redis_agent_kit/mcp/__init__.py +5 -0
- redis_agent_kit-0.1.0/redis_agent_kit/mcp/server.py +340 -0
- redis_agent_kit-0.1.0/redis_agent_kit/memory.py +700 -0
- redis_agent_kit-0.1.0/redis_agent_kit/middleware.py +481 -0
- redis_agent_kit-0.1.0/redis_agent_kit/models.py +329 -0
- redis_agent_kit-0.1.0/redis_agent_kit/pipelines/__init__.py +64 -0
- redis_agent_kit-0.1.0/redis_agent_kit/pipelines/artifact_storage.py +189 -0
- redis_agent_kit-0.1.0/redis_agent_kit/pipelines/config_loader.py +113 -0
- redis_agent_kit-0.1.0/redis_agent_kit/pipelines/deduplicator.py +114 -0
- redis_agent_kit-0.1.0/redis_agent_kit/pipelines/frontmatter.py +109 -0
- redis_agent_kit-0.1.0/redis_agent_kit/pipelines/ingest_stage.py +100 -0
- redis_agent_kit-0.1.0/redis_agent_kit/pipelines/models.py +209 -0
- redis_agent_kit-0.1.0/redis_agent_kit/pipelines/orchestrator.py +285 -0
- redis_agent_kit-0.1.0/redis_agent_kit/pipelines/pipeline.py +309 -0
- redis_agent_kit-0.1.0/redis_agent_kit/pipelines/prepare_stage.py +160 -0
- redis_agent_kit-0.1.0/redis_agent_kit/pipelines/processor.py +120 -0
- redis_agent_kit-0.1.0/redis_agent_kit/pipelines/scraper.py +96 -0
- redis_agent_kit-0.1.0/redis_agent_kit/pipelines/vector_store.py +386 -0
- redis_agent_kit-0.1.0/redis_agent_kit/protocols/__init__.py +23 -0
- redis_agent_kit-0.1.0/redis_agent_kit/protocols/a2a/__init__.py +35 -0
- redis_agent_kit-0.1.0/redis_agent_kit/protocols/a2a/adapter.py +148 -0
- redis_agent_kit-0.1.0/redis_agent_kit/protocols/a2a/models.py +101 -0
- redis_agent_kit-0.1.0/redis_agent_kit/protocols/a2a/router.py +196 -0
- redis_agent_kit-0.1.0/redis_agent_kit/protocols/acp/__init__.py +28 -0
- redis_agent_kit-0.1.0/redis_agent_kit/protocols/acp/adapter.py +160 -0
- redis_agent_kit-0.1.0/redis_agent_kit/protocols/acp/models.py +65 -0
- redis_agent_kit-0.1.0/redis_agent_kit/protocols/acp/router.py +108 -0
- redis_agent_kit-0.1.0/redis_agent_kit/protocols/base.py +134 -0
- redis_agent_kit-0.1.0/redis_agent_kit/protocols/unified.py +111 -0
- redis_agent_kit-0.1.0/redis_agent_kit/side_effects.py +381 -0
- redis_agent_kit-0.1.0/redis_agent_kit/streaming.py +148 -0
- redis_agent_kit-0.1.0/redis_agent_kit/task_manager.py +601 -0
- redis_agent_kit-0.1.0/redis_agent_kit/thread_manager.py +176 -0
- redis_agent_kit-0.1.0/redis_agent_kit/tools/__init__.py +33 -0
- redis_agent_kit-0.1.0/redis_agent_kit/tools/decorator.py +553 -0
- redis_agent_kit-0.1.0/redis_agent_kit/tools/knowledge_provider.py +82 -0
- redis_agent_kit-0.1.0/redis_agent_kit/tools/manager.py +141 -0
- redis_agent_kit-0.1.0/redis_agent_kit/tools/models.py +67 -0
- redis_agent_kit-0.1.0/redis_agent_kit/tools/provider.py +106 -0
- redis_agent_kit-0.1.0/redis_agent_kit/vectorizer.py +197 -0
- redis_agent_kit-0.1.0/tests/__init__.py +1 -0
- redis_agent_kit-0.1.0/tests/api/__init__.py +2 -0
- redis_agent_kit-0.1.0/tests/api/test_app.py +175 -0
- redis_agent_kit-0.1.0/tests/api/test_auth.py +141 -0
- redis_agent_kit-0.1.0/tests/api/test_pipelines.py +371 -0
- redis_agent_kit-0.1.0/tests/api/test_tasks.py +919 -0
- redis_agent_kit-0.1.0/tests/api/test_v1.py +105 -0
- redis_agent_kit-0.1.0/tests/api/test_v1_extended.py +254 -0
- redis_agent_kit-0.1.0/tests/cli/__init__.py +2 -0
- redis_agent_kit-0.1.0/tests/cli/test_api_common.py +135 -0
- redis_agent_kit-0.1.0/tests/cli/test_chat.py +97 -0
- redis_agent_kit-0.1.0/tests/cli/test_main.py +90 -0
- redis_agent_kit-0.1.0/tests/cli/test_operator_commands.py +57 -0
- redis_agent_kit-0.1.0/tests/cli/test_pipelines.py +457 -0
- redis_agent_kit-0.1.0/tests/cli/test_tasks.py +107 -0
- redis_agent_kit-0.1.0/tests/cli/test_unified_commands_extended.py +232 -0
- redis_agent_kit-0.1.0/tests/cli/test_worker.py +249 -0
- redis_agent_kit-0.1.0/tests/conftest.py +125 -0
- redis_agent_kit-0.1.0/tests/mcp/__init__.py +2 -0
- redis_agent_kit-0.1.0/tests/mcp/test_pipelines.py +305 -0
- redis_agent_kit-0.1.0/tests/mcp/test_server.py +274 -0
- redis_agent_kit-0.1.0/tests/mcp/test_tasks.py +64 -0
- redis_agent_kit-0.1.0/tests/pipelines/__init__.py +2 -0
- redis_agent_kit-0.1.0/tests/pipelines/test_artifact_storage.py +251 -0
- redis_agent_kit-0.1.0/tests/pipelines/test_config_loader.py +171 -0
- redis_agent_kit-0.1.0/tests/pipelines/test_deduplicator.py +148 -0
- redis_agent_kit-0.1.0/tests/pipelines/test_frontmatter.py +219 -0
- redis_agent_kit-0.1.0/tests/pipelines/test_ingest_stage.py +186 -0
- redis_agent_kit-0.1.0/tests/pipelines/test_models.py +677 -0
- redis_agent_kit-0.1.0/tests/pipelines/test_orchestrator.py +284 -0
- redis_agent_kit-0.1.0/tests/pipelines/test_pipeline.py +477 -0
- redis_agent_kit-0.1.0/tests/pipelines/test_prepare_stage.py +165 -0
- redis_agent_kit-0.1.0/tests/pipelines/test_processor.py +198 -0
- redis_agent_kit-0.1.0/tests/pipelines/test_scraper.py +171 -0
- redis_agent_kit-0.1.0/tests/pipelines/test_vector_store.py +419 -0
- redis_agent_kit-0.1.0/tests/protocols/__init__.py +1 -0
- redis_agent_kit-0.1.0/tests/protocols/a2a/__init__.py +1 -0
- redis_agent_kit-0.1.0/tests/protocols/a2a/test_adapter.py +155 -0
- redis_agent_kit-0.1.0/tests/protocols/a2a/test_models.py +166 -0
- redis_agent_kit-0.1.0/tests/protocols/a2a/test_router.py +305 -0
- redis_agent_kit-0.1.0/tests/protocols/acp/__init__.py +1 -0
- redis_agent_kit-0.1.0/tests/protocols/acp/test_adapter.py +121 -0
- redis_agent_kit-0.1.0/tests/protocols/acp/test_models.py +118 -0
- redis_agent_kit-0.1.0/tests/protocols/acp/test_router.py +216 -0
- redis_agent_kit-0.1.0/tests/protocols/test_base.py +123 -0
- redis_agent_kit-0.1.0/tests/protocols/test_unified.py +148 -0
- redis_agent_kit-0.1.0/tests/test_agent.py +382 -0
- redis_agent_kit-0.1.0/tests/test_agentkit_docket.py +764 -0
- redis_agent_kit-0.1.0/tests/test_attachments.py +192 -0
- redis_agent_kit-0.1.0/tests/test_config.py +241 -0
- redis_agent_kit-0.1.0/tests/test_docket.py +79 -0
- redis_agent_kit-0.1.0/tests/test_docs_examples.py +331 -0
- redis_agent_kit-0.1.0/tests/test_emitter.py +119 -0
- redis_agent_kit-0.1.0/tests/test_integration.py +149 -0
- redis_agent_kit-0.1.0/tests/test_keys.py +104 -0
- redis_agent_kit-0.1.0/tests/test_knowledge.py +149 -0
- redis_agent_kit-0.1.0/tests/test_memory.py +1309 -0
- redis_agent_kit-0.1.0/tests/test_middleware.py +1097 -0
- redis_agent_kit-0.1.0/tests/test_models.py +562 -0
- redis_agent_kit-0.1.0/tests/test_side_effects.py +722 -0
- redis_agent_kit-0.1.0/tests/test_task_manager.py +562 -0
- redis_agent_kit-0.1.0/tests/test_thread_manager.py +184 -0
- redis_agent_kit-0.1.0/tests/test_tools.py +1018 -0
- redis_agent_kit-0.1.0/tests/test_vectorizer.py +288 -0
- 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
|