composio-strale 0.1.4__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,20 @@
1
+ node_modules/
2
+ dist/
3
+ .env
4
+ .env.local
5
+ .env.production
6
+ *.log
7
+ .DS_Store
8
+ .turbo
9
+ coverage/
10
+ __pycache__/
11
+ *.pyc
12
+ *.egg-info/
13
+ .venv/
14
+ build/
15
+ *.whl
16
+ *.tar.gz
17
+ strale-frontend/
18
+
19
+ # Claude Code settings (contains local API keys)
20
+ .claude/
@@ -0,0 +1,111 @@
1
+ Metadata-Version: 2.4
2
+ Name: composio-strale
3
+ Version: 0.1.4
4
+ Summary: Composio integration for Strale — 270+ business capabilities as agent tools
5
+ Project-URL: Homepage, https://strale.dev
6
+ Project-URL: Repository, https://github.com/strale-io/strale/tree/main/packages/composio-strale
7
+ Project-URL: Documentation, https://strale.dev/docs
8
+ Author-email: Strale <hello@strale.io>
9
+ License-Expression: MIT
10
+ Keywords: agent,ai,capabilities,compliance,composio,mcp,strale,tools,web3
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>=0.7.0
22
+ Requires-Dist: httpx>=0.24.0
23
+ Requires-Dist: pydantic>=2.0.0
24
+ Description-Content-Type: text/markdown
25
+
26
+ # composio-strale
27
+
28
+ [Composio](https://composio.dev) integration for [Strale](https://strale.dev) — 270+ quality-scored API capabilities as Composio custom tools.
29
+
30
+ ## Install
31
+
32
+ ```bash
33
+ pip install composio-strale
34
+ ```
35
+
36
+ ## Quick start
37
+
38
+ ```python
39
+ from composio import Composio
40
+ from composio_strale import register_strale_tools
41
+
42
+ composio = Composio()
43
+ register_strale_tools(composio, api_key="sk_live_...")
44
+
45
+ # Search for capabilities
46
+ result = composio.tools.execute(
47
+ user_id="default",
48
+ slug="STRALE_SEARCH",
49
+ arguments={"query": "sanctions screening"},
50
+ )
51
+
52
+ # Execute a capability
53
+ result = composio.tools.execute(
54
+ user_id="default",
55
+ slug="STRALE_EXECUTE",
56
+ arguments={
57
+ "capability_slug": "sanctions-check",
58
+ "inputs": {"name": "Acme Corp"},
59
+ },
60
+ )
61
+ ```
62
+
63
+ ## Use with an agent
64
+
65
+ ```python
66
+ from composio import Composio
67
+ from composio_openai import OpenAIProvider
68
+ from composio_strale import register_strale_tools
69
+
70
+ composio = Composio(provider=OpenAIProvider())
71
+ register_strale_tools(composio)
72
+
73
+ tools = composio.tools.get(user_id="default", toolkits=["strale"])
74
+
75
+ from openai import OpenAI
76
+ client = OpenAI()
77
+ response = client.chat.completions.create(
78
+ model="gpt-4o",
79
+ tools=tools,
80
+ messages=[{"role": "user", "content": "Run a sanctions check on 'Acme Corp'"}],
81
+ )
82
+ ```
83
+
84
+ ## What's included
85
+
86
+ Three tools registered under the `strale` toolkit:
87
+
88
+ | Tool | Description |
89
+ |------|-------------|
90
+ | `STRALE_SEARCH` | Search 270+ capabilities by keyword or category |
91
+ | `STRALE_EXECUTE` | Execute any capability with structured input |
92
+ | `STRALE_BALANCE` | Check your wallet balance |
93
+
94
+ ## Get an API key
95
+
96
+ Sign up at [strale.dev](https://strale.dev) — new accounts get €2.00 trial credits, no card required.
97
+
98
+ ## x402 pay-per-use access
99
+
100
+ All Strale capabilities are also available via [x402](https://x402.org) — the HTTP-native payment protocol for AI agents. Pay per request with USDC on Base mainnet. No signup or API key needed.
101
+
102
+ - Catalog: https://api.strale.io/x402/catalog
103
+ - Protocol: USDC on Base (eip155:8453)
104
+ - Discovery: https://api.strale.io/.well-known/x402.json
105
+
106
+ ## Resources
107
+
108
+ - [Documentation](https://strale.dev/docs)
109
+ - [Examples](https://github.com/strale-io/strale-examples)
110
+ - [Pricing](https://strale.dev/pricing)
111
+ - [Quality methodology](https://strale.dev/methodology)
@@ -0,0 +1,86 @@
1
+ # composio-strale
2
+
3
+ [Composio](https://composio.dev) integration for [Strale](https://strale.dev) — 270+ quality-scored API capabilities as Composio custom tools.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pip install composio-strale
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ ```python
14
+ from composio import Composio
15
+ from composio_strale import register_strale_tools
16
+
17
+ composio = Composio()
18
+ register_strale_tools(composio, api_key="sk_live_...")
19
+
20
+ # Search for capabilities
21
+ result = composio.tools.execute(
22
+ user_id="default",
23
+ slug="STRALE_SEARCH",
24
+ arguments={"query": "sanctions screening"},
25
+ )
26
+
27
+ # Execute a capability
28
+ result = composio.tools.execute(
29
+ user_id="default",
30
+ slug="STRALE_EXECUTE",
31
+ arguments={
32
+ "capability_slug": "sanctions-check",
33
+ "inputs": {"name": "Acme Corp"},
34
+ },
35
+ )
36
+ ```
37
+
38
+ ## Use with an agent
39
+
40
+ ```python
41
+ from composio import Composio
42
+ from composio_openai import OpenAIProvider
43
+ from composio_strale import register_strale_tools
44
+
45
+ composio = Composio(provider=OpenAIProvider())
46
+ register_strale_tools(composio)
47
+
48
+ tools = composio.tools.get(user_id="default", toolkits=["strale"])
49
+
50
+ from openai import OpenAI
51
+ client = OpenAI()
52
+ response = client.chat.completions.create(
53
+ model="gpt-4o",
54
+ tools=tools,
55
+ messages=[{"role": "user", "content": "Run a sanctions check on 'Acme Corp'"}],
56
+ )
57
+ ```
58
+
59
+ ## What's included
60
+
61
+ Three tools registered under the `strale` toolkit:
62
+
63
+ | Tool | Description |
64
+ |------|-------------|
65
+ | `STRALE_SEARCH` | Search 270+ capabilities by keyword or category |
66
+ | `STRALE_EXECUTE` | Execute any capability with structured input |
67
+ | `STRALE_BALANCE` | Check your wallet balance |
68
+
69
+ ## Get an API key
70
+
71
+ Sign up at [strale.dev](https://strale.dev) — new accounts get €2.00 trial credits, no card required.
72
+
73
+ ## x402 pay-per-use access
74
+
75
+ All Strale capabilities are also available via [x402](https://x402.org) — the HTTP-native payment protocol for AI agents. Pay per request with USDC on Base mainnet. No signup or API key needed.
76
+
77
+ - Catalog: https://api.strale.io/x402/catalog
78
+ - Protocol: USDC on Base (eip155:8453)
79
+ - Discovery: https://api.strale.io/.well-known/x402.json
80
+
81
+ ## Resources
82
+
83
+ - [Documentation](https://strale.dev/docs)
84
+ - [Examples](https://github.com/strale-io/strale-examples)
85
+ - [Pricing](https://strale.dev/pricing)
86
+ - [Quality methodology](https://strale.dev/methodology)
@@ -0,0 +1,5 @@
1
+ """composio-strale — 270+ Strale capabilities as Composio custom tools."""
2
+
3
+ from .toolkit import register_strale_tools, StraleToolkit
4
+
5
+ __all__ = ["register_strale_tools", "StraleToolkit"]
@@ -0,0 +1,178 @@
1
+ """Register Strale capabilities as Composio custom tools."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from typing import Any, Optional
7
+
8
+ import httpx
9
+ from pydantic import BaseModel, Field
10
+
11
+
12
+ _BASE_URL = "https://api.strale.io"
13
+
14
+
15
+ class StraleSearchInput(BaseModel):
16
+ query: str = Field(..., description="Search keyword (e.g., 'sanctions', 'IBAN', 'company data')")
17
+ category: Optional[str] = Field(
18
+ None,
19
+ description="Filter by category: compliance, validation, web3, company-data, finance, developer-tools",
20
+ )
21
+
22
+
23
+ class StraleExecuteInput(BaseModel):
24
+ capability_slug: str = Field(
25
+ ...,
26
+ description="Capability slug from strale_search results (e.g., 'sanctions-check', 'iban-validate')",
27
+ )
28
+ inputs: dict = Field(
29
+ ...,
30
+ description="Input parameters matching the capability's required fields",
31
+ )
32
+ max_price_cents: int = Field(
33
+ 200,
34
+ description="Maximum price in EUR cents. Default: 200 (€2.00). Execution fails if capability costs more.",
35
+ )
36
+
37
+
38
+ class StraleBalanceInput(BaseModel):
39
+ pass
40
+
41
+
42
+ class StraleToolkit:
43
+ """Registers Strale tools with a Composio instance.
44
+
45
+ Usage::
46
+
47
+ from composio import Composio
48
+ from composio_strale import StraleToolkit
49
+
50
+ composio = Composio()
51
+ toolkit = StraleToolkit(api_key="sk_live_...")
52
+ toolkit.register(composio)
53
+
54
+ # Now use composio.tools.get() or composio.tools.execute() with Strale tools
55
+ result = composio.tools.execute(
56
+ user_id="default",
57
+ slug="STRALE_EXECUTE",
58
+ arguments={
59
+ "capability_slug": "iban-validate",
60
+ "inputs": {"iban": "DE89370400440532013000"},
61
+ },
62
+ )
63
+ """
64
+
65
+ def __init__(
66
+ self,
67
+ api_key: str | None = None,
68
+ base_url: str = _BASE_URL,
69
+ ):
70
+ self.api_key = api_key or os.environ.get("STRALE_API_KEY", "")
71
+ self.base_url = base_url.rstrip("/")
72
+
73
+ def _headers(self) -> dict[str, str]:
74
+ h: dict[str, str] = {"Content-Type": "application/json", "Accept": "application/json"}
75
+ if self.api_key:
76
+ h["Authorization"] = f"Bearer {self.api_key}"
77
+ return h
78
+
79
+ def register(self, composio: Any) -> None:
80
+ """Register all Strale tools with the given Composio instance."""
81
+ toolkit = self # capture for closures
82
+
83
+ @composio.tools.custom_tool(toolkit="strale")
84
+ def strale_search(request: StraleSearchInput) -> dict:
85
+ """Search Strale's 270+ API capabilities. Returns matching capabilities with slugs, descriptions, and pricing. Use this first to discover available capabilities, then use strale_execute to run one."""
86
+ params = {"q": request.query, "limit": "10"}
87
+ if request.category:
88
+ params["category"] = request.category
89
+ resp = httpx.get(
90
+ f"{toolkit.base_url}/v1/suggest/typeahead",
91
+ params=params,
92
+ headers=toolkit._headers(),
93
+ timeout=10,
94
+ )
95
+ if resp.status_code == 200:
96
+ data = resp.json()
97
+ return {
98
+ "capabilities": [
99
+ {
100
+ "slug": c.get("slug"),
101
+ "name": c.get("name"),
102
+ "description": c.get("description", "")[:120],
103
+ "price_cents": c.get("price_cents"),
104
+ "category": c.get("category"),
105
+ }
106
+ for c in data.get("suggestions", data.get("capabilities", []))
107
+ ]
108
+ }
109
+ # Fallback to keyword search
110
+ resp2 = httpx.get(
111
+ f"{toolkit.base_url}/v1/capabilities",
112
+ params={"search": request.query},
113
+ headers={"Accept": "application/json"},
114
+ timeout=10,
115
+ )
116
+ if resp2.status_code != 200:
117
+ return {"error": f"Search failed: HTTP {resp2.status_code}"}
118
+ caps = resp2.json().get("capabilities", [])
119
+ return {
120
+ "capabilities": [
121
+ {
122
+ "slug": c["slug"],
123
+ "name": c["name"],
124
+ "description": c.get("description", "")[:120],
125
+ "price_cents": c.get("price_cents"),
126
+ }
127
+ for c in caps[:10]
128
+ ]
129
+ }
130
+
131
+ @composio.tools.custom_tool(toolkit="strale")
132
+ def strale_execute(request: StraleExecuteInput) -> dict:
133
+ """Execute a Strale capability. Pass the slug from strale_search and the required inputs. Returns structured output with quality score, latency, and data provenance."""
134
+ if not toolkit.api_key:
135
+ return {"error": "STRALE_API_KEY required. Get one at https://strale.dev/signup (€2 free credits)."}
136
+ resp = httpx.post(
137
+ f"{toolkit.base_url}/v1/do",
138
+ json={
139
+ "capability_slug": request.capability_slug,
140
+ "inputs": request.inputs,
141
+ "max_price_cents": request.max_price_cents,
142
+ },
143
+ headers=toolkit._headers(),
144
+ timeout=30,
145
+ )
146
+ return resp.json()
147
+
148
+ @composio.tools.custom_tool(toolkit="strale")
149
+ def strale_balance(request: StraleBalanceInput) -> dict:
150
+ """Check your Strale wallet balance in EUR cents."""
151
+ if not toolkit.api_key:
152
+ return {"error": "STRALE_API_KEY required."}
153
+ resp = httpx.get(
154
+ f"{toolkit.base_url}/v1/wallet/balance",
155
+ headers=toolkit._headers(),
156
+ timeout=10,
157
+ )
158
+ return resp.json()
159
+
160
+
161
+ def register_strale_tools(
162
+ composio: Any,
163
+ api_key: str | None = None,
164
+ base_url: str = _BASE_URL,
165
+ ) -> StraleToolkit:
166
+ """Convenience function: create a StraleToolkit and register it.
167
+
168
+ Usage::
169
+
170
+ from composio import Composio
171
+ from composio_strale import register_strale_tools
172
+
173
+ composio = Composio()
174
+ register_strale_tools(composio, api_key="sk_live_...")
175
+ """
176
+ toolkit = StraleToolkit(api_key=api_key, base_url=base_url)
177
+ toolkit.register(composio)
178
+ return toolkit
@@ -0,0 +1,46 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "composio-strale"
7
+ version = "0.1.4"
8
+ description = "Composio integration for Strale — 270+ business capabilities as agent tools"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ { name = "Strale", email = "hello@strale.io" },
14
+ ]
15
+ keywords = [
16
+ "composio",
17
+ "strale",
18
+ "ai",
19
+ "agent",
20
+ "tools",
21
+ "capabilities",
22
+ "compliance",
23
+ "web3",
24
+ "mcp",
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
+ "composio>=0.7.0",
39
+ "httpx>=0.24.0",
40
+ "pydantic>=2.0.0",
41
+ ]
42
+
43
+ [project.urls]
44
+ Homepage = "https://strale.dev"
45
+ Repository = "https://github.com/strale-io/strale/tree/main/packages/composio-strale"
46
+ Documentation = "https://strale.dev/docs"
@@ -0,0 +1,33 @@
1
+ """Basic import and structure tests for composio-strale."""
2
+
3
+ import os
4
+ import unittest
5
+
6
+
7
+ class TestImport(unittest.TestCase):
8
+ def test_import(self):
9
+ from composio_strale import StraleToolkit, register_strale_tools
10
+ assert StraleToolkit is not None
11
+ assert register_strale_tools is not None
12
+
13
+ def test_toolkit_init(self):
14
+ from composio_strale import StraleToolkit
15
+ toolkit = StraleToolkit(api_key="sk_test_123")
16
+ assert toolkit.api_key == "sk_test_123"
17
+ assert toolkit.base_url == "https://api.strale.io"
18
+
19
+ def test_toolkit_env_key(self):
20
+ from composio_strale import StraleToolkit
21
+ os.environ["STRALE_API_KEY"] = "sk_env_test"
22
+ toolkit = StraleToolkit()
23
+ assert toolkit.api_key == "sk_env_test"
24
+ del os.environ["STRALE_API_KEY"]
25
+
26
+ def test_toolkit_custom_url(self):
27
+ from composio_strale import StraleToolkit
28
+ toolkit = StraleToolkit(api_key="test", base_url="http://localhost:3000")
29
+ assert toolkit.base_url == "http://localhost:3000"
30
+
31
+
32
+ if __name__ == "__main__":
33
+ unittest.main()