sensu-sdk 0.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,93 @@
1
+ # ============================================================
2
+ # Environment & Secrets — NEVER commit these
3
+ # ============================================================
4
+ # Claude Code project settings may contain API keys in allowed-command lists
5
+ .claude/
6
+ .env
7
+ .env.*
8
+ **/.env
9
+ **/.env.*
10
+ !.env.example
11
+ !**/.env.example
12
+
13
+ # ============================================================
14
+ # Node
15
+ # ============================================================
16
+ node_modules/
17
+ .pnp
18
+ .pnp.js
19
+
20
+ # ============================================================
21
+ # Build outputs
22
+ # ============================================================
23
+ dist/
24
+ build/
25
+ **/dist/
26
+ **/build/
27
+ apps/vscode-extension/out/
28
+ apps/vscode-extension/.vsix-stage/
29
+ apps/vscode-extension/*.vsix
30
+
31
+ # ============================================================
32
+ # Logs
33
+ # ============================================================
34
+ *.log
35
+ npm-debug.log*
36
+ yarn-debug.log*
37
+ yarn-error.log*
38
+ pnpm-debug.log*
39
+
40
+ # ============================================================
41
+ # OS / Editor
42
+ # ============================================================
43
+ .DS_Store
44
+ Thumbs.db
45
+ .vscode/settings.json
46
+ .idea/
47
+ *.swp
48
+ *.swo
49
+
50
+ # ============================================================
51
+ # Testing / Coverage
52
+ # ============================================================
53
+ coverage/
54
+ .nyc_output/
55
+
56
+ # ============================================================
57
+ # Vite / Turbo caches
58
+ # ============================================================
59
+ .vite/
60
+ .turbo/
61
+
62
+ # ============================================================
63
+ # VS Code extension
64
+ # ============================================================
65
+ apps/web/.env.local
66
+
67
+ # ============================================================
68
+ # pnpm
69
+ # ============================================================
70
+ .pnpm-store/
71
+
72
+
73
+ COMPANY_INFO.md
74
+ DEPLOYMENT_STRATEGY.md
75
+ MONETIZATION_STRATEGY.md
76
+ PLANNING_FOR_PHASE_1.md
77
+ PLANNING_FOR_PHASE_*.md
78
+ EVENT_TRACKING_VALUE_ADD.md
79
+ STYLING_SUGGESTIONS.md
80
+ PYTHON_DISCOVERY.md
81
+ QUOTA_ENFORCEMENT_STRATEGY.md
82
+ PRODUCT_DIFFERENTIATION_ENHANCEMENTS.md
83
+ PLANNED_PRODUCT_ENHANCEMENTS.md
84
+ FIX_CURRENTLY_BROKEN.md
85
+ CURRENT_DEVELOPMENT_ITEMS.md
86
+ DEMO_IDEAS.md
87
+ FURTHER_RESEARCH_FOR_YCOMBINATOR.md
88
+ LIVE_PRICING_FEATURE.md
89
+ .npmrc
90
+
91
+ **/.npmrc
92
+ packages/.npmrc
93
+
@@ -0,0 +1,109 @@
1
+ Metadata-Version: 2.4
2
+ Name: sensu-sdk
3
+ Version: 0.6.0
4
+ Summary: Python SDK for the Sensu AI observability platform
5
+ Project-URL: Homepage, https://sensu-ai.com
6
+ Project-URL: Repository, https://github.com/sensu-inc/sensu
7
+ Author: Sensu Inc
8
+ License: MIT
9
+ Keywords: agents,ai,llm,observability,telemetry
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Requires-Python: >=3.9
17
+ Requires-Dist: httpx>=0.25.0
18
+ Requires-Dist: typing-extensions>=4.0; python_version < '3.11'
19
+ Provides-Extra: all
20
+ Requires-Dist: anthropic>=0.20.0; extra == 'all'
21
+ Requires-Dist: langchain>=0.1.0; extra == 'all'
22
+ Requires-Dist: openai>=1.0.0; extra == 'all'
23
+ Provides-Extra: anthropic
24
+ Requires-Dist: anthropic>=0.20.0; extra == 'anthropic'
25
+ Provides-Extra: dev
26
+ Requires-Dist: anyio[trio]; extra == 'dev'
27
+ Requires-Dist: mypy>=1.0; extra == 'dev'
28
+ Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
29
+ Requires-Dist: pytest>=7.0; extra == 'dev'
30
+ Requires-Dist: ruff; extra == 'dev'
31
+ Provides-Extra: langchain
32
+ Requires-Dist: langchain>=0.1.0; extra == 'langchain'
33
+ Provides-Extra: openai
34
+ Requires-Dist: openai>=1.0.0; extra == 'openai'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # sensu-sdk
38
+
39
+ Python SDK for the [Sensu](https://sensu-ai.com) AI observability platform.
40
+
41
+ > Migrating from `senzu-sdk`? The package was renamed; install `sensu-sdk` and replace `from senzu import SenzuClient` with `from sensu import SensuClient`. The legacy `senzu-sdk` v0.5.x package will continue to work but receives no further updates.
42
+
43
+ ## Installation
44
+
45
+ ```bash
46
+ pip install sensu-sdk # core
47
+ pip install "sensu-sdk[anthropic]" # + Anthropic auto-tracking
48
+ pip install "sensu-sdk[openai]" # + OpenAI auto-tracking
49
+ pip install "sensu-sdk[langchain]" # + LangChain callback handler
50
+ pip install "sensu-sdk[all]" # everything
51
+ ```
52
+
53
+ ## Quick start
54
+
55
+ ```python
56
+ import sensu
57
+
58
+ client = sensu.SensuClient({
59
+ "api_key": "your-api-key",
60
+ "agent_id": "your-agent-id",
61
+ "org_id": "your-org-id",
62
+ })
63
+
64
+ # High-level API with automatic context propagation
65
+ async def handle_request():
66
+ async with client.run({"session_id": "abc"}) as run:
67
+ step = run.start_step({"name": "fetch", "step_type": "tool"})
68
+ result = await step.track_tool({"tool_name": "search", "fn": search})
69
+ await step.end()
70
+
71
+ # Anthropic auto-tracking
72
+ from anthropic import AsyncAnthropic
73
+ from sensu.integrations.anthropic import WrapAnthropicOptions, wrap_anthropic
74
+
75
+ anthropic = wrap_anthropic(
76
+ AsyncAnthropic(),
77
+ WrapAnthropicOptions(client=client),
78
+ )
79
+
80
+ async def chat():
81
+ async with client.run({}) as run:
82
+ # messages.create() is tracked automatically
83
+ return await anthropic.messages.create(
84
+ model="claude-sonnet-4-6",
85
+ max_tokens=1024,
86
+ messages=[{"role": "user", "content": "Hello"}],
87
+ )
88
+ ```
89
+
90
+ ## Environment variables
91
+
92
+ | Variable | Description |
93
+ |---|---|
94
+ | `SENSU_API_KEY` | API key |
95
+ | `SENSU_BASE_URL` | API base URL (default: `http://localhost:3001`) |
96
+ | `SENSU_AGENT_ID` | Agent ID |
97
+ | `SENSU_ORG_ID` | Organisation ID |
98
+
99
+ > The legacy `SENZU_*` names are still read as a fallback and emit a deprecation warning. They will be removed in a future release.
100
+
101
+ Use `from_env=True` to load from environment:
102
+
103
+ ```python
104
+ client = sensu.SensuClient({"from_env": True})
105
+ ```
106
+
107
+ ## License
108
+
109
+ MIT
@@ -0,0 +1,73 @@
1
+ # sensu-sdk
2
+
3
+ Python SDK for the [Sensu](https://sensu-ai.com) AI observability platform.
4
+
5
+ > Migrating from `senzu-sdk`? The package was renamed; install `sensu-sdk` and replace `from senzu import SenzuClient` with `from sensu import SensuClient`. The legacy `senzu-sdk` v0.5.x package will continue to work but receives no further updates.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install sensu-sdk # core
11
+ pip install "sensu-sdk[anthropic]" # + Anthropic auto-tracking
12
+ pip install "sensu-sdk[openai]" # + OpenAI auto-tracking
13
+ pip install "sensu-sdk[langchain]" # + LangChain callback handler
14
+ pip install "sensu-sdk[all]" # everything
15
+ ```
16
+
17
+ ## Quick start
18
+
19
+ ```python
20
+ import sensu
21
+
22
+ client = sensu.SensuClient({
23
+ "api_key": "your-api-key",
24
+ "agent_id": "your-agent-id",
25
+ "org_id": "your-org-id",
26
+ })
27
+
28
+ # High-level API with automatic context propagation
29
+ async def handle_request():
30
+ async with client.run({"session_id": "abc"}) as run:
31
+ step = run.start_step({"name": "fetch", "step_type": "tool"})
32
+ result = await step.track_tool({"tool_name": "search", "fn": search})
33
+ await step.end()
34
+
35
+ # Anthropic auto-tracking
36
+ from anthropic import AsyncAnthropic
37
+ from sensu.integrations.anthropic import WrapAnthropicOptions, wrap_anthropic
38
+
39
+ anthropic = wrap_anthropic(
40
+ AsyncAnthropic(),
41
+ WrapAnthropicOptions(client=client),
42
+ )
43
+
44
+ async def chat():
45
+ async with client.run({}) as run:
46
+ # messages.create() is tracked automatically
47
+ return await anthropic.messages.create(
48
+ model="claude-sonnet-4-6",
49
+ max_tokens=1024,
50
+ messages=[{"role": "user", "content": "Hello"}],
51
+ )
52
+ ```
53
+
54
+ ## Environment variables
55
+
56
+ | Variable | Description |
57
+ |---|---|
58
+ | `SENSU_API_KEY` | API key |
59
+ | `SENSU_BASE_URL` | API base URL (default: `http://localhost:3001`) |
60
+ | `SENSU_AGENT_ID` | Agent ID |
61
+ | `SENSU_ORG_ID` | Organisation ID |
62
+
63
+ > The legacy `SENZU_*` names are still read as a fallback and emit a deprecation warning. They will be removed in a future release.
64
+
65
+ Use `from_env=True` to load from environment:
66
+
67
+ ```python
68
+ client = sensu.SensuClient({"from_env": True})
69
+ ```
70
+
71
+ ## License
72
+
73
+ MIT
@@ -0,0 +1,53 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "sensu-sdk"
7
+ version = "0.6.0"
8
+ description = "Python SDK for the Sensu AI observability platform"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "Sensu Inc" }]
13
+ keywords = ["ai", "observability", "telemetry", "llm", "agents"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.9",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "License :: OSI Approved :: MIT License",
21
+ ]
22
+
23
+ dependencies = [
24
+ "httpx>=0.25.0",
25
+ "typing_extensions>=4.0; python_version < '3.11'",
26
+ ]
27
+
28
+ [project.optional-dependencies]
29
+ anthropic = ["anthropic>=0.20.0"]
30
+ openai = ["openai>=1.0.0"]
31
+ langchain = ["langchain>=0.1.0"]
32
+ all = ["anthropic>=0.20.0", "openai>=1.0.0", "langchain>=0.1.0"]
33
+ dev = [
34
+ "pytest>=7.0",
35
+ "pytest-asyncio>=0.21",
36
+ "anyio[trio]",
37
+ "mypy>=1.0",
38
+ "ruff",
39
+ ]
40
+
41
+ [project.urls]
42
+ Homepage = "https://sensu-ai.com"
43
+ Repository = "https://github.com/sensu-inc/sensu"
44
+
45
+ [tool.hatch.build.targets.wheel]
46
+ packages = ["sensu"]
47
+
48
+ [tool.pytest.ini_options]
49
+ asyncio_mode = "auto"
50
+
51
+ [tool.mypy]
52
+ python_version = "3.9"
53
+ strict = true
@@ -0,0 +1,45 @@
1
+ # Changelog
2
+
3
+ All notable changes to `senzu-sdk` are documented here.
4
+
5
+ Format: each release has a **Breaking Changes**, **Added**, **Changed**, and **Fixed** section. Sections are omitted when empty.
6
+
7
+ ---
8
+
9
+ ## [0.5.3] — 2026-05-07
10
+
11
+ ### Added
12
+ - Initial public release of the Python SDK.
13
+ - `SenzuClient` — core telemetry client with batched event flushing, async context propagation via `contextvars.ContextVar`, thread-safe buffer, and `atexit` process-exit flush.
14
+ - `RunHandle` — represents an agent run; exposes `start_step()`, `record_feedback()`, `record_eval_score()`, `handoff()`, `end()`, and `async with` context manager support.
15
+ - `StepHandle` — represents a step within a run; exposes `track_llm()`, `track_streaming_llm()`, `record_llm()`, `track_tool()`, `track_retrieval()`, `record_retrieval()`, `track_embedding()`, `record_embedding()`, `track_guardrail()`, `record_guardrail()`, `record_prompt_render()`, `end()`, and `async with` support.
16
+ - `senzu.run()` high-level API — wraps an async function with automatic run start/end and ContextVar propagation so nested `track_*` calls resolve the active run implicitly.
17
+ - Client-level shortcut methods — `track_tool()`, `track_retrieval()`, `track_embedding()`, `track_guardrail()` auto-find the active run from context.
18
+ - Multi-agent support — `spawn_run()` (shared trace and session) and `handoff()`.
19
+ - Session management — `start_session()` and `resume_session()`.
20
+ - Prompt management — `deploy_prompt_version()` and `StepHandle.record_prompt_render()`.
21
+ - Loop detection — configurable `loop_threshold` and `on_loop_detected` callback.
22
+ - Dynamic pricing — `resolve_pricing()` fetches live rates from `GET /api/v1/pricing/models/{provider}/{model}` with per-client session cache; returns a `(0.0, 0.0)` sentinel when unavailable rather than fabricating a number.
23
+ - `senzu.integrations.anthropic` — `wrap_anthropic()` patches `client.messages.create()` to auto-track LLM calls including cache token counts.
24
+ - `senzu.integrations.openai` — `wrap_openai()` patches `client.chat.completions.create()` to auto-track LLM calls.
25
+ - `senzu.integrations.langchain` — `SenzuCallbackHandler` for LangChain chains and agents; tracks LLM calls, tool calls, streaming TTFT, and retry detection.
26
+ - Full `TypedDict` type annotations throughout; compatible with Python 3.9+.
27
+ - GitHub Actions workflow for Trusted Publishing to PyPI on `sdk-python/v*` tag push.
28
+
29
+ ---
30
+
31
+ ## How to release
32
+
33
+ 1. Update `version` in [pyproject.toml](../pyproject.toml) and `__version__` in [senzu/\_\_init\_\_.py](../senzu/__init__.py).
34
+ 2. Add a release entry at the top of this file.
35
+ 3. Commit: `git commit -m "chore(sdk-python): release vX.Y.Z"`
36
+ 4. Tag and push: `git tag sdk-python/vX.Y.Z && git push origin sdk-python/vX.Y.Z`
37
+ 5. GitHub Actions builds and publishes to PyPI automatically via Trusted Publishing.
38
+
39
+ ## Version policy
40
+
41
+ This SDK follows [Semantic Versioning](https://semver.org):
42
+
43
+ - **Patch** (0.5.x) — bug fixes, non-breaking additions (new optional fields, new event types).
44
+ - **Minor** (0.x.0) — new features, new methods, new integrations. Backwards compatible.
45
+ - **Major** (x.0.0) — breaking changes to public method signatures or wire format.
@@ -0,0 +1,117 @@
1
+ """
2
+ Sensu Python SDK — AI observability for agent systems.
3
+
4
+ Quick start (async context propagation):
5
+
6
+ import sensu
7
+
8
+ client = sensu.SensuClient({"from_env": True})
9
+ anthropic = sensu.wrap_anthropic(Anthropic(), sensu.WrapAnthropicOptions(client=client))
10
+
11
+ async def handle_request(user_input: str) -> str:
12
+ async with client.run({}) as run:
13
+ step = run.start_step({"name": "main", "step_type": "llm"})
14
+ result = await anthropic.messages.create(model="claude-sonnet-4-6", ...)
15
+ await step.end()
16
+ return result.content[0].text
17
+
18
+ Quick start (explicit run/step):
19
+
20
+ client = sensu.SensuClient({"api_key": "...", "agent_id": "...", "org_id": "..."})
21
+ run = client.start_run({"session_id": "abc"})
22
+ step = run.start_step({"name": "fetch", "step_type": "tool"})
23
+ result = await step.track_tool({"tool_name": "web_search", "fn": search})
24
+ await step.end()
25
+ await run.end()
26
+ """
27
+
28
+ from sensu._client import RunHandle, SensuClient, StepHandle
29
+ from sensu._types import (
30
+ ContextBreakdown,
31
+ DeployPromptVersionOptions,
32
+ GuardrailResult,
33
+ GuardrailType,
34
+ HandoffOptions,
35
+ MessageSnapshotItem,
36
+ RawEmbeddingOptions,
37
+ RawGuardrailOptions,
38
+ RawLlmCallOptions,
39
+ RawRetrievalOptions,
40
+ RecordEvalScoreOptions,
41
+ RecordFeedbackOptions,
42
+ RecordPromptRenderOptions,
43
+ ResumeSessionOptions,
44
+ RetrievalChunkInput,
45
+ RunOptions,
46
+ SensuClientOptions,
47
+ SpawnRunOptions,
48
+ StartRunOptions,
49
+ StartSessionOptions,
50
+ StartStepOptions,
51
+ TrackEmbeddingOptions,
52
+ TrackGuardrailOptions,
53
+ TrackLlmOptions,
54
+ TrackRetrievalOptions,
55
+ TrackStreamingLlmOptions,
56
+ TrackToolOptions,
57
+ )
58
+
59
+ # Integration option classes — re-exported for ergonomic imports
60
+ from sensu.integrations.anthropic import WrapAnthropicOptions
61
+ from sensu.integrations.openai import WrapOpenAIOptions
62
+
63
+
64
+ def wrap_anthropic(anthropic_client: object, opts: WrapAnthropicOptions) -> object:
65
+ """Wrap an Anthropic client to auto-track messages.create() calls."""
66
+ from sensu.integrations.anthropic import wrap_anthropic as _wrap
67
+ return _wrap(anthropic_client, opts)
68
+
69
+
70
+ def wrap_openai(openai_client: object, opts: WrapOpenAIOptions) -> object:
71
+ """Wrap an OpenAI client to auto-track chat.completions.create() calls."""
72
+ from sensu.integrations.openai import wrap_openai as _wrap
73
+ return _wrap(openai_client, opts)
74
+
75
+
76
+ __version__ = "0.5.3"
77
+
78
+ __all__ = [
79
+ # Core classes
80
+ "SensuClient",
81
+ "RunHandle",
82
+ "StepHandle",
83
+ # Integration helpers
84
+ "wrap_anthropic",
85
+ "wrap_openai",
86
+ "WrapAnthropicOptions",
87
+ "WrapOpenAIOptions",
88
+ # TypedDicts — option types
89
+ "SensuClientOptions",
90
+ "StartRunOptions",
91
+ "RunOptions",
92
+ "StartStepOptions",
93
+ "TrackLlmOptions",
94
+ "TrackStreamingLlmOptions",
95
+ "TrackToolOptions",
96
+ "TrackRetrievalOptions",
97
+ "TrackEmbeddingOptions",
98
+ "TrackGuardrailOptions",
99
+ "RawLlmCallOptions",
100
+ "RawRetrievalOptions",
101
+ "RawEmbeddingOptions",
102
+ "RawGuardrailOptions",
103
+ "RecordFeedbackOptions",
104
+ "RecordEvalScoreOptions",
105
+ "SpawnRunOptions",
106
+ "HandoffOptions",
107
+ "RecordPromptRenderOptions",
108
+ "DeployPromptVersionOptions",
109
+ "StartSessionOptions",
110
+ "ResumeSessionOptions",
111
+ # Supporting types
112
+ "ContextBreakdown",
113
+ "MessageSnapshotItem",
114
+ "RetrievalChunkInput",
115
+ "GuardrailResult",
116
+ "GuardrailType",
117
+ ]