stigmer-sdk 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- stigmer_sdk-0.1.0/.gitignore +181 -0
- stigmer_sdk-0.1.0/Makefile +62 -0
- stigmer_sdk-0.1.0/PKG-INFO +295 -0
- stigmer_sdk-0.1.0/README.md +268 -0
- stigmer_sdk-0.1.0/examples/quickstart.py +34 -0
- stigmer_sdk-0.1.0/pyproject.toml +43 -0
- stigmer_sdk-0.1.0/src/stigmer/__init__.py +165 -0
- stigmer_sdk-0.1.0/src/stigmer/_billing.py +220 -0
- stigmer_sdk-0.1.0/src/stigmer/_client.py +222 -0
- stigmer_sdk-0.1.0/src/stigmer/_file.py +245 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/__init__.py +159 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_agent.py +348 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_apikey.py +146 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_bidi.py +40 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_channel.py +384 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_channelapp.py +169 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_client.py +69 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_environment.py +190 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_errors.py +98 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_eval.py +178 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_evalrun.py +206 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_federationissuer.py +145 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_file.py +134 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_grant.py +187 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_identityaccount.py +213 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_invitation.py +117 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_license.py +174 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_memory.py +143 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_oauthapp.py +154 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_organization.py +229 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_plan.py +130 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_plugin.py +195 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_providerkey.py +54 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_routine.py +296 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_run.py +450 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_score.py +184 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_scoringrule.py +102 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_session.py +247 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_skill.py +166 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_subscription.py +97 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_team.py +124 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_types.py +43 -0
- stigmer_sdk-0.1.0/src/stigmer/_gen/_vault.py +284 -0
- stigmer_sdk-0.1.0/src/stigmer/_github.py +95 -0
- stigmer_sdk-0.1.0/src/stigmer/_interceptors.py +85 -0
- stigmer_sdk-0.1.0/src/stigmer/_runner_adapter.py +58 -0
- stigmer_sdk-0.1.0/src/stigmer/_search.py +97 -0
- stigmer_sdk-0.1.0/src/stigmer/_skill.py +101 -0
- stigmer_sdk-0.1.0/src/stigmer/_tokens.py +137 -0
- stigmer_sdk-0.1.0/src/stigmer/_transport.py +51 -0
- stigmer_sdk-0.1.0/src/stigmer/_turns.py +340 -0
- stigmer_sdk-0.1.0/src/stigmer/py.typed +0 -0
- stigmer_sdk-0.1.0/tests/__init__.py +0 -0
- stigmer_sdk-0.1.0/tests/test_agent_mcp_servers.py +48 -0
- stigmer_sdk-0.1.0/tests/test_billing.py +103 -0
- stigmer_sdk-0.1.0/tests/test_client.py +101 -0
- stigmer_sdk-0.1.0/tests/test_file_routing.py +337 -0
- stigmer_sdk-0.1.0/tests/test_generated_annotations.py +52 -0
- stigmer_sdk-0.1.0/tests/test_github.py +243 -0
- stigmer_sdk-0.1.0/tests/test_optional_scalar_presence.py +41 -0
- stigmer_sdk-0.1.0/tests/test_orgless_kind_input.py +37 -0
- stigmer_sdk-0.1.0/tests/test_pages.py +136 -0
- stigmer_sdk-0.1.0/tests/test_runner_adapter.py +89 -0
- stigmer_sdk-0.1.0/tests/test_skill_routing.py +149 -0
- stigmer_sdk-0.1.0/tests/test_tokens.py +137 -0
- stigmer_sdk-0.1.0/tests/test_transport.py +60 -0
- stigmer_sdk-0.1.0/tests/test_turns.py +277 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Binaries for programs and plugins
|
|
2
|
+
*.exe
|
|
3
|
+
*.exe~
|
|
4
|
+
*.dll
|
|
5
|
+
*.so
|
|
6
|
+
*.dylib
|
|
7
|
+
bin/
|
|
8
|
+
dist/
|
|
9
|
+
# Turborepo's local task cache and per-package task logs (turbo.json).
|
|
10
|
+
.turbo
|
|
11
|
+
dist-slim/
|
|
12
|
+
dist-slim-pkgs/
|
|
13
|
+
# Per-arch trees the Docker image build stages (scripts/smoke-docker-image.mjs).
|
|
14
|
+
dist-slim-amd64/
|
|
15
|
+
dist-slim-arm64/
|
|
16
|
+
# The compose-runner image's CLI tarballs (scripts/stage-compose-runner-cli.mjs).
|
|
17
|
+
backend/services/runner/stage/
|
|
18
|
+
# The server library tarballs a consumer installs (scripts/stage-server-library.mjs).
|
|
19
|
+
backend/services/stigmer-server/stage/
|
|
20
|
+
|
|
21
|
+
# Desktop embedded-runner staging: a symlink in dev (setup-runner-dev.sh),
|
|
22
|
+
# the staged slim artifact in packaged builds (stage-runner-slim.sh).
|
|
23
|
+
client-apps/desktop/src-tauri/resources/runner
|
|
24
|
+
client-apps/desktop/src-tauri/resources/runtime
|
|
25
|
+
|
|
26
|
+
# Test binary, built with `go test -c`
|
|
27
|
+
*.test
|
|
28
|
+
|
|
29
|
+
# Output of the go coverage tool
|
|
30
|
+
*.out
|
|
31
|
+
coverage.txt
|
|
32
|
+
coverage.html
|
|
33
|
+
|
|
34
|
+
# A vitest run's v8 coverage (`--coverage.enabled`), in each package
|
|
35
|
+
coverage/
|
|
36
|
+
|
|
37
|
+
# Stryker's copies of the files it changes in place during a mutation sweep
|
|
38
|
+
# (scripts/mutation-sweep.mjs), which it removes when the run ends
|
|
39
|
+
.stryker-tmp/
|
|
40
|
+
|
|
41
|
+
# Go workspace sum file (auto-generated, can be ignored)
|
|
42
|
+
go.work.sum
|
|
43
|
+
|
|
44
|
+
# Dependency directories (Go)
|
|
45
|
+
vendor/
|
|
46
|
+
|
|
47
|
+
# Python
|
|
48
|
+
__pycache__/
|
|
49
|
+
*.py[cod]
|
|
50
|
+
*$py.class
|
|
51
|
+
*.so
|
|
52
|
+
.Python
|
|
53
|
+
build/
|
|
54
|
+
develop-eggs/
|
|
55
|
+
downloads/
|
|
56
|
+
eggs/
|
|
57
|
+
.eggs/
|
|
58
|
+
/lib/
|
|
59
|
+
/lib64/
|
|
60
|
+
parts/
|
|
61
|
+
sdist/
|
|
62
|
+
var/
|
|
63
|
+
wheels/
|
|
64
|
+
*.egg-info/
|
|
65
|
+
.installed.cfg
|
|
66
|
+
*.egg
|
|
67
|
+
# The setuptools sdist artifact (a FILE named MANIFEST). With
|
|
68
|
+
# core.ignorecase this pattern also swallows source directories named
|
|
69
|
+
# manifest/ (e.g. sdk/*/src/manifest) — the negation re-includes those
|
|
70
|
+
# while the artifact file stays ignored.
|
|
71
|
+
MANIFEST
|
|
72
|
+
!**/manifest/
|
|
73
|
+
*.pyc
|
|
74
|
+
.pytest_cache/
|
|
75
|
+
.coverage
|
|
76
|
+
htmlcov/
|
|
77
|
+
|
|
78
|
+
# Virtual environments
|
|
79
|
+
venv/
|
|
80
|
+
env/
|
|
81
|
+
ENV/
|
|
82
|
+
.venv
|
|
83
|
+
|
|
84
|
+
# IDEs
|
|
85
|
+
.idea/
|
|
86
|
+
.vscode/
|
|
87
|
+
*.swp
|
|
88
|
+
*.swo
|
|
89
|
+
*~
|
|
90
|
+
.DS_Store
|
|
91
|
+
|
|
92
|
+
# Java / Maven
|
|
93
|
+
target/
|
|
94
|
+
|
|
95
|
+
# Node.js
|
|
96
|
+
node_modules/
|
|
97
|
+
|
|
98
|
+
# Stigmer specific
|
|
99
|
+
.stigmer/
|
|
100
|
+
*.skill
|
|
101
|
+
*.db
|
|
102
|
+
*.db-shm
|
|
103
|
+
*.db-wal
|
|
104
|
+
|
|
105
|
+
# Temporary files
|
|
106
|
+
*.log
|
|
107
|
+
# ...except the benchmark fixture's sync log, data the instrument reads
|
|
108
|
+
# (test/conformance/fixtures/working-agent/README.md).
|
|
109
|
+
!test/conformance/fixtures/working-agent/evals/_fixture/workspace/logs/*.log
|
|
110
|
+
*.tmp
|
|
111
|
+
tmp/
|
|
112
|
+
|
|
113
|
+
# Proto generated files (tracked, but ignore in development)
|
|
114
|
+
# We'll commit generated code for now
|
|
115
|
+
# *.pb.go
|
|
116
|
+
# *_pb2.py
|
|
117
|
+
# *_pb2.pyi
|
|
118
|
+
|
|
119
|
+
# Build artifacts
|
|
120
|
+
*.o
|
|
121
|
+
*.a
|
|
122
|
+
*.out
|
|
123
|
+
.agent-runner-image-built
|
|
124
|
+
|
|
125
|
+
# Codegen tool binaries (go build drops these in the module/repo root)
|
|
126
|
+
/generator
|
|
127
|
+
/proto2schema
|
|
128
|
+
tools/codegen/generator/generator
|
|
129
|
+
|
|
130
|
+
# Go service binaries (prevent accidental commits of built binaries in service dirs)
|
|
131
|
+
backend/services/*/stigmer-server
|
|
132
|
+
backend/services/*/agent-runner
|
|
133
|
+
backend/services/*/cmd/*/server
|
|
134
|
+
backend/services/*/server
|
|
135
|
+
|
|
136
|
+
# npm auth tokens (never commit)
|
|
137
|
+
.npmrc
|
|
138
|
+
|
|
139
|
+
# Vale (downloaded style packages — run `vale sync` to fetch)
|
|
140
|
+
vale/styles/Google/
|
|
141
|
+
vale/styles/Microsoft/
|
|
142
|
+
vale/styles/alex/
|
|
143
|
+
|
|
144
|
+
# uv lockfile (project uses Poetry; uv.lock is auto-generated noise)
|
|
145
|
+
uv.lock
|
|
146
|
+
|
|
147
|
+
# Environment files (local secrets, never commit)
|
|
148
|
+
.env
|
|
149
|
+
.env_export
|
|
150
|
+
# Vite local env overrides (e.g. desktop .env.development.local — machine-specific paths)
|
|
151
|
+
.env*.local
|
|
152
|
+
|
|
153
|
+
# Integration test output
|
|
154
|
+
.test-output*/
|
|
155
|
+
|
|
156
|
+
# TypeDoc JSON intermediates (regenerated by `make gen-react-sdk-docs` /
|
|
157
|
+
# `gen-ink-sdk-docs` before every use; they embed the HEAD commit SHA in
|
|
158
|
+
# every source URL, so tracking them creates churn on every SDK commit)
|
|
159
|
+
sdk/*/typedoc-output.json
|
|
160
|
+
|
|
161
|
+
# Cursor
|
|
162
|
+
_cursor/
|
|
163
|
+
_aacursor/
|
|
164
|
+
*.bak
|
|
165
|
+
|
|
166
|
+
# Internal planning/history migrated to the private stigmer-cloud repo (do not re-add)
|
|
167
|
+
_changelog/
|
|
168
|
+
_investigations/
|
|
169
|
+
_projects/
|
|
170
|
+
_roles/
|
|
171
|
+
.cursor/plans/
|
|
172
|
+
|
|
173
|
+
# Compiled codegen toolchain binaries (built ad hoc via `go build` in tools/;
|
|
174
|
+
# the tools are always run via `go run ./tools/codegen/...` — never commit them)
|
|
175
|
+
/tools/generator
|
|
176
|
+
/tools/proto2schema
|
|
177
|
+
/tools/codegen/generator/generator
|
|
178
|
+
/tools/codegen/proto2schema/proto2schema
|
|
179
|
+
|
|
180
|
+
# The docs snippet gate's Python venv and Java classpath (make docs-snippets-toolchains)
|
|
181
|
+
/.docs-snippets-toolchains/
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Stigmer Python SDK - Makefile
|
|
2
|
+
|
|
3
|
+
.PHONY: help
|
|
4
|
+
help: ## Display this help message
|
|
5
|
+
@echo "Stigmer Python SDK - Available targets:"
|
|
6
|
+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-20s\033[0m %s\n", $$1, $$2}'
|
|
7
|
+
|
|
8
|
+
.PHONY: codegen-clients
|
|
9
|
+
codegen-clients: ## Generate SDK client code from service schemas
|
|
10
|
+
@echo "Generating Python SDK client code..."
|
|
11
|
+
@echo " Wiping src/stigmer/_gen/ directory..."
|
|
12
|
+
@rm -rf src/stigmer/_gen
|
|
13
|
+
@mkdir -p src/stigmer/_gen
|
|
14
|
+
@# The generator runs from TypeScript source via the repo-pinned tsx
|
|
15
|
+
@# (never bare npx — oss#531) and reads proto metadata from
|
|
16
|
+
@# @stigmer/apis, which must be built first (incremental; a no-op when
|
|
17
|
+
@# fresh). A bare CI checkout has no dist/ — skipping this fails module
|
|
18
|
+
@# resolution.
|
|
19
|
+
@cd ../.. && test -x node_modules/.bin/tsx || { echo "error: node_modules/.bin/tsx not found — run 'npm install' at the repo root"; exit 1; }
|
|
20
|
+
@cd ../.. && npm run build -w @stigmer/apis --silent
|
|
21
|
+
@cd ../.. && node_modules/.bin/tsx tools/codegen/src/generator/main.ts \
|
|
22
|
+
--schema-dir tools/codegen/schemas \
|
|
23
|
+
--output-dir sdk/python/src/stigmer/_gen \
|
|
24
|
+
--target sdk-client-python
|
|
25
|
+
|
|
26
|
+
.PHONY: codegen
|
|
27
|
+
codegen: codegen-clients ## Run code generation pipeline
|
|
28
|
+
@echo ""
|
|
29
|
+
@echo "Python SDK code generation complete!"
|
|
30
|
+
@echo "Generated files live in src/stigmer/_gen/"
|
|
31
|
+
|
|
32
|
+
.PHONY: codegen-verify
|
|
33
|
+
codegen-verify: codegen ## Generate code and verify syntax
|
|
34
|
+
@echo "Verifying generated Python files..."
|
|
35
|
+
@python3 -c "import ast, pathlib; \
|
|
36
|
+
files = list(pathlib.Path('src/stigmer/_gen').glob('*.py')); \
|
|
37
|
+
[ast.parse(f.read_text()) for f in files]; \
|
|
38
|
+
print(f' {len(files)} files passed syntax check')"
|
|
39
|
+
@echo ""
|
|
40
|
+
@echo "Code generation verified successfully!"
|
|
41
|
+
|
|
42
|
+
# The tests run in a virtual environment (the system Python on Homebrew and
|
|
43
|
+
# Ubuntu 24.04 refuses a global pip install, PEP 668) against the in-tree
|
|
44
|
+
# proto stubs, never PyPI's stigmer-apis, which lags the tree. VENV may sit
|
|
45
|
+
# outside the package, where a build here can never pack it.
|
|
46
|
+
VENV ?= .venv
|
|
47
|
+
PYTHON ?= python3
|
|
48
|
+
|
|
49
|
+
.PHONY: test
|
|
50
|
+
test: ## Run the SDK's tests against the in-tree proto stubs
|
|
51
|
+
@test -x $(VENV)/bin/python || $(PYTHON) -m venv $(VENV)
|
|
52
|
+
@# A .venv made by uv has no pip.
|
|
53
|
+
@$(VENV)/bin/python -m pip --version >/dev/null 2>&1 || $(VENV)/bin/python -m ensurepip --default-pip >/dev/null
|
|
54
|
+
@$(VENV)/bin/python -m pip install --quiet --disable-pip-version-check ../../apis/stubs/python/stigmer
|
|
55
|
+
@$(VENV)/bin/python -m pip install --quiet --disable-pip-version-check -e '.[test]'
|
|
56
|
+
@$(VENV)/bin/python -m pytest tests
|
|
57
|
+
|
|
58
|
+
.PHONY: clean
|
|
59
|
+
clean: ## Clean build artifacts and the test environment
|
|
60
|
+
@rm -rf dist build *.egg-info src/*.egg-info .venv .pytest_cache
|
|
61
|
+
|
|
62
|
+
.DEFAULT_GOAL := help
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: stigmer-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for Stigmer, the open-source backend for the agents in your product
|
|
5
|
+
Project-URL: Homepage, https://stigmer.ai
|
|
6
|
+
Project-URL: Repository, https://github.com/stigmer/stigmer
|
|
7
|
+
Project-URL: Documentation, https://stigmer.ai/docs/sdk/python
|
|
8
|
+
Author-email: Stigmer <engineering@stigmer.ai>
|
|
9
|
+
License-Expression: Apache-2.0
|
|
10
|
+
Keywords: ai-agents,api-client,grpc,sdk,stigmer
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Requires-Dist: grpcio>=1.60.0
|
|
21
|
+
Requires-Dist: protobuf>=6.32.0
|
|
22
|
+
Requires-Dist: stigmer-apis==0.1.0
|
|
23
|
+
Provides-Extra: test
|
|
24
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'test'
|
|
25
|
+
Requires-Dist: pytest>=8; extra == 'test'
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# stigmer
|
|
29
|
+
|
|
30
|
+
Python client for [Stigmer](https://stigmer.ai), the open-source backend for the agents in your product. Provides typed API clients for every Stigmer resource with authentication, error handling, and cross-resource search.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install stigmer-sdk
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
`stigmer-apis` (generated protobuf stubs) is installed automatically as a dependency.
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
Before you start, run Stigmer on your machine with `stigmer up` and give it a model key ([Start Stigmer and add your model key](https://stigmer.ai/docs/getting-started/quickstart#start-stigmer-and-add-your-model-key)). Without a key the server refuses the message, and the program prints why.
|
|
43
|
+
|
|
44
|
+
This program connects to that Stigmer, sets up a small agent, asks it one thing and prints its answer:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
"""The Stigmer quick start: connect to the Stigmer running on this machine,
|
|
48
|
+
set up a small agent, ask it one thing and print its answer.
|
|
49
|
+
|
|
50
|
+
Start Stigmer first with `stigmer up` (given a model key), then:
|
|
51
|
+
python quickstart.py
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
import sys
|
|
55
|
+
|
|
56
|
+
from stigmer import AgentInput, ResourceRef, SessionSpecInput, StigmerClient, StigmerError
|
|
57
|
+
|
|
58
|
+
try:
|
|
59
|
+
# `stigmer up` serves on localhost:7234 and needs no key on your machine.
|
|
60
|
+
with StigmerClient(base_url="localhost:7234", insecure=True) as client:
|
|
61
|
+
# apply creates the agent, or updates it when you run this again.
|
|
62
|
+
agent = client.agents.apply(
|
|
63
|
+
AgentInput(
|
|
64
|
+
name="greeter",
|
|
65
|
+
org="stigmer",
|
|
66
|
+
instructions="You greet people in one short, friendly sentence.",
|
|
67
|
+
)
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
turn = client.send_and_wait(
|
|
71
|
+
org="stigmer",
|
|
72
|
+
session_spec=SessionSpecInput(agent_ref=ResourceRef(org="stigmer", slug=agent.metadata.slug)),
|
|
73
|
+
message="Say hello to a developer trying Stigmer for the first time.",
|
|
74
|
+
)
|
|
75
|
+
except StigmerError as err:
|
|
76
|
+
sys.exit(f"stigmer: {err}")
|
|
77
|
+
|
|
78
|
+
if turn.phase != "completed":
|
|
79
|
+
sys.exit(f"the turn did not complete ({turn.phase}): {turn.error}")
|
|
80
|
+
print(turn.answer)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
It is `examples/quickstart.py`. Run `python quickstart.py`; it prints the agent's answer, for example "Hello, and welcome to Stigmer!".
|
|
84
|
+
|
|
85
|
+
`send_and_wait` sends the message and waits for the agent's answer, reconnecting if the stream drops. A turn that waits for a person's approval returns with `phase` `"waiting"` and its `asks`; answer them with `client.sessions.confirm_tool_use` and call `client.wait_for_turn` with the outcome's `last_seq`.
|
|
86
|
+
|
|
87
|
+
### On Stigmer Cloud
|
|
88
|
+
|
|
89
|
+
Make two changes: connect with an API key, `StigmerClient(os.environ["STIGMER_API_KEY"])` (keys read `stk_…`), and use your own organization, `os.environ["STIGMER_ORG"]`, where the program says `"stigmer"`.
|
|
90
|
+
|
|
91
|
+
## Resource Clients
|
|
92
|
+
|
|
93
|
+
Every resource type has a typed client accessible as a property on `StigmerClient`:
|
|
94
|
+
|
|
95
|
+
| Property | Resource |
|
|
96
|
+
|------------------------|--------------------|
|
|
97
|
+
| `agents` | Agent |
|
|
98
|
+
| `runs` | Run |
|
|
99
|
+
| `api_keys` | ApiKey |
|
|
100
|
+
| `grants` | Grant |
|
|
101
|
+
| `identity_accounts` | IdentityAccount |
|
|
102
|
+
| `federation_issuers` | FederationIssuer |
|
|
103
|
+
| `organizations` | Organization |
|
|
104
|
+
| `plugins` | Plugin |
|
|
105
|
+
| `sessions` | Session |
|
|
106
|
+
| `skills` | Skill |
|
|
107
|
+
| `vaults` | Vault |
|
|
108
|
+
| `search` | Cross-resource search |
|
|
109
|
+
| `tokens` | User-token minting (service-account keys) |
|
|
110
|
+
|
|
111
|
+
## Common Operations
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
import os
|
|
115
|
+
|
|
116
|
+
from ai.stigmer.agentic.agent.v1 import io_pb2 as agent_io_pb2
|
|
117
|
+
from ai.stigmer.commons.apiresource import io_pb2 as apiresource_io_pb2
|
|
118
|
+
from stigmer import StigmerClient, AgentInput, ResourceRef
|
|
119
|
+
|
|
120
|
+
with StigmerClient(os.environ["STIGMER_API_KEY"]) as client:
|
|
121
|
+
# Create
|
|
122
|
+
agent = client.agents.create(AgentInput(
|
|
123
|
+
name="my-agent",
|
|
124
|
+
org="my-org",
|
|
125
|
+
description="Turns a customer's ledger into a variance report",
|
|
126
|
+
instructions="Be helpful and concise.",
|
|
127
|
+
))
|
|
128
|
+
|
|
129
|
+
# Get by ID
|
|
130
|
+
agent = client.agents.get("agent-id")
|
|
131
|
+
|
|
132
|
+
# Get by reference (org + slug)
|
|
133
|
+
agent = client.agents.get_by_reference(ResourceRef(org="my-org", slug="my-agent"))
|
|
134
|
+
|
|
135
|
+
# Update: read, change, then name the fields you changed. Every other
|
|
136
|
+
# field keeps its stored value. The read's etag makes the save fail with
|
|
137
|
+
# "aborted" if someone changed the agent since.
|
|
138
|
+
current = client.agents.get("agent-id")
|
|
139
|
+
current.spec.description = "Updated description"
|
|
140
|
+
updated = client.agents.update(current, ["spec.description"])
|
|
141
|
+
|
|
142
|
+
# Rename: change the slug people type. The id stays, so everything that
|
|
143
|
+
# points at the agent keeps working; the old slug reads for 30 days.
|
|
144
|
+
renamed = client.agents.rename(
|
|
145
|
+
apiresource_io_pb2.RenameInput(resource_id="agent-id", slug="variance-reporter")
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Delete
|
|
149
|
+
deleted = client.agents.delete("agent-id")
|
|
150
|
+
|
|
151
|
+
# List: one page of the org's agents, newest first. A page carries
|
|
152
|
+
# next_page_token while more follow; page_size 0 asks for the default 50.
|
|
153
|
+
page = client.agents.list(agent_io_pb2.ListAgentsRequest(org="my-org", page_size=20))
|
|
154
|
+
|
|
155
|
+
# Every agent, page after page: list_all follows the tokens.
|
|
156
|
+
for a in client.agents.list_all(agent_io_pb2.ListAgentsRequest(org="my-org")):
|
|
157
|
+
print(a.metadata.slug)
|
|
158
|
+
|
|
159
|
+
# Only the agents carrying every label given.
|
|
160
|
+
finance = client.agents.list(
|
|
161
|
+
agent_io_pb2.ListAgentsRequest(org="my-org", labels={"team": "finance"})
|
|
162
|
+
)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Cross-Resource Search
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
import os
|
|
169
|
+
|
|
170
|
+
from stigmer import StigmerClient, ApiResourceKind, SearchParams
|
|
171
|
+
|
|
172
|
+
with StigmerClient(os.environ["STIGMER_API_KEY"]) as client:
|
|
173
|
+
results = client.search.query(SearchParams(
|
|
174
|
+
kinds=[ApiResourceKind.agent, ApiResourceKind.skill],
|
|
175
|
+
org="my-org",
|
|
176
|
+
query="variance report",
|
|
177
|
+
))
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## User Tokens
|
|
181
|
+
|
|
182
|
+
A product that embeds Stigmer mints a short-lived token for each person
|
|
183
|
+
signed in to it, from its own backend, with an ordinary client built on a
|
|
184
|
+
service account's API key. The account must be an admin of the organization
|
|
185
|
+
the token is for, or of its parent organization; a person's key is refused.
|
|
186
|
+
Pass `access_token` to the React SDK's `StigmerProvider` through
|
|
187
|
+
`getAccessToken`:
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
import os
|
|
191
|
+
|
|
192
|
+
from stigmer import StigmerClient
|
|
193
|
+
|
|
194
|
+
with StigmerClient(os.environ["STIGMER_API_KEY"]) as client:
|
|
195
|
+
result = client.tokens.mint_user_token(
|
|
196
|
+
org="acme",
|
|
197
|
+
user_id=user.id,
|
|
198
|
+
user_email=user.email,
|
|
199
|
+
user_name=user.name,
|
|
200
|
+
)
|
|
201
|
+
print(result.access_token, result.expires_at)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Billing
|
|
205
|
+
|
|
206
|
+
An organization's billing account (its Stripe customer), the Stripe portal
|
|
207
|
+
and card setup sessions. Token usage is read from the run client's usage
|
|
208
|
+
reports (`get_run_usage_report`, `get_session_usage_report`,
|
|
209
|
+
`get_agent_usage_report`, `get_org_usage_report`), counted in tokens and never
|
|
210
|
+
priced. Queries require `can_view_billing` on the org and the org's own
|
|
211
|
+
billing commands require `can_manage_billing`. The operator pricing methods
|
|
212
|
+
(`list_model_pricing_baselines`, `upsert_model_pricing_baseline`,
|
|
213
|
+
`retire_model_pricing_baseline`) require `can_manage_model_pricing` on the
|
|
214
|
+
platform:
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
import os
|
|
218
|
+
|
|
219
|
+
from stigmer import CreatePaymentMethodSetupSessionParams, StigmerClient
|
|
220
|
+
|
|
221
|
+
with StigmerClient(os.environ["STIGMER_API_KEY"]) as client:
|
|
222
|
+
account = client.billing.get_billing_account(org)
|
|
223
|
+
|
|
224
|
+
setup = client.billing.create_payment_method_setup_session(
|
|
225
|
+
CreatePaymentMethodSetupSessionParams(
|
|
226
|
+
org=org,
|
|
227
|
+
success_url="https://example.com/billing?setup=success",
|
|
228
|
+
cancel_url="https://example.com/billing",
|
|
229
|
+
)
|
|
230
|
+
)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Error Handling
|
|
234
|
+
|
|
235
|
+
All SDK operations raise `StigmerError` with structured error codes:
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
import os
|
|
239
|
+
|
|
240
|
+
from stigmer import StigmerClient, StigmerError, is_not_found, is_retryable
|
|
241
|
+
|
|
242
|
+
with StigmerClient(os.environ["STIGMER_API_KEY"]) as client:
|
|
243
|
+
try:
|
|
244
|
+
agent = client.agents.get("nonexistent")
|
|
245
|
+
except StigmerError as err:
|
|
246
|
+
if is_not_found(err):
|
|
247
|
+
print("Agent not found")
|
|
248
|
+
elif is_retryable(err):
|
|
249
|
+
print("Transient error, retry later")
|
|
250
|
+
else:
|
|
251
|
+
print(f"Error [{err.code.value}]: {err}")
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
Error codes: `not-found`, `permission-denied`, `unauthenticated`, `invalid-argument`, `already-exists`, `resource-exhausted`, `failed-precondition`, `internal`, `unavailable`, `cancelled`, `unknown`.
|
|
255
|
+
|
|
256
|
+
## Configuration
|
|
257
|
+
|
|
258
|
+
```python
|
|
259
|
+
StigmerClient(
|
|
260
|
+
api_key: str | None = None, # Stigmer API key, "stk_…" (required unless insecure)
|
|
261
|
+
*,
|
|
262
|
+
base_url: str = "api.stigmer.ai:443", # gRPC target address
|
|
263
|
+
insecure: bool = False, # Skip TLS (local development only)
|
|
264
|
+
)
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
On your machine, `stigmer up` serves on `localhost:7234` and needs no key; leave the key out on that plain-text connection, and the client sends no `authorization` header:
|
|
268
|
+
|
|
269
|
+
```python
|
|
270
|
+
client = StigmerClient(base_url="localhost:7234", insecure=True)
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
A client with no key on a TLS connection is refused at construction, as is an empty key.
|
|
274
|
+
|
|
275
|
+
For a CI job or a script, use a [service account's](https://stigmer.ai/docs/guides/authentication/service-accounts) API key, not a person's: it keeps working when that person leaves and works only in its own organization.
|
|
276
|
+
|
|
277
|
+
## Code Generation
|
|
278
|
+
|
|
279
|
+
The resource clients in `src/stigmer/_gen/` are generated from protobuf service schemas. To regenerate after proto changes:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
cd sdk/python
|
|
283
|
+
make codegen
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Handwritten code lives in `src/stigmer/` (outside `_gen/`): `_client.py`, `_transport.py`, `_interceptors.py`, `_search.py`, `_tokens.py`, `_turns.py`, and `__init__.py`.
|
|
287
|
+
|
|
288
|
+
## Tests
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
cd sdk/python
|
|
292
|
+
make test
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
It makes a virtual environment in `.venv`, installs the SDK and the proto stubs from this repository into it (not PyPI's `stigmer-apis`, which can lag the tree), and runs `pytest`. `make clean` removes the environment.
|