re-uploading work
This commit is contained in:
21
packs/core/actions/echo.sh
Executable file
21
packs/core/actions/echo.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/bin/bash
|
||||
# Echo Action - Core Pack
|
||||
# Outputs a message to stdout with optional uppercase conversion
|
||||
|
||||
set -e
|
||||
|
||||
# Parse parameters from environment variables
|
||||
# Attune passes action parameters as environment variables prefixed with ATTUNE_ACTION_
|
||||
MESSAGE="${ATTUNE_ACTION_MESSAGE:-Hello, World!}"
|
||||
UPPERCASE="${ATTUNE_ACTION_UPPERCASE:-false}"
|
||||
|
||||
# Convert to uppercase if requested
|
||||
if [ "$UPPERCASE" = "true" ]; then
|
||||
MESSAGE=$(echo "$MESSAGE" | tr '[:lower:]' '[:upper:]')
|
||||
fi
|
||||
|
||||
# Echo the message
|
||||
echo "$MESSAGE"
|
||||
|
||||
# Exit successfully
|
||||
exit 0
|
||||
51
packs/core/actions/echo.yaml
Normal file
51
packs/core/actions/echo.yaml
Normal file
@@ -0,0 +1,51 @@
|
||||
# Echo Action
|
||||
# Outputs a message to stdout
|
||||
|
||||
name: echo
|
||||
ref: core.echo
|
||||
description: "Echo a message to stdout"
|
||||
enabled: true
|
||||
|
||||
# Runner type determines how the action is executed
|
||||
runner_type: shell
|
||||
|
||||
# Entry point is the shell command or script to execute
|
||||
entry_point: echo.sh
|
||||
|
||||
# Action parameters schema (standard JSON Schema format)
|
||||
parameters:
|
||||
type: object
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
description: "Message to echo"
|
||||
default: "Hello, World!"
|
||||
uppercase:
|
||||
type: boolean
|
||||
description: "Convert message to uppercase before echoing"
|
||||
default: false
|
||||
required:
|
||||
- message
|
||||
|
||||
# Output schema
|
||||
output_schema:
|
||||
type: object
|
||||
properties:
|
||||
stdout:
|
||||
type: string
|
||||
description: "Standard output from the echo command"
|
||||
stderr:
|
||||
type: string
|
||||
description: "Standard error output (usually empty)"
|
||||
exit_code:
|
||||
type: integer
|
||||
description: "Exit code of the command (0 = success)"
|
||||
result:
|
||||
type: string
|
||||
description: "The echoed message"
|
||||
|
||||
# Tags for categorization
|
||||
tags:
|
||||
- utility
|
||||
- testing
|
||||
- debug
|
||||
206
packs/core/actions/http_request.py
Executable file
206
packs/core/actions/http_request.py
Executable file
@@ -0,0 +1,206 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
HTTP Request Action - Core Pack
|
||||
Make HTTP requests to external APIs with support for various methods, headers, and authentication
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
try:
|
||||
import requests
|
||||
from requests.auth import HTTPBasicAuth
|
||||
except ImportError:
|
||||
print(
|
||||
"ERROR: requests library not installed. Run: pip install requests>=2.28.0",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def get_env_param(name: str, default: Any = None, required: bool = False) -> Any:
|
||||
"""Get action parameter from environment variable."""
|
||||
env_key = f"ATTUNE_ACTION_{name.upper()}"
|
||||
value = os.environ.get(env_key, default)
|
||||
|
||||
if required and value is None:
|
||||
raise ValueError(f"Required parameter '{name}' not provided")
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def parse_json_param(name: str, default: Any = None) -> Any:
|
||||
"""Parse JSON parameter from environment variable."""
|
||||
value = get_env_param(name)
|
||||
if value is None:
|
||||
return default
|
||||
|
||||
try:
|
||||
return json.loads(value)
|
||||
except json.JSONDecodeError as e:
|
||||
raise ValueError(f"Invalid JSON for parameter '{name}': {e}")
|
||||
|
||||
|
||||
def parse_bool_param(name: str, default: bool = False) -> bool:
|
||||
"""Parse boolean parameter from environment variable."""
|
||||
value = get_env_param(name)
|
||||
if value is None:
|
||||
return default
|
||||
|
||||
if isinstance(value, bool):
|
||||
return value
|
||||
|
||||
return str(value).lower() in ("true", "1", "yes", "on")
|
||||
|
||||
|
||||
def parse_int_param(name: str, default: int = 0) -> int:
|
||||
"""Parse integer parameter from environment variable."""
|
||||
value = get_env_param(name)
|
||||
if value is None:
|
||||
return default
|
||||
|
||||
try:
|
||||
return int(value)
|
||||
except (ValueError, TypeError):
|
||||
raise ValueError(f"Invalid integer for parameter '{name}': {value}")
|
||||
|
||||
|
||||
def make_http_request() -> Dict[str, Any]:
|
||||
"""Execute HTTP request with provided parameters."""
|
||||
|
||||
# Parse required parameters
|
||||
url = get_env_param("url", required=True)
|
||||
|
||||
# Parse optional parameters
|
||||
method = get_env_param("method", "GET").upper()
|
||||
headers = parse_json_param("headers", {})
|
||||
body = get_env_param("body")
|
||||
json_body = parse_json_param("json_body")
|
||||
query_params = parse_json_param("query_params", {})
|
||||
timeout = parse_int_param("timeout", 30)
|
||||
verify_ssl = parse_bool_param("verify_ssl", True)
|
||||
auth_type = get_env_param("auth_type", "none")
|
||||
follow_redirects = parse_bool_param("follow_redirects", True)
|
||||
max_redirects = parse_int_param("max_redirects", 10)
|
||||
|
||||
# Prepare request kwargs
|
||||
request_kwargs = {
|
||||
"method": method,
|
||||
"url": url,
|
||||
"headers": headers,
|
||||
"params": query_params,
|
||||
"timeout": timeout,
|
||||
"verify": verify_ssl,
|
||||
"allow_redirects": follow_redirects,
|
||||
}
|
||||
|
||||
# Handle authentication
|
||||
if auth_type == "basic":
|
||||
username = get_env_param("auth_username")
|
||||
password = get_env_param("auth_password")
|
||||
if username and password:
|
||||
request_kwargs["auth"] = HTTPBasicAuth(username, password)
|
||||
elif auth_type == "bearer":
|
||||
token = get_env_param("auth_token")
|
||||
if token:
|
||||
request_kwargs["headers"]["Authorization"] = f"Bearer {token}"
|
||||
|
||||
# Handle request body
|
||||
if json_body is not None:
|
||||
request_kwargs["json"] = json_body
|
||||
elif body is not None:
|
||||
request_kwargs["data"] = body
|
||||
|
||||
# Make the request
|
||||
start_time = time.time()
|
||||
|
||||
try:
|
||||
response = requests.request(**request_kwargs)
|
||||
elapsed_ms = int((time.time() - start_time) * 1000)
|
||||
|
||||
# Parse response
|
||||
result = {
|
||||
"status_code": response.status_code,
|
||||
"headers": dict(response.headers),
|
||||
"body": response.text,
|
||||
"elapsed_ms": elapsed_ms,
|
||||
"url": response.url,
|
||||
"success": 200 <= response.status_code < 300,
|
||||
}
|
||||
|
||||
# Try to parse JSON response
|
||||
try:
|
||||
result["json"] = response.json()
|
||||
except (json.JSONDecodeError, ValueError):
|
||||
result["json"] = None
|
||||
|
||||
return result
|
||||
|
||||
except requests.exceptions.Timeout:
|
||||
return {
|
||||
"status_code": 0,
|
||||
"headers": {},
|
||||
"body": "",
|
||||
"json": None,
|
||||
"elapsed_ms": int((time.time() - start_time) * 1000),
|
||||
"url": url,
|
||||
"success": False,
|
||||
"error": "Request timeout",
|
||||
}
|
||||
except requests.exceptions.ConnectionError as e:
|
||||
return {
|
||||
"status_code": 0,
|
||||
"headers": {},
|
||||
"body": "",
|
||||
"json": None,
|
||||
"elapsed_ms": int((time.time() - start_time) * 1000),
|
||||
"url": url,
|
||||
"success": False,
|
||||
"error": f"Connection error: {str(e)}",
|
||||
}
|
||||
except requests.exceptions.RequestException as e:
|
||||
return {
|
||||
"status_code": 0,
|
||||
"headers": {},
|
||||
"body": "",
|
||||
"json": None,
|
||||
"elapsed_ms": int((time.time() - start_time) * 1000),
|
||||
"url": url,
|
||||
"success": False,
|
||||
"error": f"Request error: {str(e)}",
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
"""Main entry point for the action."""
|
||||
try:
|
||||
result = make_http_request()
|
||||
|
||||
# Output result as JSON
|
||||
print(json.dumps(result, indent=2))
|
||||
|
||||
# Exit with success/failure based on HTTP status
|
||||
if result.get("success", False):
|
||||
sys.exit(0)
|
||||
else:
|
||||
# Non-2xx status code or error
|
||||
error = result.get("error")
|
||||
if error:
|
||||
print(f"ERROR: {error}", file=sys.stderr)
|
||||
else:
|
||||
print(
|
||||
f"ERROR: HTTP request failed with status {result.get('status_code')}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERROR: {str(e)}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
119
packs/core/actions/http_request.yaml
Normal file
119
packs/core/actions/http_request.yaml
Normal file
@@ -0,0 +1,119 @@
|
||||
# HTTP Request Action
|
||||
# Make HTTP requests to external APIs
|
||||
|
||||
name: http_request
|
||||
ref: core.http_request
|
||||
description: "Make HTTP requests to external APIs with support for various methods, headers, and authentication"
|
||||
enabled: true
|
||||
|
||||
# Runner type determines how the action is executed
|
||||
runner_type: python
|
||||
|
||||
# Entry point is the Python script to execute
|
||||
entry_point: http_request.py
|
||||
|
||||
# Action parameters schema (standard JSON Schema format)
|
||||
parameters:
|
||||
type: object
|
||||
properties:
|
||||
url:
|
||||
type: string
|
||||
description: "URL to send the request to"
|
||||
method:
|
||||
type: string
|
||||
description: "HTTP method to use"
|
||||
default: "GET"
|
||||
enum:
|
||||
- GET
|
||||
- POST
|
||||
- PUT
|
||||
- PATCH
|
||||
- DELETE
|
||||
- HEAD
|
||||
- OPTIONS
|
||||
headers:
|
||||
type: object
|
||||
description: "HTTP headers to include in the request"
|
||||
default: {}
|
||||
body:
|
||||
type: string
|
||||
description: "Request body (for POST, PUT, PATCH methods)"
|
||||
json_body:
|
||||
type: object
|
||||
description: "JSON request body (alternative to body parameter)"
|
||||
query_params:
|
||||
type: object
|
||||
description: "URL query parameters as key-value pairs"
|
||||
default: {}
|
||||
timeout:
|
||||
type: integer
|
||||
description: "Request timeout in seconds"
|
||||
default: 30
|
||||
minimum: 1
|
||||
maximum: 300
|
||||
verify_ssl:
|
||||
type: boolean
|
||||
description: "Verify SSL certificates"
|
||||
default: true
|
||||
auth_type:
|
||||
type: string
|
||||
description: "Authentication type"
|
||||
enum:
|
||||
- none
|
||||
- basic
|
||||
- bearer
|
||||
auth_username:
|
||||
type: string
|
||||
description: "Username for basic authentication"
|
||||
auth_password:
|
||||
type: string
|
||||
description: "Password for basic authentication"
|
||||
secret: true
|
||||
auth_token:
|
||||
type: string
|
||||
description: "Bearer token for bearer authentication"
|
||||
secret: true
|
||||
follow_redirects:
|
||||
type: boolean
|
||||
description: "Follow HTTP redirects"
|
||||
default: true
|
||||
max_redirects:
|
||||
type: integer
|
||||
description: "Maximum number of redirects to follow"
|
||||
default: 10
|
||||
required:
|
||||
- url
|
||||
|
||||
# Output schema
|
||||
output_schema:
|
||||
type: object
|
||||
properties:
|
||||
status_code:
|
||||
type: integer
|
||||
description: "HTTP status code"
|
||||
headers:
|
||||
type: object
|
||||
description: "Response headers"
|
||||
body:
|
||||
type: string
|
||||
description: "Response body as text"
|
||||
json:
|
||||
type: object
|
||||
description: "Parsed JSON response (if applicable)"
|
||||
elapsed_ms:
|
||||
type: integer
|
||||
description: "Request duration in milliseconds"
|
||||
url:
|
||||
type: string
|
||||
description: "Final URL after redirects"
|
||||
success:
|
||||
type: boolean
|
||||
description: "Whether the request was successful (2xx status code)"
|
||||
|
||||
# Tags for categorization
|
||||
tags:
|
||||
- http
|
||||
- api
|
||||
- web
|
||||
- utility
|
||||
- integration
|
||||
31
packs/core/actions/noop.sh
Executable file
31
packs/core/actions/noop.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
# No Operation Action - Core Pack
|
||||
# Does nothing - useful for testing and placeholder workflows
|
||||
|
||||
set -e
|
||||
|
||||
# Parse parameters from environment variables
|
||||
MESSAGE="${ATTUNE_ACTION_MESSAGE:-}"
|
||||
EXIT_CODE="${ATTUNE_ACTION_EXIT_CODE:-0}"
|
||||
|
||||
# Validate exit code parameter
|
||||
if ! [[ "$EXIT_CODE" =~ ^[0-9]+$ ]]; then
|
||||
echo "ERROR: exit_code must be a positive integer" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$EXIT_CODE" -lt 0 ] || [ "$EXIT_CODE" -gt 255 ]; then
|
||||
echo "ERROR: exit_code must be between 0 and 255" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Log message if provided
|
||||
if [ -n "$MESSAGE" ]; then
|
||||
echo "[NOOP] $MESSAGE"
|
||||
fi
|
||||
|
||||
# Output result
|
||||
echo "No operation completed successfully"
|
||||
|
||||
# Exit with specified code
|
||||
exit "$EXIT_CODE"
|
||||
52
packs/core/actions/noop.yaml
Normal file
52
packs/core/actions/noop.yaml
Normal file
@@ -0,0 +1,52 @@
|
||||
# No Operation Action
|
||||
# Does nothing - useful for testing and placeholder workflows
|
||||
|
||||
name: noop
|
||||
ref: core.noop
|
||||
description: "Does nothing - useful for testing and placeholder workflows"
|
||||
enabled: true
|
||||
|
||||
# Runner type determines how the action is executed
|
||||
runner_type: shell
|
||||
|
||||
# Entry point is the shell command or script to execute
|
||||
entry_point: noop.sh
|
||||
|
||||
# Action parameters schema (standard JSON Schema format)
|
||||
parameters:
|
||||
type: object
|
||||
properties:
|
||||
message:
|
||||
type: string
|
||||
description: "Optional message to log (for debugging)"
|
||||
exit_code:
|
||||
type: integer
|
||||
description: "Exit code to return (default: 0 for success)"
|
||||
default: 0
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
required: []
|
||||
|
||||
# Output schema
|
||||
output_schema:
|
||||
type: object
|
||||
properties:
|
||||
stdout:
|
||||
type: string
|
||||
description: "Standard output (empty unless message provided)"
|
||||
stderr:
|
||||
type: string
|
||||
description: "Standard error output (usually empty)"
|
||||
exit_code:
|
||||
type: integer
|
||||
description: "Exit code of the command"
|
||||
result:
|
||||
type: string
|
||||
description: "Operation result"
|
||||
|
||||
# Tags for categorization
|
||||
tags:
|
||||
- utility
|
||||
- testing
|
||||
- placeholder
|
||||
- noop
|
||||
34
packs/core/actions/sleep.sh
Executable file
34
packs/core/actions/sleep.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# Sleep Action - Core Pack
|
||||
# Pauses execution for a specified duration
|
||||
|
||||
set -e
|
||||
|
||||
# Parse parameters from environment variables
|
||||
SLEEP_SECONDS="${ATTUNE_ACTION_SECONDS:-1}"
|
||||
MESSAGE="${ATTUNE_ACTION_MESSAGE:-}"
|
||||
|
||||
# Validate seconds parameter
|
||||
if ! [[ "$SLEEP_SECONDS" =~ ^[0-9]+$ ]]; then
|
||||
echo "ERROR: seconds must be a positive integer" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$SLEEP_SECONDS" -lt 0 ] || [ "$SLEEP_SECONDS" -gt 3600 ]; then
|
||||
echo "ERROR: seconds must be between 0 and 3600" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Display message if provided
|
||||
if [ -n "$MESSAGE" ]; then
|
||||
echo "$MESSAGE"
|
||||
fi
|
||||
|
||||
# Sleep for the specified duration
|
||||
sleep "$SLEEP_SECONDS"
|
||||
|
||||
# Output result
|
||||
echo "Slept for $SLEEP_SECONDS seconds"
|
||||
|
||||
# Exit successfully
|
||||
exit 0
|
||||
53
packs/core/actions/sleep.yaml
Normal file
53
packs/core/actions/sleep.yaml
Normal file
@@ -0,0 +1,53 @@
|
||||
# Sleep Action
|
||||
# Pauses execution for a specified duration
|
||||
|
||||
name: sleep
|
||||
ref: core.sleep
|
||||
description: "Sleep for a specified number of seconds"
|
||||
enabled: true
|
||||
|
||||
# Runner type determines how the action is executed
|
||||
runner_type: shell
|
||||
|
||||
# Entry point is the shell command or script to execute
|
||||
entry_point: sleep.sh
|
||||
|
||||
# Action parameters schema (standard JSON Schema format)
|
||||
parameters:
|
||||
type: object
|
||||
properties:
|
||||
seconds:
|
||||
type: integer
|
||||
description: "Number of seconds to sleep"
|
||||
default: 1
|
||||
minimum: 0
|
||||
maximum: 3600
|
||||
message:
|
||||
type: string
|
||||
description: "Optional message to display before sleeping"
|
||||
required:
|
||||
- seconds
|
||||
|
||||
# Output schema
|
||||
output_schema:
|
||||
type: object
|
||||
properties:
|
||||
stdout:
|
||||
type: string
|
||||
description: "Standard output (empty unless message provided)"
|
||||
stderr:
|
||||
type: string
|
||||
description: "Standard error output (usually empty)"
|
||||
exit_code:
|
||||
type: integer
|
||||
description: "Exit code of the command (0 = success)"
|
||||
duration:
|
||||
type: integer
|
||||
description: "Number of seconds slept"
|
||||
|
||||
# Tags for categorization
|
||||
tags:
|
||||
- utility
|
||||
- testing
|
||||
- delay
|
||||
- timing
|
||||
Reference in New Issue
Block a user