Add Business Context
Business context attributes captured agent cost and usage to the customer, user, session, application, use case, request, region, or other reporting dimension that generated the activity.
Set context once around the relevant request, workflow, session, or job. Supported AI calls and metered operations created inside that boundary inherit the same values.
How context is inherited
Context flows inward from the block where it is set. Nested contexts merge with the outer context. If an inner context sets the same field or tag, the inner value takes precedence until that block ends.
Python and JavaScript / TypeScript use the same attribution model, but the trace representation differs slightly. withMvkContext() in TypeScript can create an mvk.context grouping span. Python mvk.context() applies the context without creating that additional grouping span.
Supported context fields
|
Field |
Use |
|---|---|
|
|
End user or internal actor |
|
|
Email address when permitted by the organization's data policy |
|
|
Conversation or workflow spanning multiple operations |
|
|
Customer or account receiving the work |
|
|
Application or product surface |
|
|
Business process being performed |
|
|
Application request correlation ID |
|
|
Runtime or business region |
|
|
Stable additional reporting dimensions |
Every field is optional. Configure only the fields required for reporting or allocation.
Add context in Python
import mvk_sdk as mvk
with mvk.context(
customer_id="acme",
user_id="user-123",
session_id="session-456",
use_case="customer_support",
tags={"channel": "web", "team": "support"},
):
run_agent()
Supported operations created inside the block inherit the context values.
Add context in JavaScript / TypeScript
import { withMvkContext } from '@mavvrikai/sdk';
await withMvkContext(
{
customerId: 'acme',
userId: 'user-123',
sessionId: 'session-456',
useCase: 'customer_support',
tags: { channel: 'web', team: 'support' },
},
async () => {
await runAgent();
},
);
Add context to a complete function
Use the decorator form when a function always belongs to the same business context.
Python
@mvk.context(
use_case="claims_adjudication",
tags={"line_of_business": "commercial"},
)
def adjudicate_claim(claim_ref):
return run_adjudication(claim_ref)
JavaScript / TypeScript
import { mvkContext } from '@mavvrikai/sdk';
class ClaimsService {
@mvkContext({
useCase: 'claims_adjudication',
tags: { line_of_business: 'commercial' },
})
async adjudicateClaim(claimRef: string) {
return runAdjudication(claimRef);
}
}
TypeScript decorator syntax requires decorator support in the application configuration. Use withMvkContext() when decorators are not enabled.
Example: SaaS support agent
@app.post("/chat")
async def chat(request: Request, message: str):
with mvk.context(
customer_id=request.headers["X-Customer-ID"],
user_id=request.headers["X-User-ID"],
session_id=request.headers["X-Session-ID"],
use_case="customer_support",
):
return run_support_agent(message)
This enables reporting by customer, support session, user, and use case.
Example: internal developer assistant
with mvk.context(
user_id="emp-4821",
user_email="developer@example.com",
use_case="developer_assistant",
tags={"team": "platform", "env": "production"},
):
answer = developer_agent.ask(question)
Use user_email only when the identity is appropriate for telemetry export and permitted by the organization's data policy.
Example: batch document processing
for document in batch:
with mvk.context(
customer_id=document.customer_id,
session_id=batch_id,
request_id=document.job_id,
use_case="document_processing",
):
process_document(document)
A batch can share one session_id while each document uses a separate request_id.
Use nested context
with mvk.context(
customer_id="acme",
session_id="session-456",
tags={"team": "support"},
):
classify_request()
with mvk.context(
use_case="refund_review",
tags={"workflow_stage": "refund"},
):
review_refund()
Nested contexts merge. An inner context overrides an outer value when both set the same field or tag.
Use context and signals for different purposes
-
Context identifies who or what the work belongs to.
-
Signal identifies a step that occurred in the workflow.
Do not create a custom signal only to repeat customer or session identity on an LLM call that Mavvrik already captures automatically.
with mvk.context(
customer_id="acme",
session_id="session-456",
):
with mvk.create_signal(
name="ocr-document",
step_type=MVKStepType.TOOL,
operation="ocr",
tool_name="textract",
):
text = run_ocr(file)
summary = client.chat.completions.create(...)
The OCR signal and automatically captured model call inherit the same customer and session context.
Configure tags
Use tags for stable categories that will be grouped across many executions.
team=support
channel=web
env=production
product=claims
line_of_business=commercial
Avoid high-cardinality tags such as request UUIDs, timestamps, raw user prompts, document IDs, or session IDs. Use first-class context fields for those identifiers where available.
Python tag rules include:
-
key: lowercase
[a-z0-9._-], maximum 64 characters; -
value: text, maximum 256 characters;
-
maximum 10 custom tags per span.
Python enforces these validation rules. JavaScript / TypeScript sends tags as configured, so use the same naming and cardinality discipline even where the SDK does not enforce the rule locally.
Do not use customer-defined tags beginning with mvk_, otel., or service. because they can collide with system attributes.
Configure global tags
mvk.instrument(
wrappers={"include": ["genai"]},
tags={"env": "production", "region": "us-east-1"},
)
Request-level tags apply only inside the context:
with mvk.context(tags={"team": "claims"}):
run_agent()
Use global tags for deployment-level attributes and request context for per-request identity.
Add context in web applications
Set context as early as possible in request handling.
@app.post("/claim")
async def claim(request: Request):
with mvk.context(
user_id=request.headers.get("X-User-ID"),
customer_id=request.headers.get("X-Customer-ID"),
session_id=request.headers.get("X-Session-ID"),
):
return adjudicate_claim()
If work moves to another thread, process, queue, or background job, set the required context again inside that execution boundary.
Propagate context across services
Supported web integrations can carry context between services. Context can also be extracted explicitly on the receiving service.
Python:
from mvk_sdk import extract_context_from_headers
ctx = extract_context_from_headers(request.headers)
JavaScript / TypeScript:
import { extractContextFromHeaders } from '@mavvrikai/sdk';
const ctx = extractContextFromHeaders(request.headers);
JavaScript / TypeScript can explicitly inject context into outbound headers:
import { injectContextIntoHeaders } from '@mavvrikai/sdk';
injectContextIntoHeaders(ctx, outgoingHeaders);
user_email is not propagated through Mavvrik context headers. Set it separately in each service that requires that identity.
For public traffic, strip or validate untrusted Mavvrik context headers at the gateway so external callers cannot control internal cost attribution.
Verify business context
-
Run one request using a known
session_id. -
Open Home → Agentic → Sessions.
-
Search for the test session.
-
Open a downstream AI or tool operation.
-
Confirm the expected customer, user, session, use-case fields, and tags are present.
If an operation appears without context, confirm that the operation executed inside the context boundary. For asynchronous or background work, set the context inside the worker that performs the operation.