amsdal_langgraph 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.
- amsdal_langgraph-0.1.0/.amsdal/.environment +1 -0
- amsdal_langgraph-0.1.0/.amsdal-cli +13 -0
- amsdal_langgraph-0.1.0/.github/workflows/ci.yml +62 -0
- amsdal_langgraph-0.1.0/.github/workflows/release.yml +102 -0
- amsdal_langgraph-0.1.0/.github/workflows/tag_check.yml +29 -0
- amsdal_langgraph-0.1.0/.gitignore +18 -0
- amsdal_langgraph-0.1.0/PKG-INFO +292 -0
- amsdal_langgraph-0.1.0/README.md +281 -0
- amsdal_langgraph-0.1.0/amsdal_langgraph/Third-Party Materials - AMSDAL Dependencies - License Notices.md +30 -0
- amsdal_langgraph-0.1.0/amsdal_langgraph/__about__.py +1 -0
- amsdal_langgraph-0.1.0/amsdal_langgraph/__init__.py +0 -0
- amsdal_langgraph-0.1.0/amsdal_langgraph/app.py +8 -0
- amsdal_langgraph-0.1.0/amsdal_langgraph/checkpoint.py +616 -0
- amsdal_langgraph-0.1.0/amsdal_langgraph/migrations/0000_initial.py +66 -0
- amsdal_langgraph-0.1.0/amsdal_langgraph/models/__init__.py +0 -0
- amsdal_langgraph-0.1.0/amsdal_langgraph/models/checkpoint.py +24 -0
- amsdal_langgraph-0.1.0/amsdal_langgraph/models/checkpoint_writes.py +24 -0
- amsdal_langgraph-0.1.0/amsdal_langgraph/py.typed +0 -0
- amsdal_langgraph-0.1.0/amsdal_langgraph/utils.py +67 -0
- amsdal_langgraph-0.1.0/change-logs.md +5 -0
- amsdal_langgraph-0.1.0/config.yml +20 -0
- amsdal_langgraph-0.1.0/latest-changelogs.md +5 -0
- amsdal_langgraph-0.1.0/license_check.py +38 -0
- amsdal_langgraph-0.1.0/pyproject.toml +196 -0
- amsdal_langgraph-0.1.0/tests/conftest.py +57 -0
- amsdal_langgraph-0.1.0/tests/test_checkpoint.py +308 -0
- amsdal_langgraph-0.1.0/uv.lock +3526 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
main
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"src_dir": "amsdal_langgraph",
|
|
3
|
+
"config_path": "./config.yml",
|
|
4
|
+
"http_port": 8080,
|
|
5
|
+
"check_model_exists": true,
|
|
6
|
+
"indent": 4,
|
|
7
|
+
"verbose": true,
|
|
8
|
+
"vcs": null,
|
|
9
|
+
"application_uuid": "p1ebf57e2d01f4f19ba4d66cc3bd6f6d",
|
|
10
|
+
"application_name": "amsdal_langgraph",
|
|
11
|
+
"models_format": "py",
|
|
12
|
+
"is_plugin": true
|
|
13
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
|
|
6
|
+
jobs:
|
|
7
|
+
license-check:
|
|
8
|
+
name: License check
|
|
9
|
+
runs-on: self-hosted
|
|
10
|
+
steps:
|
|
11
|
+
- name: Reset permissions
|
|
12
|
+
run: |
|
|
13
|
+
sudo chown -R $(id -u):$(id -g) .
|
|
14
|
+
- uses: actions/checkout@v5
|
|
15
|
+
|
|
16
|
+
- name: Python install
|
|
17
|
+
uses: actions/setup-python@v6
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.11"
|
|
20
|
+
- name: License check
|
|
21
|
+
run: |
|
|
22
|
+
pip install toml
|
|
23
|
+
python license_check.py
|
|
24
|
+
|
|
25
|
+
test-lint:
|
|
26
|
+
name: Run tests and check style
|
|
27
|
+
needs: [license-check]
|
|
28
|
+
runs-on: self-hosted
|
|
29
|
+
strategy:
|
|
30
|
+
max-parallel: 1
|
|
31
|
+
fail-fast: false
|
|
32
|
+
matrix:
|
|
33
|
+
python-version: ["3.11", "3.12"]
|
|
34
|
+
env:
|
|
35
|
+
PYTHON: ${{ matrix.python-version }}
|
|
36
|
+
DEPS: yes
|
|
37
|
+
_TYPER_FORCE_DISABLE_TERMINAL: true
|
|
38
|
+
steps:
|
|
39
|
+
- uses: actions/checkout@v5
|
|
40
|
+
- uses: szenius/set-timezone@v2.0
|
|
41
|
+
with:
|
|
42
|
+
timezoneLinux: "EEST"
|
|
43
|
+
|
|
44
|
+
- name: Set up python
|
|
45
|
+
uses: actions/setup-python@v6
|
|
46
|
+
with:
|
|
47
|
+
python-version: ${{ matrix.python-version }}
|
|
48
|
+
|
|
49
|
+
- name: Hatch and UV setup
|
|
50
|
+
run: |
|
|
51
|
+
pip install --upgrade uv hatch==1.14.2
|
|
52
|
+
hatch env prune
|
|
53
|
+
hatch env create
|
|
54
|
+
hatch run sync
|
|
55
|
+
|
|
56
|
+
- name: Run style checks
|
|
57
|
+
if: always()
|
|
58
|
+
run: hatch run all
|
|
59
|
+
|
|
60
|
+
- name: Run tests
|
|
61
|
+
if: always()
|
|
62
|
+
run: hatch run cov tests/
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
name: CD
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
license-check:
|
|
10
|
+
name: License check
|
|
11
|
+
runs-on: self-hosted
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v5
|
|
14
|
+
|
|
15
|
+
- name: Python install
|
|
16
|
+
uses: actions/setup-python@v6
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.12"
|
|
19
|
+
- name: License check
|
|
20
|
+
run: |
|
|
21
|
+
pip install toml
|
|
22
|
+
python license_check.py
|
|
23
|
+
|
|
24
|
+
build:
|
|
25
|
+
name: Build and compile
|
|
26
|
+
needs: [license-check]
|
|
27
|
+
runs-on: self-hosted
|
|
28
|
+
strategy:
|
|
29
|
+
fail-fast: false
|
|
30
|
+
matrix:
|
|
31
|
+
python-version: [ "3.12" ]
|
|
32
|
+
env:
|
|
33
|
+
PYTHON: ${{ matrix.python-version }}
|
|
34
|
+
DEPS: yes
|
|
35
|
+
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v5
|
|
38
|
+
|
|
39
|
+
- name: Set up python
|
|
40
|
+
uses: actions/setup-python@v6
|
|
41
|
+
with:
|
|
42
|
+
python-version: ${{ matrix.python-version }}
|
|
43
|
+
|
|
44
|
+
- name: Install hatch
|
|
45
|
+
run: |
|
|
46
|
+
python -m pip install --upgrade setuptools
|
|
47
|
+
python -m pip install --upgrade hatch==1.14.2
|
|
48
|
+
python -m pip install --upgrade uv
|
|
49
|
+
|
|
50
|
+
- name: Build
|
|
51
|
+
run: |
|
|
52
|
+
hatch env create build
|
|
53
|
+
hatch build
|
|
54
|
+
|
|
55
|
+
- name: Store the distribution packages
|
|
56
|
+
uses: actions/upload-artifact@v4
|
|
57
|
+
with:
|
|
58
|
+
name: python-package-distributions
|
|
59
|
+
path: dist/
|
|
60
|
+
|
|
61
|
+
publish:
|
|
62
|
+
name: Publish to PyPi
|
|
63
|
+
runs-on: self-hosted
|
|
64
|
+
needs: build
|
|
65
|
+
strategy:
|
|
66
|
+
fail-fast: false
|
|
67
|
+
matrix:
|
|
68
|
+
python-version: [ "3.12" ]
|
|
69
|
+
steps:
|
|
70
|
+
- name: Set up python
|
|
71
|
+
uses: actions/setup-python@v6
|
|
72
|
+
with:
|
|
73
|
+
python-version: ${{ matrix.python-version }}
|
|
74
|
+
|
|
75
|
+
- name: Download all the dists
|
|
76
|
+
uses: actions/download-artifact@v4
|
|
77
|
+
with:
|
|
78
|
+
name: python-package-distributions
|
|
79
|
+
path: dist/
|
|
80
|
+
|
|
81
|
+
- name: Branch info
|
|
82
|
+
id: branch_info
|
|
83
|
+
run: |
|
|
84
|
+
echo ::set-output name=SOURCE_TAG::${GITHUB_REF#refs/tags/}
|
|
85
|
+
|
|
86
|
+
- name: Install hatch
|
|
87
|
+
run: |
|
|
88
|
+
python -m pip install --upgrade setuptools
|
|
89
|
+
python -m pip install --upgrade hatch==1.14.2
|
|
90
|
+
|
|
91
|
+
- name: Publish
|
|
92
|
+
run: |
|
|
93
|
+
hatch publish --user ${{ secrets.PYPI_USERNAME }} --auth ${{ secrets.PYPI_TOKEN }}
|
|
94
|
+
|
|
95
|
+
- name: Create Release
|
|
96
|
+
uses: softprops/action-gh-release@v2
|
|
97
|
+
with:
|
|
98
|
+
body_path: latest-changelogs.md
|
|
99
|
+
files: dist/*
|
|
100
|
+
name: ${{ steps.branch_info.outputs.SOURCE_TAG }}
|
|
101
|
+
draft: false
|
|
102
|
+
prerelease: false
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Tags Check
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
types: [closed]
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
tags_check:
|
|
12
|
+
name: Tags Check
|
|
13
|
+
if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'main' && startsWith(github.event.pull_request.head.ref, 'release/')
|
|
14
|
+
runs-on: self-hosted
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v5
|
|
17
|
+
with:
|
|
18
|
+
token: ${{ secrets.ACCESS_KEY }}
|
|
19
|
+
|
|
20
|
+
- name: Install jq
|
|
21
|
+
run: |
|
|
22
|
+
sudo apt-get update
|
|
23
|
+
sudo apt-get install -y jq
|
|
24
|
+
|
|
25
|
+
- name: Create tag
|
|
26
|
+
env:
|
|
27
|
+
GITHUB_TOKEN: ${{ secrets.ACCESS_KEY }}
|
|
28
|
+
run: |
|
|
29
|
+
bash ./scripts/tag_check.sh
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: amsdal_langgraph
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: amsdal_langgraph plugin for AMSDAL Framework
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Requires-Dist: amsdal[cli]>=0.5.14
|
|
7
|
+
Requires-Dist: langgraph>=0.6.8
|
|
8
|
+
Provides-Extra: openai
|
|
9
|
+
Requires-Dist: langchain[openai]; extra == 'openai'
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# AMSDAL Workflow
|
|
13
|
+
|
|
14
|
+
[](https://www.python.org/downloads/)
|
|
15
|
+
[](LICENSE)
|
|
16
|
+
|
|
17
|
+
A LangGraph checkpoint persistence plugin for the [AMSDAL Framework](https://github.com/amsdal/amsdal). This plugin enables persistent and recoverable LangGraph workflows by storing checkpoint state in AMSDAL-managed databases.
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- **Persistent Workflow State**: Store LangGraph checkpoints in any AMSDAL-supported database (SQLite, PostgreSQL, etc.)
|
|
22
|
+
- **Dual Mode Support**: Both synchronous and asynchronous operations
|
|
23
|
+
- **Thread-based Organization**: Manage multiple workflow threads with checkpoint namespacing
|
|
24
|
+
- **Drop-in Replacement**: Compatible with LangGraph's `BaseCheckpointSaver` interface
|
|
25
|
+
- **Production Ready**: Built on the robust AMSDAL ORM with comprehensive testing
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
Install via pip:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install amsdal-workflow
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or with optional dependencies:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# With OpenAI support
|
|
39
|
+
pip install amsdal-workflow[openai]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
### Basic Usage
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from langgraph.graph import StateGraph
|
|
48
|
+
from amsdal_langgraph.checkpoint import AmsdalCheckpointSaver
|
|
49
|
+
|
|
50
|
+
# Initialize the checkpoint saver
|
|
51
|
+
checkpointer = AmsdalCheckpointSaver()
|
|
52
|
+
|
|
53
|
+
# Create your LangGraph workflow
|
|
54
|
+
workflow = StateGraph(...)
|
|
55
|
+
# ... define your workflow nodes and edges ...
|
|
56
|
+
|
|
57
|
+
# Compile with checkpoint support
|
|
58
|
+
app = workflow.compile(checkpointer=checkpointer)
|
|
59
|
+
|
|
60
|
+
# Run with persistence
|
|
61
|
+
config = {'configurable': {'thread_id': 'user-123'}}
|
|
62
|
+
result = app.invoke(input_data, config=config)
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### Async Usage
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from amsdal_langgraph.checkpoint import AmsdalCheckpointSaver
|
|
69
|
+
|
|
70
|
+
# Same checkpointer works for async
|
|
71
|
+
checkpointer = AmsdalCheckpointSaver()
|
|
72
|
+
|
|
73
|
+
# Compile async workflow
|
|
74
|
+
app = workflow.compile(checkpointer=checkpointer)
|
|
75
|
+
|
|
76
|
+
# Run async with persistence
|
|
77
|
+
config = {'configurable': {'thread_id': 'user-123'}}
|
|
78
|
+
result = await app.ainvoke(input_data, config=config)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Advanced Configuration
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from langchain_core.runnables import RunnableConfig
|
|
85
|
+
from amsdal_langgraph.checkpoint import AmsdalCheckpointSaver
|
|
86
|
+
|
|
87
|
+
checkpointer = AmsdalCheckpointSaver()
|
|
88
|
+
|
|
89
|
+
# Configuration with checkpoint namespace
|
|
90
|
+
config: RunnableConfig = {
|
|
91
|
+
'configurable': {
|
|
92
|
+
'thread_id': 'conversation-456',
|
|
93
|
+
'checkpoint_ns': 'production', # Optional namespace
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
# Run workflow
|
|
98
|
+
result = app.invoke(input_data, config=config)
|
|
99
|
+
|
|
100
|
+
# Resume from checkpoint
|
|
101
|
+
checkpoint_tuple = checkpointer.get_tuple(config)
|
|
102
|
+
if checkpoint_tuple:
|
|
103
|
+
# Continue from last checkpoint
|
|
104
|
+
result = app.invoke(input_data, config=config)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Architecture
|
|
108
|
+
|
|
109
|
+
### Core Components
|
|
110
|
+
|
|
111
|
+
- **AmsdalCheckpointSaver**: Main class implementing LangGraph's `BaseCheckpointSaver` protocol
|
|
112
|
+
- **Checkpoint Model**: Stores checkpoint snapshots with metadata
|
|
113
|
+
- **CheckpointWrites Model**: Stores pending write operations for each checkpoint
|
|
114
|
+
|
|
115
|
+
### Data Models
|
|
116
|
+
|
|
117
|
+
#### Checkpoint
|
|
118
|
+
Stores workflow state snapshots:
|
|
119
|
+
- `thread_id`: Workflow thread identifier
|
|
120
|
+
- `checkpoint_ns`: Optional namespace for organization
|
|
121
|
+
- `checkpoint_id`: Unique checkpoint identifier
|
|
122
|
+
- `parent_checkpoint_id`: Reference to parent checkpoint
|
|
123
|
+
- `checkpoint`: Serialized checkpoint data
|
|
124
|
+
- `meta`: Checkpoint metadata
|
|
125
|
+
|
|
126
|
+
#### CheckpointWrites
|
|
127
|
+
Stores pending writes associated with checkpoints:
|
|
128
|
+
- `thread_id`, `checkpoint_ns`, `checkpoint_id`: Links to checkpoint
|
|
129
|
+
- `task_id`: Task identifier
|
|
130
|
+
- `idx`: Write operation index
|
|
131
|
+
- `channel`: Channel name
|
|
132
|
+
- `value`: Serialized write value
|
|
133
|
+
|
|
134
|
+
## API Reference
|
|
135
|
+
|
|
136
|
+
### AmsdalCheckpointSaver
|
|
137
|
+
|
|
138
|
+
#### Methods
|
|
139
|
+
|
|
140
|
+
##### Synchronous Methods
|
|
141
|
+
|
|
142
|
+
- `get_tuple(config: RunnableConfig) -> CheckpointTuple | None`
|
|
143
|
+
- Retrieve a checkpoint tuple by configuration
|
|
144
|
+
|
|
145
|
+
- `list(config: RunnableConfig | None, *, filter: dict | None = None, before: RunnableConfig | None = None, limit: int | None = None) -> Iterator[CheckpointTuple]`
|
|
146
|
+
- List checkpoints with optional filtering
|
|
147
|
+
|
|
148
|
+
- `put(config: RunnableConfig, checkpoint: Checkpoint, metadata: CheckpointMetadata, new_versions: ChannelVersions) -> RunnableConfig`
|
|
149
|
+
- Store a new checkpoint
|
|
150
|
+
|
|
151
|
+
- `put_writes(config: RunnableConfig, writes: Sequence[tuple[str, Any]], task_id: str) -> None`
|
|
152
|
+
- Store pending writes for a checkpoint
|
|
153
|
+
|
|
154
|
+
- `delete_thread(thread_id: str) -> None`
|
|
155
|
+
- Delete all checkpoints and writes for a thread
|
|
156
|
+
|
|
157
|
+
##### Asynchronous Methods
|
|
158
|
+
|
|
159
|
+
All synchronous methods have async equivalents prefixed with `a`:
|
|
160
|
+
- `aget_tuple(...)`
|
|
161
|
+
- `alist(...)`
|
|
162
|
+
- `aput(...)`
|
|
163
|
+
- `aput_writes(...)`
|
|
164
|
+
- `adelete_thread(...)`
|
|
165
|
+
|
|
166
|
+
## Configuration
|
|
167
|
+
|
|
168
|
+
### Database Setup
|
|
169
|
+
|
|
170
|
+
AMSDAL Workflow uses your existing AMSDAL configuration. Ensure you have configured your database connection:
|
|
171
|
+
|
|
172
|
+
```python
|
|
173
|
+
from amsdal.manager import AmsdalManager
|
|
174
|
+
|
|
175
|
+
# Initialize AMSDAL
|
|
176
|
+
manager = AmsdalManager()
|
|
177
|
+
manager.setup()
|
|
178
|
+
|
|
179
|
+
# Now use AmsdalCheckpointSaver
|
|
180
|
+
checkpointer = AmsdalCheckpointSaver()
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Migration
|
|
184
|
+
|
|
185
|
+
The plugin includes migration files for creating the required tables. Run migrations before first use:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
amsdal migrate
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Development
|
|
192
|
+
|
|
193
|
+
### Setup Development Environment
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# Clone the repository
|
|
197
|
+
git clone https://github.com/amsdal/amsdal-workflow.git
|
|
198
|
+
cd amsdal-workflow
|
|
199
|
+
|
|
200
|
+
# Install dependencies
|
|
201
|
+
hatch run sync
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Running Tests
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
# Run all tests
|
|
208
|
+
hatch run test
|
|
209
|
+
|
|
210
|
+
# Run with coverage
|
|
211
|
+
hatch run cov
|
|
212
|
+
|
|
213
|
+
# Run specific test file
|
|
214
|
+
hatch run test tests/test_checkpoint.py
|
|
215
|
+
|
|
216
|
+
# Run with verbose output
|
|
217
|
+
hatch run test -v
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Code Quality
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
# Format code
|
|
224
|
+
hatch run fmt
|
|
225
|
+
|
|
226
|
+
# Check code style
|
|
227
|
+
hatch run style
|
|
228
|
+
|
|
229
|
+
# Run type checking
|
|
230
|
+
hatch run typing
|
|
231
|
+
|
|
232
|
+
# Run all checks
|
|
233
|
+
hatch run all
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Project Structure
|
|
237
|
+
|
|
238
|
+
```
|
|
239
|
+
amsdal_langgraph/
|
|
240
|
+
├── amsdal_langgraph/ # Main package
|
|
241
|
+
│ ├── __init__.py
|
|
242
|
+
│ ├── checkpoint.py # AmsdalCheckpointSaver implementation
|
|
243
|
+
│ ├── utils.py # Utility functions
|
|
244
|
+
│ ├── models/ # Data models
|
|
245
|
+
│ │ ├── checkpoint.py # Checkpoint model
|
|
246
|
+
│ │ └── checkpoint_writes.py # CheckpointWrites model
|
|
247
|
+
│ └── migrations/ # Database migrations
|
|
248
|
+
├── tests/ # Test suite
|
|
249
|
+
│ ├── conftest.py # Test fixtures
|
|
250
|
+
│ └── test_checkpoint.py # Checkpoint tests
|
|
251
|
+
├── pyproject.toml # Project configuration
|
|
252
|
+
├── README.md # This file
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Contributing
|
|
256
|
+
|
|
257
|
+
Contributions are welcome! Please follow these steps:
|
|
258
|
+
|
|
259
|
+
1. Fork the repository
|
|
260
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
261
|
+
3. Make your changes
|
|
262
|
+
4. Run tests and code quality checks
|
|
263
|
+
5. Commit your changes (`git commit -m 'Add amazing feature'`)
|
|
264
|
+
6. Push to the branch (`git push origin feature/amazing-feature`)
|
|
265
|
+
7. Open a Pull Request
|
|
266
|
+
|
|
267
|
+
### Code Standards
|
|
268
|
+
|
|
269
|
+
- Python 3.11+ required
|
|
270
|
+
- Follow PEP 8 style guide (enforced by Ruff)
|
|
271
|
+
- Add type hints to all functions
|
|
272
|
+
- Write tests for new features
|
|
273
|
+
- Maintain test coverage above 90%
|
|
274
|
+
|
|
275
|
+
## License
|
|
276
|
+
|
|
277
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
278
|
+
|
|
279
|
+
## Acknowledgments
|
|
280
|
+
|
|
281
|
+
- Built on [LangGraph](https://github.com/langchain-ai/langgraph) by LangChain
|
|
282
|
+
- Powered by [AMSDAL Framework](https://github.com/amsdal/amsdal)
|
|
283
|
+
|
|
284
|
+
## Support
|
|
285
|
+
|
|
286
|
+
- **Documentation**: [AMSDAL Docs](https://docs.amsdal.com)
|
|
287
|
+
- **Issues**: [GitHub Issues](https://github.com/amsdal/amsdal-workflow/issues)
|
|
288
|
+
- **Discussions**: [GitHub Discussions](https://github.com/amsdal/amsdal-workflow/discussions)
|
|
289
|
+
|
|
290
|
+
## Changelog
|
|
291
|
+
|
|
292
|
+
See [CHANGELOG.md](CHANGELOG.md) for a list of changes in each release.
|