@amsterdamdatalabs/traces 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.
Files changed (41) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +89 -0
  3. package/dist/conventions/enact-extensions.d.ts +115 -0
  4. package/dist/conventions/enact-extensions.js +135 -0
  5. package/dist/conventions/index.d.ts +2 -0
  6. package/dist/conventions/index.js +2 -0
  7. package/dist/conventions/openinference.d.ts +1 -0
  8. package/dist/conventions/openinference.js +19 -0
  9. package/dist/emit/emit.d.ts +11 -0
  10. package/dist/emit/emit.js +80 -0
  11. package/dist/index.d.ts +4 -0
  12. package/dist/index.js +4 -0
  13. package/dist/payloads/agent-lifecycle.d.ts +27 -0
  14. package/dist/payloads/agent-lifecycle.js +1 -0
  15. package/dist/payloads/cache-hit.d.ts +17 -0
  16. package/dist/payloads/cache-hit.js +1 -0
  17. package/dist/payloads/hand.d.ts +8 -0
  18. package/dist/payloads/hand.js +1 -0
  19. package/dist/payloads/hook-fired.d.ts +21 -0
  20. package/dist/payloads/hook-fired.js +1 -0
  21. package/dist/payloads/index.d.ts +9 -0
  22. package/dist/payloads/index.js +9 -0
  23. package/dist/payloads/llm-call.d.ts +135 -0
  24. package/dist/payloads/llm-call.js +84 -0
  25. package/dist/payloads/memory-search.d.ts +21 -0
  26. package/dist/payloads/memory-search.js +1 -0
  27. package/dist/payloads/memory-write.d.ts +1 -0
  28. package/dist/payloads/memory-write.js +1 -0
  29. package/dist/payloads/proc-tap.d.ts +20 -0
  30. package/dist/payloads/proc-tap.js +1 -0
  31. package/dist/payloads/tool-call.d.ts +11 -0
  32. package/dist/payloads/tool-call.js +1 -0
  33. package/dist/types/context.d.ts +16 -0
  34. package/dist/types/context.js +1 -0
  35. package/dist/types/envelope.d.ts +15 -0
  36. package/dist/types/envelope.js +1 -0
  37. package/dist/types/index.d.ts +3 -0
  38. package/dist/types/index.js +3 -0
  39. package/dist/types/span-kinds.d.ts +14 -0
  40. package/dist/types/span-kinds.js +14 -0
  41. package/package.json +47 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,9 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 — 2026-05-18
4
+
5
+ Initial release.
6
+
7
+ - Canonical trace types and payload schemas for enact-os observability
8
+ - `LlmCallPayload`, `LLM_CALL_STAGES`, `expandMessages`, `expandTools`, `flattenPayload`
9
+ - Sub-path exports: `@amsterdamdatalabs/traces`, `@amsterdamdatalabs/traces/conventions`, `@amsterdamdatalabs/traces/emit`, `@amsterdamdatalabs/traces/payloads`
package/README.md ADDED
@@ -0,0 +1,89 @@
1
+ <p align="center">
2
+ <strong>@amsterdamdatalabs/traces</strong>
3
+ </p>
4
+ <p align="center">
5
+ Shared OpenInference tracing types, span attribute constants, and event emit for enact-os packages
6
+ </p>
7
+
8
+ ## What is it?
9
+
10
+ `@amsterdamdatalabs/traces` is the canonical tracing contract for the enact-os observability stack. It provides:
11
+
12
+ - **Payload schemas** — typed event payloads for every span kind: LLM calls, tool calls, memory reads/writes, proc-tap, agent lifecycle, hook-fired, cache hits, and hand runs
13
+ - **Span attribute constants** — `enact.*` and `llm.*` extension attributes on top of the OpenInference semantic conventions
14
+ - **Emit** — a zero-dependency `emitEvent()` that writes NDJSON to the watchdog dir and publishes to Apache Iggy in parallel
15
+
16
+ Used by `enact-gateway`, `enact-factory`, `enact-memory`, `enact-agent`, and `enact-watchdog`.
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install @amsterdamdatalabs/traces
22
+ ```
23
+
24
+ ## Usage
25
+
26
+ ### Emit a trace event
27
+
28
+ ```typescript
29
+ import { emitEvent } from '@amsterdamdatalabs/traces/emit';
30
+ import type { EnactRawV1Event } from '@amsterdamdatalabs/traces';
31
+
32
+ const event: EnactRawV1Event = {
33
+ schema: 'enact.raw.v1',
34
+ ts: Date.now(),
35
+ span_kind: 'llm_call',
36
+ payload: { /* ... */ },
37
+ };
38
+
39
+ await emitEvent(event, { ndjsonFile: 'factory-events.ndjson' });
40
+ ```
41
+
42
+ ### Use span attribute constants
43
+
44
+ ```typescript
45
+ import {
46
+ ENACT_ROUTING_TIER,
47
+ ENACT_PROVIDER,
48
+ LLM_ENDPOINT_KEY,
49
+ } from '@amsterdamdatalabs/traces/conventions';
50
+
51
+ span.setAttribute(ENACT_ROUTING_TIER, 'standard');
52
+ span.setAttribute(ENACT_PROVIDER, 'anthropic');
53
+ ```
54
+
55
+ ### Use typed payloads
56
+
57
+ ```typescript
58
+ import type { LlmCallPayload } from '@amsterdamdatalabs/traces/payloads';
59
+
60
+ const payload: LlmCallPayload = {
61
+ model: 'claude-sonnet-4-6',
62
+ input_tokens: 1200,
63
+ output_tokens: 340,
64
+ };
65
+ ```
66
+
67
+ ## Sub-path exports
68
+
69
+ | Import | Contents |
70
+ |--------|----------|
71
+ | `@amsterdamdatalabs/traces` | All types, payloads, conventions, and emit |
72
+ | `@amsterdamdatalabs/traces/conventions` | `enact.*` and `llm.*` span attribute constants |
73
+ | `@amsterdamdatalabs/traces/payloads` | Typed payload schemas for each span kind |
74
+ | `@amsterdamdatalabs/traces/emit` | `emitEvent()` — NDJSON + Iggy publish |
75
+
76
+ ## Environment variables
77
+
78
+ | Variable | Default | Purpose |
79
+ |----------|---------|---------|
80
+ | `ENACT_WATCHDOG_DIR` | `.enact/watchdog` | Directory for NDJSON output files |
81
+ | `IGGY_HTTP_URL` | `http://127.0.0.1:43214` | Apache Iggy HTTP endpoint |
82
+ | `IGGY_HTTP_ACCESS_TOKEN` | — | Bearer token for Iggy auth |
83
+ | `IGGY_HTTP_USERNAME` | `iggy` | Iggy username (if no token) |
84
+ | `IGGY_HTTP_PASSWORD` | `iggy` | Iggy password (if no token) |
85
+ | `ENACT_OBSERVABILITY_DEBUG` | — | Log emit errors to stderr |
86
+
87
+ ## License
88
+
89
+ Proprietary — Copyright © 2026 Amsterdam Data Labs.
@@ -0,0 +1,115 @@
1
+ export declare const ENACT_ROUTING_TIER: "enact.routing_tier";
2
+ export declare const ENACT_ROUTING_REASON: "enact.routing_reason";
3
+ export declare const ENACT_SPECIFICITY_CATEGORY: "enact.specificity_category";
4
+ export declare const ENACT_FALLBACK_FROM_MODEL: "enact.fallback_from_model";
5
+ export declare const ENACT_AUTH_TYPE: "enact.auth_type";
6
+ export declare const ENACT_PROVIDER: "enact.provider";
7
+ export declare const ENACT_DURATION_MS: "enact.duration_ms";
8
+ export declare const ENACT_SUCCESS: "enact.success";
9
+ export declare const ENACT_ROUTING_DECISION_PATH: "enact.routing.decision_path";
10
+ export declare const ENACT_ROUTING_CONFIDENCE: "enact.routing.confidence";
11
+ export declare const ENACT_ROUTING_SCORE: "enact.routing.score";
12
+ export declare const ENACT_ROUTING_IS_SPECIFICITY: "enact.routing.routing_is_specificity";
13
+ export declare const ENACT_ROUTING_PASSTHROUGH_MATCH_SOURCE: "enact.routing.passthrough_match_source";
14
+ export declare const ENACT_ROUTING_HEARTBEAT_DETECTED: "enact.routing.heartbeat_detected";
15
+ export declare const ENACT_ROUTING_SCORING_MESSAGES_DROPPED: "enact.routing.scoring_messages_dropped";
16
+ export declare const ENACT_ROUTING_SCORING_MESSAGES_TRUNCATED: "enact.routing.scoring_messages_truncated";
17
+ export declare const ENACT_ROUTING_PROVIDER_KEY_LABEL: "enact.routing.provider_key_label";
18
+ export declare const ENACT_ROUTING_HEADER_TIER_ID: "enact.routing.header_tier_id";
19
+ export declare const ENACT_ROUTING_HEADER_TIER_NAME: "enact.routing.header_tier_name";
20
+ export declare const ENACT_ROUTING_HEADER_TIER_COLOR: "enact.routing.header_tier_color";
21
+ export declare const ENACT_ROUTING_BILLING_TYPE: "enact.routing.billing_type";
22
+ export declare const ENACT_ROUTING_PARAM_DEFAULTS_SOURCE: "enact.routing.param_defaults_source";
23
+ export declare const ENACT_ROUTING_PARAM_DEFAULTS_DROPPED: "enact.routing.param_defaults_dropped";
24
+ export declare const ENACT_ROUTING_API_MODE_INBOUND: "enact.routing.api_mode_inbound";
25
+ export declare const ENACT_ROUTING_FORWARDED_API_PATH: "enact.routing.forwarded_api_path";
26
+ export declare const ENACT_ROUTING_ATTEMPT_INDEX: "enact.routing.attempt_index";
27
+ export declare const ENACT_ROUTING_ATTEMPT_ROLE: "enact.routing.attempt_role";
28
+ export declare const ENACT_ROUTING_ATTEMPT_COUNT: "enact.routing.attempt_count";
29
+ export declare const ENACT_ROUTING_FALLBACK_CHAIN_SOURCE: "enact.routing.fallback_chain_source";
30
+ export declare const ENACT_ROUTING_PROVIDERS_ATTEMPTED: "enact.routing.providers_attempted";
31
+ export declare const ENACT_ROUTING_AUTH_TYPES_ATTEMPTED: "enact.routing.auth_types_attempted";
32
+ export declare const ENACT_ROUTING_SKIPPED_ATTEMPTS: "enact.routing.skipped_attempts";
33
+ export declare const ENACT_SPECIFICITY_CONFIDENCE: "enact.specificity.confidence";
34
+ export declare const ENACT_SPECIFICITY_GATE_THRESHOLD: "enact.specificity.gate_threshold";
35
+ export declare const ENACT_SPECIFICITY_MATCH_SOURCE: "enact.specificity.match_source";
36
+ export declare const ENACT_SPECIFICITY_PENALTY_APPLIED: "enact.specificity.penalty_applied";
37
+ export declare const ENACT_SPECIFICITY_ROUTE_SOURCE: "enact.specificity.route_source";
38
+ export declare const ENACT_SPECIFICITY_FALLBACK_COUNT: "enact.specificity.fallback_count";
39
+ export declare const ENACT_TIER_SLOT: "enact.tier.slot";
40
+ export declare const ENACT_TIER_ROUTE_SOURCE: "enact.tier.route_source";
41
+ export declare const ENACT_TIER_FALLBACK_COUNT: "enact.tier.fallback_count";
42
+ export declare const ENACT_TIER_OVERRIDE_ACTIVE: "enact.tier.override_active";
43
+ export declare const ENACT_TIER_AUTO_ASSIGNED_MODEL: "enact.tier.auto_assigned_model";
44
+ export declare const ENACT_TIER_SLOTS_BACKFILLED: "enact.tier.slots_backfilled";
45
+ export declare const ENACT_TRANSPORT_ERROR_CATEGORY: "enact.transport_error_category";
46
+ export declare const ENACT_SSRF_REVALIDATED: "enact.ssrf_revalidated";
47
+ export declare const ENACT_SSRF_PASSED: "enact.ssrf_passed";
48
+ export declare const ENACT_WARMUP_OUTCOME: "enact.warmup.outcome";
49
+ export declare const ENACT_WARMUP_DURATION_MS: "enact.warmup.duration_ms";
50
+ export declare const ENACT_WARMUP_REASON: "enact.warmup.reason";
51
+ export declare const ENACT_DEBUG_CAPTURE_ID: "enact.debug_capture_id";
52
+ export declare const LLM_BODY_TRANSFORMATIONS: "llm.body.transformations";
53
+ export declare const LLM_SYSTEM_MESSAGE_MERGE_APPLIED: "llm.system_message_merge_applied";
54
+ export declare const LLM_CACHE_INJECTION_KIND: "llm.cache_injection.kind";
55
+ export declare const LLM_CACHE_INJECTION_BREAKPOINT_COUNT: "llm.cache_injection.breakpoint_count";
56
+ export declare const LLM_CODEX_RESPONSES_SHAPING_APPLIED: "llm.codex_responses_shaping_applied";
57
+ export declare const LLM_COPILOT_FORCE_STREAM_APPLIED: "llm.copilot_force_stream_applied";
58
+ export declare const LLM_ENDPOINT_KEY: "llm.endpoint_key";
59
+ export declare const LLM_ENDPOINT_FORMAT: "llm.endpoint_format";
60
+ export declare const LLM_ENDPOINT_BASE_URL_HOST: "llm.endpoint_base_url_host";
61
+ export declare const LLM_API_VERSION: "llm.api_version";
62
+ export declare const LLM_ENDPOINT_USED_CUSTOM: "llm.endpoint_used_custom";
63
+ export declare const LLM_ENDPOINT_USED_REGION_OVERRIDE: "llm.endpoint_used_region_override";
64
+ export declare const LLM_ENDPOINT_USED_SUBSCRIPTION: "llm.endpoint_used_subscription";
65
+ export declare const ENACT_ROUTING_API_VERSION_SOURCE: "enact.routing.api_version_source";
66
+ export declare const ENACT_CHANNEL: "enact.channel";
67
+ export declare const ENACT_DIRECTION: "enact.direction";
68
+ export declare const ENACT_HAND_NAME: "enact.hand_name";
69
+ export declare const ENACT_FINDINGS_COUNT: "enact.findings_count";
70
+ export declare const ENACT_DEPLOY_ID: "enact.deploy_id";
71
+ export declare const ENACT_COMMIT_SHA: "enact.commit_sha";
72
+ export declare const ENACT_REASON: "enact.reason";
73
+ export declare const ENACT_COST_USD: "enact.cost_usd";
74
+ export declare const ENACT_PATH: "enact.path";
75
+ export declare const ENACT_COMMAND_HASH: "enact.command_hash";
76
+ export declare const ENACT_TOKENS_BEFORE: "enact.tokens_before";
77
+ export declare const ENACT_TOKENS_AFTER: "enact.tokens_after";
78
+ export declare const ENACT_COMPRESSION_RATIO: "enact.compression_ratio";
79
+ export declare const ENACT_PATTERN_COUNT: "enact.pattern_count";
80
+ export declare const LLM_RESPONSE_TTFB_MS: "llm.response.ttfb_ms";
81
+ export declare const LLM_RESPONSE_REQUEST_ID: "llm.response.request_id";
82
+ export declare const LLM_RESPONSE_RATE_LIMIT_REMAINING_REQUESTS: "llm.response.rate_limit_remaining_requests";
83
+ export declare const LLM_RESPONSE_RATE_LIMIT_REMAINING_TOKENS: "llm.response.rate_limit_remaining_tokens";
84
+ export declare const LLM_RESPONSE_RATE_LIMIT_RESET: "llm.response.rate_limit_reset";
85
+ export declare const LLM_RESPONSE_RETRY_AFTER: "llm.response.retry_after";
86
+ export declare const LLM_RESPONSE_CONTENT_LENGTH: "llm.response.content_length";
87
+ export declare const LLM_RESPONSE_UPSTREAM_WAS_STREAMING: "llm.response.upstream_was_streaming";
88
+ export declare const ENACT_ACTOR: "enact.actor";
89
+ export declare const ENACT_HOOK_EVENT: "enact.hook_event";
90
+ export declare const ENACT_PRESET: "enact.preset";
91
+ export declare const ENACT_OUTCOME: "enact.outcome";
92
+ export declare const ENACT_VERDICT: "enact.verdict";
93
+ export declare const ENACT_BLOCKERS: "enact.blockers";
94
+ export declare const ENACT_ENTITY: "enact.entity";
95
+ export declare const ENACT_ENTITY_ID: "enact.entity_id";
96
+ export declare const ENACT_FROM_STATE: "enact.from_state";
97
+ export declare const ENACT_TO_STATE: "enact.to_state";
98
+ export declare const ENACT_TOOL: "enact.tool";
99
+ export declare const ENACT_MODE: "enact.mode";
100
+ export declare const ENACT_TOKENS_SAVED: "enact.tokens_saved";
101
+ export declare const ENACT_VAULT: "enact.vault";
102
+ export declare const ENACT_SEARCH_TYPE: "enact.search_type";
103
+ export declare const ENACT_ITEMS_PROCESSED: "enact.items_processed";
104
+ export declare const ENACT_QUERY_HASH: "enact.query_hash";
105
+ export declare const ENACT_RESULTS_COUNT: "enact.results_count";
106
+ export declare const ENACT_SLUG: "enact.slug";
107
+ export declare const ENACT_MEMORY_TYPE: "enact.memory_type";
108
+ export declare const ENACT_IMPORTANCE: "enact.importance";
109
+ export declare const ENACT_SOURCE: "enact.source";
110
+ export declare const ENACT_TOKENS_USED: "enact.tokens_used";
111
+ export declare const ENACT_COMPONENT: "enact.component";
112
+ export declare const ENACT_MESSAGE: "enact.message";
113
+ export declare const ENACT_PID: "enact.pid";
114
+ export declare const ENACT_COMMAND: "enact.command";
115
+ export declare const ENACT_EXIT_CODE: "enact.exit_code";
@@ -0,0 +1,135 @@
1
+ // enact.* extension attributes — gateway routing (existing)
2
+ export const ENACT_ROUTING_TIER = 'enact.routing_tier';
3
+ export const ENACT_ROUTING_REASON = 'enact.routing_reason';
4
+ export const ENACT_SPECIFICITY_CATEGORY = 'enact.specificity_category';
5
+ export const ENACT_FALLBACK_FROM_MODEL = 'enact.fallback_from_model';
6
+ export const ENACT_AUTH_TYPE = 'enact.auth_type';
7
+ export const ENACT_PROVIDER = 'enact.provider';
8
+ export const ENACT_DURATION_MS = 'enact.duration_ms';
9
+ export const ENACT_SUCCESS = 'enact.success';
10
+ // enact.routing.* — routing decision detail (new, from gap analysis)
11
+ export const ENACT_ROUTING_DECISION_PATH = 'enact.routing.decision_path';
12
+ export const ENACT_ROUTING_CONFIDENCE = 'enact.routing.confidence';
13
+ export const ENACT_ROUTING_SCORE = 'enact.routing.score';
14
+ export const ENACT_ROUTING_IS_SPECIFICITY = 'enact.routing.routing_is_specificity';
15
+ export const ENACT_ROUTING_PASSTHROUGH_MATCH_SOURCE = 'enact.routing.passthrough_match_source';
16
+ export const ENACT_ROUTING_HEARTBEAT_DETECTED = 'enact.routing.heartbeat_detected';
17
+ export const ENACT_ROUTING_SCORING_MESSAGES_DROPPED = 'enact.routing.scoring_messages_dropped';
18
+ export const ENACT_ROUTING_SCORING_MESSAGES_TRUNCATED = 'enact.routing.scoring_messages_truncated';
19
+ // enact.routing.* — route metadata
20
+ export const ENACT_ROUTING_PROVIDER_KEY_LABEL = 'enact.routing.provider_key_label';
21
+ export const ENACT_ROUTING_HEADER_TIER_ID = 'enact.routing.header_tier_id';
22
+ export const ENACT_ROUTING_HEADER_TIER_NAME = 'enact.routing.header_tier_name';
23
+ export const ENACT_ROUTING_HEADER_TIER_COLOR = 'enact.routing.header_tier_color';
24
+ export const ENACT_ROUTING_BILLING_TYPE = 'enact.routing.billing_type';
25
+ export const ENACT_ROUTING_PARAM_DEFAULTS_SOURCE = 'enact.routing.param_defaults_source';
26
+ export const ENACT_ROUTING_PARAM_DEFAULTS_DROPPED = 'enact.routing.param_defaults_dropped';
27
+ export const ENACT_ROUTING_API_MODE_INBOUND = 'enact.routing.api_mode_inbound';
28
+ export const ENACT_ROUTING_FORWARDED_API_PATH = 'enact.routing.forwarded_api_path';
29
+ // enact.routing.* — per-attempt detail
30
+ export const ENACT_ROUTING_ATTEMPT_INDEX = 'enact.routing.attempt_index';
31
+ export const ENACT_ROUTING_ATTEMPT_ROLE = 'enact.routing.attempt_role';
32
+ export const ENACT_ROUTING_ATTEMPT_COUNT = 'enact.routing.attempt_count';
33
+ export const ENACT_ROUTING_FALLBACK_CHAIN_SOURCE = 'enact.routing.fallback_chain_source';
34
+ export const ENACT_ROUTING_PROVIDERS_ATTEMPTED = 'enact.routing.providers_attempted';
35
+ export const ENACT_ROUTING_AUTH_TYPES_ATTEMPTED = 'enact.routing.auth_types_attempted';
36
+ export const ENACT_ROUTING_SKIPPED_ATTEMPTS = 'enact.routing.skipped_attempts';
37
+ // enact.specificity.* — specificity gate detail
38
+ export const ENACT_SPECIFICITY_CONFIDENCE = 'enact.specificity.confidence';
39
+ export const ENACT_SPECIFICITY_GATE_THRESHOLD = 'enact.specificity.gate_threshold';
40
+ export const ENACT_SPECIFICITY_MATCH_SOURCE = 'enact.specificity.match_source';
41
+ export const ENACT_SPECIFICITY_PENALTY_APPLIED = 'enact.specificity.penalty_applied';
42
+ export const ENACT_SPECIFICITY_ROUTE_SOURCE = 'enact.specificity.route_source';
43
+ export const ENACT_SPECIFICITY_FALLBACK_COUNT = 'enact.specificity.fallback_count';
44
+ // enact.tier.* — tier state
45
+ export const ENACT_TIER_SLOT = 'enact.tier.slot';
46
+ export const ENACT_TIER_ROUTE_SOURCE = 'enact.tier.route_source';
47
+ export const ENACT_TIER_FALLBACK_COUNT = 'enact.tier.fallback_count';
48
+ export const ENACT_TIER_OVERRIDE_ACTIVE = 'enact.tier.override_active';
49
+ export const ENACT_TIER_AUTO_ASSIGNED_MODEL = 'enact.tier.auto_assigned_model';
50
+ export const ENACT_TIER_SLOTS_BACKFILLED = 'enact.tier.slots_backfilled';
51
+ // enact.* — transport / SSRF / warmup
52
+ export const ENACT_TRANSPORT_ERROR_CATEGORY = 'enact.transport_error_category';
53
+ export const ENACT_SSRF_REVALIDATED = 'enact.ssrf_revalidated';
54
+ export const ENACT_SSRF_PASSED = 'enact.ssrf_passed';
55
+ export const ENACT_WARMUP_OUTCOME = 'enact.warmup.outcome';
56
+ export const ENACT_WARMUP_DURATION_MS = 'enact.warmup.duration_ms';
57
+ export const ENACT_WARMUP_REASON = 'enact.warmup.reason';
58
+ export const ENACT_DEBUG_CAPTURE_ID = 'enact.debug_capture_id';
59
+ // llm.* gateway extensions — body transformation (not in core OpenInference spec)
60
+ export const LLM_BODY_TRANSFORMATIONS = 'llm.body.transformations';
61
+ export const LLM_SYSTEM_MESSAGE_MERGE_APPLIED = 'llm.system_message_merge_applied';
62
+ export const LLM_CACHE_INJECTION_KIND = 'llm.cache_injection.kind';
63
+ export const LLM_CACHE_INJECTION_BREAKPOINT_COUNT = 'llm.cache_injection.breakpoint_count';
64
+ export const LLM_CODEX_RESPONSES_SHAPING_APPLIED = 'llm.codex_responses_shaping_applied';
65
+ export const LLM_COPILOT_FORCE_STREAM_APPLIED = 'llm.copilot_force_stream_applied';
66
+ // llm.* gateway extensions — endpoint resolution
67
+ export const LLM_ENDPOINT_KEY = 'llm.endpoint_key';
68
+ export const LLM_ENDPOINT_FORMAT = 'llm.endpoint_format';
69
+ export const LLM_ENDPOINT_BASE_URL_HOST = 'llm.endpoint_base_url_host';
70
+ export const LLM_API_VERSION = 'llm.api_version';
71
+ export const LLM_ENDPOINT_USED_CUSTOM = 'llm.endpoint_used_custom';
72
+ export const LLM_ENDPOINT_USED_REGION_OVERRIDE = 'llm.endpoint_used_region_override';
73
+ export const LLM_ENDPOINT_USED_SUBSCRIPTION = 'llm.endpoint_used_subscription';
74
+ export const ENACT_ROUTING_API_VERSION_SOURCE = 'enact.routing.api_version_source';
75
+ // enact.* extension attributes — agent channel messages
76
+ export const ENACT_CHANNEL = 'enact.channel';
77
+ export const ENACT_DIRECTION = 'enact.direction';
78
+ // enact.* extension attributes — hand runs
79
+ export const ENACT_HAND_NAME = 'enact.hand_name';
80
+ export const ENACT_FINDINGS_COUNT = 'enact.findings_count';
81
+ // enact.* extension attributes — deployments
82
+ export const ENACT_DEPLOY_ID = 'enact.deploy_id';
83
+ export const ENACT_COMMIT_SHA = 'enact.commit_sha';
84
+ export const ENACT_REASON = 'enact.reason';
85
+ // enact.* extension attributes — cost
86
+ export const ENACT_COST_USD = 'enact.cost_usd';
87
+ // enact.* extension attributes — context compression
88
+ export const ENACT_PATH = 'enact.path';
89
+ export const ENACT_COMMAND_HASH = 'enact.command_hash';
90
+ export const ENACT_TOKENS_BEFORE = 'enact.tokens_before';
91
+ export const ENACT_TOKENS_AFTER = 'enact.tokens_after';
92
+ export const ENACT_COMPRESSION_RATIO = 'enact.compression_ratio';
93
+ export const ENACT_PATTERN_COUNT = 'enact.pattern_count';
94
+ // llm.* gateway extensions — upstream response metadata
95
+ export const LLM_RESPONSE_TTFB_MS = 'llm.response.ttfb_ms';
96
+ export const LLM_RESPONSE_REQUEST_ID = 'llm.response.request_id';
97
+ export const LLM_RESPONSE_RATE_LIMIT_REMAINING_REQUESTS = 'llm.response.rate_limit_remaining_requests';
98
+ export const LLM_RESPONSE_RATE_LIMIT_REMAINING_TOKENS = 'llm.response.rate_limit_remaining_tokens';
99
+ export const LLM_RESPONSE_RATE_LIMIT_RESET = 'llm.response.rate_limit_reset';
100
+ export const LLM_RESPONSE_RETRY_AFTER = 'llm.response.retry_after';
101
+ export const LLM_RESPONSE_CONTENT_LENGTH = 'llm.response.content_length';
102
+ export const LLM_RESPONSE_UPSTREAM_WAS_STREAMING = 'llm.response.upstream_was_streaming';
103
+ // enact.* extension attributes — factory / hooks
104
+ export const ENACT_ACTOR = 'enact.actor';
105
+ export const ENACT_HOOK_EVENT = 'enact.hook_event';
106
+ export const ENACT_PRESET = 'enact.preset';
107
+ export const ENACT_OUTCOME = 'enact.outcome';
108
+ export const ENACT_VERDICT = 'enact.verdict';
109
+ export const ENACT_BLOCKERS = 'enact.blockers';
110
+ export const ENACT_ENTITY = 'enact.entity';
111
+ export const ENACT_ENTITY_ID = 'enact.entity_id';
112
+ export const ENACT_FROM_STATE = 'enact.from_state';
113
+ export const ENACT_TO_STATE = 'enact.to_state';
114
+ // enact.* extension attributes — context
115
+ export const ENACT_TOOL = 'enact.tool';
116
+ export const ENACT_MODE = 'enact.mode';
117
+ export const ENACT_TOKENS_SAVED = 'enact.tokens_saved';
118
+ // enact.* extension attributes — memory
119
+ export const ENACT_VAULT = 'enact.vault';
120
+ export const ENACT_SEARCH_TYPE = 'enact.search_type';
121
+ export const ENACT_ITEMS_PROCESSED = 'enact.items_processed';
122
+ export const ENACT_QUERY_HASH = 'enact.query_hash';
123
+ export const ENACT_RESULTS_COUNT = 'enact.results_count';
124
+ export const ENACT_SLUG = 'enact.slug';
125
+ export const ENACT_MEMORY_TYPE = 'enact.memory_type';
126
+ export const ENACT_IMPORTANCE = 'enact.importance';
127
+ // enact.* extension attributes — agent
128
+ export const ENACT_SOURCE = 'enact.source';
129
+ export const ENACT_TOKENS_USED = 'enact.tokens_used';
130
+ export const ENACT_COMPONENT = 'enact.component';
131
+ export const ENACT_MESSAGE = 'enact.message';
132
+ // enact.* extension attributes — proc-tap
133
+ export const ENACT_PID = 'enact.pid';
134
+ export const ENACT_COMMAND = 'enact.command';
135
+ export const ENACT_EXIT_CODE = 'enact.exit_code';
@@ -0,0 +1,2 @@
1
+ export * from './openinference.js';
2
+ export * from './enact-extensions.js';
@@ -0,0 +1,2 @@
1
+ export * from './openinference.js';
2
+ export * from './enact-extensions.js';
@@ -0,0 +1 @@
1
+ export { SemanticConventions, OpenInferenceSpanKind, MimeType, LLMSystem, LLMProvider, SemanticAttributePrefixes, LLMAttributePostfixes, LLM_MODEL_NAME, LLM_SYSTEM, LLM_PROVIDER, LLM_INPUT_MESSAGES, LLM_OUTPUT_MESSAGES, LLM_INVOCATION_PARAMETERS, LLM_TOKEN_COUNT_PROMPT, LLM_TOKEN_COUNT_COMPLETION, LLM_TOKEN_COUNT_TOTAL, LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_WRITE, LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_READ, LLM_TOKEN_COUNT_COMPLETION_DETAILS_REASONING, LLM_FINISH_REASON, LLM_TOOLS, LLM_PROMPTS, LLM_COST, LLM_COST_PROMPT, LLM_COST_COMPLETION, LLM_COST_TOTAL, INPUT_VALUE, INPUT_MIME_TYPE, OUTPUT_VALUE, OUTPUT_MIME_TYPE, MESSAGE_ROLE, MESSAGE_CONTENT, MESSAGE_CONTENTS, MESSAGE_NAME, MESSAGE_TOOL_CALLS, MESSAGE_TOOL_CALL_ID, TOOL_CALL_FUNCTION_NAME, TOOL_CALL_FUNCTION_ARGUMENTS_JSON, TOOL_CALL_ID, TOOL_NAME, TOOL_DESCRIPTION, TOOL_PARAMETERS, TOOL_JSON_SCHEMA, TOOL_ID, RETRIEVAL_DOCUMENTS, DOCUMENT_ID, DOCUMENT_CONTENT, DOCUMENT_SCORE, DOCUMENT_METADATA, EMBEDDING_EMBEDDINGS, EMBEDDING_TEXT, EMBEDDING_MODEL_NAME, EMBEDDING_VECTOR, SESSION_ID, USER_ID, METADATA, TAG_TAGS, PROMPT_TEMPLATE_VARIABLES, PROMPT_TEMPLATE_TEMPLATE, PROMPT_TEMPLATE_VERSION, AGENT_NAME, GRAPH_NODE_ID, GRAPH_NODE_NAME, GRAPH_NODE_PARENT_ID, } from '@arizeai/openinference-semantic-conventions';
@@ -0,0 +1,19 @@
1
+ export { SemanticConventions, OpenInferenceSpanKind, MimeType, LLMSystem, LLMProvider, SemanticAttributePrefixes, LLMAttributePostfixes,
2
+ // Individual attribute constants — llm.*
3
+ LLM_MODEL_NAME, LLM_SYSTEM, LLM_PROVIDER, LLM_INPUT_MESSAGES, LLM_OUTPUT_MESSAGES, LLM_INVOCATION_PARAMETERS, LLM_TOKEN_COUNT_PROMPT, LLM_TOKEN_COUNT_COMPLETION, LLM_TOKEN_COUNT_TOTAL, LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_WRITE, LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_READ, LLM_TOKEN_COUNT_COMPLETION_DETAILS_REASONING, LLM_FINISH_REASON, LLM_TOOLS, LLM_PROMPTS, LLM_COST, LLM_COST_PROMPT, LLM_COST_COMPLETION, LLM_COST_TOTAL,
4
+ // input / output
5
+ INPUT_VALUE, INPUT_MIME_TYPE, OUTPUT_VALUE, OUTPUT_MIME_TYPE,
6
+ // message attributes
7
+ MESSAGE_ROLE, MESSAGE_CONTENT, MESSAGE_CONTENTS, MESSAGE_NAME, MESSAGE_TOOL_CALLS, MESSAGE_TOOL_CALL_ID,
8
+ // tool call attributes
9
+ TOOL_CALL_FUNCTION_NAME, TOOL_CALL_FUNCTION_ARGUMENTS_JSON, TOOL_CALL_ID, TOOL_NAME, TOOL_DESCRIPTION, TOOL_PARAMETERS, TOOL_JSON_SCHEMA, TOOL_ID,
10
+ // document / retrieval
11
+ RETRIEVAL_DOCUMENTS, DOCUMENT_ID, DOCUMENT_CONTENT, DOCUMENT_SCORE, DOCUMENT_METADATA,
12
+ // embedding
13
+ EMBEDDING_EMBEDDINGS, EMBEDDING_TEXT, EMBEDDING_MODEL_NAME, EMBEDDING_VECTOR,
14
+ // session / user / metadata
15
+ SESSION_ID, USER_ID, METADATA, TAG_TAGS,
16
+ // prompt template
17
+ PROMPT_TEMPLATE_VARIABLES, PROMPT_TEMPLATE_TEMPLATE, PROMPT_TEMPLATE_VERSION,
18
+ // agent / graph
19
+ AGENT_NAME, GRAPH_NODE_ID, GRAPH_NODE_NAME, GRAPH_NODE_PARENT_ID, } from '@arizeai/openinference-semantic-conventions';
@@ -0,0 +1,11 @@
1
+ import type { EnactRawV1Event } from '../types/envelope.js';
2
+ export type { EnactRawV1Event };
3
+ export interface EmitOptions {
4
+ /** NDJSON filename within the watchdog dir, e.g. 'factory-events.ndjson' */
5
+ ndjsonFile: string;
6
+ /** Override ENACT_WATCHDOG_DIR env var */
7
+ watchdogDir?: string;
8
+ /** Override IGGY_HTTP_URL env var */
9
+ iggyUrl?: string;
10
+ }
11
+ export declare function emitEvent(event: EnactRawV1Event, opts: EmitOptions): Promise<void>;
@@ -0,0 +1,80 @@
1
+ import { appendFileSync, mkdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ const DEFAULT_IGGY_URL = 'http://127.0.0.1:43214';
4
+ export async function emitEvent(event, opts) {
5
+ const watchdogDir = opts.watchdogDir ?? process.env.ENACT_WATCHDOG_DIR ?? '.enact/watchdog';
6
+ mkdirSync(watchdogDir, { recursive: true });
7
+ const ndjsonPath = join(watchdogDir, opts.ndjsonFile);
8
+ const rawIggyUrl = opts.iggyUrl ?? process.env.IGGY_HTTP_URL;
9
+ const iggyUrl = !rawIggyUrl || rawIggyUrl === 'undefined' || rawIggyUrl === 'null'
10
+ ? DEFAULT_IGGY_URL
11
+ : rawIggyUrl;
12
+ const results = await Promise.allSettled([
13
+ Promise.resolve().then(() => {
14
+ appendFileSync(ndjsonPath, `${JSON.stringify(event)}\n`, 'utf8');
15
+ }),
16
+ publishToIggy(iggyUrl, event),
17
+ ]);
18
+ for (const result of results) {
19
+ if (result.status === 'rejected') {
20
+ if (process.env.ENACT_OBSERVABILITY_DEBUG) {
21
+ console.error(`[enact-traces] emit error: ${String(result.reason)}`);
22
+ }
23
+ }
24
+ }
25
+ }
26
+ async function publishToIggy(baseUrl, event) {
27
+ const authHeader = await resolveIggyAuthHeader(baseUrl);
28
+ const payload = {
29
+ partitioning: { kind: 'balanced', value: '' },
30
+ messages: [
31
+ {
32
+ id: 0,
33
+ payload: Buffer.from(JSON.stringify(event)).toString('base64'),
34
+ },
35
+ ],
36
+ };
37
+ try {
38
+ const response = await fetch(`${baseUrl}/streams/enact-telemetry/topics/worker_telemetry/messages`, {
39
+ method: 'POST',
40
+ headers: {
41
+ 'Content-Type': 'application/json',
42
+ Authorization: authHeader,
43
+ },
44
+ body: JSON.stringify(payload),
45
+ signal: AbortSignal.timeout(500),
46
+ });
47
+ if (!response.ok) {
48
+ throw new Error(`Iggy publish failed: ${response.status}`);
49
+ }
50
+ }
51
+ catch (error) {
52
+ const message = error instanceof Error ? error.message : String(error);
53
+ if (message.includes('ECONNREFUSED') || message.includes('fetch failed')) {
54
+ return;
55
+ }
56
+ throw error;
57
+ }
58
+ }
59
+ async function resolveIggyAuthHeader(baseUrl) {
60
+ const rawToken = process.env.IGGY_HTTP_ACCESS_TOKEN ?? process.env.IGGY_ACCESS_TOKEN;
61
+ if (rawToken?.trim()) {
62
+ return `Bearer ${rawToken.trim()}`;
63
+ }
64
+ const username = process.env.IGGY_HTTP_USERNAME ?? process.env.IGGY_ROOT_USERNAME ?? 'iggy';
65
+ const password = process.env.IGGY_HTTP_PASSWORD ?? process.env.IGGY_ROOT_PASSWORD ?? 'iggy';
66
+ const response = await fetch(`${baseUrl}/users/login`, {
67
+ method: 'POST',
68
+ headers: { 'Content-Type': 'application/json' },
69
+ body: JSON.stringify({ username, password }),
70
+ signal: AbortSignal.timeout(500),
71
+ });
72
+ if (!response.ok) {
73
+ throw new Error(`Iggy login failed: ${response.status}`);
74
+ }
75
+ const data = (await response.json());
76
+ const token = data.access_token?.token;
77
+ if (!token)
78
+ throw new Error('Iggy login response missing access token');
79
+ return `Bearer ${token}`;
80
+ }
@@ -0,0 +1,4 @@
1
+ export * from './conventions/index.js';
2
+ export * from './types/index.js';
3
+ export * from './payloads/index.js';
4
+ export * from './emit/emit.js';
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from './conventions/index.js';
2
+ export * from './types/index.js';
3
+ export * from './payloads/index.js';
4
+ export * from './emit/emit.js';
@@ -0,0 +1,27 @@
1
+ export interface AgentThreadStartedPayload {
2
+ 'openinference.span.kind': 'AGENT';
3
+ 'enact.source'?: string;
4
+ 'session.id'?: string;
5
+ [key: string]: unknown;
6
+ }
7
+ export interface AgentTurnPayload {
8
+ 'openinference.span.kind': 'AGENT';
9
+ 'enact.source'?: string;
10
+ turn_index?: number;
11
+ [key: string]: unknown;
12
+ }
13
+ export interface AgentTokenUsagePayload {
14
+ 'openinference.span.kind': 'CHAIN';
15
+ 'enact.source'?: string;
16
+ 'enact.tokens_used'?: number;
17
+ 'llm.token_count.prompt'?: number;
18
+ 'llm.token_count.completion'?: number;
19
+ 'llm.token_count.total'?: number;
20
+ }
21
+ export interface AgentErrorPayload {
22
+ 'openinference.span.kind': 'CHAIN';
23
+ 'enact.component'?: string;
24
+ 'enact.message'?: string;
25
+ error_type?: string;
26
+ }
27
+ export type AgentLifecyclePayload = AgentThreadStartedPayload | AgentTurnPayload | AgentTokenUsagePayload | AgentErrorPayload;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ export interface CacheHitPayload {
2
+ 'openinference.span.kind': 'CHAIN';
3
+ 'enact.tool'?: string;
4
+ 'enact.mode'?: string;
5
+ 'enact.tokens_saved'?: number;
6
+ }
7
+ export interface CacheMissPayload {
8
+ 'openinference.span.kind': 'CHAIN';
9
+ 'enact.tool'?: string;
10
+ 'enact.mode'?: string;
11
+ }
12
+ export interface ShellCompressedPayload {
13
+ 'openinference.span.kind': 'CHAIN';
14
+ 'enact.tool'?: string;
15
+ 'enact.tokens_saved'?: number;
16
+ command?: string;
17
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,8 @@
1
+ export interface HandPayload {
2
+ 'openinference.span.kind': 'CHAIN';
3
+ 'enact.hand_name': string;
4
+ 'enact.success': boolean;
5
+ 'enact.findings_count'?: number;
6
+ 'enact.duration_ms'?: number;
7
+ 'exception.message'?: string;
8
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,21 @@
1
+ export interface HookFiredPayload {
2
+ 'openinference.span.kind': 'CHAIN';
3
+ 'enact.hook_event': string;
4
+ 'enact.preset'?: string;
5
+ 'enact.outcome': string;
6
+ 'enact.duration_ms'?: number;
7
+ 'input.value'?: string;
8
+ 'output.value'?: string;
9
+ }
10
+ export interface StopVerdictPayload {
11
+ 'openinference.span.kind': 'CHAIN';
12
+ 'enact.verdict': string;
13
+ 'enact.blockers'?: string[];
14
+ }
15
+ export interface StateTransitionPayload {
16
+ 'openinference.span.kind': 'CHAIN';
17
+ 'enact.entity': string;
18
+ 'enact.entity_id'?: string;
19
+ 'enact.from_state': string;
20
+ 'enact.to_state': string;
21
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,9 @@
1
+ export * from './llm-call.js';
2
+ export * from './hook-fired.js';
3
+ export * from './tool-call.js';
4
+ export * from './memory-search.js';
5
+ export * from './memory-write.js';
6
+ export * from './cache-hit.js';
7
+ export * from './agent-lifecycle.js';
8
+ export * from './proc-tap.js';
9
+ export * from './hand.js';
@@ -0,0 +1,9 @@
1
+ export * from './llm-call.js';
2
+ export * from './hook-fired.js';
3
+ export * from './tool-call.js';
4
+ export * from './memory-search.js';
5
+ export * from './memory-write.js';
6
+ export * from './cache-hit.js';
7
+ export * from './agent-lifecycle.js';
8
+ export * from './proc-tap.js';
9
+ export * from './hand.js';
@@ -0,0 +1,135 @@
1
+ export declare const LLM_CALL_STAGES: readonly ["request.received", "request.normalized", "request.scored", "request.limit_blocked", "request.credentials_missing", "request.provider-bound", "request.warmup_failed", "routing.attempt.started", "routing.attempt.skipped", "routing.attempt.failed", "routing.attempt.succeeded", "routing.fallback.chain_resolved", "routing.fallback.exhausted", "provider.endpoint.resolved", "provider.body.transformed", "provider.model.normalized", "provider.fetch.completed", "provider.fetch.transport_failed", "response.headers", "response.body.observed", "response.streaming.partial", "response.transformed", "response.completed", "response.interrupted"];
2
+ export type LlmCallStage = (typeof LLM_CALL_STAGES)[number];
3
+ export interface LlmToolCallInMessage {
4
+ 'tool_call.id'?: string;
5
+ 'tool_call.function.name': string;
6
+ 'tool_call.function.arguments': string;
7
+ }
8
+ export interface LlmMessage {
9
+ 'message.role': 'system' | 'user' | 'assistant' | 'tool';
10
+ 'message.content'?: string | null;
11
+ /** For assistant messages that request tool calls */
12
+ 'message.tool_calls'?: LlmToolCallInMessage[];
13
+ /** For tool result messages (role=tool) */
14
+ 'message.tool_call_id'?: string;
15
+ /** For tool result messages — the function name that produced this result */
16
+ 'message.name'?: string;
17
+ }
18
+ export interface LlmToolDefinition {
19
+ 'tool.json_schema': string;
20
+ }
21
+ export interface LlmCallPayload {
22
+ stage: LlmCallStage;
23
+ 'llm.system'?: string;
24
+ 'llm.model_name'?: string;
25
+ 'llm.provider'?: string;
26
+ 'llm.invocation_parameters'?: string;
27
+ 'llm.finish_reason'?: string;
28
+ 'llm.token_count.prompt'?: number;
29
+ 'llm.token_count.completion'?: number;
30
+ 'llm.token_count.total'?: number;
31
+ 'llm.token_count.prompt_details.cache_write'?: number;
32
+ 'llm.token_count.prompt_details.cache_read'?: number;
33
+ 'llm.token_count.prompt_details.audio'?: number;
34
+ 'llm.token_count.completion_details.reasoning'?: number;
35
+ 'llm.token_count.completion_details.audio'?: number;
36
+ 'llm.cost.prompt'?: number;
37
+ 'llm.cost.completion'?: number;
38
+ 'llm.cost.total'?: number;
39
+ 'llm.cost.prompt_details.input'?: number;
40
+ 'llm.cost.prompt_details.cache_write'?: number;
41
+ 'llm.cost.prompt_details.cache_read'?: number;
42
+ 'llm.cost.prompt_details.cache_input'?: number;
43
+ 'llm.cost.prompt_details.audio'?: number;
44
+ 'llm.cost.completion_details.output'?: number;
45
+ 'llm.cost.completion_details.reasoning'?: number;
46
+ 'llm.cost.completion_details.audio'?: number;
47
+ 'openinference.span.kind'?: string;
48
+ 'input.value'?: string;
49
+ 'input.mime_type'?: string;
50
+ 'output.value'?: string;
51
+ 'output.mime_type'?: string;
52
+ 'enact.routing_tier'?: string;
53
+ 'enact.routing_reason'?: string;
54
+ 'enact.specificity_category'?: string | null;
55
+ 'enact.fallback_from_model'?: string | null;
56
+ 'enact.auth_type'?: string;
57
+ 'enact.provider'?: string;
58
+ 'enact.duration_ms'?: number;
59
+ 'enact.success'?: boolean;
60
+ 'enact.routing.decision_path'?: string;
61
+ 'enact.routing.confidence'?: number;
62
+ 'enact.routing.score'?: number;
63
+ 'enact.routing.routing_is_specificity'?: boolean;
64
+ 'enact.routing.passthrough_match_source'?: string;
65
+ 'enact.routing.heartbeat_detected'?: boolean;
66
+ 'enact.routing.scoring_messages_dropped'?: number;
67
+ 'enact.routing.scoring_messages_truncated'?: number;
68
+ 'enact.routing.provider_key_label'?: string;
69
+ 'enact.routing.header_tier_id'?: string;
70
+ 'enact.routing.header_tier_name'?: string;
71
+ 'enact.routing.header_tier_color'?: string;
72
+ 'enact.routing.billing_type'?: string;
73
+ 'enact.routing.param_defaults_source'?: string;
74
+ 'enact.routing.param_defaults_dropped'?: number;
75
+ 'enact.routing.api_mode_inbound'?: string;
76
+ 'enact.routing.forwarded_api_path'?: string;
77
+ 'enact.routing.attempt_index'?: number;
78
+ 'enact.routing.attempt_role'?: 'primary' | 'fallback';
79
+ 'enact.routing.attempt_count'?: number;
80
+ 'enact.routing.fallback_chain_source'?: string;
81
+ 'enact.routing.providers_attempted'?: string[];
82
+ 'enact.routing.auth_types_attempted'?: string[];
83
+ 'enact.routing.skipped_attempts'?: number;
84
+ 'enact.specificity.confidence'?: number;
85
+ 'enact.specificity.gate_threshold'?: number;
86
+ 'enact.specificity.match_source'?: string;
87
+ 'enact.specificity.penalty_applied'?: boolean;
88
+ 'enact.specificity.route_source'?: string;
89
+ 'enact.specificity.fallback_count'?: number;
90
+ 'enact.tier.slot'?: string;
91
+ 'enact.tier.route_source'?: string;
92
+ 'enact.tier.fallback_count'?: number;
93
+ 'enact.tier.override_active'?: boolean;
94
+ 'enact.tier.auto_assigned_model'?: string;
95
+ 'enact.tier.slots_backfilled'?: string[];
96
+ 'llm.body.transformations'?: string[];
97
+ 'llm.system_message_merge_applied'?: boolean;
98
+ 'llm.cache_injection.kind'?: string;
99
+ 'llm.cache_injection.breakpoint_count'?: number;
100
+ 'llm.codex_responses_shaping_applied'?: boolean;
101
+ 'llm.copilot_force_stream_applied'?: boolean;
102
+ 'llm.endpoint_key'?: string;
103
+ 'llm.endpoint_format'?: string;
104
+ 'llm.endpoint_base_url_host'?: string;
105
+ 'llm.api_version'?: string;
106
+ 'llm.endpoint_used_custom'?: boolean;
107
+ 'llm.endpoint_used_region_override'?: boolean;
108
+ 'llm.endpoint_used_subscription'?: boolean;
109
+ 'enact.routing.api_version_source'?: string;
110
+ 'llm.response.ttfb_ms'?: number;
111
+ 'llm.response.request_id'?: string;
112
+ 'llm.response.rate_limit_remaining_requests'?: number;
113
+ 'llm.response.rate_limit_remaining_tokens'?: number;
114
+ 'llm.response.rate_limit_reset'?: string;
115
+ 'llm.response.retry_after'?: number;
116
+ 'llm.response.content_length'?: number;
117
+ 'llm.response.upstream_was_streaming'?: boolean;
118
+ 'enact.transport_error_category'?: string;
119
+ 'enact.ssrf_revalidated'?: boolean;
120
+ 'enact.ssrf_passed'?: boolean;
121
+ 'enact.warmup.outcome'?: string;
122
+ 'enact.warmup.duration_ms'?: number;
123
+ 'enact.warmup.reason'?: string;
124
+ 'enact.debug_capture_id'?: string;
125
+ _input_messages?: LlmMessage[];
126
+ _output_messages?: LlmMessage[];
127
+ _tools?: LlmToolDefinition[];
128
+ request_message_count?: number;
129
+ stream?: boolean;
130
+ extras?: Record<string, unknown>;
131
+ [key: string]: unknown;
132
+ }
133
+ export declare function expandMessages(prefix: 'llm.input_messages' | 'llm.output_messages', messages: LlmMessage[]): Record<string, unknown>;
134
+ export declare function expandTools(tools: LlmToolDefinition[]): Record<string, unknown>;
135
+ export declare function flattenPayload(payload: LlmCallPayload): LlmCallPayload;
@@ -0,0 +1,84 @@
1
+ export const LLM_CALL_STAGES = [
2
+ // Request lifecycle
3
+ 'request.received',
4
+ 'request.normalized',
5
+ 'request.scored',
6
+ 'request.limit_blocked',
7
+ 'request.credentials_missing',
8
+ 'request.provider-bound',
9
+ 'request.warmup_failed',
10
+ // Routing attempt lifecycle (emitted once per upstream call)
11
+ 'routing.attempt.started',
12
+ 'routing.attempt.skipped',
13
+ 'routing.attempt.failed',
14
+ 'routing.attempt.succeeded',
15
+ 'routing.fallback.chain_resolved',
16
+ 'routing.fallback.exhausted',
17
+ // Provider-side events
18
+ 'provider.endpoint.resolved',
19
+ 'provider.body.transformed',
20
+ 'provider.model.normalized',
21
+ 'provider.fetch.completed',
22
+ 'provider.fetch.transport_failed',
23
+ // Response lifecycle
24
+ 'response.headers',
25
+ 'response.body.observed',
26
+ 'response.streaming.partial',
27
+ 'response.transformed',
28
+ 'response.completed',
29
+ 'response.interrupted',
30
+ ];
31
+ // ── Helpers: expand structured messages/tools into flat indexed OI attributes ──
32
+ export function expandMessages(prefix, messages) {
33
+ const attrs = {};
34
+ messages.forEach((msg, i) => {
35
+ const base = `${prefix}.${i}.message`;
36
+ attrs[`${base}.role`] = msg['message.role'];
37
+ if (msg['message.content'] !== undefined) {
38
+ attrs[`${base}.content`] = msg['message.content'];
39
+ }
40
+ if (msg['message.tool_call_id'] !== undefined) {
41
+ attrs[`${base}.tool_call_id`] = msg['message.tool_call_id'];
42
+ }
43
+ if (msg['message.name'] !== undefined) {
44
+ attrs[`${base}.name`] = msg['message.name'];
45
+ }
46
+ if (msg['message.tool_calls']) {
47
+ msg['message.tool_calls'].forEach((tc, j) => {
48
+ const tcBase = `${base}.tool_calls.${j}.tool_call`;
49
+ if (tc['tool_call.id'])
50
+ attrs[`${tcBase}.id`] = tc['tool_call.id'];
51
+ attrs[`${tcBase}.function.name`] = tc['tool_call.function.name'];
52
+ attrs[`${tcBase}.function.arguments`] = tc['tool_call.function.arguments'];
53
+ });
54
+ }
55
+ });
56
+ return attrs;
57
+ }
58
+ export function expandTools(tools) {
59
+ const attrs = {};
60
+ tools.forEach((t, i) => {
61
+ attrs[`llm.tools.${i}.tool.json_schema`] = t['tool.json_schema'];
62
+ });
63
+ return attrs;
64
+ }
65
+ export function flattenPayload(payload) {
66
+ const { _input_messages, _output_messages, _tools, ...rest } = payload;
67
+ const flat = { ...rest };
68
+ if (_input_messages?.length) {
69
+ Object.assign(flat, expandMessages('llm.input_messages', _input_messages));
70
+ const lastUser = [..._input_messages].reverse().find((m) => m['message.role'] === 'user');
71
+ if (lastUser?.['message.content'])
72
+ flat['input.value'] = lastUser['message.content'];
73
+ }
74
+ if (_output_messages?.length) {
75
+ Object.assign(flat, expandMessages('llm.output_messages', _output_messages));
76
+ const assistant = _output_messages.find((m) => m['message.role'] === 'assistant');
77
+ if (assistant?.['message.content'])
78
+ flat['output.value'] = assistant['message.content'];
79
+ }
80
+ if (_tools?.length) {
81
+ Object.assign(flat, expandTools(_tools));
82
+ }
83
+ return flat;
84
+ }
@@ -0,0 +1,21 @@
1
+ export interface MemorySearchPayload {
2
+ 'openinference.span.kind': 'RETRIEVER';
3
+ 'input.value'?: string;
4
+ 'retrieval.documents'?: unknown[];
5
+ 'enact.query_hash'?: string;
6
+ 'enact.results_count'?: number;
7
+ 'enact.duration_ms'?: number;
8
+ }
9
+ export interface MemoryWritePayload {
10
+ 'openinference.span.kind': 'CHAIN';
11
+ 'enact.slug'?: string;
12
+ 'enact.memory_type'?: string;
13
+ 'enact.importance'?: number;
14
+ 'input.value'?: string;
15
+ }
16
+ export interface MemoryLifecyclePayload {
17
+ 'openinference.span.kind': 'CHAIN';
18
+ lifecycle_event: string;
19
+ 'enact.memory_type'?: string;
20
+ [key: string]: unknown;
21
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export { MemoryWritePayload, MemoryLifecyclePayload } from './memory-search.js';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ export interface ProcessStartPayload {
2
+ 'openinference.span.kind': 'CHAIN';
3
+ 'enact.pid'?: number;
4
+ 'enact.command'?: string;
5
+ cwd?: string;
6
+ args?: string[];
7
+ }
8
+ export interface ProcessExitPayload {
9
+ 'openinference.span.kind': 'CHAIN';
10
+ 'enact.pid'?: number;
11
+ 'enact.exit_code'?: number;
12
+ 'enact.duration_ms'?: number;
13
+ }
14
+ export interface ProcessMetricsPayload {
15
+ 'openinference.span.kind': 'CHAIN';
16
+ metric_type: 'cpu' | 'memory' | 'idle';
17
+ 'enact.pid'?: number;
18
+ value?: number;
19
+ [key: string]: unknown;
20
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ export interface ToolCallPayload {
2
+ 'openinference.span.kind': 'TOOL';
3
+ 'tool.name': string;
4
+ 'tool.description'?: string;
5
+ 'tool.parameters'?: string;
6
+ 'input.value'?: string;
7
+ 'output.value'?: string;
8
+ 'enact.duration_ms'?: number;
9
+ 'enact.success'?: boolean;
10
+ caller?: string;
11
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ export interface LlmCallContext {
2
+ sessionId: string;
3
+ runId: string;
4
+ correlationId: string;
5
+ authType?: string;
6
+ agentId?: string;
7
+ startedAt: number;
8
+ _seq: {
9
+ value: number;
10
+ };
11
+ }
12
+ export interface EventContext {
13
+ sessionId: string;
14
+ runId: string;
15
+ source: string;
16
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,15 @@
1
+ import type { LlmCallPayload, HookFiredPayload, ToolCallPayload, MemorySearchPayload, MemoryWritePayload, CacheHitPayload, AgentLifecyclePayload } from '../payloads/index.js';
2
+ export type EventPayload = LlmCallPayload | HookFiredPayload | ToolCallPayload | MemorySearchPayload | MemoryWritePayload | CacheHitPayload | AgentLifecyclePayload | Record<string, unknown>;
3
+ export interface EnactRawV1Event {
4
+ schema_version: 'enact.raw.v1';
5
+ source: string;
6
+ event_type: string;
7
+ ts: string;
8
+ session_id: string;
9
+ run_id: string;
10
+ seq?: number;
11
+ pid?: number;
12
+ parent_pid?: number;
13
+ correlation_id?: string;
14
+ payload: EventPayload;
15
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export * from './envelope.js';
2
+ export * from './context.js';
3
+ export * from './span-kinds.js';
@@ -0,0 +1,3 @@
1
+ export * from './envelope.js';
2
+ export * from './context.js';
3
+ export * from './span-kinds.js';
@@ -0,0 +1,14 @@
1
+ export { OpenInferenceSpanKind } from '@arizeai/openinference-semantic-conventions';
2
+ export declare const OPENINFERENCE_SPAN_KIND: "openinference.span.kind";
3
+ export declare const SpanKindMap: {
4
+ readonly llmCall: "LLM";
5
+ readonly agent: "AGENT";
6
+ readonly tool: "TOOL";
7
+ readonly chain: "CHAIN";
8
+ readonly retriever: "RETRIEVER";
9
+ readonly reranker: "RERANKER";
10
+ readonly embedding: "EMBEDDING";
11
+ readonly guardrail: "GUARDRAIL";
12
+ readonly evaluator: "EVALUATOR";
13
+ readonly prompt: "PROMPT";
14
+ };
@@ -0,0 +1,14 @@
1
+ export { OpenInferenceSpanKind } from '@arizeai/openinference-semantic-conventions';
2
+ export const OPENINFERENCE_SPAN_KIND = 'openinference.span.kind';
3
+ export const SpanKindMap = {
4
+ llmCall: 'LLM',
5
+ agent: 'AGENT',
6
+ tool: 'TOOL',
7
+ chain: 'CHAIN',
8
+ retriever: 'RETRIEVER',
9
+ reranker: 'RERANKER',
10
+ embedding: 'EMBEDDING',
11
+ guardrail: 'GUARDRAIL',
12
+ evaluator: 'EVALUATOR',
13
+ prompt: 'PROMPT',
14
+ };
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@amsterdamdatalabs/traces",
3
+ "version": "0.1.0",
4
+ "description": "Shared OpenInference tracing types and emit for enact-os packages",
5
+ "license": "UNLICENSED",
6
+ "type": "module",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.js",
13
+ "default": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ },
16
+ "./conventions": {
17
+ "import": "./dist/conventions/index.js",
18
+ "types": "./dist/conventions/index.d.ts"
19
+ },
20
+ "./payloads": {
21
+ "import": "./dist/payloads/index.js",
22
+ "types": "./dist/payloads/index.d.ts"
23
+ },
24
+ "./emit": {
25
+ "import": "./dist/emit/emit.js",
26
+ "types": "./dist/emit/emit.d.ts"
27
+ }
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "README.md",
32
+ "CHANGELOG.md"
33
+ ],
34
+ "scripts": {
35
+ "build": "rm -rf dist && tsc",
36
+ "dev": "tsc --watch",
37
+ "lint": "oxlint src/"
38
+ },
39
+ "dependencies": {
40
+ "@arizeai/openinference-semantic-conventions": "^2.3.0"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "^25.9.0",
44
+ "oxlint": "^0.13.0",
45
+ "typescript": "^5.4.5"
46
+ }
47
+ }