@senpi/runtime 3.0.6-dev.runtime-phase-2.20260627082846 → 3.0.6-dev.runtime-phase-2.20260630134307

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.
Files changed (66) hide show
  1. package/dist/actions/close-position/close-position.action.d.ts.map +1 -1
  2. package/dist/actions/close-position/close-position.action.js +95 -65
  3. package/dist/actions/close-position/close-position.action.js.map +1 -1
  4. package/dist/actions/decision-engine.d.ts.map +1 -1
  5. package/dist/actions/decision-engine.js +40 -28
  6. package/dist/actions/decision-engine.js.map +1 -1
  7. package/dist/actions/open-position/open-position.action.d.ts.map +1 -1
  8. package/dist/actions/open-position/open-position.action.js +261 -202
  9. package/dist/actions/open-position/open-position.action.js.map +1 -1
  10. package/dist/dsl/monitor/create-monitor.d.ts +3 -0
  11. package/dist/dsl/monitor/create-monitor.d.ts.map +1 -1
  12. package/dist/dsl/monitor/create-monitor.js +76 -28
  13. package/dist/dsl/monitor/create-monitor.js.map +1 -1
  14. package/dist/dsl/monitor/process-one-position.d.ts +2 -1
  15. package/dist/dsl/monitor/process-one-position.d.ts.map +1 -1
  16. package/dist/dsl/monitor/process-one-position.js +84 -38
  17. package/dist/dsl/monitor/process-one-position.js.map +1 -1
  18. package/dist/dsl/plugin/index.d.ts +2 -0
  19. package/dist/dsl/plugin/index.d.ts.map +1 -1
  20. package/dist/dsl/plugin/index.js +6 -2
  21. package/dist/dsl/plugin/index.js.map +1 -1
  22. package/dist/dsl/plugin/options.d.ts +3 -0
  23. package/dist/dsl/plugin/options.d.ts.map +1 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +7 -12
  26. package/dist/index.js.map +1 -1
  27. package/dist/runtime/create-actions.d.ts.map +1 -1
  28. package/dist/runtime/create-actions.js +40 -5
  29. package/dist/runtime/create-actions.js.map +1 -1
  30. package/dist/runtime/create-scanner-module.d.ts +2 -1
  31. package/dist/runtime/create-scanner-module.d.ts.map +1 -1
  32. package/dist/runtime/create-scanner-module.js +2 -1
  33. package/dist/runtime/create-scanner-module.js.map +1 -1
  34. package/dist/runtime/runtime.d.ts +10 -0
  35. package/dist/runtime/runtime.d.ts.map +1 -1
  36. package/dist/runtime/runtime.js +143 -73
  37. package/dist/runtime/runtime.js.map +1 -1
  38. package/dist/scanners/engine/data-providers.d.ts +3 -0
  39. package/dist/scanners/engine/data-providers.d.ts.map +1 -1
  40. package/dist/scanners/engine/data-providers.js.map +1 -1
  41. package/dist/scanners/engine/engine.d.ts +18 -0
  42. package/dist/scanners/engine/engine.d.ts.map +1 -1
  43. package/dist/scanners/engine/engine.js +93 -2
  44. package/dist/scanners/engine/engine.js.map +1 -1
  45. package/dist/scanners/engine/input-resolver.d.ts.map +1 -1
  46. package/dist/scanners/engine/input-resolver.js +9 -7
  47. package/dist/scanners/engine/input-resolver.js.map +1 -1
  48. package/dist/scanners/runtime-module.d.ts +3 -0
  49. package/dist/scanners/runtime-module.d.ts.map +1 -1
  50. package/dist/scanners/runtime-module.js +1 -0
  51. package/dist/scanners/runtime-module.js.map +1 -1
  52. package/dist/telemetry/otel-sdk.d.ts +105 -0
  53. package/dist/telemetry/otel-sdk.d.ts.map +1 -0
  54. package/dist/telemetry/otel-sdk.js +268 -0
  55. package/dist/telemetry/otel-sdk.js.map +1 -0
  56. package/dist/telemetry/trace-identity.d.ts +31 -0
  57. package/dist/telemetry/trace-identity.d.ts.map +1 -0
  58. package/dist/telemetry/trace-identity.js +58 -0
  59. package/dist/telemetry/trace-identity.js.map +1 -0
  60. package/dist/telemetry/tracing.d.ts +32 -0
  61. package/dist/telemetry/tracing.d.ts.map +1 -0
  62. package/dist/telemetry/tracing.js +70 -0
  63. package/dist/telemetry/tracing.js.map +1 -0
  64. package/dist/types/scanner.d.ts +2 -0
  65. package/dist/types/scanner.d.ts.map +1 -1
  66. package/package.json +6 -2
@@ -0,0 +1,268 @@
1
+ /**
2
+ * OpenTelemetry SDK stand-up: initialises HyperDX's OTel distribution
3
+ * (`@hyperdx/node-opentelemetry`) — auto-instrumentation, console-capture logs,
4
+ * uncaught-exception capture — against a self-hosted OTLP collector, with a
5
+ * standardised resource-attribute set.
6
+ *
7
+ * Init runs from `Runtime.start()`, not at process entry: resource attributes
8
+ * are immutable after `init()` and are built from the recipe/strategy identity
9
+ * and the `telemetry.enabled` gate, none of which exist before a runtime starts.
10
+ * On Node >= 22 the diagnostics_channel HTTP instrumentation hooks lazily, so
11
+ * deferring init still instruments outbound HTTP.
12
+ *
13
+ * The package is imported dynamically (not at top level) because it captures the
14
+ * OTLP transport config from the `OTEL_EXPORTER_OTLP_*` env vars at module-load time
15
+ * and exposes no endpoint/header option on `init()` — so those vars must be set before
16
+ * it loads.
17
+ *
18
+ * Under openclaw the operator must set ALL of these in the container env (the SDK does
19
+ * not derive them; this module only defaults the base endpoint below, for standalone runs):
20
+ * OTEL_EXPORTER_OTLP_ENDPOINT (base, e.g. http://host.docker.internal:4318)
21
+ * OTEL_EXPORTER_OTLP_TRACES_ENDPOINT (.../v1/traces)
22
+ * OTEL_EXPORTER_OTLP_LOGS_ENDPOINT (.../v1/logs)
23
+ * OTEL_EXPORTER_OTLP_METRICS_ENDPOINT (.../v1/metrics)
24
+ * OTEL_EXPORTER_OTLP_HEADERS (e.g. Authorization=<collector-token>)
25
+ * See docs/runtime-docs/runtime-api.md (Tracing) for why each is required.
26
+ */
27
+ import { randomUUID } from "node:crypto";
28
+ import { createLogger } from "../utils/logger.js";
29
+ const logger = createLogger("telemetry/otel-sdk");
30
+ /** Base OTLP endpoint defaulted for standalone Node runs only; ignored under openclaw (see module header). */
31
+ export const DEFAULT_OTLP_ENDPOINT = "http://localhost:4318";
32
+ /**
33
+ * Process-level instance id for `service.instance.id`. Distinct from the
34
+ * per-runtime `IdentityEnvelope.bootId`: resource attributes are process-global,
35
+ * so this must identify the PROCESS (disambiguating restarts), not a single
36
+ * runtime — N runtimes share one of these.
37
+ */
38
+ const PROCESS_INSTANCE_ID = randomUUID();
39
+ /**
40
+ * Re-enable the undici (global `fetch`) auto-instrumentation after `hyperdx.init()`.
41
+ *
42
+ * HyperDX's `init()` leaves undici disabled: across init it calls
43
+ * `setConfig → enable (subscribe undici:request:*) → disable`, with no re-enable
44
+ * (observed by instrumenting the class). So `undici:request:create` ends with no
45
+ * subscribers and no `fetch()` produces an HTTP client span — untracing everything on
46
+ * global `fetch`: the Senpi MCP client (`StreamableHTTPClientTransport`), the LLM
47
+ * client, etc. (`net`/`dns`/`tls` are independent and still emit, so connections show
48
+ * up while the requests riding them don't.)
49
+ *
50
+ * Fix: enable our own `UndiciInstrumentation`; with no provider set it resolves the
51
+ * global one `init()` registered, and HyperDX's instance stays disabled (no double
52
+ * instrumentation). Best-effort — a failure must not fail boot. Also a prerequisite
53
+ * for the manual `mcp.*`/`dsl.*` spans (Task 9b), which assume outbound `fetch` calls
54
+ * auto-nest as HTTP children.
55
+ *
56
+ * Seen with `@hyperdx/node-opentelemetry` 0.11 / `instrumentation-undici` 0.28, Node 24
57
+ * — re-check on upgrade; drop if HyperDX stops disabling undici.
58
+ */
59
+ async function reinstrumentUndici() {
60
+ try {
61
+ const mod = (await import("@opentelemetry/instrumentation-undici"));
62
+ new mod.UndiciInstrumentation().enable();
63
+ logger.debug("undici (fetch) instrumentation re-enabled post-init");
64
+ }
65
+ catch (err) {
66
+ logger.warn("failed to re-enable undici instrumentation; fetch client spans will be missing", {
67
+ err: err instanceof Error ? err.message : String(err),
68
+ });
69
+ }
70
+ }
71
+ /** Process-global once-only guard; resource attributes are immutable after init(). */
72
+ let initialized = false;
73
+ /**
74
+ * Reference to the loaded HyperDX module, captured at init so {@link shutdownOtelSdk}
75
+ * can flush the SDK without a second dynamic import. Process-global like the SDK itself.
76
+ */
77
+ let hyperdxModule;
78
+ /**
79
+ * Whether {@link initOtelSdk} has completed. Code that loads `@hyperdx/node-opentelemetry`
80
+ * lazily (e.g. per-trace attribute stamping) gates on this so the package — which captures
81
+ * its OTLP transport env at module-load — never loads when telemetry is disabled or under test.
82
+ */
83
+ export function isOtelInitialized() {
84
+ return initialized;
85
+ }
86
+ /**
87
+ * Decode the `senpi_user_id` claim from a JWT without verifying its signature.
88
+ * Returns `undefined` for any non-JWT / malformed / missing-claim input; never throws.
89
+ *
90
+ * The claim name is assumed, not confirmed against a real token — if the id lives
91
+ * under a different claim (e.g. `sub`), this must change before `user.id` is trusted.
92
+ */
93
+ export function decodeSenpiUserId(token) {
94
+ if (typeof token !== "string" || token.length === 0)
95
+ return undefined;
96
+ try {
97
+ const segments = token.split(".");
98
+ if (segments.length < 2)
99
+ return undefined;
100
+ const payloadSegment = segments[1];
101
+ if (!payloadSegment)
102
+ return undefined;
103
+ const json = Buffer.from(payloadSegment, "base64url").toString("utf8");
104
+ if (json.length === 0)
105
+ return undefined;
106
+ const payload = JSON.parse(json);
107
+ const claim = payload?.senpi_user_id;
108
+ // Only string/number; anything else (object/array) would coerce to junk.
109
+ if (typeof claim !== "string" && typeof claim !== "number")
110
+ return undefined;
111
+ const asString = String(claim);
112
+ return asString.length > 0 ? asString : undefined;
113
+ }
114
+ catch {
115
+ return undefined;
116
+ }
117
+ }
118
+ /**
119
+ * Build the `OTEL_RESOURCE_ATTRIBUTES` value as a `key=value,key=value` string.
120
+ * Values are percent-encoded so spaces/commas stay valid; empty keys are omitted.
121
+ *
122
+ * SCOPING (multi-runtime): resource attributes are process-global and immutable
123
+ * after the first init(), but N runtimes (one per wallet) share one process — so
124
+ * only PROCESS-STABLE values belong here. We carry:
125
+ * - service.name, service.version, deployment.environment — process-stable.
126
+ * - service.instance.id — a PROCESS-level id ({@link PROCESS_INSTANCE_ID}), not
127
+ * the per-runtime `IdentityEnvelope.bootId`.
128
+ * - user.id — process-stable: single-tenant, one SENPI_API_KEY = one user for
129
+ * the whole process, so it is the same across every runtime here.
130
+ *
131
+ * The per-runtime keys (senpi.strategy.address, senpi.recipe, senpi.recipe.version,
132
+ * senpi.runtime, senpi.config.hash) are deliberately OMITTED — on a process-global
133
+ * resource they would stamp the first runtime's value onto every other runtime's
134
+ * telemetry. They return as per-trace/per-log attributes in 9b (`setTraceAttributes`)
135
+ * / 9c (LogRecordProcessor).
136
+ */
137
+ export function buildOtelResourceAttributes(serviceName, extras) {
138
+ const pairs = [
139
+ ["service.name", serviceName],
140
+ ["service.instance.id", extras.serviceInstanceId],
141
+ ["service.version", extras.serviceVersion],
142
+ ["deployment.environment", extras.deploymentEnvironment],
143
+ ["user.id", extras.userId],
144
+ ];
145
+ return pairs
146
+ .filter(([, value]) => value !== undefined && String(value).length > 0)
147
+ .map(([key, value]) => `${key}=${encodeURIComponent(String(value))}`)
148
+ .join(",");
149
+ }
150
+ /**
151
+ * Resolve the OTLP endpoint: `OTEL_EXPORTER_OTLP_ENDPOINT` env >
152
+ * {@link DEFAULT_OTLP_ENDPOINT}.
153
+ */
154
+ export function resolveOtlpEndpoint() {
155
+ const envOverride = process.env.OTEL_EXPORTER_OTLP_ENDPOINT?.trim();
156
+ if (envOverride)
157
+ return envOverride;
158
+ return DEFAULT_OTLP_ENDPOINT;
159
+ }
160
+ /**
161
+ * Initialise the OTel SDK. Idempotent, side-effecting, and never crashes boot:
162
+ * no-ops when disabled, already initialised, or under test.
163
+ */
164
+ export async function initOtelSdk(params) {
165
+ if (initialized)
166
+ return;
167
+ if (!params.enabled) {
168
+ logger.debug("OTel SDK init skipped: telemetry disabled");
169
+ return;
170
+ }
171
+ // Skip under test: the enable gate defaults to true, so without this the SDK
172
+ // would init (start exporters, patch core modules) during the vitest run.
173
+ if (process.env.VITEST || process.env.NODE_ENV === "test") {
174
+ logger.debug("OTel SDK init skipped: running under test");
175
+ return;
176
+ }
177
+ try {
178
+ const identity = params.identity();
179
+ // Commit the guard before any fallible work: a failed init must not let a
180
+ // later Runtime.start() re-enter and double-append OTEL_RESOURCE_ATTRIBUTES.
181
+ // identity() above threw before this, so env is still untouched on that path.
182
+ initialized = true;
183
+ // Source the environment label from NODE_ENV (Node-standard). Pass the value
184
+ // through verbatim (so `staging`/custom envs are faithful), defaulting to
185
+ // "development" when unset/empty — a label must never claim production by
186
+ // accident; prod deployments set NODE_ENV=production as standard practice.
187
+ const nodeEnv = process.env.NODE_ENV?.trim();
188
+ const deploymentEnvironment = nodeEnv && nodeEnv.length > 0 ? nodeEnv : "development";
189
+ const userId = decodeSenpiUserId(params.userToken);
190
+ // Append to any host-set value rather than clobber operator attrs.
191
+ const ourAttrs = buildOtelResourceAttributes(identity.service, {
192
+ serviceInstanceId: PROCESS_INSTANCE_ID,
193
+ serviceVersion: params.serviceVersion,
194
+ deploymentEnvironment,
195
+ userId,
196
+ });
197
+ const existingAttrs = process.env.OTEL_RESOURCE_ATTRIBUTES?.trim();
198
+ process.env.OTEL_RESOURCE_ATTRIBUTES = existingAttrs
199
+ ? `${existingAttrs},${ourAttrs}`
200
+ : ourAttrs;
201
+ // Must be set before the import below — HyperDX reads it at module-load.
202
+ if (!process.env.OTEL_EXPORTER_OTLP_ENDPOINT) {
203
+ process.env.OTEL_EXPORTER_OTLP_ENDPOINT = resolveOtlpEndpoint();
204
+ }
205
+ // Dynamic import: loads only now, after the env var above is set.
206
+ const hyperdx = (await import("@hyperdx/node-opentelemetry"));
207
+ hyperdxModule = hyperdx;
208
+ hyperdx.init({
209
+ // No apiKey on init(): the exporter authenticates to the collector via the
210
+ // Authorization header in OTEL_EXPORTER_OTLP_HEADERS (read from env at
211
+ // module-load), not through the SDK's HyperDX apiKey field.
212
+ service: identity.service,
213
+ // Routes createLogger() → console.* output into OTel logs.
214
+ consoleCapture: true,
215
+ experimentalExceptionCapture: true,
216
+ // Don't let HyperDX install its own SIGTERM/SIGINT handlers. Its default
217
+ // handler calls process.exit() once its own _shutdown() settles, without
218
+ // awaiting our teardown. OpenClaw owns process lifecycle and drives
219
+ // Runtime.stop() → disposeRecording(), whose recording-batcher drain is an
220
+ // async network flush; HyperDX's exit would preempt that and drop buffered
221
+ // rows. Leaving this false hands shutdown ordering back to the gateway.
222
+ stopOnTerminationSignals: false,
223
+ // Arms setTraceAttributes: without it the span processor that copies per-trace
224
+ // identity onto every span and log stays disabled, and the stamping no-ops.
225
+ betaMode: true,
226
+ });
227
+ await reinstrumentUndici();
228
+ logger.info("OTel SDK initialised", {
229
+ service: identity.service,
230
+ endpoint: process.env.OTEL_EXPORTER_OTLP_ENDPOINT,
231
+ deploymentEnvironment,
232
+ });
233
+ }
234
+ catch (err) {
235
+ logger.warn("OTel SDK init failed; continuing without telemetry transport", {
236
+ err: err instanceof Error ? err.message : String(err),
237
+ });
238
+ }
239
+ }
240
+ /**
241
+ * Flush and stop the OTel SDK. Best-effort, idempotent, never throws.
242
+ *
243
+ * Required because {@link initOtelSdk} disables HyperDX's own SIGTERM handler
244
+ * (`stopOnTerminationSignals: false`) — that handler was the SDK's only on-exit
245
+ * flush, so without an explicit shutdown the span/log batch processors' buffers
246
+ * are dropped at process exit. The SDK is process-global (one per process,
247
+ * shared across all hosted runtimes), so this must be called ONCE at process /
248
+ * plugin teardown, after every span has been emitted — never per-runtime, which
249
+ * would cut off telemetry for sibling runtimes still running.
250
+ */
251
+ export async function shutdownOtelSdk() {
252
+ if (!initialized || !hyperdxModule)
253
+ return;
254
+ // Flip the guard first so a concurrent/duplicate teardown can't double-shutdown.
255
+ initialized = false;
256
+ const mod = hyperdxModule;
257
+ hyperdxModule = undefined;
258
+ try {
259
+ await mod.shutdown();
260
+ logger.debug("OTel SDK shut down (final flush complete)");
261
+ }
262
+ catch (err) {
263
+ logger.warn("OTel SDK shutdown failed; buffered spans/logs may be lost", {
264
+ err: err instanceof Error ? err.message : String(err),
265
+ });
266
+ }
267
+ }
268
+ //# sourceMappingURL=otel-sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otel-sdk.js","sourceRoot":"","sources":["../../src/telemetry/otel-sdk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Pure, vendor-neutral mapping `IdentityEnvelope → senpi.* attributes`, set per-trace
3
+ * at each root span's birth. Per-runtime identity can't live on the process-global OTel
4
+ * resource — N wallets share one process, so a resource attribute would stamp the first
5
+ * runtime's value onto everyone's telemetry (see `otel-sdk.ts` SCOPING note).
6
+ *
7
+ * The actual stamping is HyperDX's `setTraceAttributes` (rides every span in the trace),
8
+ * called at the root-span seams — NOT here: importing `@hyperdx/node-opentelemetry`
9
+ * captures its OTLP transport env at module-load, so it must stay behind code that runs
10
+ * only after `initOtelSdk()`.
11
+ */
12
+ import type { Attributes } from "@opentelemetry/api";
13
+ import type { IdentityEnvelope } from "../recording/identity.js";
14
+ /**
15
+ * Map the runtime {@link IdentityEnvelope} to its `senpi.*` trace attributes. Optional
16
+ * envelope fields are omitted when unset rather than emitted as empty/undefined, so a
17
+ * trace never carries a hollow `senpi.config.hash=""`.
18
+ */
19
+ export declare function identityTraceAttributes(identity: IdentityEnvelope): Attributes;
20
+ /**
21
+ * Stamp the runtime's `senpi.*` identity onto the active trace via HyperDX's
22
+ * `setTraceAttributes`, which rides every span in the trace. Call it from a root-span
23
+ * seam (inside an active span's context) so the whole trace carries the identity.
24
+ *
25
+ * No-ops until the SDK is initialised: the import is dynamic so `@hyperdx/node-opentelemetry`
26
+ * (which captures its OTLP env at module-load) only loads after `initOtelSdk()`, and there is
27
+ * no trace to stamp before then. Best-effort: a failure is logged and swallowed — tracing must
28
+ * never break trading.
29
+ */
30
+ export declare function setTraceIdentityAttributes(identity: IdentityEnvelope): Promise<void>;
31
+ //# sourceMappingURL=trace-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-identity.d.ts","sourceRoot":"","sources":["../../src/telemetry/trace-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAMjE;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,UAAU,CAc9E;AAED;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAY1F"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Pure, vendor-neutral mapping `IdentityEnvelope → senpi.* attributes`, set per-trace
3
+ * at each root span's birth. Per-runtime identity can't live on the process-global OTel
4
+ * resource — N wallets share one process, so a resource attribute would stamp the first
5
+ * runtime's value onto everyone's telemetry (see `otel-sdk.ts` SCOPING note).
6
+ *
7
+ * The actual stamping is HyperDX's `setTraceAttributes` (rides every span in the trace),
8
+ * called at the root-span seams — NOT here: importing `@hyperdx/node-opentelemetry`
9
+ * captures its OTLP transport env at module-load, so it must stay behind code that runs
10
+ * only after `initOtelSdk()`.
11
+ */
12
+ import { isOtelInitialized } from "./otel-sdk.js";
13
+ import { createLogger } from "../utils/logger.js";
14
+ const logger = createLogger("telemetry/trace-identity");
15
+ /**
16
+ * Map the runtime {@link IdentityEnvelope} to its `senpi.*` trace attributes. Optional
17
+ * envelope fields are omitted when unset rather than emitted as empty/undefined, so a
18
+ * trace never carries a hollow `senpi.config.hash=""`.
19
+ */
20
+ export function identityTraceAttributes(identity) {
21
+ const attributes = {
22
+ "senpi.strategy.address": identity.strategyAddress,
23
+ "senpi.recipe": identity.recipe,
24
+ "senpi.runtime": identity.runtime,
25
+ "senpi.boot.id": identity.bootId,
26
+ };
27
+ if (identity.recipeVersion !== undefined) {
28
+ attributes["senpi.recipe.version"] = String(identity.recipeVersion);
29
+ }
30
+ if (identity.configHash !== undefined) {
31
+ attributes["senpi.config.hash"] = identity.configHash;
32
+ }
33
+ return attributes;
34
+ }
35
+ /**
36
+ * Stamp the runtime's `senpi.*` identity onto the active trace via HyperDX's
37
+ * `setTraceAttributes`, which rides every span in the trace. Call it from a root-span
38
+ * seam (inside an active span's context) so the whole trace carries the identity.
39
+ *
40
+ * No-ops until the SDK is initialised: the import is dynamic so `@hyperdx/node-opentelemetry`
41
+ * (which captures its OTLP env at module-load) only loads after `initOtelSdk()`, and there is
42
+ * no trace to stamp before then. Best-effort: a failure is logged and swallowed — tracing must
43
+ * never break trading.
44
+ */
45
+ export async function setTraceIdentityAttributes(identity) {
46
+ if (!isOtelInitialized())
47
+ return;
48
+ try {
49
+ const hyperdx = (await import("@hyperdx/node-opentelemetry"));
50
+ hyperdx.setTraceAttributes(identityTraceAttributes(identity));
51
+ }
52
+ catch (err) {
53
+ logger.warn("failed to stamp per-trace identity attributes", {
54
+ err: err instanceof Error ? err.message : String(err),
55
+ });
56
+ }
57
+ }
58
+ //# sourceMappingURL=trace-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace-identity.js","sourceRoot":"","sources":["../../src/telemetry/trace-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,MAAM,GAAG,YAAY,CAAC,0BAA0B,CAAC,CAAC;AAExD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,QAA0B;IAChE,MAAM,UAAU,GAAe;QAC7B,wBAAwB,EAAE,QAAQ,CAAC,eAAe;QAClD,cAAc,EAAE,QAAQ,CAAC,MAAM;QAC/B,eAAe,EAAE,QAAQ,CAAC,OAAO;QACjC,eAAe,EAAE,QAAQ,CAAC,MAAM;KACjC,CAAC;IACF,IAAI,QAAQ,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;QACzC,UAAU,CAAC,sBAAsB,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACtC,UAAU,CAAC,mBAAmB,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC;IACxD,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,QAA0B;IACzE,IAAI,CAAC,iBAAiB,EAAE;QAAE,OAAO;IACjC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,6BAA6B,CAAC,CAE3D,CAAC;QACF,OAAO,CAAC,kBAAkB,CAAC,uBAAuB,CAAC,QAAQ,CAAC,CAAC,CAAC;IAChE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,+CAA+C,EAAE;YAC3D,GAAG,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACtD,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The one place runtime code touches the OTel trace API: manual spans are created
3
+ * exclusively through {@link withSpan}. Vendor-neutral (depends only on
4
+ * `@opentelemetry/api`); the SDK itself is stood up in `otel-sdk.ts`. When the SDK
5
+ * is not initialised (telemetry off, or under test) the API resolves a no-op tracer,
6
+ * so `withSpan` runs the callback with near-zero overhead — no `enabled` gate needed.
7
+ */
8
+ import { type Span, type Attributes, type Tracer } from "@opentelemetry/api";
9
+ /** The single tracer for our manual spans. Resolves the no-op tracer pre-init. */
10
+ export declare function getTracer(): Tracer;
11
+ /**
12
+ * Run `fn` inside a new active span, standardising the lifecycle:
13
+ *
14
+ * - `startActiveSpan`, so the span is the active context: auto-instrumented HTTP
15
+ * children and nested {@link withSpan} calls nest under it while work stays on the
16
+ * synchronous `await` chain. (`startSpan` would detach children into roots.)
17
+ * - Passes the span **handle** into `fn` — use it for `addEvent`/`setAttribute`/
18
+ * `recordException`, never `trace.getActiveSpan()` (ambiguous under concurrent
19
+ * sibling spans, e.g. a `Promise.all` fan-out).
20
+ * - On throw: records the exception, sets ERROR status, then **rethrows** — tracing
21
+ * observes, never alters control flow. Pass `options.expected` to mark control-flow
22
+ * throws (e.g. `SkipScan`) that should propagate *without* painting the span red.
23
+ * - Always ends the span (`finally`), so a span can never leak.
24
+ *
25
+ * Tracing must never break runtime code: the span operations are guarded so a throw
26
+ * from the SDK — or from a caller's `expected` predicate — can neither mask `fn`'s
27
+ * error nor corrupt its result.
28
+ */
29
+ export declare function withSpan<T>(name: string, attributes: Attributes, fn: (span: Span) => Promise<T>, options?: {
30
+ expected?: (err: unknown) => boolean;
31
+ }): Promise<T>;
32
+ //# sourceMappingURL=tracing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracing.d.ts","sourceRoot":"","sources":["../../src/telemetry/tracing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAGL,KAAK,IAAI,EACT,KAAK,UAAU,EACf,KAAK,MAAM,EACZ,MAAM,oBAAoB,CAAC;AAK5B,kFAAkF;AAClF,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACxB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9B,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAA;CAAE,GACjD,OAAO,CAAC,CAAC,CAAC,CA8BZ"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * The one place runtime code touches the OTel trace API: manual spans are created
3
+ * exclusively through {@link withSpan}. Vendor-neutral (depends only on
4
+ * `@opentelemetry/api`); the SDK itself is stood up in `otel-sdk.ts`. When the SDK
5
+ * is not initialised (telemetry off, or under test) the API resolves a no-op tracer,
6
+ * so `withSpan` runs the callback with near-zero overhead — no `enabled` gate needed.
7
+ */
8
+ import { trace, SpanStatusCode, } from "@opentelemetry/api";
9
+ /** Instrumentation scope for every span this runtime creates. */
10
+ const TRACER_NAME = "senpi-trading-runtime";
11
+ /** The single tracer for our manual spans. Resolves the no-op tracer pre-init. */
12
+ export function getTracer() {
13
+ return trace.getTracer(TRACER_NAME);
14
+ }
15
+ /**
16
+ * Run `fn` inside a new active span, standardising the lifecycle:
17
+ *
18
+ * - `startActiveSpan`, so the span is the active context: auto-instrumented HTTP
19
+ * children and nested {@link withSpan} calls nest under it while work stays on the
20
+ * synchronous `await` chain. (`startSpan` would detach children into roots.)
21
+ * - Passes the span **handle** into `fn` — use it for `addEvent`/`setAttribute`/
22
+ * `recordException`, never `trace.getActiveSpan()` (ambiguous under concurrent
23
+ * sibling spans, e.g. a `Promise.all` fan-out).
24
+ * - On throw: records the exception, sets ERROR status, then **rethrows** — tracing
25
+ * observes, never alters control flow. Pass `options.expected` to mark control-flow
26
+ * throws (e.g. `SkipScan`) that should propagate *without* painting the span red.
27
+ * - Always ends the span (`finally`), so a span can never leak.
28
+ *
29
+ * Tracing must never break runtime code: the span operations are guarded so a throw
30
+ * from the SDK — or from a caller's `expected` predicate — can neither mask `fn`'s
31
+ * error nor corrupt its result.
32
+ */
33
+ export function withSpan(name, attributes, fn, options) {
34
+ return getTracer().startActiveSpan(name, { attributes }, async (span) => {
35
+ try {
36
+ return await fn(span);
37
+ }
38
+ catch (err) {
39
+ let expected = false;
40
+ try {
41
+ expected = options?.expected?.(err) ?? false;
42
+ }
43
+ catch {
44
+ // A throwing predicate must never mask the real error; treat as unexpected.
45
+ }
46
+ if (expected)
47
+ throw err;
48
+ try {
49
+ span.recordException(err);
50
+ span.setStatus({
51
+ code: SpanStatusCode.ERROR,
52
+ message: err instanceof Error ? err.message : String(err),
53
+ });
54
+ }
55
+ catch {
56
+ // A tracing failure must never replace the real error the caller needs.
57
+ }
58
+ throw err;
59
+ }
60
+ finally {
61
+ try {
62
+ span.end();
63
+ }
64
+ catch {
65
+ // Span teardown must never break the caller's result or error.
66
+ }
67
+ }
68
+ });
69
+ }
70
+ //# sourceMappingURL=tracing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracing.js","sourceRoot":"","sources":["../../src/telemetry/tracing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACL,KAAK,EACL,cAAc,GAIf,MAAM,oBAAoB,CAAC;AAE5B,iEAAiE;AACjE,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAE5C,kFAAkF;AAClF,MAAM,UAAU,SAAS;IACvB,OAAO,KAAK,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,QAAQ,CACtB,IAAY,EACZ,UAAsB,EACtB,EAA8B,EAC9B,OAAkD;IAElD,OAAO,SAAS,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QACtE,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,QAAQ,GAAG,KAAK,CAAC;YACrB,IAAI,CAAC;gBACH,QAAQ,GAAG,OAAO,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,4EAA4E;YAC9E,CAAC;YACD,IAAI,QAAQ;gBAAE,MAAM,GAAG,CAAC;YACxB,IAAI,CAAC;gBACH,IAAI,CAAC,eAAe,CAAC,GAAY,CAAC,CAAC;gBACnC,IAAI,CAAC,SAAS,CAAC;oBACb,IAAI,EAAE,cAAc,CAAC,KAAK;oBAC1B,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBAC1D,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,wEAAwE;YAC1E,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC;gBACH,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,CAAC;YAAC,MAAM,CAAC;gBACP,+DAA+D;YACjE,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -71,5 +71,7 @@ export interface ScanResult {
71
71
  reason?: string;
72
72
  /** Aggregated run metrics/details. */
73
73
  summary: Record<string, unknown>;
74
+ /** Telemetry-owned per-run id; join key linking scanner.run → signal.process. */
75
+ runId?: string;
74
76
  }
75
77
  //# sourceMappingURL=scanner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/types/scanner.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAC/B,2CAA2C;AAC3C,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAIhC,uEAAuE;AACvE,oBAAY,UAAU;IACpB,EAAE,OAAO;IACT,SAAS,cAAc;IACvB,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,KAAK,UAAU;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,EAAE,SAAS,CAAC;IACrB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IACnC,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,mEAAmE;AACnE,MAAM,WAAW,UAAU;IACzB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,SAAS,EAAE,SAAS,CAAC;IACrB,0DAA0D;IAC1D,MAAM,EAAE,UAAU,CAAC;IACnB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,oDAAoD;IACpD,eAAe,EAAE,MAAM,CAAC;IACxB,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC"}
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../src/types/scanner.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC;AAC/B,2CAA2C;AAC3C,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAIhC,uEAAuE;AACvE,oBAAY,UAAU;IACpB,EAAE,OAAO;IACT,SAAS,cAAc;IACvB,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,KAAK,UAAU;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,EAAE,SAAS,CAAC;IACrB,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,SAAS,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IACnC,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,mEAAmE;AACnE,MAAM,WAAW,UAAU;IACzB,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,SAAS,EAAE,SAAS,CAAC;IACrB,0DAA0D;IAC1D,MAAM,EAAE,UAAU,CAAC;IACnB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,oDAAoD;IACpD,eAAe,EAAE,MAAM,CAAC;IACxB,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,iFAAiF;IACjF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@senpi/runtime",
3
- "version": "3.0.6-dev.runtime-phase-2.20260627082846",
3
+ "version": "3.0.6-dev.runtime-phase-2.20260630134307",
4
4
  "description": "Senpi runtime plugin for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,11 +32,13 @@
32
32
  },
33
33
  "dependencies": {
34
34
  "@anthropic-ai/sdk": "^0.39.0",
35
+ "@hyperdx/node-opentelemetry": "^0.11.0",
35
36
  "@modelcontextprotocol/sdk": "^1.0.0",
37
+ "@opentelemetry/api": "^1.9.1",
38
+ "@opentelemetry/instrumentation-undici": "^0.28.0",
36
39
  "@sinclair/typebox": "^0.34.0",
37
40
  "async-retry": "^1.3.3",
38
41
  "bip39": "^3.1.0",
39
- "dd-trace": "^5.99.1",
40
42
  "dotenv": "^16.4.5",
41
43
  "fastify": "^5.8.5",
42
44
  "mcporter": "^0.7.3",
@@ -48,6 +50,8 @@
48
50
  "openclaw": ">=2026.5.0"
49
51
  },
50
52
  "devDependencies": {
53
+ "@opentelemetry/context-async-hooks": "^2.8.0",
54
+ "@opentelemetry/sdk-trace-base": "^2.8.0",
51
55
  "@types/async-retry": "^1.4.9",
52
56
  "@types/node": "^22.0.0",
53
57
  "tsx": "^4.21.0",