@openbox-ai/openbox-mastra-sdk 0.1.0
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.
- package/LICENSE +21 -0
- package/README.md +158 -0
- package/dist/client/index.d.ts +4 -0
- package/dist/client/index.js +2 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/openbox-client.d.ts +42 -0
- package/dist/client/openbox-client.js +405 -0
- package/dist/client/openbox-client.js.map +1 -0
- package/dist/config/index.d.ts +5 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/openbox-config.d.ts +54 -0
- package/dist/config/openbox-config.js +162 -0
- package/dist/config/openbox-config.js.map +1 -0
- package/dist/governance/activity-runtime.d.ts +42 -0
- package/dist/governance/activity-runtime.js +712 -0
- package/dist/governance/activity-runtime.js.map +1 -0
- package/dist/governance/approval-registry.d.ts +17 -0
- package/dist/governance/approval-registry.js +32 -0
- package/dist/governance/approval-registry.js.map +1 -0
- package/dist/governance/context.d.ts +16 -0
- package/dist/governance/context.js +13 -0
- package/dist/governance/context.js.map +1 -0
- package/dist/governance/index.d.ts +2 -0
- package/dist/governance/index.js +1 -0
- package/dist/governance/index.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/mastra/index.d.ts +16 -0
- package/dist/mastra/index.js +5 -0
- package/dist/mastra/index.js.map +1 -0
- package/dist/mastra/with-openbox.d.ts +30 -0
- package/dist/mastra/with-openbox.js +243 -0
- package/dist/mastra/with-openbox.js.map +1 -0
- package/dist/mastra/wrap-agent.d.ts +14 -0
- package/dist/mastra/wrap-agent.js +1744 -0
- package/dist/mastra/wrap-agent.js.map +1 -0
- package/dist/mastra/wrap-tool.d.ts +18 -0
- package/dist/mastra/wrap-tool.js +49 -0
- package/dist/mastra/wrap-tool.js.map +1 -0
- package/dist/mastra/wrap-workflow.d.ts +14 -0
- package/dist/mastra/wrap-workflow.js +386 -0
- package/dist/mastra/wrap-workflow.js.map +1 -0
- package/dist/otel/index.d.ts +11 -0
- package/dist/otel/index.js +2 -0
- package/dist/otel/index.js.map +1 -0
- package/dist/otel/setup-openbox-opentelemetry.d.ts +38 -0
- package/dist/otel/setup-openbox-opentelemetry.js +2249 -0
- package/dist/otel/setup-openbox-opentelemetry.js.map +1 -0
- package/dist/span/index.d.ts +5 -0
- package/dist/span/index.js +2 -0
- package/dist/span/index.js.map +1 -0
- package/dist/span/openbox-span-processor.d.ts +90 -0
- package/dist/span/openbox-span-processor.js +580 -0
- package/dist/span/openbox-span-processor.js.map +1 -0
- package/dist/types/errors.d.ts +25 -0
- package/dist/types/errors.js +40 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/governance-verdict-response.d.ts +57 -0
- package/dist/types/governance-verdict-response.js +84 -0
- package/dist/types/governance-verdict-response.js.map +1 -0
- package/dist/types/guardrails.d.ts +23 -0
- package/dist/types/guardrails.js +27 -0
- package/dist/types/guardrails.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/verdict.d.ts +22 -0
- package/dist/types/verdict.js +55 -0
- package/dist/types/verdict.js.map +1 -0
- package/dist/types/workflow-event-type.d.ts +10 -0
- package/dist/types/workflow-event-type.js +13 -0
- package/dist/types/workflow-event-type.js.map +1 -0
- package/dist/types/workflow-span-buffer.d.ts +31 -0
- package/dist/types/workflow-span-buffer.js +42 -0
- package/dist/types/workflow-span-buffer.js.map +1 -0
- package/docs/README.md +66 -0
- package/docs/api-reference.md +348 -0
- package/docs/approvals-and-guardrails.md +163 -0
- package/docs/architecture.md +186 -0
- package/docs/configuration.md +214 -0
- package/docs/event-model.md +215 -0
- package/docs/installation.md +108 -0
- package/docs/integration-patterns.md +214 -0
- package/docs/security-and-privacy.md +174 -0
- package/docs/telemetry.md +196 -0
- package/docs/troubleshooting.md +210 -0
- package/package.json +136 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Integration Patterns
|
|
2
|
+
|
|
3
|
+
This SDK supports three integration patterns:
|
|
4
|
+
|
|
5
|
+
1. `withOpenBox()` for standard application bootstrap
|
|
6
|
+
2. manual wrapping with `wrapTool()`, `wrapWorkflow()`, and `wrapAgent()`
|
|
7
|
+
3. telemetry-only setup with `setupOpenBoxOpenTelemetry()` and optional `traced()`
|
|
8
|
+
|
|
9
|
+
## Choose The Right Pattern
|
|
10
|
+
|
|
11
|
+
| Pattern | Use it when |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| `withOpenBox()` | you want one production runtime to govern the whole Mastra instance |
|
|
14
|
+
| manual wrappers | you need explicit startup order or selective adoption |
|
|
15
|
+
| telemetry-only | you want OpenBox span capture without full Mastra wrapping |
|
|
16
|
+
|
|
17
|
+
## `withOpenBox()`
|
|
18
|
+
|
|
19
|
+
`withOpenBox()` is the recommended integration path for most applications.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { withOpenBox } from "@openbox-ai/openbox-mastra-sdk";
|
|
23
|
+
|
|
24
|
+
const governedMastra = await withOpenBox(mastra, {
|
|
25
|
+
apiKey: process.env.OPENBOX_API_KEY,
|
|
26
|
+
apiUrl: process.env.OPENBOX_URL
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
What it does:
|
|
31
|
+
|
|
32
|
+
- parses and validates configuration
|
|
33
|
+
- creates an `OpenBoxClient`
|
|
34
|
+
- creates an `OpenBoxSpanProcessor`
|
|
35
|
+
- installs process-wide telemetry
|
|
36
|
+
- wraps current top-level tools, workflows, and agents
|
|
37
|
+
- patches future `addTool()`, `addWorkflow()`, and `addAgent()` calls
|
|
38
|
+
- hydrates agent-local tool and workflow registries where Mastra exposes them
|
|
39
|
+
|
|
40
|
+
### Idempotency
|
|
41
|
+
|
|
42
|
+
Calling `withOpenBox()` again on the same Mastra instance reuses the existing runtime instead of creating a second one.
|
|
43
|
+
|
|
44
|
+
### Accepted Targets
|
|
45
|
+
|
|
46
|
+
`withOpenBox()` accepts either:
|
|
47
|
+
|
|
48
|
+
- a Mastra instance
|
|
49
|
+
- an object with a `.mastra` property
|
|
50
|
+
|
|
51
|
+
Example:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
await withOpenBox({ mastra }, {
|
|
55
|
+
apiKey: process.env.OPENBOX_API_KEY,
|
|
56
|
+
apiUrl: process.env.OPENBOX_URL
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Manual Wrapping
|
|
61
|
+
|
|
62
|
+
Use manual wiring when you need to control bootstrap order or govern only a subset of components.
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import {
|
|
66
|
+
OpenBoxClient,
|
|
67
|
+
OpenBoxSpanProcessor,
|
|
68
|
+
parseOpenBoxConfig,
|
|
69
|
+
setupOpenBoxOpenTelemetry,
|
|
70
|
+
wrapAgent,
|
|
71
|
+
wrapTool,
|
|
72
|
+
wrapWorkflow
|
|
73
|
+
} from "@openbox-ai/openbox-mastra-sdk";
|
|
74
|
+
|
|
75
|
+
const config = parseOpenBoxConfig({
|
|
76
|
+
apiKey: process.env.OPENBOX_API_KEY,
|
|
77
|
+
apiUrl: process.env.OPENBOX_URL
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
const client = new OpenBoxClient({
|
|
81
|
+
apiKey: config.apiKey,
|
|
82
|
+
apiUrl: config.apiUrl,
|
|
83
|
+
evaluateMaxRetries: config.evaluateMaxRetries,
|
|
84
|
+
evaluateRetryBaseDelayMs: config.evaluateRetryBaseDelayMs,
|
|
85
|
+
onApiError: config.onApiError,
|
|
86
|
+
timeoutSeconds: config.governanceTimeout
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const spanProcessor = new OpenBoxSpanProcessor({
|
|
90
|
+
ignoredUrlPrefixes: [config.apiUrl]
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const telemetry = setupOpenBoxOpenTelemetry({
|
|
94
|
+
captureHttpBodies: config.httpCapture,
|
|
95
|
+
governanceClient: client,
|
|
96
|
+
ignoredUrls: [config.apiUrl],
|
|
97
|
+
instrumentDatabases: config.instrumentDatabases,
|
|
98
|
+
instrumentFileIo: config.instrumentFileIo,
|
|
99
|
+
spanProcessor
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const governedTool = wrapTool(tool, {
|
|
103
|
+
client,
|
|
104
|
+
config,
|
|
105
|
+
spanProcessor
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const governedWorkflow = wrapWorkflow(workflow, {
|
|
109
|
+
client,
|
|
110
|
+
config,
|
|
111
|
+
spanProcessor
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const governedAgent = wrapAgent(agent, {
|
|
115
|
+
client,
|
|
116
|
+
config,
|
|
117
|
+
spanProcessor
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
await telemetry.shutdown();
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Use this pattern when:
|
|
124
|
+
|
|
125
|
+
- another subsystem owns telemetry bootstrap order
|
|
126
|
+
- you only want to govern selected tools, workflows, or agents
|
|
127
|
+
- you need a custom `OpenBoxClient` or `OpenBoxSpanProcessor`
|
|
128
|
+
|
|
129
|
+
## Telemetry-Only Setup
|
|
130
|
+
|
|
131
|
+
If you want telemetry capture without automatic Mastra patching, install the telemetry layer directly:
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import {
|
|
135
|
+
OpenBoxClient,
|
|
136
|
+
OpenBoxSpanProcessor,
|
|
137
|
+
setupOpenBoxOpenTelemetry,
|
|
138
|
+
traced
|
|
139
|
+
} from "@openbox-ai/openbox-mastra-sdk";
|
|
140
|
+
|
|
141
|
+
const client = new OpenBoxClient({
|
|
142
|
+
apiKey: process.env.OPENBOX_API_KEY!,
|
|
143
|
+
apiUrl: process.env.OPENBOX_URL!
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const spanProcessor = new OpenBoxSpanProcessor({
|
|
147
|
+
ignoredUrlPrefixes: [process.env.OPENBOX_URL!]
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
const telemetry = setupOpenBoxOpenTelemetry({
|
|
151
|
+
governanceClient: client,
|
|
152
|
+
ignoredUrls: [process.env.OPENBOX_URL!],
|
|
153
|
+
spanProcessor
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const governedFn = traced(
|
|
157
|
+
async function sendEmail(input: { to: string }) {
|
|
158
|
+
return { delivered: true, to: input.to };
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
captureArgs: true,
|
|
162
|
+
captureResult: true,
|
|
163
|
+
module: "email"
|
|
164
|
+
}
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
await telemetry.shutdown();
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
This pattern is useful when:
|
|
171
|
+
|
|
172
|
+
- orchestration is not fully Mastra-managed
|
|
173
|
+
- you want function-level tracing without wrapping all Mastra boundaries
|
|
174
|
+
- you intend to emit lifecycle events yourself
|
|
175
|
+
|
|
176
|
+
## Wrapper Behavior Summary
|
|
177
|
+
|
|
178
|
+
### `wrapTool()`
|
|
179
|
+
|
|
180
|
+
`wrapTool()` adds:
|
|
181
|
+
|
|
182
|
+
- `ActivityStarted` and `ActivityCompleted`
|
|
183
|
+
- verdict enforcement
|
|
184
|
+
- guardrail input and output handling
|
|
185
|
+
- approval suspension or polling
|
|
186
|
+
- telemetry association for work performed during the tool call
|
|
187
|
+
|
|
188
|
+
### `wrapWorkflow()`
|
|
189
|
+
|
|
190
|
+
`wrapWorkflow()` adds:
|
|
191
|
+
|
|
192
|
+
- `WorkflowStarted`, `WorkflowCompleted`, and `WorkflowFailed`
|
|
193
|
+
- `SignalReceived` on resume
|
|
194
|
+
- governed execution for non-tool workflow steps
|
|
195
|
+
|
|
196
|
+
Tool component steps are intentionally not double-wrapped.
|
|
197
|
+
|
|
198
|
+
### `wrapAgent()`
|
|
199
|
+
|
|
200
|
+
`wrapAgent()` models an agent run as a workflow-like unit and adds:
|
|
201
|
+
|
|
202
|
+
- workflow lifecycle events for the agent run
|
|
203
|
+
- `SignalReceived` for `user_input`, `resume`, and `agent_output`
|
|
204
|
+
- agent goal propagation
|
|
205
|
+
- agent-only LLM spans routed through `agent_output`
|
|
206
|
+
|
|
207
|
+
## Bootstrap Guidance
|
|
208
|
+
|
|
209
|
+
For production services:
|
|
210
|
+
|
|
211
|
+
1. initialize the SDK once during process startup
|
|
212
|
+
2. keep a reference to the governed Mastra instance or runtime
|
|
213
|
+
3. shut telemetry down during process termination
|
|
214
|
+
4. avoid calling `setupOpenBoxOpenTelemetry()` multiple times in the same process unless you intentionally want to replace the active controller
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Security And Privacy
|
|
2
|
+
|
|
3
|
+
This SDK is designed for governance-sensitive workloads. The defaults are conservative where transport, capture, and failure behavior matter most.
|
|
4
|
+
|
|
5
|
+
## Transport Security
|
|
6
|
+
|
|
7
|
+
The SDK rejects insecure non-localhost OpenBox URLs.
|
|
8
|
+
|
|
9
|
+
Allowed:
|
|
10
|
+
|
|
11
|
+
- `https://openbox.example.com`
|
|
12
|
+
- `http://localhost:8086`
|
|
13
|
+
- `http://127.0.0.1:8086`
|
|
14
|
+
- `http://[::1]:8086`
|
|
15
|
+
|
|
16
|
+
Rejected:
|
|
17
|
+
|
|
18
|
+
- `http://openbox.example.com`
|
|
19
|
+
|
|
20
|
+
Reason:
|
|
21
|
+
|
|
22
|
+
- API keys must not be sent over plaintext HTTP outside local development
|
|
23
|
+
|
|
24
|
+
## API Key Validation
|
|
25
|
+
|
|
26
|
+
API keys must match:
|
|
27
|
+
|
|
28
|
+
- `obx_live_*`
|
|
29
|
+
- `obx_test_*`
|
|
30
|
+
|
|
31
|
+
When `validate` is `true`, startup also verifies the key against OpenBox Core using `/api/v1/auth/validate`.
|
|
32
|
+
|
|
33
|
+
Use `validate: false` only for:
|
|
34
|
+
|
|
35
|
+
- tests
|
|
36
|
+
- mock servers
|
|
37
|
+
- deliberately offline local development
|
|
38
|
+
|
|
39
|
+
## Capture Boundary
|
|
40
|
+
|
|
41
|
+
The SDK can capture request and response bodies for HTTP telemetry, but it does so inside its own runtime rather than exposing that data as ordinary OTel span attributes.
|
|
42
|
+
|
|
43
|
+
Key properties:
|
|
44
|
+
|
|
45
|
+
- HTTP bodies are not stored as ordinary OTel span attributes
|
|
46
|
+
- bodies and headers are buffered inside the SDK span processor
|
|
47
|
+
- the data is merged into governance payloads only when required
|
|
48
|
+
|
|
49
|
+
This reduces accidental leakage through generic tracing exporters.
|
|
50
|
+
|
|
51
|
+
## Default Capture Posture
|
|
52
|
+
|
|
53
|
+
| Setting | Default | Why |
|
|
54
|
+
| --- | --- | --- |
|
|
55
|
+
| `httpCapture` | `true` | useful governance and incident context |
|
|
56
|
+
| `instrumentDatabases` | `true` | low-friction visibility into data access |
|
|
57
|
+
| `instrumentFileIo` | `false` | file telemetry can be noisy and sensitive |
|
|
58
|
+
|
|
59
|
+
If your environment is highly sensitive:
|
|
60
|
+
|
|
61
|
+
- consider disabling `httpCapture`
|
|
62
|
+
- enable it selectively in lower environments first
|
|
63
|
+
- review OpenBox retention and policy posture before broad rollout
|
|
64
|
+
|
|
65
|
+
## Text-Only HTTP Body Capture
|
|
66
|
+
|
|
67
|
+
The SDK only treats text-like content as body-capturable text.
|
|
68
|
+
|
|
69
|
+
Examples:
|
|
70
|
+
|
|
71
|
+
- `text/*`
|
|
72
|
+
- `application/json`
|
|
73
|
+
- `application/xml`
|
|
74
|
+
- `application/javascript`
|
|
75
|
+
- `application/x-www-form-urlencoded`
|
|
76
|
+
|
|
77
|
+
This avoids nonsensical capture of binary payloads.
|
|
78
|
+
|
|
79
|
+
## File I/O Is Opt-In
|
|
80
|
+
|
|
81
|
+
File instrumentation is disabled by default.
|
|
82
|
+
|
|
83
|
+
When enabled, the SDK still skips common system and binary paths such as:
|
|
84
|
+
|
|
85
|
+
- `/dev/`
|
|
86
|
+
- `/proc/`
|
|
87
|
+
- `/sys/`
|
|
88
|
+
- `__pycache__`
|
|
89
|
+
- `.so`
|
|
90
|
+
- `.dylib`
|
|
91
|
+
|
|
92
|
+
Do not enable file telemetry broadly unless you have a concrete policy or audit requirement for it.
|
|
93
|
+
|
|
94
|
+
## Ignore Internal Service URLs
|
|
95
|
+
|
|
96
|
+
Always ignore service URLs that should not be governed.
|
|
97
|
+
|
|
98
|
+
Minimum recommendation:
|
|
99
|
+
|
|
100
|
+
- ignore your OpenBox Core URL
|
|
101
|
+
|
|
102
|
+
Why:
|
|
103
|
+
|
|
104
|
+
- prevents the SDK from tracing and governing its own API calls
|
|
105
|
+
- reduces noise
|
|
106
|
+
- avoids governance loops
|
|
107
|
+
|
|
108
|
+
`withOpenBox()` already adds `apiUrl` to the ignored URL set.
|
|
109
|
+
|
|
110
|
+
## API Failure Policy
|
|
111
|
+
|
|
112
|
+
`onApiError` controls what happens if OpenBox cannot be reached.
|
|
113
|
+
|
|
114
|
+
### `fail_open`
|
|
115
|
+
|
|
116
|
+
Use when:
|
|
117
|
+
|
|
118
|
+
- service availability is more important than strict governance enforcement
|
|
119
|
+
- governance outages must not stop production traffic
|
|
120
|
+
|
|
121
|
+
Tradeoff:
|
|
122
|
+
|
|
123
|
+
- requests can continue without a live governance decision
|
|
124
|
+
|
|
125
|
+
### `fail_closed`
|
|
126
|
+
|
|
127
|
+
Use when:
|
|
128
|
+
|
|
129
|
+
- governance enforcement is mandatory
|
|
130
|
+
- ungoverned execution is unacceptable
|
|
131
|
+
|
|
132
|
+
Tradeoff:
|
|
133
|
+
|
|
134
|
+
- OpenBox outages become execution blockers
|
|
135
|
+
|
|
136
|
+
## Payload Size And Data Minimization
|
|
137
|
+
|
|
138
|
+
The SDK limits large governance payloads through `maxEvaluatePayloadBytes`.
|
|
139
|
+
|
|
140
|
+
When agent completion payloads are too large:
|
|
141
|
+
|
|
142
|
+
- the SDK retries with a compact version
|
|
143
|
+
- then retries with an ultra-minimal version if needed
|
|
144
|
+
|
|
145
|
+
This keeps governance requests bounded without requiring unbounded payload growth.
|
|
146
|
+
|
|
147
|
+
## Debug Logging
|
|
148
|
+
|
|
149
|
+
`OPENBOX_DEBUG=true` enables summarized request and response logging.
|
|
150
|
+
|
|
151
|
+
It logs:
|
|
152
|
+
|
|
153
|
+
- event type
|
|
154
|
+
- activity and workflow identity
|
|
155
|
+
- presence of inputs, outputs, spans, and errors
|
|
156
|
+
- retry attempts
|
|
157
|
+
- verdict metadata summary
|
|
158
|
+
|
|
159
|
+
It does not try to print full raw governance payloads by default.
|
|
160
|
+
|
|
161
|
+
Recommendation:
|
|
162
|
+
|
|
163
|
+
- enable it in development, staging, and incident response
|
|
164
|
+
- keep it disabled by default in steady-state production unless your logging posture explicitly allows it
|
|
165
|
+
|
|
166
|
+
## Production Hardening Checklist
|
|
167
|
+
|
|
168
|
+
1. Use HTTPS for OpenBox Core.
|
|
169
|
+
2. Keep `validate` enabled in production.
|
|
170
|
+
3. Keep OpenBox Core ignored in telemetry capture.
|
|
171
|
+
4. Decide explicitly between `fail_open` and `fail_closed`.
|
|
172
|
+
5. Enable file I/O capture only if you need it.
|
|
173
|
+
6. Review policy so hook-triggered telemetry is not mistaken for a second user action.
|
|
174
|
+
7. Use OpenBox guardrails and retention controls for sensitive prompts or outputs.
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Telemetry
|
|
2
|
+
|
|
3
|
+
This SDK uses OpenTelemetry internally, but it does not simply forward raw spans to OpenBox. It captures, buffers, enriches, and normalizes telemetry into governance-ready payloads.
|
|
4
|
+
|
|
5
|
+
## What The SDK Captures
|
|
6
|
+
|
|
7
|
+
### HTTP
|
|
8
|
+
|
|
9
|
+
Enabled by default through `httpCapture: true`.
|
|
10
|
+
|
|
11
|
+
The SDK installs:
|
|
12
|
+
|
|
13
|
+
- Node HTTP instrumentation
|
|
14
|
+
- Undici instrumentation
|
|
15
|
+
- fetch patching for request and response body capture
|
|
16
|
+
|
|
17
|
+
This covers:
|
|
18
|
+
|
|
19
|
+
- `fetch`
|
|
20
|
+
- Node `http` and `https`
|
|
21
|
+
- Undici-based clients
|
|
22
|
+
|
|
23
|
+
Captured fields can include:
|
|
24
|
+
|
|
25
|
+
- method
|
|
26
|
+
- URL
|
|
27
|
+
- request headers
|
|
28
|
+
- response headers
|
|
29
|
+
- request body
|
|
30
|
+
- response body
|
|
31
|
+
- status code
|
|
32
|
+
|
|
33
|
+
Only text-like content types are treated as body-capturable text. Binary payloads are not captured as text.
|
|
34
|
+
|
|
35
|
+
### Databases
|
|
36
|
+
|
|
37
|
+
Enabled by default through `instrumentDatabases: true`.
|
|
38
|
+
|
|
39
|
+
Supported selectors:
|
|
40
|
+
|
|
41
|
+
- `pg`
|
|
42
|
+
- `postgres`
|
|
43
|
+
- `mysql`
|
|
44
|
+
- `mysql2`
|
|
45
|
+
- `mongodb`
|
|
46
|
+
- `mongoose`
|
|
47
|
+
- `redis`
|
|
48
|
+
- `ioredis`
|
|
49
|
+
- `knex`
|
|
50
|
+
- `oracledb`
|
|
51
|
+
- `cassandra`
|
|
52
|
+
- `tedious`
|
|
53
|
+
|
|
54
|
+
If `dbLibraries` is omitted, the SDK enables every supported DB instrumentation it can resolve.
|
|
55
|
+
|
|
56
|
+
### File I/O
|
|
57
|
+
|
|
58
|
+
Disabled by default through `instrumentFileIo: false`.
|
|
59
|
+
|
|
60
|
+
When enabled, the SDK can emit spans for file operations such as:
|
|
61
|
+
|
|
62
|
+
- open
|
|
63
|
+
- read
|
|
64
|
+
- write
|
|
65
|
+
- readline
|
|
66
|
+
- readlines
|
|
67
|
+
- writelines
|
|
68
|
+
- close
|
|
69
|
+
|
|
70
|
+
Built-in skip patterns include:
|
|
71
|
+
|
|
72
|
+
- `/dev/`
|
|
73
|
+
- `/proc/`
|
|
74
|
+
- `/sys/`
|
|
75
|
+
- `\\?\pipe\`
|
|
76
|
+
- `__pycache__`
|
|
77
|
+
- `.pyc`
|
|
78
|
+
- `.pyo`
|
|
79
|
+
- `.so`
|
|
80
|
+
- `.dylib`
|
|
81
|
+
|
|
82
|
+
Override them with `fileSkipPatterns` when you install telemetry manually.
|
|
83
|
+
|
|
84
|
+
### Traced Functions
|
|
85
|
+
|
|
86
|
+
You can create explicit function spans with `traced()`:
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
import { traced } from "@openbox-ai/openbox-mastra-sdk";
|
|
90
|
+
|
|
91
|
+
const summarize = traced(
|
|
92
|
+
async function summarize(text: string) {
|
|
93
|
+
return text.slice(0, 120);
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
captureArgs: true,
|
|
97
|
+
captureResult: true,
|
|
98
|
+
module: "summary"
|
|
99
|
+
}
|
|
100
|
+
);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Supported options:
|
|
104
|
+
|
|
105
|
+
- `captureArgs`
|
|
106
|
+
- `captureResult`
|
|
107
|
+
- `module`
|
|
108
|
+
- `name`
|
|
109
|
+
- `tracerName`
|
|
110
|
+
|
|
111
|
+
## How Telemetry Reaches OpenBox
|
|
112
|
+
|
|
113
|
+
The SDK has two telemetry paths:
|
|
114
|
+
|
|
115
|
+
1. buffered spans attached to later workflow, activity, or signal payloads
|
|
116
|
+
2. hook-triggered governance payloads sent during execution
|
|
117
|
+
|
|
118
|
+
Hook-triggered payloads are used for internal operational spans such as HTTP, DB, file, and traced-function activity.
|
|
119
|
+
|
|
120
|
+
## Hook Payload Characteristics
|
|
121
|
+
|
|
122
|
+
Hook payloads:
|
|
123
|
+
|
|
124
|
+
- include `hook_trigger: true`
|
|
125
|
+
- include normalized OpenBox spans under `spans`
|
|
126
|
+
- carry one started or completed span phase per hook event
|
|
127
|
+
- attach to an existing parent workflow, activity, or agent context
|
|
128
|
+
|
|
129
|
+
For agent-only LLM traffic with no separate business activity parent:
|
|
130
|
+
|
|
131
|
+
- spans are queued
|
|
132
|
+
- they are later emitted on `SignalReceived(agent_output)`
|
|
133
|
+
|
|
134
|
+
## Privacy Boundary
|
|
135
|
+
|
|
136
|
+
Bodies and headers are not stored as ordinary OTel span attributes. Instead:
|
|
137
|
+
|
|
138
|
+
1. the SDK captures them into its internal span processor
|
|
139
|
+
2. the SDK merges them into governance payloads when required
|
|
140
|
+
3. generic OTel exporters are not relied on to carry those bodies
|
|
141
|
+
|
|
142
|
+
This keeps OpenBox-specific governance context separate from generic tracing infrastructure.
|
|
143
|
+
|
|
144
|
+
## Ignored URLs
|
|
145
|
+
|
|
146
|
+
Always ignore URLs that should not be governed. At minimum, ignore your OpenBox Core URL.
|
|
147
|
+
|
|
148
|
+
`withOpenBox()` already does this automatically by adding `apiUrl` to the ignored URL set.
|
|
149
|
+
|
|
150
|
+
If you install telemetry manually, do the same:
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
const telemetry = setupOpenBoxOpenTelemetry({
|
|
154
|
+
governanceClient: client,
|
|
155
|
+
ignoredUrls: [config.apiUrl],
|
|
156
|
+
spanProcessor
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Payload Budgeting
|
|
161
|
+
|
|
162
|
+
Agent `WorkflowCompleted` payloads can grow large because they may include:
|
|
163
|
+
|
|
164
|
+
- workflow output
|
|
165
|
+
- model metadata
|
|
166
|
+
- usage metrics
|
|
167
|
+
- buffered spans
|
|
168
|
+
|
|
169
|
+
The SDK handles this by attempting progressively smaller payloads:
|
|
170
|
+
|
|
171
|
+
1. full payload
|
|
172
|
+
2. compact payload
|
|
173
|
+
3. ultra-minimal payload
|
|
174
|
+
|
|
175
|
+
The threshold is controlled by `maxEvaluatePayloadBytes`.
|
|
176
|
+
|
|
177
|
+
## Operational Recommendations
|
|
178
|
+
|
|
179
|
+
- Keep `httpCapture` enabled unless payload sensitivity or volume makes that unacceptable.
|
|
180
|
+
- Keep `instrumentDatabases` enabled in most environments.
|
|
181
|
+
- Enable `instrumentFileIo` only when you need file-governance visibility.
|
|
182
|
+
- Keep `ignoredUrls` aligned with internal service endpoints that should not be governed.
|
|
183
|
+
- Do not initialize telemetry twice in the same process unless you intentionally want to replace the active controller.
|
|
184
|
+
|
|
185
|
+
## Common Policy Interaction
|
|
186
|
+
|
|
187
|
+
If policy treats hook-triggered telemetry as a second user action, you can see:
|
|
188
|
+
|
|
189
|
+
- duplicate approvals
|
|
190
|
+
- noisy `http_request`, `db_query`, `file_operation`, or `function_call` rows
|
|
191
|
+
- approval loops while a parent activity is already pending approval
|
|
192
|
+
|
|
193
|
+
Recommended policy behavior:
|
|
194
|
+
|
|
195
|
+
- govern workflow and activity boundary events
|
|
196
|
+
- treat hook-triggered payloads as internal telemetry unless you have a specific reason to gate them directly
|