soothe-plugins 0.2.6__py3-none-any.whl
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.
- soothe_plugins/.plugin_template/PLUGIN_TEMPLATE.md +40 -0
- soothe_plugins/.plugin_template/README.md.template +152 -0
- soothe_plugins/.plugin_template/__init__.py.template +174 -0
- soothe_plugins/.plugin_template/events.py.template +34 -0
- soothe_plugins/.plugin_template/implementation.py.template +112 -0
- soothe_plugins/.plugin_template/models.py.template +39 -0
- soothe_plugins/.plugin_template/state.py.template +48 -0
- soothe_plugins/README.md +150 -0
- soothe_plugins/__init__.py +20 -0
- soothe_plugins/_paths.py +17 -0
- soothe_plugins/sample_echo/__init__.py +44 -0
- soothe_plugins/sample_echo/implementation.py +47 -0
- soothe_plugins/skillify/__init__.py +288 -0
- soothe_plugins/skillify/events.py +148 -0
- soothe_plugins/skillify/indexer.py +312 -0
- soothe_plugins/skillify/models.py +36 -0
- soothe_plugins/skillify/retriever.py +165 -0
- soothe_plugins/skillify/warehouse.py +96 -0
- soothe_plugins/weaver/__init__.py +507 -0
- soothe_plugins/weaver/analyzer.py +81 -0
- soothe_plugins/weaver/composer.py +322 -0
- soothe_plugins/weaver/events.py +223 -0
- soothe_plugins/weaver/generator.py +177 -0
- soothe_plugins/weaver/models.py +136 -0
- soothe_plugins/weaver/registry.py +214 -0
- soothe_plugins/weaver/reuse.py +151 -0
- soothe_plugins-0.2.6.dist-info/METADATA +156 -0
- soothe_plugins-0.2.6.dist-info/RECORD +30 -0
- soothe_plugins-0.2.6.dist-info/WHEEL +4 -0
- soothe_plugins-0.2.6.dist-info/entry_points.txt +4 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Plugin Template
|
|
2
|
+
|
|
3
|
+
This directory serves as a template for creating new plugins in soothe-plugins.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
1. Copy this template:
|
|
8
|
+
```bash
|
|
9
|
+
cp -r src/soothe_plugins/.plugin_template src/soothe_plugins/your_plugin
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
2. Rename files:
|
|
13
|
+
- `__init__.py.template` → `__init__.py`
|
|
14
|
+
- `events.py.template` → `events.py`
|
|
15
|
+
- `models.py.template` → `models.py`
|
|
16
|
+
- `state.py.template` → `state.py`
|
|
17
|
+
- `implementation.py.template` → `implementation.py`
|
|
18
|
+
|
|
19
|
+
3. Update content:
|
|
20
|
+
- Replace `your_plugin` with your plugin name
|
|
21
|
+
- Replace `YourPlugin` with your class name
|
|
22
|
+
- Add your dependencies to `pyproject.toml`
|
|
23
|
+
- Register entry point in `pyproject.toml`
|
|
24
|
+
|
|
25
|
+
4. Add tests in `tests/test_your_plugin/`
|
|
26
|
+
|
|
27
|
+
5. Update documentation in your plugin's `README.md`
|
|
28
|
+
|
|
29
|
+
## Template Files
|
|
30
|
+
|
|
31
|
+
- `__init__.py.template` - Plugin class with decorators
|
|
32
|
+
- `events.py.template` - Custom events
|
|
33
|
+
- `models.py.template` - Data models
|
|
34
|
+
- `state.py.template` - State definitions (for subagents)
|
|
35
|
+
- `implementation.py.template` - Core logic
|
|
36
|
+
- `README.md.template` - Plugin documentation
|
|
37
|
+
|
|
38
|
+
## Example: PaperScout Plugin
|
|
39
|
+
|
|
40
|
+
See `src/soothe_plugins/paperscout/` for a complete example.
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Your Plugin Name
|
|
2
|
+
|
|
3
|
+
Brief description of your plugin and what it does.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Feature 1
|
|
8
|
+
- Feature 2
|
|
9
|
+
- Feature 3
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install soothe-community
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
Add to your Soothe `config.yml`:
|
|
20
|
+
|
|
21
|
+
```yaml
|
|
22
|
+
subagents:
|
|
23
|
+
your_agent:
|
|
24
|
+
enabled: true
|
|
25
|
+
model: "openai:gpt-4o-mini"
|
|
26
|
+
config:
|
|
27
|
+
option1: value1
|
|
28
|
+
option2: value2
|
|
29
|
+
max_items: 100
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Configuration Options
|
|
33
|
+
|
|
34
|
+
| Option | Type | Default | Description |
|
|
35
|
+
|--------|------|---------|-------------|
|
|
36
|
+
| `option1` | str | "default_value" | Description of option1 |
|
|
37
|
+
| `option2` | int | 10 | Description of option2 |
|
|
38
|
+
| `max_items` | int | 100 | Maximum items to process |
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
### As Subagent
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Via TUI (default)
|
|
46
|
+
soothe "your query here" --subagent your_agent
|
|
47
|
+
|
|
48
|
+
# Headless mode
|
|
49
|
+
soothe "your query" --subagent your_agent --no-tui
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### As Tool
|
|
53
|
+
|
|
54
|
+
The plugin also provides tools that can be used directly:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from soothe_community.your_plugin import YourPlugin
|
|
58
|
+
|
|
59
|
+
plugin = YourPlugin()
|
|
60
|
+
result = plugin.your_tool("input")
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Examples
|
|
64
|
+
|
|
65
|
+
### Example 1: Basic Usage
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
soothe "process data" --subagent your_agent
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Example 2: Advanced Usage
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
soothe "complex operation with parameters" --subagent your_agent --config custom_config.yml
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Architecture
|
|
78
|
+
|
|
79
|
+
Your plugin consists of:
|
|
80
|
+
|
|
81
|
+
- **Plugin Class**: Main entry point with `@plugin` decorator
|
|
82
|
+
- **Subagent**: Agent graph for complex workflows
|
|
83
|
+
- **Tools**: Individual tools for simple operations
|
|
84
|
+
- **Events**: Custom events for monitoring
|
|
85
|
+
|
|
86
|
+
## Development
|
|
87
|
+
|
|
88
|
+
### Setup
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# Clone soothe-community
|
|
92
|
+
git clone <repo>
|
|
93
|
+
cd soothe-community
|
|
94
|
+
|
|
95
|
+
# Install in dev mode
|
|
96
|
+
pip install -e ".[dev]"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Testing
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pytest tests/test_your_plugin/
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Code Quality
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Format
|
|
109
|
+
ruff format src/soothe_community/your_plugin/
|
|
110
|
+
|
|
111
|
+
# Lint
|
|
112
|
+
ruff check --fix src/soothe_community/your_plugin/
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## API Reference
|
|
116
|
+
|
|
117
|
+
### YourPlugin
|
|
118
|
+
|
|
119
|
+
Main plugin class.
|
|
120
|
+
|
|
121
|
+
#### Methods
|
|
122
|
+
|
|
123
|
+
- `on_load(context)`: Initialize plugin
|
|
124
|
+
- `create_subagent(model, config, context, **kwargs)`: Create subagent
|
|
125
|
+
- `your_tool(arg)`: Tool function
|
|
126
|
+
|
|
127
|
+
### YourConfig
|
|
128
|
+
|
|
129
|
+
Configuration model.
|
|
130
|
+
|
|
131
|
+
### YourState
|
|
132
|
+
|
|
133
|
+
State model for subagent.
|
|
134
|
+
|
|
135
|
+
## Dependencies
|
|
136
|
+
|
|
137
|
+
- `soothe>=0.1.0` - Core framework
|
|
138
|
+
- `langgraph>=0.2.0` - Graph orchestration
|
|
139
|
+
- `required-package>=1.0.0` - Your dependency
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT
|
|
144
|
+
|
|
145
|
+
## Support
|
|
146
|
+
|
|
147
|
+
- **Issues**: GitHub Issues
|
|
148
|
+
- **Documentation**: See `docs/` in soothe-community repo
|
|
149
|
+
|
|
150
|
+
## Contributing
|
|
151
|
+
|
|
152
|
+
See [CONTRIBUTING.md](../CONTRIBUTING.md) for guidelines.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"""Your plugin description.
|
|
2
|
+
|
|
3
|
+
Detailed description of what your plugin does, its features, and use cases.
|
|
4
|
+
|
|
5
|
+
Installation:
|
|
6
|
+
pip install soothe-community
|
|
7
|
+
|
|
8
|
+
Configuration (config.yml):
|
|
9
|
+
subagents:
|
|
10
|
+
your_agent:
|
|
11
|
+
enabled: true
|
|
12
|
+
model: "openai:gpt-4o-mini"
|
|
13
|
+
config:
|
|
14
|
+
option1: value1
|
|
15
|
+
option2: value2
|
|
16
|
+
|
|
17
|
+
Usage:
|
|
18
|
+
soothe "your query" --subagent your_agent
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import logging
|
|
24
|
+
from typing import Any
|
|
25
|
+
|
|
26
|
+
from soothe_sdk.core.exceptions import PluginError
|
|
27
|
+
from soothe_sdk.plugin import plugin, subagent, tool
|
|
28
|
+
|
|
29
|
+
__all__ = [
|
|
30
|
+
"YourPlugin",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
logger = logging.getLogger(__name__)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@plugin(
|
|
37
|
+
name="your_plugin",
|
|
38
|
+
version="1.0.0",
|
|
39
|
+
description="Brief description of your plugin",
|
|
40
|
+
dependencies=[
|
|
41
|
+
"required-package>=1.0.0",
|
|
42
|
+
],
|
|
43
|
+
trust_level="standard",
|
|
44
|
+
)
|
|
45
|
+
class YourPlugin:
|
|
46
|
+
"""Your plugin implementation.
|
|
47
|
+
|
|
48
|
+
This plugin provides:
|
|
49
|
+
- Feature 1
|
|
50
|
+
- Feature 2
|
|
51
|
+
- Feature 3
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
async def on_load(self, context: Any) -> None:
|
|
55
|
+
"""Validate dependencies and initialize plugin.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
context: Plugin context with config, logger, and utilities.
|
|
59
|
+
|
|
60
|
+
Raises:
|
|
61
|
+
PluginError: If required dependencies are not installed.
|
|
62
|
+
"""
|
|
63
|
+
context.logger.info("Loading your_plugin...")
|
|
64
|
+
|
|
65
|
+
# Validate dependencies
|
|
66
|
+
missing_deps = []
|
|
67
|
+
|
|
68
|
+
try:
|
|
69
|
+
import required_package # noqa: F401
|
|
70
|
+
except ImportError:
|
|
71
|
+
missing_deps.append("required-package>=1.0.0")
|
|
72
|
+
|
|
73
|
+
if missing_deps:
|
|
74
|
+
msg = (
|
|
75
|
+
f"Missing required dependencies: {', '.join(missing_deps)}. "
|
|
76
|
+
"Install with: pip install soothe-community"
|
|
77
|
+
)
|
|
78
|
+
raise PluginError(msg)
|
|
79
|
+
|
|
80
|
+
context.logger.info("your_plugin loaded successfully")
|
|
81
|
+
|
|
82
|
+
@subagent(
|
|
83
|
+
name="your_agent",
|
|
84
|
+
description=(
|
|
85
|
+
"Detailed description of what your agent does and when to use it. "
|
|
86
|
+
"This helps the orchestrator decide when to invoke your subagent."
|
|
87
|
+
),
|
|
88
|
+
model="openai:gpt-4o-mini",
|
|
89
|
+
)
|
|
90
|
+
async def create_subagent(
|
|
91
|
+
self,
|
|
92
|
+
model: Any,
|
|
93
|
+
config: Any,
|
|
94
|
+
context: Any,
|
|
95
|
+
**kwargs: Any,
|
|
96
|
+
) -> dict[str, Any]:
|
|
97
|
+
"""Create your subagent.
|
|
98
|
+
|
|
99
|
+
Args:
|
|
100
|
+
model: Resolved model (BaseChatModel or string).
|
|
101
|
+
config: Soothe configuration.
|
|
102
|
+
context: Plugin context.
|
|
103
|
+
**kwargs: Additional configuration (store, user_id, etc.).
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
Subagent dict with name, description, and runnable.
|
|
107
|
+
"""
|
|
108
|
+
from .implementation import create_your_subagent
|
|
109
|
+
from .state import YourConfig
|
|
110
|
+
|
|
111
|
+
# Get plugin configuration
|
|
112
|
+
plugin_config = None
|
|
113
|
+
if hasattr(config, "subagents") and "your_agent" in config.subagents:
|
|
114
|
+
subagent_config = config.subagents["your_agent"]
|
|
115
|
+
if subagent_config.enabled and subagent_config.config:
|
|
116
|
+
plugin_config = YourConfig(**subagent_config.config)
|
|
117
|
+
|
|
118
|
+
if not plugin_config:
|
|
119
|
+
plugin_config = YourConfig()
|
|
120
|
+
|
|
121
|
+
# AsyncPersistStore from plugin context (daemon injects persistence)
|
|
122
|
+
store = kwargs.get("store")
|
|
123
|
+
if not store and hasattr(config, "services"):
|
|
124
|
+
store = config.services.get("persistence")
|
|
125
|
+
if not store:
|
|
126
|
+
msg = "your_agent requires AsyncPersistStore (e.g. kwargs['store'] or config.services)"
|
|
127
|
+
raise ValueError(msg)
|
|
128
|
+
|
|
129
|
+
user_id = kwargs.get("user_id", "default")
|
|
130
|
+
|
|
131
|
+
# Create subagent
|
|
132
|
+
subagent_dict = create_your_subagent(
|
|
133
|
+
config=plugin_config,
|
|
134
|
+
store=store,
|
|
135
|
+
user_id=user_id,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
context.logger.info(
|
|
139
|
+
f"Created your_agent subagent for user {user_id}"
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
return subagent_dict
|
|
143
|
+
|
|
144
|
+
@tool(
|
|
145
|
+
name="your_tool",
|
|
146
|
+
description="Brief description of what your tool does",
|
|
147
|
+
)
|
|
148
|
+
def your_tool(self, arg: str) -> str:
|
|
149
|
+
"""Your tool implementation.
|
|
150
|
+
|
|
151
|
+
Args:
|
|
152
|
+
arg: Description of argument.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
Description of return value.
|
|
156
|
+
"""
|
|
157
|
+
# Tool logic here
|
|
158
|
+
return f"Result: {arg}"
|
|
159
|
+
|
|
160
|
+
def get_subagents(self) -> list[Any]:
|
|
161
|
+
"""Get list of subagent factory functions.
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
List containing subagent factory methods.
|
|
165
|
+
"""
|
|
166
|
+
return [self.create_subagent]
|
|
167
|
+
|
|
168
|
+
def get_tools(self) -> list[Any]:
|
|
169
|
+
"""Get list of tool functions.
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
List containing tool methods.
|
|
173
|
+
"""
|
|
174
|
+
return [self.your_tool]
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""Custom events for your plugin.
|
|
2
|
+
|
|
3
|
+
Register plugin-specific events that can be emitted during execution.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Literal
|
|
7
|
+
|
|
8
|
+
from pydantic import ConfigDict
|
|
9
|
+
|
|
10
|
+
from soothe_sdk.core.events import SubagentEvent
|
|
11
|
+
from soothe_sdk.core.verbosity import VerbosityTier
|
|
12
|
+
from soothe_sdk.plugin.registry import register_event
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class YourCustomEvent(SubagentEvent):
|
|
16
|
+
"""Custom event for your plugin.
|
|
17
|
+
|
|
18
|
+
Attributes:
|
|
19
|
+
type: Event type identifier.
|
|
20
|
+
data: Event data.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
type: Literal["soothe.community.your_plugin.custom"] = "soothe.community.your_plugin.custom"
|
|
24
|
+
data: str = ""
|
|
25
|
+
|
|
26
|
+
model_config = ConfigDict(extra="allow")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
# Register events at module load time
|
|
30
|
+
register_event(
|
|
31
|
+
YourCustomEvent,
|
|
32
|
+
verbosity=VerbosityTier.NORMAL,
|
|
33
|
+
summary_template="Your plugin event: {data}",
|
|
34
|
+
)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""Implementation of your plugin's core logic.
|
|
2
|
+
|
|
3
|
+
This module contains the factory function to create your subagent
|
|
4
|
+
and the node functions that make up your agent graph.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from deepagents import CompiledSubAgent
|
|
10
|
+
from langgraph.graph import END, StateGraph
|
|
11
|
+
|
|
12
|
+
from .events import YourCustomEvent
|
|
13
|
+
from .state import YourConfig, YourState
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def create_your_subagent(
|
|
17
|
+
config: YourConfig,
|
|
18
|
+
store: Any = None,
|
|
19
|
+
user_id: str = "default",
|
|
20
|
+
) -> dict[str, Any]:
|
|
21
|
+
"""Create and compile your subagent.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
config: Plugin configuration.
|
|
25
|
+
store: Persistence store for state.
|
|
26
|
+
user_id: User identifier.
|
|
27
|
+
|
|
28
|
+
Returns:
|
|
29
|
+
Dict with name, description, and runnable (CompiledSubAgent).
|
|
30
|
+
"""
|
|
31
|
+
# Create the graph
|
|
32
|
+
graph = StateGraph(YourState)
|
|
33
|
+
|
|
34
|
+
# Add nodes
|
|
35
|
+
graph.add_node("initialize", initialize_node)
|
|
36
|
+
graph.add_node("process", process_node)
|
|
37
|
+
graph.add_node("finalize", finalize_node)
|
|
38
|
+
|
|
39
|
+
# Define edges
|
|
40
|
+
graph.set_entry_point("initialize")
|
|
41
|
+
graph.add_edge("initialize", "process")
|
|
42
|
+
graph.add_edge("process", "finalize")
|
|
43
|
+
graph.add_edge("finalize", END)
|
|
44
|
+
|
|
45
|
+
# Compile the graph
|
|
46
|
+
compiled = graph.compile(
|
|
47
|
+
store=store,
|
|
48
|
+
checkpointer=None, # Add checkpointer if needed
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
"name": "your_agent",
|
|
53
|
+
"description": "What your agent does",
|
|
54
|
+
"runnable": compiled,
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
async def initialize_node(state: YourState) -> dict[str, Any]:
|
|
59
|
+
"""Initialize node: setup and validate input.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
state: Current state.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
State updates.
|
|
66
|
+
"""
|
|
67
|
+
# Initialize processing
|
|
68
|
+
# Validate inputs
|
|
69
|
+
# Setup resources
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
"results": [],
|
|
73
|
+
"errors": [],
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
async def process_node(state: YourState) -> dict[str, Any]:
|
|
78
|
+
"""Process node: main processing logic.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
state: Current state.
|
|
82
|
+
|
|
83
|
+
Returns:
|
|
84
|
+
State updates.
|
|
85
|
+
"""
|
|
86
|
+
# Main processing logic
|
|
87
|
+
# Call external APIs
|
|
88
|
+
# Process data
|
|
89
|
+
|
|
90
|
+
# Emit custom event
|
|
91
|
+
event = YourCustomEvent(data="Processing complete")
|
|
92
|
+
# Note: Events are emitted via the event system
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
"results": [result],
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
async def finalize_node(state: YourState) -> dict[str, Any]:
|
|
100
|
+
"""Finalize node: cleanup and summary.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
state: Current state.
|
|
104
|
+
|
|
105
|
+
Returns:
|
|
106
|
+
State updates.
|
|
107
|
+
"""
|
|
108
|
+
# Cleanup resources
|
|
109
|
+
# Generate summary
|
|
110
|
+
# Prepare output
|
|
111
|
+
|
|
112
|
+
return {}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""Data models for your plugin.
|
|
2
|
+
|
|
3
|
+
Define Pydantic models for structured data used by your plugin.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from datetime import datetime
|
|
7
|
+
from typing import Any, Optional
|
|
8
|
+
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class YourDataModel(BaseModel):
|
|
13
|
+
"""Sample data model.
|
|
14
|
+
|
|
15
|
+
Attributes:
|
|
16
|
+
id: Unique identifier.
|
|
17
|
+
name: Name or title.
|
|
18
|
+
created_at: Creation timestamp.
|
|
19
|
+
metadata: Optional metadata.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
id: str
|
|
23
|
+
name: str
|
|
24
|
+
created_at: datetime = Field(default_factory=datetime.now)
|
|
25
|
+
metadata: Optional[dict[str, Any]] = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class YourResult(BaseModel):
|
|
29
|
+
"""Result model for your plugin operations.
|
|
30
|
+
|
|
31
|
+
Attributes:
|
|
32
|
+
success: Whether operation succeeded.
|
|
33
|
+
data: Result data.
|
|
34
|
+
error: Error message if failed.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
success: bool
|
|
38
|
+
data: Optional[YourDataModel] = None
|
|
39
|
+
error: Optional[str] = None
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""State definitions for your subagent.
|
|
2
|
+
|
|
3
|
+
Define the state that flows through your agent's graph.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Annotated, Any, Optional
|
|
7
|
+
|
|
8
|
+
from langgraph.graph import add_messages
|
|
9
|
+
from pydantic import BaseModel, Field
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class YourConfig(BaseModel):
|
|
13
|
+
"""Configuration for your plugin.
|
|
14
|
+
|
|
15
|
+
Attributes:
|
|
16
|
+
option1: Configuration option 1.
|
|
17
|
+
option2: Configuration option 2.
|
|
18
|
+
max_items: Maximum number of items to process.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
option1: str = "default_value"
|
|
22
|
+
option2: int = 10
|
|
23
|
+
max_items: int = 100
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class YourState(BaseModel):
|
|
27
|
+
"""State for your subagent.
|
|
28
|
+
|
|
29
|
+
This state flows through the agent graph and is updated by nodes.
|
|
30
|
+
|
|
31
|
+
Attributes:
|
|
32
|
+
messages: Conversation messages (for LLM interactions).
|
|
33
|
+
input_data: Input data to process.
|
|
34
|
+
results: Processing results.
|
|
35
|
+
errors: Any errors encountered.
|
|
36
|
+
config: Plugin configuration.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
# Messages for LLM interactions
|
|
40
|
+
messages: Annotated[list[Any], add_messages] = Field(default_factory=list)
|
|
41
|
+
|
|
42
|
+
# Plugin-specific state
|
|
43
|
+
input_data: Optional[Any] = None
|
|
44
|
+
results: list[Any] = Field(default_factory=list)
|
|
45
|
+
errors: list[str] = Field(default_factory=list)
|
|
46
|
+
|
|
47
|
+
# Configuration
|
|
48
|
+
config: YourConfig = Field(default_factory=YourConfig)
|