provision-stack-composio 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,34 @@
1
+ node_modules
2
+ dist
3
+ build
4
+ coverage
5
+
6
+ .env
7
+ .env.*
8
+ !.env.example
9
+
10
+ .turbo
11
+
12
+ .DS_Store
13
+
14
+ .vscode/settings.json
15
+
16
+ *.log
17
+
18
+ # Generated Terraform deployment artifacts (written to user's cwd, not repo)
19
+ terraform/
20
+
21
+ # Local SQLite state (DATABASE_PATH default location)
22
+ data/
23
+
24
+ # Local deploy secrets (NEVER commit — deploy-time env lives here)
25
+ .env.local
26
+ deploy/.env
27
+
28
+ # Host SSH keys + terraform state (local artifacts)
29
+ deploy/hosting/provision-stack-host-key
30
+ deploy/hosting/provision-stack-host-key.pub
31
+ deploy/hosting/.terraform/
32
+ deploy/hosting/terraform.tfstate*
33
+ deploy/hosting/.terraform.lock.hcl
34
+ __pycache__/
@@ -0,0 +1,92 @@
1
+ Metadata-Version: 2.4
2
+ Name: provision-stack-composio
3
+ Version: 0.1.0
4
+ Summary: Composio integration for Provision Stack — deploy cloud infrastructure via AI agents.
5
+ Project-URL: Homepage, https://provision-stack.com
6
+ Project-URL: Documentation, https://docs.provision-stack.com
7
+ Project-URL: Repository, https://github.com/TravisLinkey/provision-stack
8
+ Author: Provision Stack
9
+ License-Expression: MIT
10
+ Keywords: ai-agents,autogen,aws,composio,crewai,gcp,infrastructure,langchain,mcp
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: composio-core>=0.6.0
22
+ Requires-Dist: provision-stack>=0.1.0
23
+ Provides-Extra: test
24
+ Requires-Dist: pytest-mock>=3.12; extra == 'test'
25
+ Requires-Dist: pytest>=8.0; extra == 'test'
26
+ Description-Content-Type: text/markdown
27
+
28
+ # provision-stack-composio
29
+
30
+ > Composio integration for Provision Stack — deploy cloud infrastructure via AI agents.
31
+
32
+ ## Install
33
+
34
+ ```bash
35
+ pip install provision-stack-composio
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ```python
41
+ from composio import ComposioToolSet
42
+ from provision_stack_composio import register_provision_stack_tools
43
+
44
+ toolset = ComposioToolSet()
45
+ register_provision_stack_tools(toolset, api_key="your-token", sandbox=True)
46
+ tools = toolset.get_tools()
47
+
48
+ # Now use with any Composio-supported framework:
49
+ # LangChain, CrewAI, AutoGen, LlamaIndex, etc.
50
+ ```
51
+
52
+ ## What This Does
53
+
54
+ Registers Provision Stack as a Composio integration, making it available
55
+ to any framework that uses Composio. One integration → all frameworks.
56
+
57
+ ## Available Actions
58
+
59
+ | Action | Description |
60
+ |--------|-------------|
61
+ | `PROVISION_STACK_SUGGEST` | Get deployment suggestions with tier options and costs |
62
+ | `PROVISION_STACK_DEPLOY` | Deploy infrastructure (fee held, captured after verification) |
63
+ | `PROVISION_STACK_STATUS` | Check deployment status and verification results |
64
+ | `PROVISION_STACK_DESTROY` | Destroy all resources owned by a deployment |
65
+ | `PROVISION_STACK_BALANCE` | Check account credit balance |
66
+ | `PROVISION_STACK_TOPUP` | Add credits via Stripe or XRP |
67
+
68
+ ## Selective Registration
69
+
70
+ ```python
71
+ # Register only specific actions
72
+ register_provision_stack_tools(
73
+ toolset,
74
+ api_key="your-token",
75
+ actions=["SUGGEST", "DEPLOY"], # only these two
76
+ )
77
+ ```
78
+
79
+ ## Configuration
80
+
81
+ ```python
82
+ register_provision_stack_tools(
83
+ toolset,
84
+ api_key="your-token", # or PROVISION_STACK_API_KEY env var
85
+ base_url="https://...", # or PROVISION_STACK_API_URL env var
86
+ sandbox=True, # use sandbox (mock Terraform)
87
+ )
88
+ ```
89
+
90
+ ## License
91
+
92
+ MIT
@@ -0,0 +1,65 @@
1
+ # provision-stack-composio
2
+
3
+ > Composio integration for Provision Stack — deploy cloud infrastructure via AI agents.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install provision-stack-composio
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```python
14
+ from composio import ComposioToolSet
15
+ from provision_stack_composio import register_provision_stack_tools
16
+
17
+ toolset = ComposioToolSet()
18
+ register_provision_stack_tools(toolset, api_key="your-token", sandbox=True)
19
+ tools = toolset.get_tools()
20
+
21
+ # Now use with any Composio-supported framework:
22
+ # LangChain, CrewAI, AutoGen, LlamaIndex, etc.
23
+ ```
24
+
25
+ ## What This Does
26
+
27
+ Registers Provision Stack as a Composio integration, making it available
28
+ to any framework that uses Composio. One integration → all frameworks.
29
+
30
+ ## Available Actions
31
+
32
+ | Action | Description |
33
+ |--------|-------------|
34
+ | `PROVISION_STACK_SUGGEST` | Get deployment suggestions with tier options and costs |
35
+ | `PROVISION_STACK_DEPLOY` | Deploy infrastructure (fee held, captured after verification) |
36
+ | `PROVISION_STACK_STATUS` | Check deployment status and verification results |
37
+ | `PROVISION_STACK_DESTROY` | Destroy all resources owned by a deployment |
38
+ | `PROVISION_STACK_BALANCE` | Check account credit balance |
39
+ | `PROVISION_STACK_TOPUP` | Add credits via Stripe or XRP |
40
+
41
+ ## Selective Registration
42
+
43
+ ```python
44
+ # Register only specific actions
45
+ register_provision_stack_tools(
46
+ toolset,
47
+ api_key="your-token",
48
+ actions=["SUGGEST", "DEPLOY"], # only these two
49
+ )
50
+ ```
51
+
52
+ ## Configuration
53
+
54
+ ```python
55
+ register_provision_stack_tools(
56
+ toolset,
57
+ api_key="your-token", # or PROVISION_STACK_API_KEY env var
58
+ base_url="https://...", # or PROVISION_STACK_API_URL env var
59
+ sandbox=True, # use sandbox (mock Terraform)
60
+ )
61
+ ```
62
+
63
+ ## License
64
+
65
+ MIT
@@ -0,0 +1,23 @@
1
+ """
2
+ Provision Stack integration for Composio.
3
+
4
+ Composio connects AI agents to 200+ apps and services.
5
+ This integration registers Provision Stack as a Composio tool,
6
+ making it available to LangChain, CrewAI, AutoGen, and other
7
+ frameworks through Composio's tool marketplace.
8
+
9
+ Usage::
10
+
11
+ from composio import ComposioToolSet
12
+ from provision_stack_composio import register_provision_stack_tools
13
+
14
+ toolset = ComposioToolSet()
15
+ register_provision_stack_tools(toolset, api_key="your-token")
16
+ tools = toolset.get_tools()
17
+
18
+ # Now use with any Composio-supported framework
19
+ """
20
+
21
+ from provision_stack_composio.tools import register_provision_stack_tools
22
+
23
+ __all__ = ["register_provision_stack_tools"]
@@ -0,0 +1,269 @@
1
+ """
2
+ Composio tool registration for Provision Stack.
3
+
4
+ Registers Provision Stack actions with the Composio toolset,
5
+ making them available to any framework that uses Composio
6
+ (LangChain, CrewAI, AutoGen, LlamaIndex, etc.).
7
+
8
+ Composio actions follow a specific pattern:
9
+ - Each action has a name, description, and input schema
10
+ - Actions are registered with the ComposioToolSet
11
+ - The toolset handles framework-specific wrapping
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import json
17
+ from typing import Any, Callable
18
+
19
+ from provision_stack.client import ProvisionStackClient
20
+ from provision_stack.config import PRODUCT_NAME
21
+
22
+
23
+ def _register_action(
24
+ toolset: Any,
25
+ name: str,
26
+ description: str,
27
+ schema: dict[str, Any],
28
+ handler: Callable[..., Any],
29
+ ) -> None:
30
+ """
31
+ Register a single action with the Composio toolset.
32
+
33
+ Composio supports custom actions via toolset.set_actions() or
34
+ by defining action classes. This helper handles both patterns.
35
+ """
36
+ try:
37
+ # Composio >=0.6: use set_actions with a dict
38
+ toolset.set_actions(
39
+ {
40
+ name: {
41
+ "description": description,
42
+ "schema": schema,
43
+ "handler": handler,
44
+ }
45
+ }
46
+ )
47
+ except AttributeError:
48
+ # Older Composio: try the action class pattern
49
+ try:
50
+ from composio import Action
51
+
52
+ action_cls = type(
53
+ f"Action{name}",
54
+ (Action,),
55
+ {
56
+ "name": name,
57
+ "description": description,
58
+ "schema": schema,
59
+ "execute": staticmethod(handler),
60
+ },
61
+ )
62
+ toolset.register_action(action_cls)
63
+ except ImportError:
64
+ raise RuntimeError(
65
+ "Composio is not installed. "
66
+ "Install with: pip install composio-core"
67
+ )
68
+
69
+
70
+ def register_provision_stack_tools(
71
+ toolset: Any,
72
+ api_key: str | None = None,
73
+ base_url: str | None = None,
74
+ sandbox: bool = False,
75
+ actions: list[str] | None = None,
76
+ ) -> None:
77
+ """
78
+ Register Provision Stack tools with a Composio toolset.
79
+
80
+ Parameters
81
+ ----------
82
+ toolset : ComposioToolSet
83
+ The Composio toolset to register actions with.
84
+ api_key : str, optional
85
+ API token. Falls back to PROVISION_STACK_API_KEY env var.
86
+ base_url : str, optional
87
+ API base URL. Falls back to env var or default.
88
+ sandbox : bool
89
+ If True, use sandbox (mock Terraform, no real deploys).
90
+ actions : list[str], optional
91
+ Subset of actions to register. None = all actions.
92
+ Options: "SUGGEST", "DEPLOY", "STATUS", "DESTROY",
93
+ "BALANCE", "TOPUP".
94
+
95
+ Examples
96
+ --------
97
+ ::
98
+
99
+ from composio import ComposioToolSet
100
+ from provision_stack_composio import register_provision_stack_tools
101
+
102
+ toolset = ComposioToolSet()
103
+ register_provision_stack_tools(toolset)
104
+ tools = toolset.get_tools()
105
+
106
+ # Register only specific actions
107
+ register_provision_stack_tools(toolset, actions=["SUGGEST", "DEPLOY"])
108
+ """
109
+ client = ProvisionStackClient(
110
+ api_key=api_key, base_url=base_url, sandbox=sandbox
111
+ )
112
+
113
+ all_actions = {
114
+ "SUGGEST": {
115
+ "name": "PROVISION_STACK_SUGGEST",
116
+ "description": (
117
+ f"Get deployment suggestions from {PRODUCT_NAME}. "
118
+ "Returns tier options (Starter/MVP/Startup/Enterprise) "
119
+ "with monthly cost estimates across cloud providers."
120
+ ),
121
+ "schema": {
122
+ "type": "object",
123
+ "properties": {
124
+ "outcome": {
125
+ "type": "string",
126
+ "description": "Natural language description of desired infrastructure",
127
+ },
128
+ "region": {
129
+ "type": "string",
130
+ "description": "Cloud region (e.g. 'us-east-1')",
131
+ },
132
+ "provider": {
133
+ "type": "string",
134
+ "enum": ["aws", "gcp", "azure", "oracle"],
135
+ "description": "Restrict to one provider",
136
+ },
137
+ "max_monthly_cost_usd": {
138
+ "type": "number",
139
+ "description": "Monthly cost cap in USD",
140
+ },
141
+ },
142
+ "required": ["outcome"],
143
+ },
144
+ "handler": lambda outcome, region=None, provider=None,
145
+ max_monthly_cost_usd=None, **kw: client.suggest(
146
+ outcome=outcome,
147
+ region=region,
148
+ provider=provider,
149
+ max_monthly_cost_usd=max_monthly_cost_usd,
150
+ ),
151
+ },
152
+ "DEPLOY": {
153
+ "name": "PROVISION_STACK_DEPLOY",
154
+ "description": (
155
+ f"Deploy infrastructure via {PRODUCT_NAME}. "
156
+ "Fee held from balance, captured after verification."
157
+ ),
158
+ "schema": {
159
+ "type": "object",
160
+ "properties": {
161
+ "outcome": {
162
+ "type": "string",
163
+ "description": "What to deploy",
164
+ },
165
+ "tier": {
166
+ "type": "string",
167
+ "enum": ["Starter", "MVP", "Startup", "Enterprise"],
168
+ "description": "Deployment tier",
169
+ },
170
+ "region": {
171
+ "type": "string",
172
+ "description": "Target region",
173
+ },
174
+ "max_monthly_cost_usd": {
175
+ "type": "number",
176
+ "description": "Monthly cost cap",
177
+ },
178
+ },
179
+ "required": ["outcome"],
180
+ },
181
+ "handler": lambda outcome, tier=None, region=None,
182
+ max_monthly_cost_usd=None, **kw: client.deploy(
183
+ outcome=outcome,
184
+ tier=tier,
185
+ region=region,
186
+ max_monthly_cost_usd=max_monthly_cost_usd,
187
+ ),
188
+ },
189
+ "STATUS": {
190
+ "name": "PROVISION_STACK_STATUS",
191
+ "description": f"Check status of a {PRODUCT_NAME} deployment.",
192
+ "schema": {
193
+ "type": "object",
194
+ "properties": {
195
+ "deployment_id": {
196
+ "type": "string",
197
+ "description": "Deployment ID to check",
198
+ },
199
+ },
200
+ "required": ["deployment_id"],
201
+ },
202
+ "handler": lambda deployment_id, **kw: client.status(deployment_id),
203
+ },
204
+ "DESTROY": {
205
+ "name": "PROVISION_STACK_DESTROY",
206
+ "description": f"Destroy all resources in a {PRODUCT_NAME} deployment.",
207
+ "schema": {
208
+ "type": "object",
209
+ "properties": {
210
+ "deployment_id": {
211
+ "type": "string",
212
+ "description": "Deployment ID to destroy",
213
+ },
214
+ },
215
+ "required": ["deployment_id"],
216
+ },
217
+ "handler": lambda deployment_id, **kw: client.destroy(deployment_id),
218
+ },
219
+ "BALANCE": {
220
+ "name": "PROVISION_STACK_BALANCE",
221
+ "description": f"Check {PRODUCT_NAME} account credit balance.",
222
+ "schema": {
223
+ "type": "object",
224
+ "properties": {},
225
+ },
226
+ "handler": lambda **kw: client.balance(),
227
+ },
228
+ "TOPUP": {
229
+ "name": "PROVISION_STACK_TOPUP",
230
+ "description": f"Add credits to {PRODUCT_NAME} account.",
231
+ "schema": {
232
+ "type": "object",
233
+ "properties": {
234
+ "amount_usd": {
235
+ "type": "number",
236
+ "description": "Amount in USD",
237
+ },
238
+ "rail": {
239
+ "type": "string",
240
+ "enum": ["stripe", "xrp"],
241
+ "description": "Payment method",
242
+ },
243
+ },
244
+ "required": ["amount_usd"],
245
+ },
246
+ "handler": lambda amount_usd, rail="stripe", **kw: (
247
+ client.topup_xrp(amount_usd) if rail == "xrp"
248
+ else client.topup_stripe(amount_usd)
249
+ ),
250
+ },
251
+ }
252
+
253
+ # Register requested actions
254
+ to_register = actions or list(all_actions.keys())
255
+
256
+ for action_key in to_register:
257
+ action = all_actions.get(action_key)
258
+ if action is None:
259
+ raise ValueError(
260
+ f"Unknown action: {action_key}. "
261
+ f"Available: {list(all_actions.keys())}"
262
+ )
263
+ _register_action(
264
+ toolset,
265
+ name=action["name"],
266
+ description=action["description"],
267
+ schema=action["schema"],
268
+ handler=action["handler"],
269
+ )
@@ -0,0 +1,54 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "provision-stack-composio"
7
+ version = "0.1.0"
8
+ description = "Composio integration for Provision Stack — deploy cloud infrastructure via AI agents."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ { name = "Provision Stack" },
14
+ ]
15
+ keywords = [
16
+ "composio",
17
+ "ai-agents",
18
+ "infrastructure",
19
+ "aws",
20
+ "gcp",
21
+ "mcp",
22
+ "langchain",
23
+ "crewai",
24
+ "autogen",
25
+ ]
26
+ classifiers = [
27
+ "Development Status :: 4 - Beta",
28
+ "Intended Audience :: Developers",
29
+ "License :: OSI Approved :: MIT License",
30
+ "Programming Language :: Python :: 3",
31
+ "Programming Language :: Python :: 3.10",
32
+ "Programming Language :: Python :: 3.11",
33
+ "Programming Language :: Python :: 3.12",
34
+ "Programming Language :: Python :: 3.13",
35
+ "Topic :: Software Development :: Libraries :: Python Modules",
36
+ ]
37
+ dependencies = [
38
+ "provision-stack>=0.1.0",
39
+ "composio-core>=0.6.0",
40
+ ]
41
+
42
+ [project.urls]
43
+ Homepage = "https://provision-stack.com"
44
+ Documentation = "https://docs.provision-stack.com"
45
+ Repository = "https://github.com/TravisLinkey/provision-stack"
46
+
47
+ [project.optional-dependencies]
48
+ test = [
49
+ "pytest>=8.0",
50
+ "pytest-mock>=3.12",
51
+ ]
52
+
53
+ [tool.pytest.ini_options]
54
+ testpaths = ["tests"]
@@ -0,0 +1,104 @@
1
+ """Tests for provision_stack_composio.tools — Composio integration."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+ from unittest.mock import MagicMock
7
+ import pytest
8
+
9
+ # Mock composio before importing our tools
10
+ mock_composio = MagicMock()
11
+ sys.modules.setdefault("composio", mock_composio)
12
+
13
+ from provision_stack_composio.tools import register_provision_stack_tools
14
+
15
+
16
+ # ── Registration ──────────────────────────────────────────────────
17
+
18
+
19
+ class TestRegisterProvisionStackTools:
20
+ def test_registers_all_actions_by_default(self):
21
+ mock_toolset = MagicMock()
22
+ register_provision_stack_tools(mock_toolset, api_key="test")
23
+ # set_actions is called once per action (6 times total)
24
+ assert mock_toolset.set_actions.call_count == 6
25
+
26
+ def test_registers_subset_when_specified(self):
27
+ mock_toolset = MagicMock()
28
+ register_provision_stack_tools(
29
+ mock_toolset, api_key="test", actions=["SUGGEST", "DEPLOY"]
30
+ )
31
+ assert mock_toolset.set_actions.call_count == 2
32
+ # Check both calls contain the right action names
33
+ registered = set()
34
+ for call in mock_toolset.set_actions.call_args_list:
35
+ registered.update(call[0][0].keys())
36
+ assert registered == {"PROVISION_STACK_SUGGEST", "PROVISION_STACK_DEPLOY"}
37
+
38
+ def test_raises_on_unknown_action(self):
39
+ mock_toolset = MagicMock()
40
+ with pytest.raises(ValueError, match="Unknown action"):
41
+ register_provision_stack_tools(
42
+ mock_toolset, api_key="test", actions=["FAKE_ACTION"]
43
+ )
44
+
45
+ def test_actions_have_schemas(self):
46
+ mock_toolset = MagicMock()
47
+ register_provision_stack_tools(mock_toolset, api_key="test")
48
+ for call in mock_toolset.set_actions.call_args_list:
49
+ action = call[0][0]
50
+ name = list(action.keys())[0]
51
+ assert "schema" in action[name], f"{name} missing schema"
52
+ assert "properties" in action[name]["schema"], f"{name} schema missing properties"
53
+
54
+ def test_actions_have_handlers(self):
55
+ mock_toolset = MagicMock()
56
+ register_provision_stack_tools(mock_toolset, api_key="test")
57
+ for call in mock_toolset.set_actions.call_args_list:
58
+ action = call[0][0]
59
+ name = list(action.keys())[0]
60
+ assert "handler" in action[name], f"{name} missing handler"
61
+ assert callable(action[name]["handler"]), f"{name} handler not callable"
62
+
63
+ def test_actions_have_descriptions(self):
64
+ mock_toolset = MagicMock()
65
+ register_provision_stack_tools(mock_toolset, api_key="test")
66
+ for call in mock_toolset.set_actions.call_args_list:
67
+ action = call[0][0]
68
+ name = list(action.keys())[0]
69
+ assert "description" in action[name], f"{name} missing description"
70
+ assert len(action[name]["description"]) > 10
71
+
72
+ def _get_action(self, mock_toolset, action_name: str) -> dict:
73
+ """Retrieve a specific action dict from the set_actions calls."""
74
+ for call in mock_toolset.set_actions.call_args_list:
75
+ action = call[0][0]
76
+ if action_name in action:
77
+ return action[action_name]
78
+ raise KeyError(f"{action_name} not found in set_actions calls")
79
+
80
+ def test_suggest_action_schema_has_outcome(self):
81
+ mock_toolset = MagicMock()
82
+ register_provision_stack_tools(mock_toolset, api_key="test")
83
+ suggest = self._get_action(mock_toolset, "PROVISION_STACK_SUGGEST")
84
+ assert "outcome" in suggest["schema"]["properties"]
85
+
86
+ def test_deploy_action_schema_has_outcome(self):
87
+ mock_toolset = MagicMock()
88
+ register_provision_stack_tools(mock_toolset, api_key="test")
89
+ deploy = self._get_action(mock_toolset, "PROVISION_STACK_DEPLOY")
90
+ assert "outcome" in deploy["schema"]["properties"]
91
+
92
+ def test_status_action_schema_has_deployment_id(self):
93
+ mock_toolset = MagicMock()
94
+ register_provision_stack_tools(mock_toolset, api_key="test")
95
+ status = self._get_action(mock_toolset, "PROVISION_STACK_STATUS")
96
+ assert "deployment_id" in status["schema"]["properties"]
97
+ assert "deployment_id" in status["schema"]["required"]
98
+
99
+ def test_topup_action_schema_has_amount(self):
100
+ mock_toolset = MagicMock()
101
+ register_provision_stack_tools(mock_toolset, api_key="test")
102
+ topup = self._get_action(mock_toolset, "PROVISION_STACK_TOPUP")
103
+ assert "amount_usd" in topup["schema"]["properties"]
104
+ assert "amount_usd" in topup["schema"]["required"]