erdo 0.1.4__tar.gz → 0.1.5__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.
Potentially problematic release.
This version of erdo might be problematic. Click here for more details.
- erdo-0.1.5/CLAUDE.md +246 -0
- {erdo-0.1.4 → erdo-0.1.5}/PKG-INFO +2 -1
- erdo-0.1.5/VERSION +1 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/__init__.py +14 -11
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/actions/__init__.py +3 -1
- erdo-0.1.5/erdo/_generated/actions/analysis.py +179 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/actions/bot.py +39 -3
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/actions/codeexec.py +53 -28
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/actions/llm.py +22 -1
- erdo-0.1.5/erdo/_generated/actions/memory.py +447 -0
- erdo-0.1.5/erdo/_generated/actions/pdfextractor.py +97 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/actions/resource_definitions.py +114 -12
- erdo-0.1.5/erdo/_generated/actions/sqlexec.py +86 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/actions/utils.py +178 -56
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/actions/webparser.py +15 -5
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/actions/websearch.py +15 -5
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/condition/__init__.py +139 -129
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/types.py +92 -48
- {erdo-0.1.4 → erdo-0.1.5}/erdo/actions/__init__.py +9 -10
- erdo-0.1.5/erdo/bot_permissions.py +266 -0
- erdo-0.1.5/erdo/config/__init__.py +5 -0
- erdo-0.1.5/erdo/config/config.py +140 -0
- erdo-0.1.5/erdo/invoke/__init__.py +10 -0
- erdo-0.1.5/erdo/invoke/client.py +213 -0
- erdo-0.1.5/erdo/invoke/invoke.py +238 -0
- erdo-0.1.5/erdo/sync/__init__.py +17 -0
- erdo-0.1.5/erdo/sync/client.py +95 -0
- erdo-0.1.5/erdo/sync/extractor.py +476 -0
- erdo-0.1.5/erdo/sync/sync.py +328 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/types.py +508 -15
- erdo-0.1.5/examples/bot_permissions_example.py +115 -0
- erdo-0.1.5/examples/simple_echo_agent.py +31 -0
- erdo-0.1.5/examples/test_agent.py +26 -0
- erdo-0.1.5/examples/test_echo_agent.py +39 -0
- {erdo-0.1.4 → erdo-0.1.5}/pyproject.toml +1 -0
- erdo-0.1.5/test_bot_permissions.py +50 -0
- erdo-0.1.5/uv.lock +1003 -0
- erdo-0.1.4/VERSION +0 -1
- erdo-0.1.4/erdo/_generated/actions/analysis.py +0 -67
- erdo-0.1.4/erdo/_generated/actions/memory.py +0 -252
- {erdo-0.1.4 → erdo-0.1.5}/.github/workflows/ci.yml +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/.github/workflows/publish.yml +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/.gitignore +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/LICENSE +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/MANIFEST.in +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/PYPI_SETUP.md +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/README.md +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/__init__.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/internal.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/internal_actions.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/parameters.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/secrets.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/_generated/template_functions.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/cli_entry.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/conditions/__init__.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/install_cli.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/integrations.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/py.typed +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/state.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/erdo/template.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/examples/agent_centric_example.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/examples/analysis_files/analysis_result.json +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/examples/analysis_files/analyze.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/examples/analysis_files/utils.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/examples/state_example.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/examples/test_data.json +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/setup.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/tests/__init__.py +0 -0
- {erdo-0.1.4 → erdo-0.1.5}/tests/test_basic.py +0 -0
erdo-0.1.5/CLAUDE.md
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Erdo Python SDK Development
|
|
2
|
+
|
|
3
|
+
This is the Python SDK for Erdo, providing the API for defining AI agents, steps, and actions.
|
|
4
|
+
|
|
5
|
+
**📚 Critical Documentation:**
|
|
6
|
+
- **[../SDK_DEVELOPMENT.md](../SDK_DEVELOPMENT.md)** - **READ THIS FIRST** - Virtual environment gotchas, testing changes end-to-end, debugging data flow issues
|
|
7
|
+
|
|
8
|
+
## Quick Start
|
|
9
|
+
|
|
10
|
+
### After Making Changes
|
|
11
|
+
|
|
12
|
+
**CRITICAL**: After modifying the SDK, you MUST update all virtual environments that use it:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# Update the SDK's own venv
|
|
16
|
+
cd erdo-python-sdk
|
|
17
|
+
uv pip install -e .
|
|
18
|
+
|
|
19
|
+
# Update the agents venv (used by CLI)
|
|
20
|
+
cd ../erdo-agents
|
|
21
|
+
uv pip install -e ../erdo-python-sdk
|
|
22
|
+
|
|
23
|
+
# Verify the correct version is loaded
|
|
24
|
+
uv run python3 -c "import erdo; print(erdo.__file__)"
|
|
25
|
+
# Should show: /Users/niall/work/erdo/erdo-python-sdk/erdo/__init__.py
|
|
26
|
+
# NOT: erdo-agents/.venv/lib/python3.XX/site-packages/erdo/__init__.py
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Why this matters**: The CLI uses `uv run python3` which runs in the `erdo-agents/.venv` virtual environment. If you don't update the venv, the CLI will use the old published PyPI version of the SDK, not your local changes.
|
|
30
|
+
|
|
31
|
+
### Testing Your Changes
|
|
32
|
+
|
|
33
|
+
1. **Test Python SDK directly**:
|
|
34
|
+
```bash
|
|
35
|
+
cd erdo-python-sdk
|
|
36
|
+
uv run python3 -c "
|
|
37
|
+
from erdo import Agent
|
|
38
|
+
from erdo.actions import utils
|
|
39
|
+
agent = Agent(key='test.test', name='Test', description='Test')
|
|
40
|
+
step = agent.step(utils.echo(data='hello'))
|
|
41
|
+
print(step.to_dict())
|
|
42
|
+
"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
2. **Test CLI integration**:
|
|
46
|
+
```bash
|
|
47
|
+
cd ../erdo-cli
|
|
48
|
+
./erdo test /path/to/test_agent.py
|
|
49
|
+
./erdo sync-agent /path/to/test_agent.py --dry-run
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
3. **Test backend integration**:
|
|
53
|
+
```bash
|
|
54
|
+
# Sync to a running backend and check logs
|
|
55
|
+
./erdo sync-agent /path/to/test_agent.py
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Project Structure
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
erdo-python-sdk/
|
|
62
|
+
├── erdo/
|
|
63
|
+
│ ├── __init__.py # Main exports (Agent, Step, etc.)
|
|
64
|
+
│ ├── types.py # Core types (Step, Agent, StepMetadata, etc.)
|
|
65
|
+
│ ├── actions/ # Action modules (utils, codeexec, llm, etc.)
|
|
66
|
+
│ └── _generated/ # Generated types (DO NOT EDIT MANUALLY)
|
|
67
|
+
│ └── types.py # Run 'erdo gen-client' to regenerate
|
|
68
|
+
├── tests/ # Unit tests
|
|
69
|
+
└── pyproject.toml # Package configuration
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Key Files
|
|
73
|
+
|
|
74
|
+
### `erdo/types.py`
|
|
75
|
+
Contains the core SDK types:
|
|
76
|
+
- `Agent` - Top-level agent definition
|
|
77
|
+
- `Step` - Individual workflow step
|
|
78
|
+
- `StepMetadata` - Base class for step configuration
|
|
79
|
+
- `ResultHandler` - Result handler configuration
|
|
80
|
+
- Enums: `OutputVisibility`, `OutputContentType`, `ParameterHydrationBehaviour`
|
|
81
|
+
|
|
82
|
+
**Important**: When adding or modifying fields:
|
|
83
|
+
1. Update the Pydantic model definition
|
|
84
|
+
2. Update the `to_dict()` method if custom serialization is needed
|
|
85
|
+
3. Filter out None values for optional fields with defaults
|
|
86
|
+
|
|
87
|
+
### `erdo/_generated/types.py`
|
|
88
|
+
Auto-generated from the OpenAPI schema. **DO NOT EDIT MANUALLY**.
|
|
89
|
+
|
|
90
|
+
To regenerate:
|
|
91
|
+
```bash
|
|
92
|
+
cd ../erdo-cli
|
|
93
|
+
./erdo gen-client
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Important Concepts
|
|
97
|
+
|
|
98
|
+
### Using step_metadata in Result Handlers
|
|
99
|
+
|
|
100
|
+
When creating steps in result handlers via `.on()`, you can configure step properties using `step_metadata`:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
step.on(IsSuccess(),
|
|
104
|
+
utils.parse_json(
|
|
105
|
+
json_data="{{output}}",
|
|
106
|
+
step_metadata=StepMetadata(
|
|
107
|
+
key="parse_result",
|
|
108
|
+
output_behavior={"data": OutputBehaviorType.MERGE}
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**How it works**:
|
|
115
|
+
1. Action param classes (EchoParams, ParseJsonParams, etc.) have a `step_metadata` field
|
|
116
|
+
2. When passed to an action, the metadata is stored on the action object
|
|
117
|
+
3. `Step.on()` extracts the metadata and merges it into the Step configuration
|
|
118
|
+
4. The `_extract_step_config_from_action()` helper handles the extraction
|
|
119
|
+
|
|
120
|
+
**Important**: The `step_metadata` parameter is specifically for use in action calls. It allows you to configure step properties (key, output_behavior, execution_mode, visibility, etc.) when the step is created from an action.
|
|
121
|
+
|
|
122
|
+
### Field Naming: American vs British Spelling
|
|
123
|
+
|
|
124
|
+
The Python SDK uses American spelling (`output_behavior`) but the Go backend expects British spelling (`output_behaviour`). The `Step.to_dict()` method automatically handles this conversion during serialization:
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
# In Step.to_dict():
|
|
128
|
+
if "output_behavior" in result:
|
|
129
|
+
result["output_behaviour"] = result.pop("output_behavior")
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
This ensures agents sync correctly to the backend.
|
|
133
|
+
|
|
134
|
+
## Common Development Tasks
|
|
135
|
+
|
|
136
|
+
### Adding a New Field to Step
|
|
137
|
+
|
|
138
|
+
Example: Adding a new optional field `my_field`:
|
|
139
|
+
|
|
140
|
+
1. **Update `types.py`**:
|
|
141
|
+
```python
|
|
142
|
+
class StepMetadata(BaseModel):
|
|
143
|
+
# ... existing fields ...
|
|
144
|
+
my_field: Optional[str] = None
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
2. **Update `to_dict()` method** (if the field should be omitted when None):
|
|
148
|
+
```python
|
|
149
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
150
|
+
result = self.model_dump(exclude={'agent', 'result_handler', 'action', 'depends_on'})
|
|
151
|
+
|
|
152
|
+
# Filter out None optional fields
|
|
153
|
+
if result.get("my_field") is None:
|
|
154
|
+
result.pop("my_field", None)
|
|
155
|
+
|
|
156
|
+
return result
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
3. **Update the backend**:
|
|
160
|
+
- Add to `erdo-common/types/bot.go` - `Step` struct
|
|
161
|
+
- Add to `erdo/backend/bot/db/migrations/` - Database migration
|
|
162
|
+
- Run `sqlc generate` in backend
|
|
163
|
+
|
|
164
|
+
4. **Test**:
|
|
165
|
+
```bash
|
|
166
|
+
# Update venvs
|
|
167
|
+
cd erdo-python-sdk && uv pip install -e .
|
|
168
|
+
cd ../erdo-agents && uv pip install -e ../erdo-python-sdk
|
|
169
|
+
|
|
170
|
+
# Test
|
|
171
|
+
cd ../erdo-cli
|
|
172
|
+
./erdo test /path/to/test_agent.py
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Changing Field Types
|
|
176
|
+
|
|
177
|
+
Example: Changing from `field: SomeEnum = SomeEnum.NONE` to `field: Optional[SomeEnum] = None`:
|
|
178
|
+
|
|
179
|
+
**See [../SDK_DEVELOPMENT.md](../SDK_DEVELOPMENT.md#type-changes-checklist)** for the complete checklist.
|
|
180
|
+
|
|
181
|
+
Key steps:
|
|
182
|
+
1. Change Python SDK type definition
|
|
183
|
+
2. Update `to_dict()` to filter None values
|
|
184
|
+
3. Update Go common types (value → pointer)
|
|
185
|
+
4. Update Go backend code handling the field
|
|
186
|
+
5. Update CLI export/sync code
|
|
187
|
+
6. Update all venvs
|
|
188
|
+
7. Test end-to-end
|
|
189
|
+
|
|
190
|
+
## Debugging
|
|
191
|
+
|
|
192
|
+
### Virtual Environment Issues
|
|
193
|
+
|
|
194
|
+
**Problem**: Changes not appearing when testing
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# Check which SDK is loaded
|
|
198
|
+
uv run python3 -c "import erdo; print(erdo.__file__)"
|
|
199
|
+
|
|
200
|
+
# If it shows .venv/lib/python3.XX/site-packages/erdo
|
|
201
|
+
# Then reinstall in editable mode:
|
|
202
|
+
uv pip install -e /Users/niall/work/erdo/erdo-python-sdk
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Field Serialization Issues
|
|
206
|
+
|
|
207
|
+
**Problem**: Field showing wrong value in database
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
# Debug the to_dict() output
|
|
211
|
+
from erdo import Agent
|
|
212
|
+
from erdo.actions import utils
|
|
213
|
+
agent = Agent(key='test.test', name='Test', description='Test')
|
|
214
|
+
step = agent.step(utils.echo(data='hello'))
|
|
215
|
+
|
|
216
|
+
# Check attribute
|
|
217
|
+
print(f"step.my_field: {step.my_field}")
|
|
218
|
+
|
|
219
|
+
# Check model_dump
|
|
220
|
+
dump = step.model_dump(exclude={'agent', 'action'})
|
|
221
|
+
print(f"model_dump: {dump.get('my_field')}")
|
|
222
|
+
|
|
223
|
+
# Check to_dict
|
|
224
|
+
step_dict = step.to_dict()
|
|
225
|
+
print(f"to_dict: {'my_field' in step_dict}")
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Testing
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
# Run unit tests
|
|
232
|
+
cd erdo-python-sdk
|
|
233
|
+
uv run pytest tests/
|
|
234
|
+
|
|
235
|
+
# Run specific test
|
|
236
|
+
uv run pytest tests/test_types.py::test_step_creation
|
|
237
|
+
|
|
238
|
+
# Test import
|
|
239
|
+
uv run python3 -c "from erdo import Agent; print('OK')"
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Related Documentation
|
|
243
|
+
|
|
244
|
+
- [../SDK_DEVELOPMENT.md](../SDK_DEVELOPMENT.md) - Comprehensive guide for SDK development
|
|
245
|
+
- [../erdo/CLAUDE.md](../erdo/CLAUDE.md) - Backend development guide
|
|
246
|
+
- [../erdo-cli/CLAUDE.md](../erdo-cli/CLAUDE.md) - CLI development guide
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: erdo
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: Python SDK for building workflow automation agents with Erdo
|
|
5
5
|
Project-URL: Homepage, https://erdo.ai
|
|
6
6
|
Project-URL: Documentation, https://docs.erdo.ai
|
|
@@ -23,6 +23,7 @@ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
|
23
23
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
24
|
Requires-Python: >=3.9
|
|
25
25
|
Requires-Dist: pydantic>=2.0.0
|
|
26
|
+
Requires-Dist: requests>=2.31.0
|
|
26
27
|
Requires-Dist: typing-extensions>=4.0.0
|
|
27
28
|
Provides-Extra: dev
|
|
28
29
|
Requires-Dist: black>=23.0.0; extra == 'dev'
|
erdo-0.1.5/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.5
|
|
@@ -4,32 +4,35 @@
|
|
|
4
4
|
|
|
5
5
|
# Import all condition functions from generated condition module
|
|
6
6
|
from ._generated.condition import * # noqa: F403,F401
|
|
7
|
-
from ._generated.condition import __all__ as condition_all
|
|
8
7
|
|
|
9
|
-
# Import all generated types
|
|
8
|
+
# Import all generated types automatically
|
|
10
9
|
from ._generated.types import * # noqa: F403,F401
|
|
11
|
-
from ._generated.types import __all__ as generated_all
|
|
12
10
|
|
|
13
11
|
# Import state object for template support
|
|
14
12
|
from .state import state # noqa: F401
|
|
15
13
|
|
|
16
|
-
# Import all handwritten SDK classes
|
|
17
|
-
from .types import * # noqa: F403,F401
|
|
18
|
-
from .types import __all__ as handwritten_all
|
|
14
|
+
# Import all handwritten SDK classes automatically
|
|
15
|
+
from .types import * # noqa: F403,F401
|
|
19
16
|
|
|
20
17
|
__version__ = "0.1.0"
|
|
21
18
|
|
|
22
19
|
# Build __all__ dynamically by combining all available types
|
|
23
20
|
__all__ = []
|
|
24
21
|
|
|
25
|
-
# Add
|
|
22
|
+
# Add handwritten SDK classes
|
|
23
|
+
from .types import __all__ as handwritten_all
|
|
24
|
+
|
|
25
|
+
__all__.extend(handwritten_all)
|
|
26
|
+
|
|
27
|
+
# Add all generated types automatically
|
|
28
|
+
from ._generated.types import __all__ as generated_all
|
|
29
|
+
|
|
26
30
|
__all__.extend(generated_all)
|
|
27
31
|
|
|
28
|
-
# Add all condition functions
|
|
29
|
-
__all__
|
|
32
|
+
# Add all condition functions automatically
|
|
33
|
+
from ._generated.condition import __all__ as condition_all
|
|
30
34
|
|
|
31
|
-
|
|
32
|
-
__all__.extend(handwritten_all)
|
|
35
|
+
__all__.extend(condition_all)
|
|
33
36
|
|
|
34
37
|
# Add state to __all__ for explicit import
|
|
35
38
|
__all__.append("state")
|
|
@@ -16,17 +16,19 @@ from . import codeexec # noqa: F401
|
|
|
16
16
|
from . import llm # noqa: F401
|
|
17
17
|
from . import memory # noqa: F401
|
|
18
18
|
from . import resource_definitions # noqa: F401
|
|
19
|
+
from . import sqlexec # noqa: F401
|
|
19
20
|
from . import utils # noqa: F401
|
|
20
21
|
from . import webparser # noqa: F401
|
|
21
22
|
from . import websearch # noqa: F401
|
|
22
|
-
from .analysis import * # noqa: F403,F401
|
|
23
23
|
|
|
24
24
|
# Import all functions from service modules
|
|
25
|
+
from .analysis import * # noqa: F403,F401
|
|
25
26
|
from .bot import * # noqa: F403,F401
|
|
26
27
|
from .codeexec import * # noqa: F403,F401
|
|
27
28
|
from .llm import * # noqa: F403,F401
|
|
28
29
|
from .memory import * # noqa: F403,F401
|
|
29
30
|
from .resource_definitions import * # noqa: F403,F401
|
|
31
|
+
from .sqlexec import * # noqa: F403,F401
|
|
30
32
|
from .utils import * # noqa: F403,F401
|
|
31
33
|
from .webparser import * # noqa: F403,F401
|
|
32
34
|
from .websearch import * # noqa: F403,F401
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Analysis actions for creating and managing data analysis service functions.
|
|
3
|
+
Auto-generated - DO NOT EDIT.
|
|
4
|
+
|
|
5
|
+
Provides type-safe action definitions for analysis service.
|
|
6
|
+
Actual execution happens in the Go backend after syncing.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from typing import Any, List, Optional, Union
|
|
10
|
+
|
|
11
|
+
from pydantic import BaseModel
|
|
12
|
+
|
|
13
|
+
from erdo.template import TemplateString
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class BaseActionParams(BaseModel):
|
|
17
|
+
"""Base class for all action parameter classes.
|
|
18
|
+
|
|
19
|
+
Provides common fields that all actions support:
|
|
20
|
+
- name: The action type identifier
|
|
21
|
+
- step_metadata: Optional configuration for the step created from this action
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
name: str
|
|
25
|
+
step_metadata: Optional[Any] = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class CreateAnalysisParams(BaseActionParams):
|
|
29
|
+
"""Create an analysis for a dataset, resource, or dataset-resource combination parameters"""
|
|
30
|
+
|
|
31
|
+
name: str = "analysis.create_analysis" # Action type for roundtrip compatibility
|
|
32
|
+
analysis: Optional[Any] = None # analysis parameter
|
|
33
|
+
dataset_id: Optional[Union[str, TemplateString]] = None # dataset_id parameter
|
|
34
|
+
resource_id: Optional[Union[str, TemplateString]] = None # resource_id parameter
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class AnalyzeCsvParams(BaseActionParams):
|
|
38
|
+
"""Analyze CSV file using Go-based CSV analyzer (fast, no Python needed) parameters"""
|
|
39
|
+
|
|
40
|
+
name: str = "analysis.analyze_csv" # Action type for roundtrip compatibility
|
|
41
|
+
file: Optional[Any] = None # file parameter
|
|
42
|
+
columns: Optional[Any] = None # columns parameter
|
|
43
|
+
rows: Optional[Any] = None # rows parameter
|
|
44
|
+
encryption_key: Optional[Union[str, TemplateString]] = (
|
|
45
|
+
None # encryption_key parameter
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class AnalyzeExcelParams(BaseActionParams):
|
|
50
|
+
"""Analyze Excel file using Go-based Excel analyzer (fast, no Python needed) parameters"""
|
|
51
|
+
|
|
52
|
+
name: str = "analysis.analyze_excel" # Action type for roundtrip compatibility
|
|
53
|
+
file: Optional[Any] = None # file parameter
|
|
54
|
+
encryption_key: Optional[Union[str, TemplateString]] = (
|
|
55
|
+
None # encryption_key parameter
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class CreateAnalysisResult(BaseModel):
|
|
60
|
+
"""Create an analysis for a dataset, resource, or dataset-resource combination result type
|
|
61
|
+
|
|
62
|
+
Result schema for analysis.create_analysis action.
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
analysis: Any
|
|
66
|
+
insights: Optional[List[str]]
|
|
67
|
+
recommendations: Optional[List[str]]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
class AnalyzeCsvResult(BaseModel):
|
|
71
|
+
"""Analyze CSV file using Go-based CSV analyzer (fast, no Python needed) result type
|
|
72
|
+
|
|
73
|
+
Result schema for analysis.analyze_csv action.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
summary: str
|
|
77
|
+
details: Any
|
|
78
|
+
dataset_file_name: str
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class AnalyzeExcelResult(BaseModel):
|
|
82
|
+
"""Analyze Excel file using Go-based Excel analyzer (fast, no Python needed) result type
|
|
83
|
+
|
|
84
|
+
Result schema for analysis.analyze_excel action.
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
summary: str
|
|
88
|
+
details: Any
|
|
89
|
+
dataset_file_name: str
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def create_analysis(
|
|
93
|
+
analysis: Optional[Any] = None,
|
|
94
|
+
dataset_id: Optional[Union[str, TemplateString]] = None,
|
|
95
|
+
resource_id: Optional[Union[str, TemplateString]] = None,
|
|
96
|
+
**params: Any,
|
|
97
|
+
) -> CreateAnalysisParams:
|
|
98
|
+
"""Create an analysis for a dataset, resource, or dataset-resource combination
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
analysis: analysis parameter
|
|
102
|
+
dataset_id: dataset_id parameter
|
|
103
|
+
resource_id: resource_id parameter
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
CreateAnalysisParams: Type-safe parameter object
|
|
107
|
+
"""
|
|
108
|
+
param_dict = {
|
|
109
|
+
"analysis": analysis,
|
|
110
|
+
"dataset_id": dataset_id,
|
|
111
|
+
"resource_id": resource_id,
|
|
112
|
+
}
|
|
113
|
+
# Remove None values for optional parameters
|
|
114
|
+
param_dict = {k: v for k, v in param_dict.items() if v is not None}
|
|
115
|
+
param_dict.update(params)
|
|
116
|
+
params_obj = CreateAnalysisParams(**param_dict)
|
|
117
|
+
return params_obj
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def analyze_csv(
|
|
121
|
+
file: Optional[Any] = None,
|
|
122
|
+
columns: Optional[Any] = None,
|
|
123
|
+
rows: Optional[Any] = None,
|
|
124
|
+
encryption_key: Optional[Union[str, TemplateString]] = None,
|
|
125
|
+
**params: Any,
|
|
126
|
+
) -> AnalyzeCsvParams:
|
|
127
|
+
"""Analyze CSV file using Go-based CSV analyzer (fast, no Python needed)
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
file: file parameter
|
|
131
|
+
columns: columns parameter
|
|
132
|
+
rows: rows parameter
|
|
133
|
+
encryption_key: encryption_key parameter
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
AnalyzeCsvParams: Type-safe parameter object
|
|
137
|
+
"""
|
|
138
|
+
param_dict = {
|
|
139
|
+
"file": file,
|
|
140
|
+
"columns": columns,
|
|
141
|
+
"rows": rows,
|
|
142
|
+
"encryption_key": encryption_key,
|
|
143
|
+
}
|
|
144
|
+
# Remove None values for optional parameters
|
|
145
|
+
param_dict = {k: v for k, v in param_dict.items() if v is not None}
|
|
146
|
+
param_dict.update(params)
|
|
147
|
+
params_obj = AnalyzeCsvParams(**param_dict)
|
|
148
|
+
return params_obj
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def analyze_excel(
|
|
152
|
+
file: Optional[Any] = None,
|
|
153
|
+
encryption_key: Optional[Union[str, TemplateString]] = None,
|
|
154
|
+
**params: Any,
|
|
155
|
+
) -> AnalyzeExcelParams:
|
|
156
|
+
"""Analyze Excel file using Go-based Excel analyzer (fast, no Python needed)
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
file: file parameter
|
|
160
|
+
encryption_key: encryption_key parameter
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
AnalyzeExcelParams: Type-safe parameter object
|
|
164
|
+
"""
|
|
165
|
+
param_dict = {
|
|
166
|
+
"file": file,
|
|
167
|
+
"encryption_key": encryption_key,
|
|
168
|
+
}
|
|
169
|
+
# Remove None values for optional parameters
|
|
170
|
+
param_dict = {k: v for k, v in param_dict.items() if v is not None}
|
|
171
|
+
param_dict.update(params)
|
|
172
|
+
params_obj = AnalyzeExcelParams(**param_dict)
|
|
173
|
+
return params_obj
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
# Associate parameter classes with their result types
|
|
177
|
+
CreateAnalysisParams._result = CreateAnalysisResult
|
|
178
|
+
AnalyzeCsvParams._result = AnalyzeCsvResult
|
|
179
|
+
AnalyzeExcelParams._result = AnalyzeExcelResult
|
|
@@ -17,10 +17,38 @@ from erdo.template import TemplateString
|
|
|
17
17
|
from erdo.types import StepMetadata
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
class InvokeResult(BaseModel):
|
|
21
|
+
"""Bot invoke result type
|
|
22
|
+
|
|
23
|
+
Result schema for bot.invoke action.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
result: Any # The bot invocation result
|
|
27
|
+
messages: list # Messages from the bot invocation
|
|
28
|
+
resources: list # Resources created/used during invocation
|
|
29
|
+
final_state: Any # Final state after invocation
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class AskResult(BaseModel):
|
|
33
|
+
"""Bot ask result type
|
|
34
|
+
|
|
35
|
+
Result schema for bot.ask action.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
success: bool # Whether the question was successfully processed
|
|
39
|
+
response: Optional[str] = None # The bot's response to the question
|
|
40
|
+
bot_id: Optional[str] = None # ID of the bot that answered
|
|
41
|
+
invocation_id: Optional[str] = None # ID of the invocation
|
|
42
|
+
error: Optional[str] = None # Error message if ask failed
|
|
43
|
+
|
|
44
|
+
|
|
20
45
|
class InvokeParams(BaseModel):
|
|
21
46
|
"""Invoke a bot with specified parameters and return the result parameters"""
|
|
22
47
|
|
|
23
48
|
name: str = "bot.invoke" # Action type for roundtrip compatibility
|
|
49
|
+
bot_key: Optional[Union[str, TemplateString]] = (
|
|
50
|
+
None # bot_key parameter (unique bot identifier like "erdo.security-checker")
|
|
51
|
+
)
|
|
24
52
|
bot_name: Optional[Union[str, TemplateString]] = (
|
|
25
53
|
None # bot_name parameter (backend expects this, not bot_id)
|
|
26
54
|
)
|
|
@@ -51,6 +79,7 @@ class AskParams(BaseModel):
|
|
|
51
79
|
|
|
52
80
|
|
|
53
81
|
def invoke(
|
|
82
|
+
bot_key: Optional[Union[str, TemplateString]] = None,
|
|
54
83
|
bot_name: Optional[Union[str, TemplateString]] = None,
|
|
55
84
|
parameters: Optional[Union[Dict[str, Any], TemplateString]] = None,
|
|
56
85
|
bot_output_visibility_behaviour: Optional[Union[str, TemplateString]] = None,
|
|
@@ -61,11 +90,12 @@ def invoke(
|
|
|
61
90
|
) -> InvokeParams:
|
|
62
91
|
"""Invoke a bot with specified parameters and return the result
|
|
63
92
|
|
|
64
|
-
The bot.invoke action expects
|
|
65
|
-
The backend will look up the bot
|
|
93
|
+
The bot.invoke action expects bot_key or bot_name as the parameter.
|
|
94
|
+
The backend will look up the bot and convert to bot_id internally.
|
|
66
95
|
|
|
67
96
|
Args:
|
|
68
|
-
|
|
97
|
+
bot_key: Unique key of the bot to invoke (e.g., "erdo.security-checker")
|
|
98
|
+
bot_name: Name of the bot to invoke (alternative to bot_key)
|
|
69
99
|
parameters: Parameters to pass to the bot
|
|
70
100
|
bot_output_visibility_behaviour: Output visibility behaviour
|
|
71
101
|
transparent: Whether the invocation is transparent
|
|
@@ -75,6 +105,7 @@ def invoke(
|
|
|
75
105
|
InvokeParams: Type-safe parameter object
|
|
76
106
|
"""
|
|
77
107
|
params_dict = {
|
|
108
|
+
"bot_key": bot_key,
|
|
78
109
|
"bot_name": bot_name,
|
|
79
110
|
"parameters": parameters,
|
|
80
111
|
"bot_output_visibility_behaviour": bot_output_visibility_behaviour,
|
|
@@ -122,3 +153,8 @@ def ask(
|
|
|
122
153
|
|
|
123
154
|
# Use normal constructor for proper validation
|
|
124
155
|
return AskParams(**params_dict)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
# Associate parameter classes with their result types
|
|
159
|
+
InvokeParams._result = InvokeResult
|
|
160
|
+
AskParams._result = AskResult
|