stackone-ai 2.7.0__tar.gz → 2.9.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.
- stackone_ai-2.9.0/.env.example +6 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.gitignore +1 -0
- stackone_ai-2.9.0/.release-please-manifest.json +3 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/CHANGELOG.md +14 -0
- stackone_ai-2.7.0/README.md → stackone_ai-2.9.0/PKG-INFO +125 -28
- stackone_ai-2.7.0/PKG-INFO → stackone_ai-2.9.0/README.md +90 -60
- stackone_ai-2.9.0/examples/auth_management.py +103 -0
- stackone_ai-2.9.0/examples/crewai_integration.py +69 -0
- stackone_ai-2.9.0/examples/langchain_integration.py +69 -0
- stackone_ai-2.9.0/examples/langgraph_integration.py +62 -0
- stackone_ai-2.9.0/examples/openai_integration.py +113 -0
- stackone_ai-2.9.0/examples/pydantic_ai_integration.py +53 -0
- stackone_ai-2.9.0/examples/search_tools.py +171 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/examples/test_examples.py +4 -8
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/justfile +4 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/pyproject.toml +6 -4
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/__init__.py +1 -1
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/models.py +44 -1
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/toolset.py +44 -1
- stackone_ai-2.9.0/tests/test_integrations_pydantic_ai.py +183 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/uv.lock +1389 -474
- stackone_ai-2.7.0/.release-please-manifest.json +0 -3
- stackone_ai-2.7.0/examples/agent_tool_search.py +0 -202
- stackone_ai-2.7.0/examples/crewai_integration.py +0 -55
- stackone_ai-2.7.0/examples/file_uploads.py +0 -83
- stackone_ai-2.7.0/examples/index.py +0 -105
- stackone_ai-2.7.0/examples/langchain_integration.py +0 -51
- stackone_ai-2.7.0/examples/openai_integration.py +0 -93
- stackone_ai-2.7.0/examples/search_tool_example.py +0 -66
- stackone_ai-2.7.0/examples/semantic_search_example.py +0 -423
- stackone_ai-2.7.0/examples/stackone_account_ids.py +0 -40
- stackone_ai-2.7.0/examples/workday_integration.py +0 -91
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.claude/rules/development-workflow.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.claude/rules/examples-standards.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.claude/rules/git-workflow.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.claude/rules/nix-workflow.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.claude/rules/no-relative-imports.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.claude/rules/package-installation.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.claude/rules/release-please-standards.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.claude/rules/uv-scripts.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.cursor/rules/development-workflow.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.cursor/rules/examples-standards.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.cursor/rules/git-workflow.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.cursor/rules/no-relative-imports.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.cursor/rules/package-installation.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.cursor/rules/release-please-standards.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.cursor/rules/uv-scripts.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.envrc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.github/actions/setup-nix/action.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.github/dependabot.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.github/workflows/ci.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.github/workflows/nix-flake-update.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.github/workflows/nix-flake.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.github/workflows/release.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.gitleaks.toml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.gitmodules +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.mcp.json +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/.release-please-config.json +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/CLAUDE.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/LICENSE +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/flake.lock +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/flake.nix +0 -0
- {stackone_ai-2.7.0/examples → stackone_ai-2.9.0/scripts}/benchmark_search.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/constants.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/feedback/__init__.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/feedback/tool.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/integrations/__init__.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/integrations/langgraph.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/local_search.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/py.typed +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/semantic_search.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/utils/__init__.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/utils/normalize.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/stackone_ai/utils/tfidf_index.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/tests/conftest.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/tests/mocks/serve.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/tests/test_agent_tools.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/tests/test_feedback.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/tests/test_fetch_tools.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/tests/test_integrations_langgraph.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/tests/test_local_search.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/tests/test_models.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/tests/test_semantic_search.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/tests/test_tfidf_index.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/tests/test_tool_calling.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/tests/test_toolset.py +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.claude/rules/development-workflow.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.claude/rules/file-operations.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.claude/rules/git-workflow.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.claude/rules/pnpm-usage.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.claude/rules/typescript-patterns.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.claude/rules/typescript-testing.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.claude/skills/orama-integration/SKILL.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.cursor/rules/development-workflow.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.cursor/rules/file-operations.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.cursor/rules/git-workflow.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.cursor/rules/orama-integration.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.cursor/rules/pnpm-usage.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.cursor/rules/typescript-patterns.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.cursor/rules/typescript-testing.mdc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.envrc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.git +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.github/CODEOWNERS +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.github/actions/setup-nix/action.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.github/workflows/check-title.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.github/workflows/ci.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.github/workflows/claude.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.github/workflows/dry-publish.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.github/workflows/nix-flake.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.github/workflows/release.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.gitignore +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.gitleaks.toml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.mcp.json +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.oxfmtrc.jsonc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/.oxlintrc.jsonc +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/AGENTS.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/CHANGELOG.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/CLAUDE.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/LICENSE +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/README.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/README.md +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/ai-sdk-integration.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/ai-sdk-integration.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/anthropic-integration.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/claude-agent-sdk-integration.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/claude-agent-sdk-integration.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/fetch-tools-debug.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/fetch-tools.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/fetch-tools.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/meta-tools.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/openai-integration.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/openai-integration.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/openai-responses-integration.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/openai-responses-integration.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/package.json +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/tanstack-ai-integration.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/tanstack-ai-integration.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/examples/tsconfig.json +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/flake.lock +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/flake.nix +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/knip.config.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/lefthook.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/mocks/handlers.example-api.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/mocks/handlers.mcp.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/mocks/handlers.openai.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/mocks/handlers.stackone-ai.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/mocks/handlers.stackone-rpc.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/mocks/handlers.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/mocks/handlers.utils.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/mocks/mcp-server.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/mocks/node.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/package.json +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/pnpm-lock.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/pnpm-workspace.yaml +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/consts.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/feedback.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/feedback.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/headers.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/headers.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/index.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/mcp-client.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/mcp-client.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/requestBuilder.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/requestBuilder.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/rpc-client.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/rpc-client.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/schema.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/tool.test-d.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/tool.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/tool.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/toolsets.test-d.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/toolsets.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/toolsets.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/types.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/utils/array.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/utils/array.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/utils/error-stackone-api.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/utils/error-stackone-api.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/utils/error-stackone.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/utils/error-stackone.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/utils/tfidf-index.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/utils/tfidf-index.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/utils/try-import.test.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/utils/try-import.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/src/utils/type.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/tsconfig.json +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/tsdown.config.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/vitest.config.ts +0 -0
- {stackone_ai-2.7.0 → stackone_ai-2.9.0}/vendor/stackone-ai-node/vitest.setup.ts +0 -0
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.9.0](https://github.com/StackOneHQ/stackone-ai-python/compare/stackone-ai-v2.8.0...stackone-ai-v2.9.0) (2026-04-30)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* **integrations:** add native Pydantic AI support ([#184](https://github.com/StackOneHQ/stackone-ai-python/issues/184)) ([8216ab6](https://github.com/StackOneHQ/stackone-ai-python/commit/8216ab6c0776b0753cf3e68461bf5e8a9b044b06))
|
|
9
|
+
|
|
10
|
+
## [2.8.0](https://github.com/StackOneHQ/stackone-ai-python/compare/stackone-ai-v2.7.0...stackone-ai-v2.8.0) (2026-04-20)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Features
|
|
14
|
+
|
|
15
|
+
* **examples:** streamline examples, standardize auth patterns and migrate examples to Workday ([#179](https://github.com/StackOneHQ/stackone-ai-python/issues/179)) ([0bdc939](https://github.com/StackOneHQ/stackone-ai-python/commit/0bdc939e2844a0dae6bf527c8c8209df0a90d1f7))
|
|
16
|
+
|
|
3
17
|
## [2.7.0](https://github.com/StackOneHQ/stackone-ai-python/compare/stackone-ai-v2.6.0...stackone-ai-v2.7.0) (2026-04-14)
|
|
4
18
|
|
|
5
19
|
|
|
@@ -1,3 +1,38 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: stackone-ai
|
|
3
|
+
Version: 2.9.0
|
|
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.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: bm25s>=0.2.2
|
|
18
|
+
Requires-Dist: httpx>=0.28.0
|
|
19
|
+
Requires-Dist: langchain-core>=0.1.0
|
|
20
|
+
Requires-Dist: numpy>=1.24.0
|
|
21
|
+
Requires-Dist: pydantic>=2.10.6
|
|
22
|
+
Requires-Dist: typing-extensions>=4.0.0
|
|
23
|
+
Provides-Extra: examples
|
|
24
|
+
Requires-Dist: crewai>=0.102.0; extra == 'examples'
|
|
25
|
+
Requires-Dist: langchain-openai>=1.1.14; extra == 'examples'
|
|
26
|
+
Requires-Dist: langgraph>=1.1.6; extra == 'examples'
|
|
27
|
+
Requires-Dist: openai>=2.32.0; extra == 'examples'
|
|
28
|
+
Requires-Dist: pydantic-ai>=1.83.0; extra == 'examples'
|
|
29
|
+
Requires-Dist: python-dotenv>=1.0.1; extra == 'examples'
|
|
30
|
+
Provides-Extra: mcp
|
|
31
|
+
Requires-Dist: mcp>=1.3.0; extra == 'mcp'
|
|
32
|
+
Provides-Extra: pydantic-ai
|
|
33
|
+
Requires-Dist: pydantic-ai-slim<2.0.0,>=1.83.0; extra == 'pydantic-ai'
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
|
|
1
36
|
# StackOne AI SDK
|
|
2
37
|
|
|
3
38
|
[](https://badge.fury.io/py/stackone-ai)
|
|
@@ -26,6 +61,7 @@ StackOne AI provides a unified interface for accessing various SaaS tools throug
|
|
|
26
61
|
- LangChain Tools
|
|
27
62
|
- CrewAI Tools
|
|
28
63
|
- LangGraph Tool Node
|
|
64
|
+
- Pydantic AI Toolset
|
|
29
65
|
|
|
30
66
|
## Requirements
|
|
31
67
|
|
|
@@ -52,17 +88,18 @@ uv add 'stackone-ai[mcp,examples]'
|
|
|
52
88
|
## Quick Start
|
|
53
89
|
|
|
54
90
|
```python
|
|
91
|
+
import os
|
|
55
92
|
from stackone_ai import StackOneToolSet
|
|
56
93
|
|
|
57
|
-
# Initialize
|
|
58
|
-
toolset = StackOneToolSet()
|
|
59
|
-
# Or explicitly: toolset = StackOneToolSet(api_key="your-api-key")
|
|
94
|
+
# Initialize — reads STACKONE_API_KEY from environment
|
|
95
|
+
toolset = StackOneToolSet()
|
|
60
96
|
|
|
61
|
-
#
|
|
62
|
-
|
|
97
|
+
# Fetch tools — pass account ID from STACKONE_ACCOUNT_ID env var
|
|
98
|
+
account_id = os.getenv("STACKONE_ACCOUNT_ID")
|
|
99
|
+
tools = toolset.fetch_tools(actions=["workday_*"], account_ids=[account_id])
|
|
63
100
|
|
|
64
101
|
# Use a specific tool with the call method
|
|
65
|
-
employee_tool = tools.get_tool("
|
|
102
|
+
employee_tool = tools.get_tool("workday_get_worker")
|
|
66
103
|
# Call with keyword arguments
|
|
67
104
|
employee = employee_tool.call(id="employee-id")
|
|
68
105
|
# Or with traditional execute method
|
|
@@ -86,7 +123,7 @@ toolset = StackOneToolSet()
|
|
|
86
123
|
tools = toolset.fetch_tools(account_ids=["acc-123", "acc-456"])
|
|
87
124
|
|
|
88
125
|
# Filter by providers (case-insensitive)
|
|
89
|
-
tools = toolset.fetch_tools(providers=["hibob", "
|
|
126
|
+
tools = toolset.fetch_tools(providers=["hibob", "workday"])
|
|
90
127
|
|
|
91
128
|
# Filter by action patterns with glob support
|
|
92
129
|
tools = toolset.fetch_tools(actions=["*_list_employees"])
|
|
@@ -106,11 +143,11 @@ tools = toolset.fetch_tools(providers=["hibob"])
|
|
|
106
143
|
**Filtering Options:**
|
|
107
144
|
|
|
108
145
|
- **`account_ids`**: Filter tools by account IDs. Tools will be loaded for each specified account.
|
|
109
|
-
- **`providers`**: Filter by provider names (e.g., `["hibob", "
|
|
146
|
+
- **`providers`**: Filter by provider names (e.g., `["hibob", "workday"]`). Case-insensitive matching.
|
|
110
147
|
- **`actions`**: Filter by action patterns with glob support:
|
|
111
|
-
- Exact match: `["
|
|
148
|
+
- Exact match: `["workday_list_workers"]`
|
|
112
149
|
- Glob pattern: `["*_list_employees"]` matches all tools ending with `_list_employees`
|
|
113
|
-
- Provider prefix: `["
|
|
150
|
+
- Provider prefix: `["workday_*"]` matches all Workday tools
|
|
114
151
|
|
|
115
152
|
## Implicit Feedback (Beta)
|
|
116
153
|
|
|
@@ -165,18 +202,20 @@ When two calls for the same session happen within a few seconds, the SDK emits a
|
|
|
165
202
|
StackOne tools work seamlessly with LangChain, enabling powerful AI agent workflows:
|
|
166
203
|
|
|
167
204
|
```python
|
|
205
|
+
import os
|
|
168
206
|
from langchain_openai import ChatOpenAI
|
|
169
207
|
from stackone_ai import StackOneToolSet
|
|
170
208
|
|
|
171
209
|
# Initialize StackOne tools
|
|
172
210
|
toolset = StackOneToolSet()
|
|
173
|
-
|
|
211
|
+
account_id = os.getenv("STACKONE_ACCOUNT_ID")
|
|
212
|
+
tools = toolset.fetch_tools(actions=["workday_*"], account_ids=[account_id])
|
|
174
213
|
|
|
175
214
|
# Convert to LangChain format
|
|
176
215
|
langchain_tools = tools.to_langchain()
|
|
177
216
|
|
|
178
217
|
# Use with LangChain models
|
|
179
|
-
model = ChatOpenAI(model="gpt-
|
|
218
|
+
model = ChatOpenAI(model="gpt-5.4")
|
|
180
219
|
model_with_tools = model.bind_tools(langchain_tools)
|
|
181
220
|
|
|
182
221
|
# Execute AI-driven tool calls
|
|
@@ -192,6 +231,43 @@ for tool_call in response.tool_calls:
|
|
|
192
231
|
|
|
193
232
|
</details>
|
|
194
233
|
|
|
234
|
+
<details>
|
|
235
|
+
<summary>Pydantic AI Integration</summary>
|
|
236
|
+
|
|
237
|
+
StackOne tools convert to Pydantic AI `Tool` instances via `.to_pydantic_ai()`, parallel to `.to_openai()` and `.to_langchain()`:
|
|
238
|
+
|
|
239
|
+
Prerequisites:
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
pip install 'stackone-ai[pydantic-ai]'
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
import os
|
|
247
|
+
from pydantic_ai import Agent
|
|
248
|
+
from stackone_ai import StackOneToolSet
|
|
249
|
+
|
|
250
|
+
toolset = StackOneToolSet()
|
|
251
|
+
tools = toolset.fetch_tools(
|
|
252
|
+
actions=["workday_list_workers", "workday_get_worker"],
|
|
253
|
+
account_ids=[os.environ["STACKONE_ACCOUNT_ID"]],
|
|
254
|
+
).to_pydantic_ai()
|
|
255
|
+
|
|
256
|
+
agent = Agent("openai:gpt-5.4", tools=tools)
|
|
257
|
+
result = agent.run_sync("List the first 5 employees")
|
|
258
|
+
print(result.output)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
For the full catalog (or the meta search/execute tools), use the `.pydantic_ai()` method on `StackOneToolSet` — parallel to `.openai()` / `.langchain()`:
|
|
262
|
+
|
|
263
|
+
```python
|
|
264
|
+
toolset = StackOneToolSet()
|
|
265
|
+
tools = toolset.pydantic_ai(account_ids=[os.environ["STACKONE_ACCOUNT_ID"]])
|
|
266
|
+
# or pydantic_ai(mode="search_and_execute") for agent-driven discovery
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
</details>
|
|
270
|
+
|
|
195
271
|
<details>
|
|
196
272
|
<summary>LangGraph Integration</summary>
|
|
197
273
|
|
|
@@ -204,6 +280,7 @@ pip install langgraph langchain-openai
|
|
|
204
280
|
```
|
|
205
281
|
|
|
206
282
|
```python
|
|
283
|
+
import os
|
|
207
284
|
from langchain_openai import ChatOpenAI
|
|
208
285
|
from typing import Annotated
|
|
209
286
|
from typing_extensions import TypedDict
|
|
@@ -217,7 +294,8 @@ from stackone_ai.integrations.langgraph import to_tool_node, bind_model_with_too
|
|
|
217
294
|
|
|
218
295
|
# Prepare tools
|
|
219
296
|
toolset = StackOneToolSet()
|
|
220
|
-
|
|
297
|
+
account_id = os.getenv("STACKONE_ACCOUNT_ID")
|
|
298
|
+
tools = toolset.fetch_tools(actions=["workday_*"], account_ids=[account_id])
|
|
221
299
|
langchain_tools = tools.to_langchain()
|
|
222
300
|
|
|
223
301
|
class State(TypedDict):
|
|
@@ -228,7 +306,7 @@ graph = StateGraph(State)
|
|
|
228
306
|
graph.add_node("tools", to_tool_node(langchain_tools))
|
|
229
307
|
|
|
230
308
|
def call_llm(state: dict):
|
|
231
|
-
llm = ChatOpenAI(model="gpt-
|
|
309
|
+
llm = ChatOpenAI(model="gpt-5.4")
|
|
232
310
|
llm = bind_model_with_tools(llm, langchain_tools)
|
|
233
311
|
resp = llm.invoke(state["messages"]) # returns AIMessage with optional tool_calls
|
|
234
312
|
return {"messages": state["messages"] + [resp]}
|
|
@@ -250,12 +328,14 @@ _ = app.invoke({"messages": [("user", "Get employee with id emp123") ]})
|
|
|
250
328
|
CrewAI uses LangChain tools natively, making integration seamless:
|
|
251
329
|
|
|
252
330
|
```python
|
|
331
|
+
import os
|
|
253
332
|
from crewai import Agent, Crew, Task
|
|
254
333
|
from stackone_ai import StackOneToolSet
|
|
255
334
|
|
|
256
335
|
# Get tools and convert to LangChain format
|
|
257
336
|
toolset = StackOneToolSet()
|
|
258
|
-
|
|
337
|
+
account_id = os.getenv("STACKONE_ACCOUNT_ID")
|
|
338
|
+
tools = toolset.fetch_tools(actions=["workday_*"], account_ids=[account_id])
|
|
259
339
|
langchain_tools = tools.to_langchain()
|
|
260
340
|
|
|
261
341
|
# Create CrewAI agent with StackOne tools
|
|
@@ -264,7 +344,7 @@ agent = Agent(
|
|
|
264
344
|
goal="Analyze employee data and generate insights",
|
|
265
345
|
backstory="Expert in HR analytics and employee management",
|
|
266
346
|
tools=langchain_tools,
|
|
267
|
-
llm="gpt-
|
|
347
|
+
llm="gpt-5.4"
|
|
268
348
|
)
|
|
269
349
|
|
|
270
350
|
# Define task and execute
|
|
@@ -297,7 +377,7 @@ feedback_tool = tools.get_tool("tool_feedback")
|
|
|
297
377
|
result = feedback_tool.call(
|
|
298
378
|
feedback="The HRIS tools are working great! Very fast response times.",
|
|
299
379
|
account_id="acc_123456",
|
|
300
|
-
tool_names=["
|
|
380
|
+
tool_names=["workday_list_workers", "workday_get_worker"]
|
|
301
381
|
)
|
|
302
382
|
```
|
|
303
383
|
|
|
@@ -313,9 +393,12 @@ Search for tools using natural language queries. Works with both semantic (cloud
|
|
|
313
393
|
### Basic Usage
|
|
314
394
|
|
|
315
395
|
```python
|
|
396
|
+
import os
|
|
397
|
+
|
|
316
398
|
# Get a callable search tool
|
|
317
399
|
toolset = StackOneToolSet()
|
|
318
|
-
|
|
400
|
+
account_id = os.getenv("STACKONE_ACCOUNT_ID")
|
|
401
|
+
all_tools = toolset.fetch_tools(account_ids=[account_id])
|
|
319
402
|
search_tool = toolset.get_search_tool()
|
|
320
403
|
|
|
321
404
|
# Search for relevant tools — returns a Tools collection
|
|
@@ -327,15 +410,17 @@ tools[0](limit=10)
|
|
|
327
410
|
|
|
328
411
|
## Semantic Search
|
|
329
412
|
|
|
330
|
-
Discover tools using natural language instead of exact names. Queries like "onboard new hire" resolve to the right actions even when the tool is called `
|
|
413
|
+
Discover tools using natural language instead of exact names. Queries like "onboard new hire" resolve to the right actions even when the tool is called `workday_create_employee`.
|
|
331
414
|
|
|
332
415
|
```python
|
|
416
|
+
import os
|
|
333
417
|
from stackone_ai import StackOneToolSet
|
|
334
418
|
|
|
335
419
|
toolset = StackOneToolSet()
|
|
336
420
|
|
|
337
421
|
# Search by intent — returns Tools collection ready for any framework
|
|
338
|
-
|
|
422
|
+
account_id = os.getenv("STACKONE_ACCOUNT_ID")
|
|
423
|
+
tools = toolset.search_tools("manage employee records", account_ids=[account_id], top_k=5)
|
|
339
424
|
openai_tools = tools.to_openai()
|
|
340
425
|
|
|
341
426
|
# Lightweight: inspect results without fetching full tool definitions
|
|
@@ -357,19 +442,31 @@ tools = toolset.search_tools("manage employees", search="semantic")
|
|
|
357
442
|
tools = toolset.search_tools("manage employees", search="local")
|
|
358
443
|
```
|
|
359
444
|
|
|
360
|
-
Results are automatically scoped to connectors in your linked accounts. See [
|
|
445
|
+
Results are automatically scoped to connectors in your linked accounts. See [Search Tools Example](examples/search_tools.py) for `SearchTool` (`get_search_tool`) integration, OpenAI, and LangChain patterns.
|
|
361
446
|
|
|
362
447
|
## Examples
|
|
363
448
|
|
|
364
449
|
For more examples, check out the [examples/](examples/) directory:
|
|
365
450
|
|
|
366
|
-
- [
|
|
367
|
-
- [
|
|
368
|
-
- [
|
|
369
|
-
- [
|
|
370
|
-
- [
|
|
371
|
-
|
|
372
|
-
|
|
451
|
+
- [OpenAI Integration](examples/openai_integration.py) — OpenAI function calling
|
|
452
|
+
- [LangChain Integration](examples/langchain_integration.py) — LangChain tools
|
|
453
|
+
- [CrewAI Integration](examples/crewai_integration.py) — CrewAI agent
|
|
454
|
+
- [Search Tools](examples/search_tools.py) — Tool discovery (semantic, local, auto search)
|
|
455
|
+
- [Auth Management](examples/auth_management.py) — API key and account ID patterns
|
|
456
|
+
|
|
457
|
+
### Running Examples
|
|
458
|
+
|
|
459
|
+
```bash
|
|
460
|
+
# 1. Set up credentials
|
|
461
|
+
cp .env.example .env
|
|
462
|
+
# Edit .env with your API keys
|
|
463
|
+
|
|
464
|
+
# 2. Install dependencies
|
|
465
|
+
uv sync --all-extras
|
|
466
|
+
|
|
467
|
+
# 3. Run any example
|
|
468
|
+
uv run examples/search_tools.py
|
|
469
|
+
```
|
|
373
470
|
|
|
374
471
|
## Development
|
|
375
472
|
|
|
@@ -1,35 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: stackone-ai
|
|
3
|
-
Version: 2.7.0
|
|
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.10
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
16
|
-
Requires-Python: >=3.10
|
|
17
|
-
Requires-Dist: bm25s>=0.2.2
|
|
18
|
-
Requires-Dist: httpx>=0.28.0
|
|
19
|
-
Requires-Dist: langchain-core>=0.1.0
|
|
20
|
-
Requires-Dist: numpy>=1.24.0
|
|
21
|
-
Requires-Dist: pydantic>=2.10.6
|
|
22
|
-
Requires-Dist: typing-extensions>=4.0.0
|
|
23
|
-
Provides-Extra: examples
|
|
24
|
-
Requires-Dist: crewai>=0.102.0; extra == 'examples'
|
|
25
|
-
Requires-Dist: langchain-openai>=0.3.6; extra == 'examples'
|
|
26
|
-
Requires-Dist: langgraph>=0.2.0; extra == 'examples'
|
|
27
|
-
Requires-Dist: openai>=1.63.2; extra == 'examples'
|
|
28
|
-
Requires-Dist: python-dotenv>=1.0.1; extra == 'examples'
|
|
29
|
-
Provides-Extra: mcp
|
|
30
|
-
Requires-Dist: mcp>=1.3.0; extra == 'mcp'
|
|
31
|
-
Description-Content-Type: text/markdown
|
|
32
|
-
|
|
33
1
|
# StackOne AI SDK
|
|
34
2
|
|
|
35
3
|
[](https://badge.fury.io/py/stackone-ai)
|
|
@@ -58,6 +26,7 @@ StackOne AI provides a unified interface for accessing various SaaS tools throug
|
|
|
58
26
|
- LangChain Tools
|
|
59
27
|
- CrewAI Tools
|
|
60
28
|
- LangGraph Tool Node
|
|
29
|
+
- Pydantic AI Toolset
|
|
61
30
|
|
|
62
31
|
## Requirements
|
|
63
32
|
|
|
@@ -84,17 +53,18 @@ uv add 'stackone-ai[mcp,examples]'
|
|
|
84
53
|
## Quick Start
|
|
85
54
|
|
|
86
55
|
```python
|
|
56
|
+
import os
|
|
87
57
|
from stackone_ai import StackOneToolSet
|
|
88
58
|
|
|
89
|
-
# Initialize
|
|
90
|
-
toolset = StackOneToolSet()
|
|
91
|
-
# Or explicitly: toolset = StackOneToolSet(api_key="your-api-key")
|
|
59
|
+
# Initialize — reads STACKONE_API_KEY from environment
|
|
60
|
+
toolset = StackOneToolSet()
|
|
92
61
|
|
|
93
|
-
#
|
|
94
|
-
|
|
62
|
+
# Fetch tools — pass account ID from STACKONE_ACCOUNT_ID env var
|
|
63
|
+
account_id = os.getenv("STACKONE_ACCOUNT_ID")
|
|
64
|
+
tools = toolset.fetch_tools(actions=["workday_*"], account_ids=[account_id])
|
|
95
65
|
|
|
96
66
|
# Use a specific tool with the call method
|
|
97
|
-
employee_tool = tools.get_tool("
|
|
67
|
+
employee_tool = tools.get_tool("workday_get_worker")
|
|
98
68
|
# Call with keyword arguments
|
|
99
69
|
employee = employee_tool.call(id="employee-id")
|
|
100
70
|
# Or with traditional execute method
|
|
@@ -118,7 +88,7 @@ toolset = StackOneToolSet()
|
|
|
118
88
|
tools = toolset.fetch_tools(account_ids=["acc-123", "acc-456"])
|
|
119
89
|
|
|
120
90
|
# Filter by providers (case-insensitive)
|
|
121
|
-
tools = toolset.fetch_tools(providers=["hibob", "
|
|
91
|
+
tools = toolset.fetch_tools(providers=["hibob", "workday"])
|
|
122
92
|
|
|
123
93
|
# Filter by action patterns with glob support
|
|
124
94
|
tools = toolset.fetch_tools(actions=["*_list_employees"])
|
|
@@ -138,11 +108,11 @@ tools = toolset.fetch_tools(providers=["hibob"])
|
|
|
138
108
|
**Filtering Options:**
|
|
139
109
|
|
|
140
110
|
- **`account_ids`**: Filter tools by account IDs. Tools will be loaded for each specified account.
|
|
141
|
-
- **`providers`**: Filter by provider names (e.g., `["hibob", "
|
|
111
|
+
- **`providers`**: Filter by provider names (e.g., `["hibob", "workday"]`). Case-insensitive matching.
|
|
142
112
|
- **`actions`**: Filter by action patterns with glob support:
|
|
143
|
-
- Exact match: `["
|
|
113
|
+
- Exact match: `["workday_list_workers"]`
|
|
144
114
|
- Glob pattern: `["*_list_employees"]` matches all tools ending with `_list_employees`
|
|
145
|
-
- Provider prefix: `["
|
|
115
|
+
- Provider prefix: `["workday_*"]` matches all Workday tools
|
|
146
116
|
|
|
147
117
|
## Implicit Feedback (Beta)
|
|
148
118
|
|
|
@@ -197,18 +167,20 @@ When two calls for the same session happen within a few seconds, the SDK emits a
|
|
|
197
167
|
StackOne tools work seamlessly with LangChain, enabling powerful AI agent workflows:
|
|
198
168
|
|
|
199
169
|
```python
|
|
170
|
+
import os
|
|
200
171
|
from langchain_openai import ChatOpenAI
|
|
201
172
|
from stackone_ai import StackOneToolSet
|
|
202
173
|
|
|
203
174
|
# Initialize StackOne tools
|
|
204
175
|
toolset = StackOneToolSet()
|
|
205
|
-
|
|
176
|
+
account_id = os.getenv("STACKONE_ACCOUNT_ID")
|
|
177
|
+
tools = toolset.fetch_tools(actions=["workday_*"], account_ids=[account_id])
|
|
206
178
|
|
|
207
179
|
# Convert to LangChain format
|
|
208
180
|
langchain_tools = tools.to_langchain()
|
|
209
181
|
|
|
210
182
|
# Use with LangChain models
|
|
211
|
-
model = ChatOpenAI(model="gpt-
|
|
183
|
+
model = ChatOpenAI(model="gpt-5.4")
|
|
212
184
|
model_with_tools = model.bind_tools(langchain_tools)
|
|
213
185
|
|
|
214
186
|
# Execute AI-driven tool calls
|
|
@@ -224,6 +196,43 @@ for tool_call in response.tool_calls:
|
|
|
224
196
|
|
|
225
197
|
</details>
|
|
226
198
|
|
|
199
|
+
<details>
|
|
200
|
+
<summary>Pydantic AI Integration</summary>
|
|
201
|
+
|
|
202
|
+
StackOne tools convert to Pydantic AI `Tool` instances via `.to_pydantic_ai()`, parallel to `.to_openai()` and `.to_langchain()`:
|
|
203
|
+
|
|
204
|
+
Prerequisites:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
pip install 'stackone-ai[pydantic-ai]'
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
import os
|
|
212
|
+
from pydantic_ai import Agent
|
|
213
|
+
from stackone_ai import StackOneToolSet
|
|
214
|
+
|
|
215
|
+
toolset = StackOneToolSet()
|
|
216
|
+
tools = toolset.fetch_tools(
|
|
217
|
+
actions=["workday_list_workers", "workday_get_worker"],
|
|
218
|
+
account_ids=[os.environ["STACKONE_ACCOUNT_ID"]],
|
|
219
|
+
).to_pydantic_ai()
|
|
220
|
+
|
|
221
|
+
agent = Agent("openai:gpt-5.4", tools=tools)
|
|
222
|
+
result = agent.run_sync("List the first 5 employees")
|
|
223
|
+
print(result.output)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
For the full catalog (or the meta search/execute tools), use the `.pydantic_ai()` method on `StackOneToolSet` — parallel to `.openai()` / `.langchain()`:
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
toolset = StackOneToolSet()
|
|
230
|
+
tools = toolset.pydantic_ai(account_ids=[os.environ["STACKONE_ACCOUNT_ID"]])
|
|
231
|
+
# or pydantic_ai(mode="search_and_execute") for agent-driven discovery
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
</details>
|
|
235
|
+
|
|
227
236
|
<details>
|
|
228
237
|
<summary>LangGraph Integration</summary>
|
|
229
238
|
|
|
@@ -236,6 +245,7 @@ pip install langgraph langchain-openai
|
|
|
236
245
|
```
|
|
237
246
|
|
|
238
247
|
```python
|
|
248
|
+
import os
|
|
239
249
|
from langchain_openai import ChatOpenAI
|
|
240
250
|
from typing import Annotated
|
|
241
251
|
from typing_extensions import TypedDict
|
|
@@ -249,7 +259,8 @@ from stackone_ai.integrations.langgraph import to_tool_node, bind_model_with_too
|
|
|
249
259
|
|
|
250
260
|
# Prepare tools
|
|
251
261
|
toolset = StackOneToolSet()
|
|
252
|
-
|
|
262
|
+
account_id = os.getenv("STACKONE_ACCOUNT_ID")
|
|
263
|
+
tools = toolset.fetch_tools(actions=["workday_*"], account_ids=[account_id])
|
|
253
264
|
langchain_tools = tools.to_langchain()
|
|
254
265
|
|
|
255
266
|
class State(TypedDict):
|
|
@@ -260,7 +271,7 @@ graph = StateGraph(State)
|
|
|
260
271
|
graph.add_node("tools", to_tool_node(langchain_tools))
|
|
261
272
|
|
|
262
273
|
def call_llm(state: dict):
|
|
263
|
-
llm = ChatOpenAI(model="gpt-
|
|
274
|
+
llm = ChatOpenAI(model="gpt-5.4")
|
|
264
275
|
llm = bind_model_with_tools(llm, langchain_tools)
|
|
265
276
|
resp = llm.invoke(state["messages"]) # returns AIMessage with optional tool_calls
|
|
266
277
|
return {"messages": state["messages"] + [resp]}
|
|
@@ -282,12 +293,14 @@ _ = app.invoke({"messages": [("user", "Get employee with id emp123") ]})
|
|
|
282
293
|
CrewAI uses LangChain tools natively, making integration seamless:
|
|
283
294
|
|
|
284
295
|
```python
|
|
296
|
+
import os
|
|
285
297
|
from crewai import Agent, Crew, Task
|
|
286
298
|
from stackone_ai import StackOneToolSet
|
|
287
299
|
|
|
288
300
|
# Get tools and convert to LangChain format
|
|
289
301
|
toolset = StackOneToolSet()
|
|
290
|
-
|
|
302
|
+
account_id = os.getenv("STACKONE_ACCOUNT_ID")
|
|
303
|
+
tools = toolset.fetch_tools(actions=["workday_*"], account_ids=[account_id])
|
|
291
304
|
langchain_tools = tools.to_langchain()
|
|
292
305
|
|
|
293
306
|
# Create CrewAI agent with StackOne tools
|
|
@@ -296,7 +309,7 @@ agent = Agent(
|
|
|
296
309
|
goal="Analyze employee data and generate insights",
|
|
297
310
|
backstory="Expert in HR analytics and employee management",
|
|
298
311
|
tools=langchain_tools,
|
|
299
|
-
llm="gpt-
|
|
312
|
+
llm="gpt-5.4"
|
|
300
313
|
)
|
|
301
314
|
|
|
302
315
|
# Define task and execute
|
|
@@ -329,7 +342,7 @@ feedback_tool = tools.get_tool("tool_feedback")
|
|
|
329
342
|
result = feedback_tool.call(
|
|
330
343
|
feedback="The HRIS tools are working great! Very fast response times.",
|
|
331
344
|
account_id="acc_123456",
|
|
332
|
-
tool_names=["
|
|
345
|
+
tool_names=["workday_list_workers", "workday_get_worker"]
|
|
333
346
|
)
|
|
334
347
|
```
|
|
335
348
|
|
|
@@ -345,9 +358,12 @@ Search for tools using natural language queries. Works with both semantic (cloud
|
|
|
345
358
|
### Basic Usage
|
|
346
359
|
|
|
347
360
|
```python
|
|
361
|
+
import os
|
|
362
|
+
|
|
348
363
|
# Get a callable search tool
|
|
349
364
|
toolset = StackOneToolSet()
|
|
350
|
-
|
|
365
|
+
account_id = os.getenv("STACKONE_ACCOUNT_ID")
|
|
366
|
+
all_tools = toolset.fetch_tools(account_ids=[account_id])
|
|
351
367
|
search_tool = toolset.get_search_tool()
|
|
352
368
|
|
|
353
369
|
# Search for relevant tools — returns a Tools collection
|
|
@@ -359,15 +375,17 @@ tools[0](limit=10)
|
|
|
359
375
|
|
|
360
376
|
## Semantic Search
|
|
361
377
|
|
|
362
|
-
Discover tools using natural language instead of exact names. Queries like "onboard new hire" resolve to the right actions even when the tool is called `
|
|
378
|
+
Discover tools using natural language instead of exact names. Queries like "onboard new hire" resolve to the right actions even when the tool is called `workday_create_employee`.
|
|
363
379
|
|
|
364
380
|
```python
|
|
381
|
+
import os
|
|
365
382
|
from stackone_ai import StackOneToolSet
|
|
366
383
|
|
|
367
384
|
toolset = StackOneToolSet()
|
|
368
385
|
|
|
369
386
|
# Search by intent — returns Tools collection ready for any framework
|
|
370
|
-
|
|
387
|
+
account_id = os.getenv("STACKONE_ACCOUNT_ID")
|
|
388
|
+
tools = toolset.search_tools("manage employee records", account_ids=[account_id], top_k=5)
|
|
371
389
|
openai_tools = tools.to_openai()
|
|
372
390
|
|
|
373
391
|
# Lightweight: inspect results without fetching full tool definitions
|
|
@@ -389,19 +407,31 @@ tools = toolset.search_tools("manage employees", search="semantic")
|
|
|
389
407
|
tools = toolset.search_tools("manage employees", search="local")
|
|
390
408
|
```
|
|
391
409
|
|
|
392
|
-
Results are automatically scoped to connectors in your linked accounts. See [
|
|
410
|
+
Results are automatically scoped to connectors in your linked accounts. See [Search Tools Example](examples/search_tools.py) for `SearchTool` (`get_search_tool`) integration, OpenAI, and LangChain patterns.
|
|
393
411
|
|
|
394
412
|
## Examples
|
|
395
413
|
|
|
396
414
|
For more examples, check out the [examples/](examples/) directory:
|
|
397
415
|
|
|
398
|
-
- [
|
|
399
|
-
- [
|
|
400
|
-
- [
|
|
401
|
-
- [
|
|
402
|
-
- [
|
|
403
|
-
|
|
404
|
-
|
|
416
|
+
- [OpenAI Integration](examples/openai_integration.py) — OpenAI function calling
|
|
417
|
+
- [LangChain Integration](examples/langchain_integration.py) — LangChain tools
|
|
418
|
+
- [CrewAI Integration](examples/crewai_integration.py) — CrewAI agent
|
|
419
|
+
- [Search Tools](examples/search_tools.py) — Tool discovery (semantic, local, auto search)
|
|
420
|
+
- [Auth Management](examples/auth_management.py) — API key and account ID patterns
|
|
421
|
+
|
|
422
|
+
### Running Examples
|
|
423
|
+
|
|
424
|
+
```bash
|
|
425
|
+
# 1. Set up credentials
|
|
426
|
+
cp .env.example .env
|
|
427
|
+
# Edit .env with your API keys
|
|
428
|
+
|
|
429
|
+
# 2. Install dependencies
|
|
430
|
+
uv sync --all-extras
|
|
431
|
+
|
|
432
|
+
# 3. Run any example
|
|
433
|
+
uv run examples/search_tools.py
|
|
434
|
+
```
|
|
405
435
|
|
|
406
436
|
## Development
|
|
407
437
|
|