a4e 0.1.5__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.
- a4e/__init__.py +0 -0
- a4e/cli.py +47 -0
- a4e/cli_commands/__init__.py +5 -0
- a4e/cli_commands/add.py +376 -0
- a4e/cli_commands/deploy.py +149 -0
- a4e/cli_commands/dev.py +162 -0
- a4e/cli_commands/info.py +206 -0
- a4e/cli_commands/init.py +211 -0
- a4e/cli_commands/list.py +227 -0
- a4e/cli_commands/mcp.py +504 -0
- a4e/cli_commands/remove.py +197 -0
- a4e/cli_commands/update.py +285 -0
- a4e/cli_commands/validate.py +117 -0
- a4e/core.py +109 -0
- a4e/dev_runner.py +425 -0
- a4e/server.py +86 -0
- a4e/templates/agent.md.j2 +168 -0
- a4e/templates/agent.py.j2 +15 -0
- a4e/templates/agents.md.j2 +99 -0
- a4e/templates/metadata.json.j2 +20 -0
- a4e/templates/prompt.md.j2 +20 -0
- a4e/templates/prompts/agent.md.j2 +206 -0
- a4e/templates/skills/agents.md.j2 +110 -0
- a4e/templates/skills/skill.md.j2 +120 -0
- a4e/templates/support_module.py.j2 +84 -0
- a4e/templates/tool.py.j2 +60 -0
- a4e/templates/tools/agent.md.j2 +192 -0
- a4e/templates/view.tsx.j2 +21 -0
- a4e/templates/views/agent.md.j2 +219 -0
- a4e/tools/__init__.py +70 -0
- a4e/tools/agent_tools/__init__.py +12 -0
- a4e/tools/agent_tools/add_support_module.py +95 -0
- a4e/tools/agent_tools/add_tool.py +115 -0
- a4e/tools/agent_tools/list_tools.py +28 -0
- a4e/tools/agent_tools/remove_tool.py +69 -0
- a4e/tools/agent_tools/update_tool.py +123 -0
- a4e/tools/deploy/__init__.py +8 -0
- a4e/tools/deploy/deploy.py +59 -0
- a4e/tools/dev/__init__.py +10 -0
- a4e/tools/dev/check_environment.py +79 -0
- a4e/tools/dev/dev_start.py +30 -0
- a4e/tools/dev/dev_stop.py +26 -0
- a4e/tools/project/__init__.py +10 -0
- a4e/tools/project/get_agent_info.py +66 -0
- a4e/tools/project/get_instructions.py +216 -0
- a4e/tools/project/initialize_project.py +231 -0
- a4e/tools/schemas/__init__.py +8 -0
- a4e/tools/schemas/generate_schemas.py +278 -0
- a4e/tools/skills/__init__.py +12 -0
- a4e/tools/skills/add_skill.py +105 -0
- a4e/tools/skills/helpers.py +137 -0
- a4e/tools/skills/list_skills.py +54 -0
- a4e/tools/skills/remove_skill.py +74 -0
- a4e/tools/skills/update_skill.py +150 -0
- a4e/tools/validation/__init__.py +8 -0
- a4e/tools/validation/validate.py +389 -0
- a4e/tools/views/__init__.py +12 -0
- a4e/tools/views/add_view.py +40 -0
- a4e/tools/views/helpers.py +91 -0
- a4e/tools/views/list_views.py +27 -0
- a4e/tools/views/remove_view.py +73 -0
- a4e/tools/views/update_view.py +124 -0
- a4e/utils/dev_manager.py +253 -0
- a4e/utils/schema_generator.py +255 -0
- a4e-0.1.5.dist-info/METADATA +427 -0
- a4e-0.1.5.dist-info/RECORD +70 -0
- a4e-0.1.5.dist-info/WHEEL +5 -0
- a4e-0.1.5.dist-info/entry_points.txt +2 -0
- a4e-0.1.5.dist-info/licenses/LICENSE +21 -0
- a4e-0.1.5.dist-info/top_level.txt +1 -0
a4e/templates/tool.py.j2
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""
|
|
2
|
+
{{ tool_name | replace('_', ' ') | title }} Tool
|
|
3
|
+
|
|
4
|
+
{{ description }}
|
|
5
|
+
"""
|
|
6
|
+
from typing import Dict, Any, Optional
|
|
7
|
+
import sys
|
|
8
|
+
import os
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def _ensure_imports():
|
|
12
|
+
"""
|
|
13
|
+
Add tools directory to sys.path if not already there.
|
|
14
|
+
This enables imports of support files (db.py, models.py, etc.) when exec()'d.
|
|
15
|
+
"""
|
|
16
|
+
if '__file__' in globals():
|
|
17
|
+
tools_dir = os.path.dirname(globals()['__file__'])
|
|
18
|
+
if tools_dir not in sys.path:
|
|
19
|
+
sys.path.insert(0, tools_dir)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def {{ tool_name }}(params: Dict[str, Any]) -> Dict[str, Any]:
|
|
23
|
+
"""
|
|
24
|
+
{{ description }}
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
params: Dictionary containing:
|
|
28
|
+
{% for param_name, param_info in parameters.items() %}
|
|
29
|
+
- {{ param_name }}: {{ param_info.description if param_info.description else param_info.type }}{% if not param_info.is_required %} (optional){% endif %}
|
|
30
|
+
|
|
31
|
+
{% endfor %}
|
|
32
|
+
Returns:
|
|
33
|
+
Dict with operation result
|
|
34
|
+
"""
|
|
35
|
+
# Extract parameters from params dict
|
|
36
|
+
{% for param_name, param_info in parameters.items() %}
|
|
37
|
+
{% if param_info.is_required %}
|
|
38
|
+
{{ param_name }} = params.get("{{ param_name }}")
|
|
39
|
+
{% else %}
|
|
40
|
+
{{ param_name }} = params.get("{{ param_name }}")
|
|
41
|
+
{% endif %}
|
|
42
|
+
{% endfor %}
|
|
43
|
+
|
|
44
|
+
# Ensure imports work in exec() context
|
|
45
|
+
_ensure_imports()
|
|
46
|
+
|
|
47
|
+
# TODO: Implement {{ tool_name }} logic here
|
|
48
|
+
# Example: Import support modules if needed
|
|
49
|
+
# try:
|
|
50
|
+
# import db
|
|
51
|
+
# except ImportError:
|
|
52
|
+
# return {"status": "error", "message": "Database module not available"}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
"status": "success",
|
|
56
|
+
"message": "{{ tool_name | replace('_', ' ') | title }} executed successfully",
|
|
57
|
+
{% for param_name, param_info in parameters.items() %}
|
|
58
|
+
"{{ param_name }}": {{ param_name }},
|
|
59
|
+
{% endfor %}
|
|
60
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# AGENTS.md — Tools Directory
|
|
2
|
+
|
|
3
|
+
> This file provides context and instructions for AI coding agents working on tools in this A4E agent project.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This `tools/` directory contains Python functions decorated with `@tool` that give the agent the ability to perform actions or retrieve information. Each tool is a self-contained Python file that gets automatically discovered and registered.
|
|
8
|
+
|
|
9
|
+
## Directory Structure
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
tools/
|
|
13
|
+
├── AGENTS.md # This file
|
|
14
|
+
├── schemas.json # Auto-generated schemas (do not edit manually)
|
|
15
|
+
├── example_tool.py # Example tool (if template includes it)
|
|
16
|
+
└── <your_tools>.py # Your custom tools
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Code Style
|
|
20
|
+
|
|
21
|
+
- Python 3.11+ required
|
|
22
|
+
- Use type hints for ALL function parameters and return types
|
|
23
|
+
- Use `Optional[T]` for optional parameters, not `T | None`
|
|
24
|
+
- Snake_case for function and file names
|
|
25
|
+
- Each tool must return a `dict` with a clear response structure
|
|
26
|
+
|
|
27
|
+
## Tool Structure
|
|
28
|
+
|
|
29
|
+
Every tool file must follow this pattern:
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from a4e.sdk import tool
|
|
33
|
+
from typing import Optional, List, Any
|
|
34
|
+
|
|
35
|
+
@tool
|
|
36
|
+
def tool_name(
|
|
37
|
+
required_param: str,
|
|
38
|
+
optional_param: Optional[int] = None
|
|
39
|
+
) -> dict:
|
|
40
|
+
"""
|
|
41
|
+
Brief description of what the tool does.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
required_param: Description of this parameter
|
|
45
|
+
optional_param: Description of this optional parameter
|
|
46
|
+
"""
|
|
47
|
+
# Implementation here
|
|
48
|
+
return {
|
|
49
|
+
"status": "success",
|
|
50
|
+
"message": "Result message",
|
|
51
|
+
"data": {} # Optional: include relevant data
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Type Mapping
|
|
56
|
+
|
|
57
|
+
When creating tools, use these Python types:
|
|
58
|
+
|
|
59
|
+
| Use Case | Type | Example |
|
|
60
|
+
| ----------------- | ------------------------ | ------------------------------ |
|
|
61
|
+
| Text | `str` | `name: str` |
|
|
62
|
+
| Integer | `int` | `count: int` |
|
|
63
|
+
| Decimal | `float` | `price: float` |
|
|
64
|
+
| Boolean | `bool` | `active: bool` |
|
|
65
|
+
| List | `List[T]` | `items: List[str]` |
|
|
66
|
+
| Dictionary | `dict` | `config: dict` |
|
|
67
|
+
| Optional | `Optional[T]` | `limit: Optional[int] = None` |
|
|
68
|
+
| Literal choices | `Literal["a", "b"]` | `mode: Literal["fast", "slow"]`|
|
|
69
|
+
| Any type | `Any` | `data: Any` |
|
|
70
|
+
|
|
71
|
+
## Return Value Conventions
|
|
72
|
+
|
|
73
|
+
Always return a dictionary with consistent keys:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
# Success response
|
|
77
|
+
return {
|
|
78
|
+
"status": "success",
|
|
79
|
+
"message": "Human-readable success message",
|
|
80
|
+
"data": {...} # Tool-specific data
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# Error response
|
|
84
|
+
return {
|
|
85
|
+
"status": "error",
|
|
86
|
+
"message": "Human-readable error message",
|
|
87
|
+
"error_code": "SPECIFIC_ERROR" # Optional: machine-readable code
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Naming Conventions
|
|
92
|
+
|
|
93
|
+
- **File names**: `snake_case.py` (e.g., `calculate_bmi.py`, `fetch_weather.py`)
|
|
94
|
+
- **Function names**: Match file name exactly (e.g., `def calculate_bmi(...)`)
|
|
95
|
+
- **Parameter names**: Descriptive snake_case (e.g., `user_weight_kg`, `max_results`)
|
|
96
|
+
|
|
97
|
+
## Adding a New Tool
|
|
98
|
+
|
|
99
|
+
1. Create a new file: `tools/<tool_name>.py`
|
|
100
|
+
2. Use the `@tool` decorator from `a4e.sdk`
|
|
101
|
+
3. Add comprehensive docstring with Args section
|
|
102
|
+
4. Implement the logic returning a dict
|
|
103
|
+
5. Run schema generation to update `schemas.json`
|
|
104
|
+
|
|
105
|
+
## Schema Generation
|
|
106
|
+
|
|
107
|
+
Schemas are auto-generated from your tool code. After adding or modifying tools:
|
|
108
|
+
|
|
109
|
+
- Schemas are regenerated automatically when using MCP tools
|
|
110
|
+
- The `schemas.json` file is auto-generated — **do not edit manually**
|
|
111
|
+
- Docstrings become the tool's description in the schema
|
|
112
|
+
|
|
113
|
+
## Testing Your Tools
|
|
114
|
+
|
|
115
|
+
Before deployment, verify your tools:
|
|
116
|
+
|
|
117
|
+
1. Check syntax: `python -m py_compile tools/<tool_name>.py`
|
|
118
|
+
2. Import test: `python -c "from tools.<tool_name> import <tool_name>; print('OK')"`
|
|
119
|
+
3. Run via dev server to test integration
|
|
120
|
+
|
|
121
|
+
## Common Patterns
|
|
122
|
+
|
|
123
|
+
### API Calls
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
import requests
|
|
127
|
+
|
|
128
|
+
@tool
|
|
129
|
+
def fetch_data(endpoint: str) -> dict:
|
|
130
|
+
"""Fetch data from an API endpoint."""
|
|
131
|
+
try:
|
|
132
|
+
response = requests.get(endpoint, timeout=10)
|
|
133
|
+
response.raise_for_status()
|
|
134
|
+
return {"status": "success", "data": response.json()}
|
|
135
|
+
except Exception as e:
|
|
136
|
+
return {"status": "error", "message": str(e)}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Calculations
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
@tool
|
|
143
|
+
def calculate_bmi(weight_kg: float, height_m: float) -> dict:
|
|
144
|
+
"""Calculate Body Mass Index."""
|
|
145
|
+
if height_m <= 0:
|
|
146
|
+
return {"status": "error", "message": "Height must be positive"}
|
|
147
|
+
|
|
148
|
+
bmi = weight_kg / (height_m ** 2)
|
|
149
|
+
return {
|
|
150
|
+
"status": "success",
|
|
151
|
+
"bmi": round(bmi, 2),
|
|
152
|
+
"category": "normal" if 18.5 <= bmi < 25 else "other"
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Data Transformation
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
from typing import List
|
|
160
|
+
|
|
161
|
+
@tool
|
|
162
|
+
def format_list(items: List[str], separator: str = ", ") -> dict:
|
|
163
|
+
"""Format a list of items into a string."""
|
|
164
|
+
return {
|
|
165
|
+
"status": "success",
|
|
166
|
+
"result": separator.join(items),
|
|
167
|
+
"count": len(items)
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Security Considerations
|
|
172
|
+
|
|
173
|
+
- Never hardcode sensitive data (API keys, passwords)
|
|
174
|
+
- Validate and sanitize all user inputs
|
|
175
|
+
- Use try/except for external calls
|
|
176
|
+
- Limit resource usage (timeouts, max sizes)
|
|
177
|
+
|
|
178
|
+
## Troubleshooting
|
|
179
|
+
|
|
180
|
+
### Tool not appearing in schema
|
|
181
|
+
|
|
182
|
+
- Verify the `@tool` decorator is present
|
|
183
|
+
- Check for syntax errors in the file
|
|
184
|
+
- Ensure the function has type hints and docstring
|
|
185
|
+
- Run schema generation manually
|
|
186
|
+
|
|
187
|
+
### Import errors
|
|
188
|
+
|
|
189
|
+
- Check all imports are available in the environment
|
|
190
|
+
- Use absolute imports when possible
|
|
191
|
+
- Verify dependency is in the project requirements
|
|
192
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { a4e } from "@/lib/sdk";
|
|
4
|
+
|
|
5
|
+
interface {{ view_name }}Props {
|
|
6
|
+
{% for prop_name, prop_info in props.items() %}
|
|
7
|
+
{{ prop_name }}: {{ prop_info.type }};
|
|
8
|
+
{% endfor %}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default function {{ view_name }}View(props: {{ view_name }}Props) {
|
|
12
|
+
const { {% for prop_name in props.keys() %}{{ prop_name }}{% if not loop.last %}, {% endif %}{% endfor %} } = props;
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div className="p-6">
|
|
16
|
+
<h2>{{ description }}</h2>
|
|
17
|
+
{/* View content */}
|
|
18
|
+
<pre>{JSON.stringify(props, null, 2)}</pre>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# AGENTS.md — Views Directory
|
|
2
|
+
|
|
3
|
+
> This file provides context and instructions for AI coding agents working on views in this A4E agent project.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This `views/` directory contains React components that provide rich graphical interfaces for the agent's responses. Each view is a self-contained directory with a `view.tsx` file.
|
|
8
|
+
|
|
9
|
+
## Directory Structure
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
views/
|
|
13
|
+
├── AGENTS.md # This file
|
|
14
|
+
├── schemas.json # Auto-generated schemas (do not edit manually)
|
|
15
|
+
├── welcome/ # Mandatory welcome view
|
|
16
|
+
│ └── view.tsx
|
|
17
|
+
└── <view_id>/ # Your custom views
|
|
18
|
+
└── view.tsx
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Code Style
|
|
22
|
+
|
|
23
|
+
- TypeScript with React
|
|
24
|
+
- Use functional components with hooks
|
|
25
|
+
- camelCase for variables and functions
|
|
26
|
+
- PascalCase for component names
|
|
27
|
+
- Props interface must be explicitly defined
|
|
28
|
+
|
|
29
|
+
## View Structure
|
|
30
|
+
|
|
31
|
+
Every view file must follow this pattern:
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
"use client";
|
|
35
|
+
import React from "react";
|
|
36
|
+
import { a4e } from "@/lib/sdk";
|
|
37
|
+
|
|
38
|
+
interface ViewNameProps {
|
|
39
|
+
title: string;
|
|
40
|
+
count: number;
|
|
41
|
+
items?: string[];
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export default function ViewNameView(props: ViewNameProps) {
|
|
45
|
+
const { title, count, items = [] } = props;
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<div className="p-6">
|
|
49
|
+
<h2 className="text-xl font-bold">{title}</h2>
|
|
50
|
+
<p>Count: {count}</p>
|
|
51
|
+
{items.length > 0 && (
|
|
52
|
+
<ul>
|
|
53
|
+
{items.map((item, i) => (
|
|
54
|
+
<li key={i}>{item}</li>
|
|
55
|
+
))}
|
|
56
|
+
</ul>
|
|
57
|
+
)}
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Naming Conventions
|
|
64
|
+
|
|
65
|
+
- **Directory names**: `snake_case` (e.g., `meal_plan`, `bmi_result`)
|
|
66
|
+
- **Component names**: `PascalCase + View` (e.g., `MealPlanView`, `BmiResultView`)
|
|
67
|
+
- **Prop names**: `camelCase` (e.g., `userName`, `maxItems`)
|
|
68
|
+
|
|
69
|
+
## Type Mapping
|
|
70
|
+
|
|
71
|
+
When defining props, use TypeScript types:
|
|
72
|
+
|
|
73
|
+
| Use Case | Type | Example |
|
|
74
|
+
| ----------------- | ------------------ | --------------------------- |
|
|
75
|
+
| Text | `string` | `title: string` |
|
|
76
|
+
| Integer/Decimal | `number` | `count: number` |
|
|
77
|
+
| Boolean | `boolean` | `isActive: boolean` |
|
|
78
|
+
| Array | `T[]` | `items: string[]` |
|
|
79
|
+
| Object | `object` | `user: object` |
|
|
80
|
+
| Optional | `T?` or `T \| undefined` | `subtitle?: string` |
|
|
81
|
+
| Union | `"a" \| "b"` | `status: "active" \| "inactive"` |
|
|
82
|
+
|
|
83
|
+
## Adding a New View
|
|
84
|
+
|
|
85
|
+
1. Create directory: `views/<view_id>/`
|
|
86
|
+
2. Create file: `views/<view_id>/view.tsx`
|
|
87
|
+
3. Define props interface at the top
|
|
88
|
+
4. Export default functional component
|
|
89
|
+
5. Run schema generation to update `schemas.json`
|
|
90
|
+
|
|
91
|
+
## Schema Generation
|
|
92
|
+
|
|
93
|
+
Schemas are auto-generated from your TypeScript interfaces:
|
|
94
|
+
|
|
95
|
+
- Props interface becomes the view's input schema
|
|
96
|
+
- Type annotations are converted to JSON Schema types
|
|
97
|
+
- Comments become descriptions in the schema
|
|
98
|
+
- The `schemas.json` file is auto-generated — **do not edit manually**
|
|
99
|
+
|
|
100
|
+
## Styling Guidelines
|
|
101
|
+
|
|
102
|
+
Use Tailwind CSS classes for styling:
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
// Good: Tailwind utilities
|
|
106
|
+
<div className="p-4 bg-white rounded-lg shadow-md">
|
|
107
|
+
<h2 className="text-lg font-semibold text-gray-900">Title</h2>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
// Prefer Tailwind over inline styles
|
|
111
|
+
<div className="p-4">Content</div>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Common Patterns
|
|
115
|
+
|
|
116
|
+
### Card Layout
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
export default function CardView(props: { title: string; content: string }) {
|
|
120
|
+
return (
|
|
121
|
+
<div className="bg-white rounded-xl shadow-lg p-6 max-w-md">
|
|
122
|
+
<h3 className="text-xl font-bold mb-4">{props.title}</h3>
|
|
123
|
+
<p className="text-gray-600">{props.content}</p>
|
|
124
|
+
</div>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### List Display
|
|
130
|
+
|
|
131
|
+
```tsx
|
|
132
|
+
interface ListViewProps {
|
|
133
|
+
title: string;
|
|
134
|
+
items: Array<{ id: string; name: string }>;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export default function ListView({ title, items }: ListViewProps) {
|
|
138
|
+
return (
|
|
139
|
+
<div className="space-y-4">
|
|
140
|
+
<h2 className="text-2xl font-bold">{title}</h2>
|
|
141
|
+
<ul className="divide-y divide-gray-200">
|
|
142
|
+
{items.map((item) => (
|
|
143
|
+
<li key={item.id} className="py-3">
|
|
144
|
+
{item.name}
|
|
145
|
+
</li>
|
|
146
|
+
))}
|
|
147
|
+
</ul>
|
|
148
|
+
</div>
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Data Visualization
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
interface ChartViewProps {
|
|
157
|
+
data: Array<{ label: string; value: number }>;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export default function ChartView({ data }: ChartViewProps) {
|
|
161
|
+
return (
|
|
162
|
+
<div className="space-y-2">
|
|
163
|
+
{data.map((item, i) => (
|
|
164
|
+
<div key={i} className="flex items-center gap-4">
|
|
165
|
+
<span className="w-24 text-sm">{item.label}</span>
|
|
166
|
+
<div className="h-6 bg-blue-500 rounded w-full" />
|
|
167
|
+
<span className="text-sm font-medium">{item.value}</span>
|
|
168
|
+
</div>
|
|
169
|
+
))}
|
|
170
|
+
</div>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## A4E SDK Integration
|
|
176
|
+
|
|
177
|
+
Use the A4E SDK for agent interactions:
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
import { a4e } from "@/lib/sdk";
|
|
181
|
+
|
|
182
|
+
export default function InteractiveView(props: { query: string }) {
|
|
183
|
+
const handleAction = async () => {
|
|
184
|
+
// Trigger agent action
|
|
185
|
+
await a4e.triggerAction("perform_search", { query: props.query });
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
return (
|
|
189
|
+
<button onClick={handleAction} className="btn-primary">
|
|
190
|
+
Search
|
|
191
|
+
</button>
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Accessibility
|
|
197
|
+
|
|
198
|
+
- Use semantic HTML elements (`<main>`, `<nav>`, `<article>`)
|
|
199
|
+
- Add `alt` text to images
|
|
200
|
+
- Ensure sufficient color contrast
|
|
201
|
+
- Support keyboard navigation
|
|
202
|
+
- Use ARIA labels where needed
|
|
203
|
+
|
|
204
|
+
## Troubleshooting
|
|
205
|
+
|
|
206
|
+
### View not appearing in schema
|
|
207
|
+
|
|
208
|
+
- Verify the props interface is exported or defined at module level
|
|
209
|
+
- Check for TypeScript syntax errors
|
|
210
|
+
- Ensure the component is the default export
|
|
211
|
+
- Run schema generation manually
|
|
212
|
+
|
|
213
|
+
### Styling not applied
|
|
214
|
+
|
|
215
|
+
- Verify Tailwind classes are valid
|
|
216
|
+
- Check for typos in class names
|
|
217
|
+
- Ensure the build process includes Tailwind
|
|
218
|
+
- Use browser dev tools to inspect applied styles
|
|
219
|
+
|
a4e/tools/__init__.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A4E MCP Tools - All tools for agent creation and management.
|
|
3
|
+
|
|
4
|
+
Structure:
|
|
5
|
+
- project/ : Project initialization (initialize_project, get_agent_info)
|
|
6
|
+
- agent_tools/ : Tool management (add_tool, list_tools, remove_tool, update_tool)
|
|
7
|
+
- views/ : View management (add_view, list_views, remove_view, update_view)
|
|
8
|
+
- skills/ : Skill management (add_skill, list_skills, remove_skill, update_skill)
|
|
9
|
+
- schemas/ : Schema generation (generate_schemas)
|
|
10
|
+
- validation/ : Validation (validate)
|
|
11
|
+
- dev/ : Development server (dev_start, dev_stop, check_environment)
|
|
12
|
+
- deploy/ : Deployment (deploy)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
# Project tools
|
|
16
|
+
from .project import initialize_project, get_agent_info, get_instructions
|
|
17
|
+
|
|
18
|
+
# Agent tools management
|
|
19
|
+
from .agent_tools import add_tool, list_tools, remove_tool, update_tool
|
|
20
|
+
|
|
21
|
+
# Views management
|
|
22
|
+
from .views import add_view, list_views, remove_view, update_view
|
|
23
|
+
|
|
24
|
+
# Skills management
|
|
25
|
+
from .skills import add_skill, list_skills, remove_skill, update_skill
|
|
26
|
+
|
|
27
|
+
# Schema generation
|
|
28
|
+
from .schemas import generate_schemas
|
|
29
|
+
|
|
30
|
+
# Validation
|
|
31
|
+
from .validation import validate
|
|
32
|
+
|
|
33
|
+
# Development
|
|
34
|
+
from .dev import dev_start, dev_stop, check_environment
|
|
35
|
+
|
|
36
|
+
# Deployment
|
|
37
|
+
from .deploy import deploy
|
|
38
|
+
|
|
39
|
+
__all__ = [
|
|
40
|
+
# Project
|
|
41
|
+
"initialize_project",
|
|
42
|
+
"get_agent_info",
|
|
43
|
+
"get_instructions",
|
|
44
|
+
# Agent tools
|
|
45
|
+
"add_tool",
|
|
46
|
+
"list_tools",
|
|
47
|
+
"remove_tool",
|
|
48
|
+
"update_tool",
|
|
49
|
+
# Views
|
|
50
|
+
"add_view",
|
|
51
|
+
"list_views",
|
|
52
|
+
"remove_view",
|
|
53
|
+
"update_view",
|
|
54
|
+
# Skills
|
|
55
|
+
"add_skill",
|
|
56
|
+
"list_skills",
|
|
57
|
+
"remove_skill",
|
|
58
|
+
"update_skill",
|
|
59
|
+
# Schemas
|
|
60
|
+
"generate_schemas",
|
|
61
|
+
# Validation
|
|
62
|
+
"validate",
|
|
63
|
+
# Development
|
|
64
|
+
"dev_start",
|
|
65
|
+
"dev_stop",
|
|
66
|
+
"check_environment",
|
|
67
|
+
# Deployment
|
|
68
|
+
"deploy",
|
|
69
|
+
]
|
|
70
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Agent tools management.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .add_tool import add_tool
|
|
6
|
+
from .add_support_module import add_support_module
|
|
7
|
+
from .list_tools import list_tools
|
|
8
|
+
from .remove_tool import remove_tool
|
|
9
|
+
from .update_tool import update_tool
|
|
10
|
+
|
|
11
|
+
__all__ = ["add_tool", "add_support_module", "list_tools", "remove_tool", "update_tool"]
|
|
12
|
+
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Add support module tool.
|
|
3
|
+
|
|
4
|
+
Creates support modules (db.py, models.py, etc.) with exec() compatibility
|
|
5
|
+
for proper loading in the A4E main application.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Optional
|
|
9
|
+
|
|
10
|
+
from ...core import mcp, jinja_env, get_project_dir
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@mcp.tool()
|
|
14
|
+
def add_support_module(
|
|
15
|
+
module_name: str,
|
|
16
|
+
description: str,
|
|
17
|
+
agent_name: Optional[str] = None
|
|
18
|
+
) -> dict:
|
|
19
|
+
"""
|
|
20
|
+
Add a support module (db.py, models.py, etc.) with exec() compatibility
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
module_name: Name of the module (snake_case, e.g., "db", "models", "helpers")
|
|
24
|
+
description: What the module does
|
|
25
|
+
agent_name: Optional agent ID if not in agent directory
|
|
26
|
+
|
|
27
|
+
Support modules are loaded by all tools and need special handling
|
|
28
|
+
to work in the exec() context used by the A4E main application.
|
|
29
|
+
|
|
30
|
+
The generated module includes:
|
|
31
|
+
- __name__ definition for exec() compatibility
|
|
32
|
+
- sys.path manipulation for imports
|
|
33
|
+
- Self-test code that only runs when executed directly
|
|
34
|
+
"""
|
|
35
|
+
# Validate module name
|
|
36
|
+
if not module_name.replace("_", "").isalnum():
|
|
37
|
+
suggested = module_name.replace("-", "_").replace(" ", "_").lower()
|
|
38
|
+
return {
|
|
39
|
+
"success": False,
|
|
40
|
+
"error": "Module name must be alphanumeric with underscores",
|
|
41
|
+
"fix": f"Try: {suggested}",
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
project_dir = get_project_dir(agent_name)
|
|
45
|
+
tools_dir = project_dir / "tools"
|
|
46
|
+
|
|
47
|
+
if not tools_dir.exists():
|
|
48
|
+
return {
|
|
49
|
+
"success": False,
|
|
50
|
+
"error": f"tools/ directory not found at {tools_dir}",
|
|
51
|
+
"fix": "Initialize an agent first with initialize_project() or specify agent_name",
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module_file = tools_dir / f"{module_name}.py"
|
|
55
|
+
if module_file.exists():
|
|
56
|
+
return {
|
|
57
|
+
"success": False,
|
|
58
|
+
"error": f"Module '{module_name}' already exists",
|
|
59
|
+
"fix": "Edit the existing file or remove it first",
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
# Get agent name for template
|
|
64
|
+
metadata_file = project_dir / "metadata.json"
|
|
65
|
+
agent_display_name = module_name
|
|
66
|
+
if metadata_file.exists():
|
|
67
|
+
import json
|
|
68
|
+
try:
|
|
69
|
+
metadata = json.loads(metadata_file.read_text())
|
|
70
|
+
agent_display_name = metadata.get("name", module_name)
|
|
71
|
+
except Exception:
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
template = jinja_env.get_template("support_module.py.j2")
|
|
75
|
+
code = template.render(
|
|
76
|
+
module_name=module_name,
|
|
77
|
+
description=description,
|
|
78
|
+
agent_name=agent_display_name
|
|
79
|
+
)
|
|
80
|
+
module_file.write_text(code)
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
"success": True,
|
|
84
|
+
"message": f"Created support module '{module_name}' with exec() compatibility",
|
|
85
|
+
"path": str(module_file),
|
|
86
|
+
"notes": [
|
|
87
|
+
"Module includes __name__ fix for exec() context",
|
|
88
|
+
"Module includes sys.path manipulation for imports",
|
|
89
|
+
"Self-test code only runs when executed directly",
|
|
90
|
+
"This module will NOT be included in tools/schemas.json"
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
except Exception as e:
|
|
94
|
+
return {"success": False, "error": str(e)}
|
|
95
|
+
|