stackone-ai 0.0.4__tar.gz → 0.3.2__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.
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/.github/workflows/docs.yml +3 -3
- stackone_ai-0.3.2/.github/workflows/lint.yml +37 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/.github/workflows/release.yml +3 -3
- stackone_ai-0.3.2/.github/workflows/test.yml +37 -0
- stackone_ai-0.3.2/.mcp.json +12 -0
- stackone_ai-0.3.2/.release-please-manifest.json +3 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/CHANGELOG.md +30 -0
- stackone_ai-0.3.2/CLAUDE.md +120 -0
- stackone_ai-0.3.2/PKG-INFO +213 -0
- stackone_ai-0.3.2/README.md +176 -0
- stackone_ai-0.3.2/examples/meta_tools_example.py +247 -0
- stackone_ai-0.3.2/examples/test_examples.py +85 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/pyproject.toml +22 -6
- stackone_ai-0.3.2/stackone_ai/__init__.py +7 -0
- stackone_ai-0.3.2/stackone_ai/meta_tools.py +278 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/models.py +118 -21
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/server.py +23 -8
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/specs/parser.py +4 -1
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/toolset.py +5 -2
- stackone_ai-0.3.2/tests/test_meta_tools.py +268 -0
- stackone_ai-0.3.2/tests/test_tool_calling.py +161 -0
- stackone_ai-0.3.2/uv.lock +5156 -0
- stackone_ai-0.0.4/.github/workflows/lint.yml +0 -29
- stackone_ai-0.0.4/.github/workflows/test.yml +0 -27
- stackone_ai-0.0.4/.release-please-manifest.json +0 -3
- stackone_ai-0.0.4/PKG-INFO +0 -84
- stackone_ai-0.0.4/README.md +0 -56
- stackone_ai-0.0.4/examples/test_examples.py +0 -39
- stackone_ai-0.0.4/stackone_ai/__init__.py +0 -6
- stackone_ai-0.0.4/uv.lock +0 -3496
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/.cursor/rules/cursor-rules-location.mdc +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/.cursor/rules/examples-standards.mdc +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/.cursor/rules/no-relative-imports.mdc +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/.cursor/rules/package-installation.mdc +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/.cursor/rules/release-please-standards.mdc +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/.cursor/rules/uv-scripts.mdc +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/.env_example +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/.gitignore +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/.pre-commit-config.yaml +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/.release-please-config.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/.vscode/settings.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/LICENSE +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/Makefile +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/examples/available_tools.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/examples/crewai_integration.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/examples/custom_base_url.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/examples/error_handling.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/examples/file_uploads.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/examples/index.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/examples/langchain_integration.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/examples/langgraph_tool_node.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/examples/mcp_server.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/examples/openai_integration.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/examples/stackone_account_ids.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/mkdocs.yml +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/py.typed +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/scripts/build_docs.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/scripts/pull_oas.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/scripts/update_version.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/constants.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/oas/ats.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/oas/core.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/oas/crm.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/oas/documents.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/oas/hris.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/oas/iam.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/oas/lms.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/oas/marketing.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/py.typed +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/stackone_ai/specs/loader.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/tests/snapshots/test_parser/test_parse_all_oas_specs/ats_tools.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/tests/snapshots/test_parser/test_parse_all_oas_specs/core_tools.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/tests/snapshots/test_parser/test_parse_all_oas_specs/crm_tools.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/tests/snapshots/test_parser/test_parse_all_oas_specs/documents_tools.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/tests/snapshots/test_parser/test_parse_all_oas_specs/hris_tools.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/tests/snapshots/test_parser/test_parse_all_oas_specs/iam_tools.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/tests/snapshots/test_parser/test_parse_all_oas_specs/lms_tools.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/tests/snapshots/test_parser/test_parse_all_oas_specs/marketing_tools.json +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/tests/test_models.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/tests/test_parser.py +0 -0
- {stackone_ai-0.0.4 → stackone_ai-0.3.2}/tests/test_toolset.py +0 -0
|
@@ -12,10 +12,10 @@ jobs:
|
|
|
12
12
|
deploy:
|
|
13
13
|
runs-on: ubuntu-latest
|
|
14
14
|
steps:
|
|
15
|
-
- uses: actions/checkout@
|
|
15
|
+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
16
16
|
|
|
17
17
|
- name: Install uv
|
|
18
|
-
uses: astral-sh/setup-uv@
|
|
18
|
+
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v6.4.3
|
|
19
19
|
with:
|
|
20
20
|
python-version: "3.11"
|
|
21
21
|
enable-cache: true
|
|
@@ -30,7 +30,7 @@ jobs:
|
|
|
30
30
|
|
|
31
31
|
- name: Deploy to GitHub Pages
|
|
32
32
|
if: github.ref == 'refs/heads/main'
|
|
33
|
-
uses: peaceiris/actions-gh-pages@
|
|
33
|
+
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
|
|
34
34
|
with:
|
|
35
35
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
36
36
|
publish_dir: ./site
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Lint & Type Check
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
lint:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.9", "3.10"]
|
|
14
|
+
include:
|
|
15
|
+
- python-version: "3.9"
|
|
16
|
+
sync-extras: "--all-extras --no-extra mcp"
|
|
17
|
+
- python-version: "3.10"
|
|
18
|
+
sync-extras: "--all-extras"
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
21
|
+
|
|
22
|
+
- name: Install uv
|
|
23
|
+
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v6.4.3
|
|
24
|
+
with:
|
|
25
|
+
python-version: ${{ matrix.python-version }}
|
|
26
|
+
enable-cache: true
|
|
27
|
+
|
|
28
|
+
- name: Install dependencies
|
|
29
|
+
run: uv sync ${{ matrix.sync-extras }}
|
|
30
|
+
|
|
31
|
+
- name: Run Ruff
|
|
32
|
+
uses: astral-sh/ruff-action@0c50076f12c38c3d0115b7b519b54a91cb9cf0ad # v3.5.0
|
|
33
|
+
with:
|
|
34
|
+
args: check .
|
|
35
|
+
|
|
36
|
+
- name: Run Mypy
|
|
37
|
+
run: uv run mypy stackone_ai --exclude stackone_ai/server.py
|
|
@@ -13,19 +13,19 @@ jobs:
|
|
|
13
13
|
release-please:
|
|
14
14
|
runs-on: ubuntu-latest
|
|
15
15
|
steps:
|
|
16
|
-
- uses: google-github-actions/release-please-action@v4
|
|
16
|
+
- uses: google-github-actions/release-please-action@e4dc86ba9405554aeba3c6bb2d169500e7d3b4ee # v4.1.1
|
|
17
17
|
id: release
|
|
18
18
|
with:
|
|
19
19
|
config-file: .release-please-config.json
|
|
20
20
|
manifest-file: .release-please-manifest.json
|
|
21
21
|
|
|
22
22
|
# Only release to PyPI when a new release is created
|
|
23
|
-
- uses: actions/checkout@
|
|
23
|
+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
24
24
|
if: ${{ steps.release.outputs.release_created }}
|
|
25
25
|
|
|
26
26
|
- name: Install uv
|
|
27
27
|
if: ${{ steps.release.outputs.release_created }}
|
|
28
|
-
uses: astral-sh/setup-uv@
|
|
28
|
+
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v6.4.3
|
|
29
29
|
with:
|
|
30
30
|
python-version: "3.11"
|
|
31
31
|
enable-cache: true
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
test:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ["3.9", "3.10", "3.13"]
|
|
14
|
+
include:
|
|
15
|
+
- python-version: "3.9"
|
|
16
|
+
test-extras: "--all-extras --no-extra mcp"
|
|
17
|
+
- python-version: "3.10"
|
|
18
|
+
test-extras: "--all-extras"
|
|
19
|
+
- python-version: "3.13"
|
|
20
|
+
test-extras: "--all-extras"
|
|
21
|
+
env:
|
|
22
|
+
STACKONE_API_KEY: ${{ secrets.STACKONE_API_KEY }}
|
|
23
|
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
|
26
|
+
|
|
27
|
+
- name: Install uv
|
|
28
|
+
uses: astral-sh/setup-uv@e92bafb6253dcd438e0484186d7669ea7a8ca1cc # v6.4.3
|
|
29
|
+
with:
|
|
30
|
+
python-version: ${{ matrix.python-version }}
|
|
31
|
+
enable-cache: true
|
|
32
|
+
|
|
33
|
+
- name: Install dependencies
|
|
34
|
+
run: uv sync ${{ matrix.test-extras }}
|
|
35
|
+
|
|
36
|
+
- name: Run tests
|
|
37
|
+
run: uv run pytest
|
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.3.2](https://github.com/StackOneHQ/stackone-ai-python/compare/stackone-ai-v0.3.1...stackone-ai-v0.3.2) (2025-08-26)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* support Python 3.9+ with optional MCP server support ([#28](https://github.com/StackOneHQ/stackone-ai-python/issues/28)) ([1a37776](https://github.com/StackOneHQ/stackone-ai-python/commit/1a377768c15223e25dbaf1e0bcd0c0e8bb0df2e8))
|
|
9
|
+
|
|
10
|
+
## [0.3.1](https://github.com/StackOneHQ/stackone-ai-python/compare/stackone-ai-v0.3.0...stackone-ai-v0.3.1) (2025-08-19)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Documentation
|
|
14
|
+
|
|
15
|
+
* add comprehensive LangChain integration section to README ([#20](https://github.com/StackOneHQ/stackone-ai-python/issues/20)) ([cbf7f68](https://github.com/StackOneHQ/stackone-ai-python/commit/cbf7f68e889839f9a501ad8f2cd47c468ffff47e))
|
|
16
|
+
* rename meta tools ([#27](https://github.com/StackOneHQ/stackone-ai-python/issues/27)) ([a9ebc03](https://github.com/StackOneHQ/stackone-ai-python/commit/a9ebc032f784863913b28d4ad3850b80bafee5f4))
|
|
17
|
+
|
|
18
|
+
## [0.3.0](https://github.com/StackOneHQ/stackone-ai-python/compare/stackone-ai-v0.0.4...stackone-ai-v0.3.0) (2025-08-19)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Features
|
|
22
|
+
|
|
23
|
+
* add CLAUDE.md for Claude Code guidance ([#15](https://github.com/StackOneHQ/stackone-ai-python/issues/15)) ([ac9fe98](https://github.com/StackOneHQ/stackone-ai-python/commit/ac9fe9857f44c19394654dfcbe23fecc5cf9fbb0))
|
|
24
|
+
* bring Python SDK to feature parity with Node SDK ([#17](https://github.com/StackOneHQ/stackone-ai-python/issues/17)) ([8b6de99](https://github.com/StackOneHQ/stackone-ai-python/commit/8b6de99184227cb7f1580964dc3eae14f8f60fc1))
|
|
25
|
+
* remove automatic STACKONE_ACCOUNT_ID environment variable loading ([#23](https://github.com/StackOneHQ/stackone-ai-python/issues/23)) ([aa0aaf6](https://github.com/StackOneHQ/stackone-ai-python/commit/aa0aaf6d6bf528f8e29def9b008db23cf94b97c7))
|
|
26
|
+
* simplify meta tool function names to match Node SDK ([#19](https://github.com/StackOneHQ/stackone-ai-python/issues/19)) ([4572609](https://github.com/StackOneHQ/stackone-ai-python/commit/4572609a9b85a88fc3067be12f821ec0bc54e769))
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
### Miscellaneous Chores
|
|
30
|
+
|
|
31
|
+
* release 0.3.0 ([#24](https://github.com/StackOneHQ/stackone-ai-python/issues/24)) ([beea911](https://github.com/StackOneHQ/stackone-ai-python/commit/beea91165ed2ba3eb5f5ad6ca8656344561b0b43))
|
|
32
|
+
|
|
3
33
|
## [0.0.4](https://github.com/StackOneHQ/stackone-ai-python/compare/stackone-ai-v0.0.3...stackone-ai-v0.0.4) (2025-03-05)
|
|
4
34
|
|
|
5
35
|
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Cursor Rules
|
|
6
|
+
|
|
7
|
+
- @./.cursor/rules/package-installation
|
|
8
|
+
- @./.cursor/rules/no-relative-imports
|
|
9
|
+
- @./.cursor/rules/uv-scripts
|
|
10
|
+
- @./.cursor/rules/release-please-standards
|
|
11
|
+
- @./.cursor/rules/examples-standards
|
|
12
|
+
|
|
13
|
+
## Project Overview
|
|
14
|
+
|
|
15
|
+
StackOne AI SDK is a Python library that provides a unified interface for accessing various SaaS tools through AI-friendly APIs. It acts as a bridge between AI applications and multiple SaaS platforms (HRIS, CRM, ATS, LMS, Marketing, etc.) with support for OpenAI, LangChain, CrewAI, and Model Context Protocol (MCP).
|
|
16
|
+
|
|
17
|
+
## Essential Development Commands
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Setup and installation
|
|
21
|
+
make install # Install dependencies and pre-commit hooks
|
|
22
|
+
|
|
23
|
+
# Code quality
|
|
24
|
+
make lint # Run ruff linting
|
|
25
|
+
make lint-fix # Auto-fix linting issues
|
|
26
|
+
make mypy # Run type checking
|
|
27
|
+
|
|
28
|
+
# Testing
|
|
29
|
+
make test # Run all tests
|
|
30
|
+
make test-tools # Run tool-specific tests
|
|
31
|
+
make test-examples # Run example tests
|
|
32
|
+
|
|
33
|
+
# Documentation
|
|
34
|
+
make docs-serve # Build and serve docs locally (http://localhost:8000)
|
|
35
|
+
make docs-build # Build docs for deployment
|
|
36
|
+
|
|
37
|
+
# MCP Development
|
|
38
|
+
make mcp-inspector # Run MCP server inspector for debugging
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Code Architecture
|
|
42
|
+
|
|
43
|
+
### Core Components
|
|
44
|
+
|
|
45
|
+
1. **StackOneToolSet** (`stackone_ai/toolset.py`): Main entry point
|
|
46
|
+
- Handles authentication (API key + optional account ID)
|
|
47
|
+
- Manages tool loading with glob pattern filtering
|
|
48
|
+
- Provides format converters for OpenAI/LangChain
|
|
49
|
+
|
|
50
|
+
2. **Models** (`stackone_ai/models.py`): Data structures
|
|
51
|
+
- `StackOneTool`: Base class with execution logic
|
|
52
|
+
- `Tools`: Container for managing multiple tools
|
|
53
|
+
- Format converters for different AI frameworks
|
|
54
|
+
|
|
55
|
+
3. **OpenAPI Parser** (`stackone_ai/specs/parser.py`): Spec conversion
|
|
56
|
+
- Converts OpenAPI specs to tool definitions
|
|
57
|
+
- Handles file upload detection (`format: binary` → `type: file`)
|
|
58
|
+
- Resolves schema references
|
|
59
|
+
|
|
60
|
+
4. **MCP Server** (`stackone_ai/server.py`): Protocol implementation
|
|
61
|
+
- Async tool execution
|
|
62
|
+
- CLI interface via `stackmcp` command
|
|
63
|
+
|
|
64
|
+
### OpenAPI Specifications
|
|
65
|
+
|
|
66
|
+
All tool definitions are generated from OpenAPI specs in `stackone_ai/oas/`:
|
|
67
|
+
- `core.json`, `ats.json`, `crm.json`, `documents.json`, `hris.json`, `iam.json`, `lms.json`, `marketing.json`
|
|
68
|
+
|
|
69
|
+
## Key Development Patterns
|
|
70
|
+
|
|
71
|
+
### Tool Filtering
|
|
72
|
+
```python
|
|
73
|
+
# Use glob patterns for tool selection
|
|
74
|
+
tools = StackOneToolSet(include_tools=["hris_*", "!hris_create_*"])
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Authentication
|
|
78
|
+
```python
|
|
79
|
+
# Uses environment variables or direct configuration
|
|
80
|
+
toolset = StackOneToolSet(
|
|
81
|
+
api_key="your-api-key", # or STACKONE_API_KEY env var
|
|
82
|
+
account_id="optional-id" # explicit account ID required
|
|
83
|
+
)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Type Safety
|
|
87
|
+
- Full type annotations required (Python 3.11+)
|
|
88
|
+
- Strict mypy configuration
|
|
89
|
+
- Use generics for better IDE support
|
|
90
|
+
|
|
91
|
+
### Testing
|
|
92
|
+
- Snapshot testing for tool parsing (`tests/snapshots/`)
|
|
93
|
+
- Async tests use `pytest-asyncio`
|
|
94
|
+
- Example validation: See @./.cursor/rules/examples-standards
|
|
95
|
+
|
|
96
|
+
## Important Considerations
|
|
97
|
+
|
|
98
|
+
1. **Dependencies**: See @./.cursor/rules/package-installation for uv dependency management
|
|
99
|
+
2. **Pre-commit**: Hooks configured for ruff and mypy - run on all commits
|
|
100
|
+
3. **Python Version**: Requires Python >=3.11
|
|
101
|
+
4. **Error Handling**: Custom exceptions (`StackOneError`, `StackOneAPIError`)
|
|
102
|
+
5. **File Uploads**: Binary parameters auto-detected from OpenAPI specs
|
|
103
|
+
6. **Context Window**: Tool loading warns when loading all tools (large context)
|
|
104
|
+
|
|
105
|
+
## Common Tasks
|
|
106
|
+
|
|
107
|
+
### Adding New SaaS Integration
|
|
108
|
+
1. Add OpenAPI spec to `stackone_ai/oas/`
|
|
109
|
+
2. Parser automatically converts to tool definitions
|
|
110
|
+
3. Test with `make test-tools`
|
|
111
|
+
|
|
112
|
+
### Modifying Tool Behavior
|
|
113
|
+
- Core execution logic in `StackOneTool.execute()` method
|
|
114
|
+
- HTTP configuration via `ExecuteConfig` class
|
|
115
|
+
- Response handling in `_process_response()`
|
|
116
|
+
|
|
117
|
+
### Updating Documentation
|
|
118
|
+
- Examples requirements: See @./.cursor/rules/examples-standards
|
|
119
|
+
- Run `make docs-serve` to preview changes
|
|
120
|
+
- MkDocs config in `mkdocs.yml`
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stackone-ai
|
|
3
|
+
Version: 0.3.2
|
|
4
|
+
Summary: agents performing actions on your SaaS
|
|
5
|
+
Author-email: StackOne <support@stackone.com>
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Classifier: Development Status :: 4 - Beta
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Requires-Dist: bm25s>=0.2.2
|
|
19
|
+
Requires-Dist: eval-type-backport; python_version < '3.10'
|
|
20
|
+
Requires-Dist: langchain-core>=0.1.0
|
|
21
|
+
Requires-Dist: numpy>=1.24.0
|
|
22
|
+
Requires-Dist: pydantic>=2.10.6
|
|
23
|
+
Requires-Dist: requests>=2.32.3
|
|
24
|
+
Requires-Dist: typing-extensions>=4.0.0
|
|
25
|
+
Provides-Extra: docs
|
|
26
|
+
Requires-Dist: mkdocs-terminal>=4.7.0; extra == 'docs'
|
|
27
|
+
Requires-Dist: pygments>=2.12; extra == 'docs'
|
|
28
|
+
Requires-Dist: pymdown-extensions; extra == 'docs'
|
|
29
|
+
Provides-Extra: examples
|
|
30
|
+
Requires-Dist: crewai>=0.102.0; (python_version >= '3.10') and extra == 'examples'
|
|
31
|
+
Requires-Dist: langchain-openai>=0.3.6; extra == 'examples'
|
|
32
|
+
Requires-Dist: openai>=1.63.2; extra == 'examples'
|
|
33
|
+
Requires-Dist: python-dotenv>=1.0.1; extra == 'examples'
|
|
34
|
+
Provides-Extra: mcp
|
|
35
|
+
Requires-Dist: mcp[cli]>=1.3.0; (python_version >= '3.10') and extra == 'mcp'
|
|
36
|
+
Description-Content-Type: text/markdown
|
|
37
|
+
|
|
38
|
+
# StackOne AI SDK
|
|
39
|
+
|
|
40
|
+
[](https://badge.fury.io/py/stackone-ai)
|
|
41
|
+
[](https://github.com/StackOneHQ/stackone-ai-python/releases)
|
|
42
|
+
|
|
43
|
+
StackOne AI provides a unified interface for accessing various SaaS tools through AI-friendly APIs.
|
|
44
|
+
|
|
45
|
+
## Features
|
|
46
|
+
|
|
47
|
+
- Unified interface for multiple SaaS tools
|
|
48
|
+
- AI-friendly tool descriptions and parameters
|
|
49
|
+
- **Tool Calling**: Direct method calling with `tool.call()` for intuitive usage
|
|
50
|
+
- **Glob Pattern Filtering**: Advanced tool filtering with patterns like `"hris_*"` and exclusions `"!hris_delete_*"`
|
|
51
|
+
- **Meta Tools** (Beta): Dynamic tool discovery and execution based on natural language queries
|
|
52
|
+
- Integration with popular AI frameworks:
|
|
53
|
+
- OpenAI Functions
|
|
54
|
+
- LangChain Tools
|
|
55
|
+
- CrewAI Tools
|
|
56
|
+
- LangGraph Tool Node
|
|
57
|
+
|
|
58
|
+
## Requirements
|
|
59
|
+
|
|
60
|
+
- Python 3.9+ (core SDK functionality)
|
|
61
|
+
- Python 3.10+ (for MCP server and CrewAI examples)
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
### Basic Installation
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install stackone-ai
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Optional Features
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Install with MCP server support (requires Python 3.10+)
|
|
75
|
+
pip install 'stackone-ai[mcp]'
|
|
76
|
+
|
|
77
|
+
# Install with CrewAI examples (requires Python 3.10+)
|
|
78
|
+
pip install 'stackone-ai[examples]'
|
|
79
|
+
|
|
80
|
+
# Install everything
|
|
81
|
+
pip install 'stackone-ai[mcp,examples]'
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Quick Start
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from stackone_ai import StackOneToolSet
|
|
88
|
+
|
|
89
|
+
# Initialize with API key
|
|
90
|
+
toolset = StackOneToolSet() # Uses STACKONE_API_KEY env var
|
|
91
|
+
# Or explicitly: toolset = StackOneToolSet(api_key="your-api-key")
|
|
92
|
+
|
|
93
|
+
# Get HRIS-related tools with glob patterns
|
|
94
|
+
tools = toolset.get_tools("hris_*", account_id="your-account-id")
|
|
95
|
+
# Exclude certain tools with negative patterns
|
|
96
|
+
tools = toolset.get_tools(["hris_*", "!hris_delete_*"])
|
|
97
|
+
|
|
98
|
+
# Use a specific tool with the new call method
|
|
99
|
+
employee_tool = tools.get_tool("hris_get_employee")
|
|
100
|
+
# Call with keyword arguments
|
|
101
|
+
employee = employee_tool.call(id="employee-id")
|
|
102
|
+
# Or with traditional execute method
|
|
103
|
+
employee = employee_tool.execute({"id": "employee-id"})
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Integration Examples
|
|
107
|
+
|
|
108
|
+
<details>
|
|
109
|
+
<summary>LangChain Integration</summary>
|
|
110
|
+
|
|
111
|
+
StackOne tools work seamlessly with LangChain, enabling powerful AI agent workflows:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from langchain_openai import ChatOpenAI
|
|
115
|
+
from stackone_ai import StackOneToolSet
|
|
116
|
+
|
|
117
|
+
# Initialize StackOne tools
|
|
118
|
+
toolset = StackOneToolSet()
|
|
119
|
+
tools = toolset.get_tools("hris_*", account_id="your-account-id")
|
|
120
|
+
|
|
121
|
+
# Convert to LangChain format
|
|
122
|
+
langchain_tools = tools.to_langchain()
|
|
123
|
+
|
|
124
|
+
# Use with LangChain models
|
|
125
|
+
model = ChatOpenAI(model="gpt-4o-mini")
|
|
126
|
+
model_with_tools = model.bind_tools(langchain_tools)
|
|
127
|
+
|
|
128
|
+
# Execute AI-driven tool calls
|
|
129
|
+
response = model_with_tools.invoke("Get employee information for ID: emp123")
|
|
130
|
+
|
|
131
|
+
# Handle tool calls
|
|
132
|
+
for tool_call in response.tool_calls:
|
|
133
|
+
tool = tools.get_tool(tool_call["name"])
|
|
134
|
+
if tool:
|
|
135
|
+
result = tool.execute(tool_call["args"])
|
|
136
|
+
print(f"Result: {result}")
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
</details>
|
|
140
|
+
|
|
141
|
+
<details>
|
|
142
|
+
<summary>CrewAI Integration (Python 3.10+)</summary>
|
|
143
|
+
|
|
144
|
+
CrewAI uses LangChain tools natively, making integration seamless:
|
|
145
|
+
|
|
146
|
+
> **Note**: CrewAI requires Python 3.10+. Install with `pip install 'stackone-ai[examples]'`
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from crewai import Agent, Crew, Task
|
|
150
|
+
from stackone_ai import StackOneToolSet
|
|
151
|
+
|
|
152
|
+
# Get tools and convert to LangChain format
|
|
153
|
+
toolset = StackOneToolSet()
|
|
154
|
+
tools = toolset.get_tools("hris_*", account_id="your-account-id")
|
|
155
|
+
langchain_tools = tools.to_langchain()
|
|
156
|
+
|
|
157
|
+
# Create CrewAI agent with StackOne tools
|
|
158
|
+
agent = Agent(
|
|
159
|
+
role="HR Manager",
|
|
160
|
+
goal="Analyze employee data and generate insights",
|
|
161
|
+
backstory="Expert in HR analytics and employee management",
|
|
162
|
+
tools=langchain_tools,
|
|
163
|
+
llm="gpt-4o-mini"
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
# Define task and execute
|
|
167
|
+
task = Task(
|
|
168
|
+
description="Find all employees in the engineering department",
|
|
169
|
+
agent=agent,
|
|
170
|
+
expected_output="List of engineering employees with their details"
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
crew = Crew(agents=[agent], tasks=[task])
|
|
174
|
+
result = crew.kickoff()
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
</details>
|
|
178
|
+
|
|
179
|
+
## Meta Tools (Beta)
|
|
180
|
+
|
|
181
|
+
Meta tools enable dynamic tool discovery and execution without hardcoding tool names:
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
# Get meta tools for dynamic discovery
|
|
185
|
+
tools = toolset.get_tools("hris_*")
|
|
186
|
+
meta_tools = tools.meta_tools()
|
|
187
|
+
|
|
188
|
+
# Search for relevant tools using natural language
|
|
189
|
+
filter_tool = meta_tools.get_tool("meta_search_tools")
|
|
190
|
+
results = filter_tool.call(query="manage employees", limit=5)
|
|
191
|
+
|
|
192
|
+
# Execute discovered tools dynamically
|
|
193
|
+
execute_tool = meta_tools.get_tool("meta_execute_tool")
|
|
194
|
+
result = execute_tool.call(toolName="hris_list_employees", params={"limit": 10})
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
## Examples
|
|
198
|
+
|
|
199
|
+
For more examples, check out the [examples/](examples/) directory:
|
|
200
|
+
|
|
201
|
+
- [Error Handling](examples/error_handling.py)
|
|
202
|
+
- [StackOne Account IDs](examples/stackone_account_ids.py)
|
|
203
|
+
- [Available Tools](examples/available_tools.py)
|
|
204
|
+
- [File Uploads](examples/file_uploads.py)
|
|
205
|
+
- [OpenAI Integration](examples/openai_integration.py)
|
|
206
|
+
- [LangChain Integration](examples/langchain_integration.py)
|
|
207
|
+
- [CrewAI Integration](examples/crewai_integration.py)
|
|
208
|
+
- [LangGraph Tool Node](examples/langgraph_tool_node.py)
|
|
209
|
+
- [Meta Tools](examples/meta_tools_example.py)
|
|
210
|
+
|
|
211
|
+
## License
|
|
212
|
+
|
|
213
|
+
Apache 2.0 License
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# StackOne AI SDK
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/py/stackone-ai)
|
|
4
|
+
[](https://github.com/StackOneHQ/stackone-ai-python/releases)
|
|
5
|
+
|
|
6
|
+
StackOne AI provides a unified interface for accessing various SaaS tools through AI-friendly APIs.
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- Unified interface for multiple SaaS tools
|
|
11
|
+
- AI-friendly tool descriptions and parameters
|
|
12
|
+
- **Tool Calling**: Direct method calling with `tool.call()` for intuitive usage
|
|
13
|
+
- **Glob Pattern Filtering**: Advanced tool filtering with patterns like `"hris_*"` and exclusions `"!hris_delete_*"`
|
|
14
|
+
- **Meta Tools** (Beta): Dynamic tool discovery and execution based on natural language queries
|
|
15
|
+
- Integration with popular AI frameworks:
|
|
16
|
+
- OpenAI Functions
|
|
17
|
+
- LangChain Tools
|
|
18
|
+
- CrewAI Tools
|
|
19
|
+
- LangGraph Tool Node
|
|
20
|
+
|
|
21
|
+
## Requirements
|
|
22
|
+
|
|
23
|
+
- Python 3.9+ (core SDK functionality)
|
|
24
|
+
- Python 3.10+ (for MCP server and CrewAI examples)
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
### Basic Installation
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install stackone-ai
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Optional Features
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Install with MCP server support (requires Python 3.10+)
|
|
38
|
+
pip install 'stackone-ai[mcp]'
|
|
39
|
+
|
|
40
|
+
# Install with CrewAI examples (requires Python 3.10+)
|
|
41
|
+
pip install 'stackone-ai[examples]'
|
|
42
|
+
|
|
43
|
+
# Install everything
|
|
44
|
+
pip install 'stackone-ai[mcp,examples]'
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Quick Start
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from stackone_ai import StackOneToolSet
|
|
51
|
+
|
|
52
|
+
# Initialize with API key
|
|
53
|
+
toolset = StackOneToolSet() # Uses STACKONE_API_KEY env var
|
|
54
|
+
# Or explicitly: toolset = StackOneToolSet(api_key="your-api-key")
|
|
55
|
+
|
|
56
|
+
# Get HRIS-related tools with glob patterns
|
|
57
|
+
tools = toolset.get_tools("hris_*", account_id="your-account-id")
|
|
58
|
+
# Exclude certain tools with negative patterns
|
|
59
|
+
tools = toolset.get_tools(["hris_*", "!hris_delete_*"])
|
|
60
|
+
|
|
61
|
+
# Use a specific tool with the new call method
|
|
62
|
+
employee_tool = tools.get_tool("hris_get_employee")
|
|
63
|
+
# Call with keyword arguments
|
|
64
|
+
employee = employee_tool.call(id="employee-id")
|
|
65
|
+
# Or with traditional execute method
|
|
66
|
+
employee = employee_tool.execute({"id": "employee-id"})
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Integration Examples
|
|
70
|
+
|
|
71
|
+
<details>
|
|
72
|
+
<summary>LangChain Integration</summary>
|
|
73
|
+
|
|
74
|
+
StackOne tools work seamlessly with LangChain, enabling powerful AI agent workflows:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from langchain_openai import ChatOpenAI
|
|
78
|
+
from stackone_ai import StackOneToolSet
|
|
79
|
+
|
|
80
|
+
# Initialize StackOne tools
|
|
81
|
+
toolset = StackOneToolSet()
|
|
82
|
+
tools = toolset.get_tools("hris_*", account_id="your-account-id")
|
|
83
|
+
|
|
84
|
+
# Convert to LangChain format
|
|
85
|
+
langchain_tools = tools.to_langchain()
|
|
86
|
+
|
|
87
|
+
# Use with LangChain models
|
|
88
|
+
model = ChatOpenAI(model="gpt-4o-mini")
|
|
89
|
+
model_with_tools = model.bind_tools(langchain_tools)
|
|
90
|
+
|
|
91
|
+
# Execute AI-driven tool calls
|
|
92
|
+
response = model_with_tools.invoke("Get employee information for ID: emp123")
|
|
93
|
+
|
|
94
|
+
# Handle tool calls
|
|
95
|
+
for tool_call in response.tool_calls:
|
|
96
|
+
tool = tools.get_tool(tool_call["name"])
|
|
97
|
+
if tool:
|
|
98
|
+
result = tool.execute(tool_call["args"])
|
|
99
|
+
print(f"Result: {result}")
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
</details>
|
|
103
|
+
|
|
104
|
+
<details>
|
|
105
|
+
<summary>CrewAI Integration (Python 3.10+)</summary>
|
|
106
|
+
|
|
107
|
+
CrewAI uses LangChain tools natively, making integration seamless:
|
|
108
|
+
|
|
109
|
+
> **Note**: CrewAI requires Python 3.10+. Install with `pip install 'stackone-ai[examples]'`
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from crewai import Agent, Crew, Task
|
|
113
|
+
from stackone_ai import StackOneToolSet
|
|
114
|
+
|
|
115
|
+
# Get tools and convert to LangChain format
|
|
116
|
+
toolset = StackOneToolSet()
|
|
117
|
+
tools = toolset.get_tools("hris_*", account_id="your-account-id")
|
|
118
|
+
langchain_tools = tools.to_langchain()
|
|
119
|
+
|
|
120
|
+
# Create CrewAI agent with StackOne tools
|
|
121
|
+
agent = Agent(
|
|
122
|
+
role="HR Manager",
|
|
123
|
+
goal="Analyze employee data and generate insights",
|
|
124
|
+
backstory="Expert in HR analytics and employee management",
|
|
125
|
+
tools=langchain_tools,
|
|
126
|
+
llm="gpt-4o-mini"
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# Define task and execute
|
|
130
|
+
task = Task(
|
|
131
|
+
description="Find all employees in the engineering department",
|
|
132
|
+
agent=agent,
|
|
133
|
+
expected_output="List of engineering employees with their details"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
crew = Crew(agents=[agent], tasks=[task])
|
|
137
|
+
result = crew.kickoff()
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
</details>
|
|
141
|
+
|
|
142
|
+
## Meta Tools (Beta)
|
|
143
|
+
|
|
144
|
+
Meta tools enable dynamic tool discovery and execution without hardcoding tool names:
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
# Get meta tools for dynamic discovery
|
|
148
|
+
tools = toolset.get_tools("hris_*")
|
|
149
|
+
meta_tools = tools.meta_tools()
|
|
150
|
+
|
|
151
|
+
# Search for relevant tools using natural language
|
|
152
|
+
filter_tool = meta_tools.get_tool("meta_search_tools")
|
|
153
|
+
results = filter_tool.call(query="manage employees", limit=5)
|
|
154
|
+
|
|
155
|
+
# Execute discovered tools dynamically
|
|
156
|
+
execute_tool = meta_tools.get_tool("meta_execute_tool")
|
|
157
|
+
result = execute_tool.call(toolName="hris_list_employees", params={"limit": 10})
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Examples
|
|
161
|
+
|
|
162
|
+
For more examples, check out the [examples/](examples/) directory:
|
|
163
|
+
|
|
164
|
+
- [Error Handling](examples/error_handling.py)
|
|
165
|
+
- [StackOne Account IDs](examples/stackone_account_ids.py)
|
|
166
|
+
- [Available Tools](examples/available_tools.py)
|
|
167
|
+
- [File Uploads](examples/file_uploads.py)
|
|
168
|
+
- [OpenAI Integration](examples/openai_integration.py)
|
|
169
|
+
- [LangChain Integration](examples/langchain_integration.py)
|
|
170
|
+
- [CrewAI Integration](examples/crewai_integration.py)
|
|
171
|
+
- [LangGraph Tool Node](examples/langgraph_tool_node.py)
|
|
172
|
+
- [Meta Tools](examples/meta_tools_example.py)
|
|
173
|
+
|
|
174
|
+
## License
|
|
175
|
+
|
|
176
|
+
Apache 2.0 License
|