actaclad-agentguard 1.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.
@@ -0,0 +1,200 @@
1
+ Metadata-Version: 2.4
2
+ Name: actaclad-agentguard
3
+ Version: 1.1.0
4
+ Summary: Agent Guard observability SDK for Python
5
+ Author: Agent Guard
6
+ Project-URL: Homepage, https://agentgaurd-a0acc6egbhced0dc.centralindia-01.azurewebsites.net
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: opentelemetry-sdk>=1.20.0
10
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.20.0
11
+ Requires-Dist: traceloop-sdk>=0.33.0; python_version >= "3.10"
12
+ Provides-Extra: auto
13
+ Requires-Dist: traceloop-sdk>=0.33.0; python_version >= "3.10" and extra == "auto"
14
+ Provides-Extra: legacy
15
+ Requires-Dist: langfuse>=2.0.0; extra == "legacy"
16
+ Provides-Extra: langchain
17
+ Requires-Dist: langchain-core>=0.2.0; extra == "langchain"
18
+ Requires-Dist: langchain-openai>=0.1.0; extra == "langchain"
19
+ Requires-Dist: langfuse>=2.0.0; extra == "langchain"
20
+
21
+ # AgentGuard SDK for Python
22
+
23
+ Install the package:
24
+
25
+ ```bash
26
+ pip install agentguard
27
+ ```
28
+
29
+ The distribution is named `agentguard` and exposes the onboarding API as
30
+ `import agentguard`.
31
+
32
+ ### Python version
33
+
34
+ - **Python 3.10+** — full auto-instrumentation. `pip install agentguard` pulls
35
+ `traceloop-sdk`, so OpenAI / Anthropic / Gemini calls are traced with no
36
+ per-call code.
37
+ - **Python 3.8 / 3.9** — installs and runs in **manual mode**. `traceloop-sdk`
38
+ requires 3.10, so it is skipped automatically (PEP 508 marker) and the SDK
39
+ falls back to manual export. Auto-instrumentation of providers is **not**
40
+ available; use `track()` and `record_generation()`. Gemini **sync** is still
41
+ traced by the SDK on 3.9; Gemini **batch** always uses `record_generation()`
42
+ (see below). To force the extra explicitly on 3.10+:
43
+ `pip install "agentguard[auto]"`.
44
+
45
+ You normally leave `AGENTGUARD_MODE=auto` (the default) — the SDK downgrades to
46
+ manual only when traceloop is unavailable. `context()` / `track()` are optional
47
+ enrichment on top of either mode, not a switch into manual mode.
48
+
49
+ ## Environment
50
+
51
+ ```bash
52
+ AGENTGUARD_HOST=https://agentgaurd-a0acc6egbhced0dc.centralindia-01.azurewebsites.net
53
+ AGENTGUARD_PUBLIC_KEY=pk-lf-...
54
+ AGENTGUARD_SECRET_KEY=sk-lf-...
55
+ APP_ENV=production
56
+ AGENTGUARD_MODE=auto
57
+ ```
58
+
59
+ Optional:
60
+
61
+ ```bash
62
+ # Drop infrastructure spans (DB, HTTP client, framework) at the exporter and
63
+ # keep only LLM/observation spans — reduces storage/egress. Default: false
64
+ # (full end-to-end agent traces are preserved).
65
+ AGENTGUARD_DROP_INFRA_SPANS=true
66
+ ```
67
+
68
+ Compatibility env vars are also accepted:
69
+
70
+ ```bash
71
+ AGENTGUARD_BASE_URL=https://agentgaurd-a0acc6egbhced0dc.centralindia-01.azurewebsites.net
72
+ AGENT_GUARD_BASE_URL=https://agentgaurd-a0acc6egbhced0dc.centralindia-01.azurewebsites.net
73
+ AGENT_GUARD_PUBLIC_KEY=pk-lf-...
74
+ AGENT_GUARD_SECRET_KEY=sk-lf-...
75
+ ```
76
+
77
+ Use API keys from an existing AgentGuard project. The Python SDK does not create
78
+ console organizations or projects; create or select the project in the console,
79
+ then copy its public and secret keys into the environment.
80
+
81
+ ## Layer 1 — Base Observability
82
+
83
+ Initialize once at startup before creating LLM clients:
84
+
85
+ ```python
86
+ import agentguard
87
+
88
+ agentguard.init(service_name="my-service")
89
+ ```
90
+
91
+ Then make LLM calls exactly as before:
92
+
93
+ ```python
94
+ from openai import OpenAI
95
+
96
+ resp = OpenAI().chat.completions.create(
97
+ model="gpt-4o",
98
+ messages=[{"role": "user", "content": "Hello"}],
99
+ )
100
+ ```
101
+
102
+ Optional Cohere/Mistral instrumentor warnings during startup are ignored by the
103
+ SDK. They do not block OpenAI or Gemini tracing when those clients are installed
104
+ and initialized after `agentguard.init()`.
105
+
106
+ ## Layer 2 — Tenant Context
107
+
108
+ Set business/channel once per request:
109
+
110
+ ```python
111
+ with agentguard.context(
112
+ business_id="caratlane",
113
+ channel="instagram_dm",
114
+ session_id=conversation_id,
115
+ ):
116
+ handle_message(message)
117
+ ```
118
+
119
+ ## Layer 3 — Feature Attribution
120
+
121
+ Wrap each feature-level LLM call:
122
+
123
+ ```python
124
+ def handle_message(message):
125
+ with agentguard.track("sentiment"):
126
+ sentiment = run_sentiment(message)
127
+
128
+ with agentguard.track("reply"):
129
+ reply = run_reply(message)
130
+ ```
131
+
132
+ `track()` emits groupable tags and filterable metadata:
133
+
134
+ - `business:*`
135
+ - `channel:*`
136
+ - `feature:*`
137
+ - `biz_channel:*`
138
+ - `biz_feat:*`
139
+ - `chan_feat:*`
140
+ - `biz_chan_feat:*`
141
+
142
+ ## Gemini — sync vs batch
143
+
144
+ **Sync** calls (`client.models.generate_content(...)`) auto-trace on Python 3.9+.
145
+ **Batch** calls (`client.batches.create(...)`) are asynchronous — there are no
146
+ tokens at submit time, so auto-instrumentation cannot capture them. Record the
147
+ cost with `record_generation()` when you fetch the results:
148
+
149
+ ```python
150
+ for line in batch_results: # each line carries usage_metadata
151
+ um = line.response.usage_metadata
152
+ agentguard.record_generation(
153
+ feature="transcription",
154
+ model="gemini-2.5-flash", # must be in the pricing table or cost shows 0
155
+ input_tokens=um.prompt_token_count,
156
+ output_tokens=um.candidates_token_count,
157
+ ) # business/channel/session inherit the surrounding context()
158
+ ```
159
+
160
+ `record_generation()` also covers any call auto-instrumentation can't reach —
161
+ custom/REST providers or an SDK without an instrumentor. Cost is computed
162
+ server-side from the model name; standard models work out of the box, new or
163
+ custom model names are added once in the AgentGuard console.
164
+
165
+ ## Manual Smoke Test
166
+
167
+ Use `manual` mode to test export without real LLM calls:
168
+
169
+ ```bash
170
+ AGENTGUARD_MODE=manual python examples/smoke_test_agentguard.py \
171
+ --business-id caratlane \
172
+ --channel instagram_dm \
173
+ --flow-id checkout-flow \
174
+ --feature-id sentiment
175
+ ```
176
+
177
+ PowerShell:
178
+
179
+ ```powershell
180
+ $env:AGENTGUARD_MODE="manual"
181
+ python examples/smoke_test_agentguard.py `
182
+ --business-id caratlane `
183
+ --channel instagram_dm `
184
+ --flow-id checkout-flow `
185
+ --feature-id sentiment
186
+ ```
187
+
188
+ ## Legacy API Compatibility
189
+
190
+ The older `agentguard_sdk` module is still included:
191
+
192
+ ```python
193
+ from agentguard_sdk import AgentGuard
194
+ ```
195
+
196
+ New onboarding docs should use:
197
+
198
+ ```python
199
+ import agentguard
200
+ ```
@@ -0,0 +1,180 @@
1
+ # AgentGuard SDK for Python
2
+
3
+ Install the package:
4
+
5
+ ```bash
6
+ pip install agentguard
7
+ ```
8
+
9
+ The distribution is named `agentguard` and exposes the onboarding API as
10
+ `import agentguard`.
11
+
12
+ ### Python version
13
+
14
+ - **Python 3.10+** — full auto-instrumentation. `pip install agentguard` pulls
15
+ `traceloop-sdk`, so OpenAI / Anthropic / Gemini calls are traced with no
16
+ per-call code.
17
+ - **Python 3.8 / 3.9** — installs and runs in **manual mode**. `traceloop-sdk`
18
+ requires 3.10, so it is skipped automatically (PEP 508 marker) and the SDK
19
+ falls back to manual export. Auto-instrumentation of providers is **not**
20
+ available; use `track()` and `record_generation()`. Gemini **sync** is still
21
+ traced by the SDK on 3.9; Gemini **batch** always uses `record_generation()`
22
+ (see below). To force the extra explicitly on 3.10+:
23
+ `pip install "agentguard[auto]"`.
24
+
25
+ You normally leave `AGENTGUARD_MODE=auto` (the default) — the SDK downgrades to
26
+ manual only when traceloop is unavailable. `context()` / `track()` are optional
27
+ enrichment on top of either mode, not a switch into manual mode.
28
+
29
+ ## Environment
30
+
31
+ ```bash
32
+ AGENTGUARD_HOST=https://agentgaurd-a0acc6egbhced0dc.centralindia-01.azurewebsites.net
33
+ AGENTGUARD_PUBLIC_KEY=pk-lf-...
34
+ AGENTGUARD_SECRET_KEY=sk-lf-...
35
+ APP_ENV=production
36
+ AGENTGUARD_MODE=auto
37
+ ```
38
+
39
+ Optional:
40
+
41
+ ```bash
42
+ # Drop infrastructure spans (DB, HTTP client, framework) at the exporter and
43
+ # keep only LLM/observation spans — reduces storage/egress. Default: false
44
+ # (full end-to-end agent traces are preserved).
45
+ AGENTGUARD_DROP_INFRA_SPANS=true
46
+ ```
47
+
48
+ Compatibility env vars are also accepted:
49
+
50
+ ```bash
51
+ AGENTGUARD_BASE_URL=https://agentgaurd-a0acc6egbhced0dc.centralindia-01.azurewebsites.net
52
+ AGENT_GUARD_BASE_URL=https://agentgaurd-a0acc6egbhced0dc.centralindia-01.azurewebsites.net
53
+ AGENT_GUARD_PUBLIC_KEY=pk-lf-...
54
+ AGENT_GUARD_SECRET_KEY=sk-lf-...
55
+ ```
56
+
57
+ Use API keys from an existing AgentGuard project. The Python SDK does not create
58
+ console organizations or projects; create or select the project in the console,
59
+ then copy its public and secret keys into the environment.
60
+
61
+ ## Layer 1 — Base Observability
62
+
63
+ Initialize once at startup before creating LLM clients:
64
+
65
+ ```python
66
+ import agentguard
67
+
68
+ agentguard.init(service_name="my-service")
69
+ ```
70
+
71
+ Then make LLM calls exactly as before:
72
+
73
+ ```python
74
+ from openai import OpenAI
75
+
76
+ resp = OpenAI().chat.completions.create(
77
+ model="gpt-4o",
78
+ messages=[{"role": "user", "content": "Hello"}],
79
+ )
80
+ ```
81
+
82
+ Optional Cohere/Mistral instrumentor warnings during startup are ignored by the
83
+ SDK. They do not block OpenAI or Gemini tracing when those clients are installed
84
+ and initialized after `agentguard.init()`.
85
+
86
+ ## Layer 2 — Tenant Context
87
+
88
+ Set business/channel once per request:
89
+
90
+ ```python
91
+ with agentguard.context(
92
+ business_id="caratlane",
93
+ channel="instagram_dm",
94
+ session_id=conversation_id,
95
+ ):
96
+ handle_message(message)
97
+ ```
98
+
99
+ ## Layer 3 — Feature Attribution
100
+
101
+ Wrap each feature-level LLM call:
102
+
103
+ ```python
104
+ def handle_message(message):
105
+ with agentguard.track("sentiment"):
106
+ sentiment = run_sentiment(message)
107
+
108
+ with agentguard.track("reply"):
109
+ reply = run_reply(message)
110
+ ```
111
+
112
+ `track()` emits groupable tags and filterable metadata:
113
+
114
+ - `business:*`
115
+ - `channel:*`
116
+ - `feature:*`
117
+ - `biz_channel:*`
118
+ - `biz_feat:*`
119
+ - `chan_feat:*`
120
+ - `biz_chan_feat:*`
121
+
122
+ ## Gemini — sync vs batch
123
+
124
+ **Sync** calls (`client.models.generate_content(...)`) auto-trace on Python 3.9+.
125
+ **Batch** calls (`client.batches.create(...)`) are asynchronous — there are no
126
+ tokens at submit time, so auto-instrumentation cannot capture them. Record the
127
+ cost with `record_generation()` when you fetch the results:
128
+
129
+ ```python
130
+ for line in batch_results: # each line carries usage_metadata
131
+ um = line.response.usage_metadata
132
+ agentguard.record_generation(
133
+ feature="transcription",
134
+ model="gemini-2.5-flash", # must be in the pricing table or cost shows 0
135
+ input_tokens=um.prompt_token_count,
136
+ output_tokens=um.candidates_token_count,
137
+ ) # business/channel/session inherit the surrounding context()
138
+ ```
139
+
140
+ `record_generation()` also covers any call auto-instrumentation can't reach —
141
+ custom/REST providers or an SDK without an instrumentor. Cost is computed
142
+ server-side from the model name; standard models work out of the box, new or
143
+ custom model names are added once in the AgentGuard console.
144
+
145
+ ## Manual Smoke Test
146
+
147
+ Use `manual` mode to test export without real LLM calls:
148
+
149
+ ```bash
150
+ AGENTGUARD_MODE=manual python examples/smoke_test_agentguard.py \
151
+ --business-id caratlane \
152
+ --channel instagram_dm \
153
+ --flow-id checkout-flow \
154
+ --feature-id sentiment
155
+ ```
156
+
157
+ PowerShell:
158
+
159
+ ```powershell
160
+ $env:AGENTGUARD_MODE="manual"
161
+ python examples/smoke_test_agentguard.py `
162
+ --business-id caratlane `
163
+ --channel instagram_dm `
164
+ --flow-id checkout-flow `
165
+ --feature-id sentiment
166
+ ```
167
+
168
+ ## Legacy API Compatibility
169
+
170
+ The older `agentguard_sdk` module is still included:
171
+
172
+ ```python
173
+ from agentguard_sdk import AgentGuard
174
+ ```
175
+
176
+ New onboarding docs should use:
177
+
178
+ ```python
179
+ import agentguard
180
+ ```
@@ -0,0 +1,200 @@
1
+ Metadata-Version: 2.4
2
+ Name: actaclad-agentguard
3
+ Version: 1.1.0
4
+ Summary: Agent Guard observability SDK for Python
5
+ Author: Agent Guard
6
+ Project-URL: Homepage, https://agentgaurd-a0acc6egbhced0dc.centralindia-01.azurewebsites.net
7
+ Requires-Python: >=3.8
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: opentelemetry-sdk>=1.20.0
10
+ Requires-Dist: opentelemetry-exporter-otlp-proto-http>=1.20.0
11
+ Requires-Dist: traceloop-sdk>=0.33.0; python_version >= "3.10"
12
+ Provides-Extra: auto
13
+ Requires-Dist: traceloop-sdk>=0.33.0; python_version >= "3.10" and extra == "auto"
14
+ Provides-Extra: legacy
15
+ Requires-Dist: langfuse>=2.0.0; extra == "legacy"
16
+ Provides-Extra: langchain
17
+ Requires-Dist: langchain-core>=0.2.0; extra == "langchain"
18
+ Requires-Dist: langchain-openai>=0.1.0; extra == "langchain"
19
+ Requires-Dist: langfuse>=2.0.0; extra == "langchain"
20
+
21
+ # AgentGuard SDK for Python
22
+
23
+ Install the package:
24
+
25
+ ```bash
26
+ pip install agentguard
27
+ ```
28
+
29
+ The distribution is named `agentguard` and exposes the onboarding API as
30
+ `import agentguard`.
31
+
32
+ ### Python version
33
+
34
+ - **Python 3.10+** — full auto-instrumentation. `pip install agentguard` pulls
35
+ `traceloop-sdk`, so OpenAI / Anthropic / Gemini calls are traced with no
36
+ per-call code.
37
+ - **Python 3.8 / 3.9** — installs and runs in **manual mode**. `traceloop-sdk`
38
+ requires 3.10, so it is skipped automatically (PEP 508 marker) and the SDK
39
+ falls back to manual export. Auto-instrumentation of providers is **not**
40
+ available; use `track()` and `record_generation()`. Gemini **sync** is still
41
+ traced by the SDK on 3.9; Gemini **batch** always uses `record_generation()`
42
+ (see below). To force the extra explicitly on 3.10+:
43
+ `pip install "agentguard[auto]"`.
44
+
45
+ You normally leave `AGENTGUARD_MODE=auto` (the default) — the SDK downgrades to
46
+ manual only when traceloop is unavailable. `context()` / `track()` are optional
47
+ enrichment on top of either mode, not a switch into manual mode.
48
+
49
+ ## Environment
50
+
51
+ ```bash
52
+ AGENTGUARD_HOST=https://agentgaurd-a0acc6egbhced0dc.centralindia-01.azurewebsites.net
53
+ AGENTGUARD_PUBLIC_KEY=pk-lf-...
54
+ AGENTGUARD_SECRET_KEY=sk-lf-...
55
+ APP_ENV=production
56
+ AGENTGUARD_MODE=auto
57
+ ```
58
+
59
+ Optional:
60
+
61
+ ```bash
62
+ # Drop infrastructure spans (DB, HTTP client, framework) at the exporter and
63
+ # keep only LLM/observation spans — reduces storage/egress. Default: false
64
+ # (full end-to-end agent traces are preserved).
65
+ AGENTGUARD_DROP_INFRA_SPANS=true
66
+ ```
67
+
68
+ Compatibility env vars are also accepted:
69
+
70
+ ```bash
71
+ AGENTGUARD_BASE_URL=https://agentgaurd-a0acc6egbhced0dc.centralindia-01.azurewebsites.net
72
+ AGENT_GUARD_BASE_URL=https://agentgaurd-a0acc6egbhced0dc.centralindia-01.azurewebsites.net
73
+ AGENT_GUARD_PUBLIC_KEY=pk-lf-...
74
+ AGENT_GUARD_SECRET_KEY=sk-lf-...
75
+ ```
76
+
77
+ Use API keys from an existing AgentGuard project. The Python SDK does not create
78
+ console organizations or projects; create or select the project in the console,
79
+ then copy its public and secret keys into the environment.
80
+
81
+ ## Layer 1 — Base Observability
82
+
83
+ Initialize once at startup before creating LLM clients:
84
+
85
+ ```python
86
+ import agentguard
87
+
88
+ agentguard.init(service_name="my-service")
89
+ ```
90
+
91
+ Then make LLM calls exactly as before:
92
+
93
+ ```python
94
+ from openai import OpenAI
95
+
96
+ resp = OpenAI().chat.completions.create(
97
+ model="gpt-4o",
98
+ messages=[{"role": "user", "content": "Hello"}],
99
+ )
100
+ ```
101
+
102
+ Optional Cohere/Mistral instrumentor warnings during startup are ignored by the
103
+ SDK. They do not block OpenAI or Gemini tracing when those clients are installed
104
+ and initialized after `agentguard.init()`.
105
+
106
+ ## Layer 2 — Tenant Context
107
+
108
+ Set business/channel once per request:
109
+
110
+ ```python
111
+ with agentguard.context(
112
+ business_id="caratlane",
113
+ channel="instagram_dm",
114
+ session_id=conversation_id,
115
+ ):
116
+ handle_message(message)
117
+ ```
118
+
119
+ ## Layer 3 — Feature Attribution
120
+
121
+ Wrap each feature-level LLM call:
122
+
123
+ ```python
124
+ def handle_message(message):
125
+ with agentguard.track("sentiment"):
126
+ sentiment = run_sentiment(message)
127
+
128
+ with agentguard.track("reply"):
129
+ reply = run_reply(message)
130
+ ```
131
+
132
+ `track()` emits groupable tags and filterable metadata:
133
+
134
+ - `business:*`
135
+ - `channel:*`
136
+ - `feature:*`
137
+ - `biz_channel:*`
138
+ - `biz_feat:*`
139
+ - `chan_feat:*`
140
+ - `biz_chan_feat:*`
141
+
142
+ ## Gemini — sync vs batch
143
+
144
+ **Sync** calls (`client.models.generate_content(...)`) auto-trace on Python 3.9+.
145
+ **Batch** calls (`client.batches.create(...)`) are asynchronous — there are no
146
+ tokens at submit time, so auto-instrumentation cannot capture them. Record the
147
+ cost with `record_generation()` when you fetch the results:
148
+
149
+ ```python
150
+ for line in batch_results: # each line carries usage_metadata
151
+ um = line.response.usage_metadata
152
+ agentguard.record_generation(
153
+ feature="transcription",
154
+ model="gemini-2.5-flash", # must be in the pricing table or cost shows 0
155
+ input_tokens=um.prompt_token_count,
156
+ output_tokens=um.candidates_token_count,
157
+ ) # business/channel/session inherit the surrounding context()
158
+ ```
159
+
160
+ `record_generation()` also covers any call auto-instrumentation can't reach —
161
+ custom/REST providers or an SDK without an instrumentor. Cost is computed
162
+ server-side from the model name; standard models work out of the box, new or
163
+ custom model names are added once in the AgentGuard console.
164
+
165
+ ## Manual Smoke Test
166
+
167
+ Use `manual` mode to test export without real LLM calls:
168
+
169
+ ```bash
170
+ AGENTGUARD_MODE=manual python examples/smoke_test_agentguard.py \
171
+ --business-id caratlane \
172
+ --channel instagram_dm \
173
+ --flow-id checkout-flow \
174
+ --feature-id sentiment
175
+ ```
176
+
177
+ PowerShell:
178
+
179
+ ```powershell
180
+ $env:AGENTGUARD_MODE="manual"
181
+ python examples/smoke_test_agentguard.py `
182
+ --business-id caratlane `
183
+ --channel instagram_dm `
184
+ --flow-id checkout-flow `
185
+ --feature-id sentiment
186
+ ```
187
+
188
+ ## Legacy API Compatibility
189
+
190
+ The older `agentguard_sdk` module is still included:
191
+
192
+ ```python
193
+ from agentguard_sdk import AgentGuard
194
+ ```
195
+
196
+ New onboarding docs should use:
197
+
198
+ ```python
199
+ import agentguard
200
+ ```
@@ -0,0 +1,16 @@
1
+ README.md
2
+ pyproject.toml
3
+ actaclad_agentguard.egg-info/PKG-INFO
4
+ actaclad_agentguard.egg-info/SOURCES.txt
5
+ actaclad_agentguard.egg-info/dependency_links.txt
6
+ actaclad_agentguard.egg-info/requires.txt
7
+ actaclad_agentguard.egg-info/top_level.txt
8
+ agentguard/__init__.py
9
+ agentguard/_config.py
10
+ agentguard/_dimensions.py
11
+ agentguard/_filtering.py
12
+ agentguard/_gemini.py
13
+ agentguard/_tracing.py
14
+ agentguard_sdk/__init__.py
15
+ agentguard_sdk/client.py
16
+ agentguard_sdk/langchain.py
@@ -0,0 +1,18 @@
1
+ opentelemetry-sdk>=1.20.0
2
+ opentelemetry-exporter-otlp-proto-http>=1.20.0
3
+
4
+ [:python_version >= "3.10"]
5
+ traceloop-sdk>=0.33.0
6
+
7
+ [auto]
8
+
9
+ [auto:python_version >= "3.10"]
10
+ traceloop-sdk>=0.33.0
11
+
12
+ [langchain]
13
+ langchain-core>=0.2.0
14
+ langchain-openai>=0.1.0
15
+ langfuse>=2.0.0
16
+
17
+ [legacy]
18
+ langfuse>=2.0.0
@@ -0,0 +1,2 @@
1
+ agentguard
2
+ agentguard_sdk
@@ -0,0 +1,3 @@
1
+ from ._tracing import context, flush, init, is_enabled, record_generation, track
2
+
3
+ __all__ = ["init", "context", "track", "record_generation", "flush", "is_enabled"]
@@ -0,0 +1,34 @@
1
+ import os
2
+
3
+
4
+ def _bool(value, default=False):
5
+ if value is None:
6
+ return default
7
+ return value.strip().lower() in {"1", "true", "yes", "on"}
8
+
9
+
10
+ class Settings:
11
+ service_name = os.getenv("AGENTGUARD_SERVICE_NAME") or os.getenv(
12
+ "SERVICE_NAME", "my-service"
13
+ )
14
+ app_env = os.getenv("APP_ENV", "production")
15
+ mode = (os.getenv("AGENTGUARD_MODE", "auto") or "auto").strip().lower()
16
+ capture_content = _bool(os.getenv("AGENTGUARD_CAPTURE_CONTENT"), False)
17
+ # When true, only LLM/observation spans are exported; infra spans (DB, HTTP
18
+ # client, framework) are dropped at the exporter to reduce storage/egress.
19
+ # Default false to preserve full end-to-end agent traces.
20
+ drop_infra_spans = _bool(os.getenv("AGENTGUARD_DROP_INFRA_SPANS"), False)
21
+ host = (
22
+ os.getenv("AGENTGUARD_HOST")
23
+ or os.getenv("AGENTGUARD_BASE_URL")
24
+ or os.getenv("AGENT_GUARD_BASE_URL")
25
+ )
26
+ public_key = os.getenv("AGENTGUARD_PUBLIC_KEY") or os.getenv(
27
+ "AGENT_GUARD_PUBLIC_KEY"
28
+ )
29
+ secret_key = os.getenv("AGENTGUARD_SECRET_KEY") or os.getenv(
30
+ "AGENT_GUARD_SECRET_KEY"
31
+ )
32
+
33
+
34
+ settings = Settings()
@@ -0,0 +1,38 @@
1
+ from __future__ import annotations
2
+
3
+ import re
4
+ from typing import Optional
5
+
6
+
7
+ def slug(value: str) -> str:
8
+ text = re.sub(r"[^a-z0-9]+", "-", (value or "").strip().lower()).strip("-")
9
+ return text or "unknown"
10
+
11
+
12
+ def call_tags(business: str, channel: str, feature: str) -> list[str]:
13
+ business_slug = slug(business)
14
+ channel_slug = slug(channel)
15
+ feature_slug = slug(feature)
16
+ return [
17
+ f"business:{business_slug}",
18
+ f"channel:{channel_slug}",
19
+ f"feature:{feature_slug}",
20
+ f"biz_channel:{business_slug}__{channel_slug}",
21
+ f"biz_feat:{business_slug}__{feature_slug}",
22
+ f"chan_feat:{channel_slug}__{feature_slug}",
23
+ f"biz_chan_feat:{business_slug}__{channel_slug}__{feature_slug}",
24
+ ]
25
+
26
+
27
+ def metadata(
28
+ business: str,
29
+ channel: str,
30
+ env: str,
31
+ feature: Optional[str] = None,
32
+ **extra,
33
+ ) -> dict:
34
+ result = {"business_id": business, "channel_name": channel, "env": env}
35
+ if feature:
36
+ result["feature_name"] = feature
37
+ result.update({key: value for key, value in extra.items() if value is not None})
38
+ return result