Skip to content

feat(ocsf): emit AI Operation events from inference proxy (class_uid 7001) - #2664

Open
zanetworker wants to merge 2 commits into
NVIDIA:mainfrom
zanetworker:feat/ocsf-ai-operation
Open

feat(ocsf): emit AI Operation events from inference proxy (class_uid 7001)#2664
zanetworker wants to merge 2 commits into
NVIDIA:mainfrom
zanetworker:feat/ocsf-ai-operation

Conversation

@zanetworker

Copy link
Copy Markdown
Contributor

Summary

Add OCSF v1.8.0 ai_operation event support. When the inference proxy routes a model call through inference.local, emit an AI Operation event (class_uid 7001) capturing model identity, token consumption, and provider routing.

No agent sandbox in the market produces AI-specific OCSF events today.

Related Issue

Closes #2663

Changes

Commit 1: Event class (openshell-ocsf crate)

  • events/ai_operation.rsAIOperationEvent struct with model, provider, input_tokens, output_tokens, latency_ms, operation_type fields
  • builders/ai_operation.rsAIOperationBuilder with chainable setters
  • events/mod.rsAIOperation variant in OcsfEvent enum with Serialize/Deserialize/class_uid/base dispatch
  • format/shorthand.rsAI:INFERENCE [INFO] claude-opus-4 via anthropic (12000 in, 3200 out) 2400ms
  • lib.rs — re-export AIOperationBuilder

Commit 2: Proxy wiring (openshell-supervisor-network crate)

  • proxy.rsextract_model_from_request(), extract_usage_from_response(), emit_ai_operation() helpers
  • Buffered path: emit after format_http_response() with model + token counts from response
  • Streaming path: emit after chunked terminator with model + latency (token counts not available without accumulating SSE chunks)

Testing

  • cargo test -p openshell-ocsf — 138 passed, 0 failed (11 new tests)
  • cargo test -p openshell-supervisor-network — 1061 passed, 0 failed
  • cargo check -p openshell-sandbox -p openshell-server — full chain compiles
  • E2E on Kubernetes — not verified; test cluster uses combined topology with port-forwarded gateway, which creates in-memory sandboxes without K8s pods. The supervisor binary was cross-compiled and containerized but new sandboxes didn't create pods to test against. Requesting maintainers run mise run e2e to verify the emit path.

Edge cases tested:

  • No model in request body (falls back to route config model)
  • Empty model string (filtered, treated as None)
  • Zero tokens (serializes as 0, not omitted)
  • Missing/malformed usage in response (emits with None tokens)
  • Streaming responses (emits without token counts)
  • All-None round-trip preserves correctly
  • Shorthand format for all token combinations (both, input-only, neither)

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Unit tests added
  • E2E tests added (requesting maintainer verification)

Add OCSF v1.8.0 ai_operation event support for tracking AI model
inference calls proxied through inference.local. This is the event
struct, builder, serialization, shorthand formatter, and tests only.
Proxy wiring is a follow-up PR.

New files:
  events/ai_operation.rs    — AIOperationEvent struct
  builders/ai_operation.rs  — AIOperationBuilder with model/provider/
                              tokens/latency setters

Fields: model, provider, input_tokens, output_tokens, latency_ms,
operation_type. All optional except class_uid/class_name.

Shorthand format: AI:INFERENCE [INFO] claude-opus-4 via anthropic
(12000 in, 3200 out) 2400ms

Edge cases tested: no model (defaults to "unknown" in shorthand),
zero tokens (serializes as 0, not omitted), input-only tokens,
all-None round-trip, operation_type override.

Closes NVIDIA#2663 (event class portion; proxy wiring is separate)

Signed-off-by: Adel Zaalouk <azaalouk@redhat.com>
Wire AIOperationBuilder into the inference proxy's buffered and
streaming response paths. When inference.local proxies a model call:

- Extract model name from request body (fallback to route config)
- For buffered responses: extract token counts from response usage
- For streaming responses: emit with model/provider/latency only
  (token counts not available without accumulating all SSE chunks)
- Emit AI:INFERENCE OCSF event through the standard pipeline

Helper functions added:
  extract_model_from_request() — parses request JSON for model field
  extract_usage_from_response() — parses response JSON for usage
  emit_ai_operation() — builds and emits the AIOperationBuilder event

Edge cases handled:
  - Missing model in request body (falls back to route.model)
  - Empty model string (filtered out, treated as None)
  - Missing or malformed usage in response (emits with None tokens)
  - Streaming responses (emits without token counts)

Closes NVIDIA#2663

Signed-off-by: Adel Zaalouk <azaalouk@redhat.com>
@copy-pr-bot

copy-pr-bot Bot commented Aug 9, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@johntmyers

Copy link
Copy Markdown
Collaborator

We vendor in the 1.7 schema. If we are going to support 1.8 events we should update the schema too. Also, what is the plan when inference does not go through inference.local?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: Emit OCSF v1.8.0 ai_operation events from inference proxy

2 participants