autotel-genai 0.10.2 → 0.12.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 (34) hide show
  1. package/README.md +11 -0
  2. package/dist/agent/index.d.cts +3 -3
  3. package/dist/agent/index.d.ts +3 -3
  4. package/dist/{agent-security-BjM1QOTr.d.cts → agent-security-DBGQNboD.d.cts} +1 -1
  5. package/dist/{agent-security-D9NfzH7I.d.ts → agent-security-DK8_SNfi.d.ts} +1 -1
  6. package/dist/ai-sdk-bridge.d.cts +1 -1
  7. package/dist/ai-sdk-bridge.d.ts +1 -1
  8. package/dist/{cost-BcW9kEgp.d.cts → cost-Buyf5nLf.d.cts} +22 -4
  9. package/dist/{cost-BcW9kEgp.d.ts → cost-Buyf5nLf.d.ts} +22 -4
  10. package/dist/cost.cjs +100 -2
  11. package/dist/cost.d.cts +2 -2
  12. package/dist/cost.d.ts +2 -2
  13. package/dist/cost.js +100 -3
  14. package/dist/{events-B1Kqejbc.d.cts → events-BMnFqbM3.d.cts} +10 -2
  15. package/dist/{events-CdjXIatQ.d.ts → events-DvDscMOg.d.ts} +10 -2
  16. package/dist/events.d.cts +1 -1
  17. package/dist/events.d.ts +1 -1
  18. package/dist/{index-DTPyokIk.d.ts → index-BnTS0guB.d.ts} +1 -1
  19. package/dist/{index-D0AAZXlJ.d.cts → index-CX04R3xM.d.cts} +80 -7
  20. package/dist/{index-D-iENrm_.d.cts → index-DCfPFetp.d.cts} +1 -1
  21. package/dist/{index-DCpmeJbI.d.ts → index-DFECcQ-f.d.ts} +80 -7
  22. package/dist/index.cjs +2 -1
  23. package/dist/index.d.cts +6 -6
  24. package/dist/index.d.ts +6 -6
  25. package/dist/index.js +3 -3
  26. package/dist/observer/index.cjs +1 -1
  27. package/dist/observer/index.d.cts +1 -1
  28. package/dist/observer/index.d.ts +1 -1
  29. package/dist/observer/index.js +1 -1
  30. package/dist/{observer-BJVqXsky.js → observer-BI2bsY_A.js} +69 -15
  31. package/dist/{observer-CfzH7gQt.cjs → observer-BOssouJu.cjs} +69 -15
  32. package/dist/trace.d.cts +1 -1
  33. package/dist/trace.d.ts +1 -1
  34. package/package.json +4 -4
package/README.md CHANGED
@@ -86,8 +86,19 @@ recordLLMCost(ctx, 'claude-sonnet-4', {
86
86
  inputTokens: 4000,
87
87
  cacheReadInputTokens: 3500, // priced at the cached rate
88
88
  });
89
+
90
+ // Hosted ids price as the model they name
91
+ estimateLLMCost('eu.anthropic.claude-3-5-haiku-20241022-v1:0', usage);
92
+
93
+ // Your own rates, merged over the built-in table
94
+ estimateLLMCost('my-finetune', usage, {
95
+ pricing: { 'my-finetune': { inputPer1M: 0.5, outputPer1M: 1.5 } },
96
+ });
89
97
  ```
90
98
 
99
+ `createGenAiObserver({ pricing })` and `autotelTelemetry({ pricing })` take the
100
+ same map once, so every span an observer prices uses it.
101
+
91
102
  **Server-side tools are money too.** Web search, code interpreter and file
92
103
  search are billed per call, outside the token counts. An agent that searches on
93
104
  every step can spend more there than on tokens, and a cost built from tokens
@@ -1,4 +1,4 @@
1
- import { $ as withScopedTool, A as TOOL_CALL_ID_LABEL, B as HoneyTokenToolOptions, C as SEQUENCE_RULES, Ct as hashPayload, D as SequenceSecurityEvent, E as SequenceRule, F as spansToSequenceEvents, G as CrossAgentMonitor, H as EVAL_IDENTITY_ATTR, I as EvalIncidentQueryResult, J as CrossAgentEvent, K as CrossAgentMonitorOptions, L as querySpansForEvalIncident, M as detectSequences, N as emitSequenceDetections, O as SequenceSeverity, P as sequenceDetectionsToSecurityEvents, Q as detectCrossAgentPattern, R as spansToCrossAgentEvents, S as POLICY_DECISION_LABEL, St as canonicalizeForHash, T as SequenceEvent, U as RecordEvalRunIdentityInput, V as createHoneyTokenTool, W as recordEvalRunIdentity, X as DetectCrossAgentPatternOptions, Y as CrossAgentSecurityEvent, Z as crossAgentDetectionsToSecurityEvents, _ as sequenceRulesToSigma, _t as recordAgentHandoff, a as AgentPlanRiskVerdict, at as RotateAgentIdentityInput, b as DETECTION_EVENT, bt as createAgentAuditMetadata, c as recordPlanRiskAssessment, ct as defineAgentAction, d as DETECTION_DISPOSITION_EVENT, dt as recordPolicyDecision, et as CreateSignedEventEnvelopeOptions, f as DetectionDispositionStatus, ft as withAgentAction, g as sequenceRuleToSigma, gt as delegateToAgent, h as SigmaDocument, ht as RecordAgentHandoffMetadata, i as AgentPlanClassifierResult, it as RevokeAgentIdentityInput, j as TOOL_NAME_LABEL, k as SequenceSpanLike, l as runAgentPlanClassifier, lt as defineAgentToolCall, m as recordDetectionDisposition, mt as DelegateToAgentInput, n as AgentPlanClassifier, nt as verifyEventEnvelopeHash, o as RecordPlanRiskAssessmentOptions, ot as createAgentIdentityRegistry, p as RecordDetectionDispositionInput, pt as withAgentToolCall, q as CrossAgentDetection, r as AgentPlanClassifierInput, rt as ProvisionAgentIdentityInput, s as heuristicPlanRiskClassifier, st as withAgentSession, t as AGENT_PLAN_RISK_ATTR, tt as createSignedEventEnvelope, u as DETECTION_DISPOSITION_ATTR, ut as recordDecisionBasis, v as AGENT_OUTCOME_LABEL, vt as flattenAgentAttributes, w as SequenceDetection, wt as AGENT_AUDIT_SCHEMA_VERSION, x as EmitSequenceDetectionsOptions, xt as HashPayloadOptions, y as DETECTION_ATTR, yt as setAgentAttributes, z as HoneyTokenToolDefinition } from "../index-D-iENrm_.cjs";
2
- import { i as ModelPricing, o as TokenUsage } from "../cost-BcW9kEgp.cjs";
3
- import { $ as PrivacyProfileName, A as AgentAiMetadata, B as AgentOutcome, C as recordMemoryAccess, D as AgentActionFactory, E as tryRecordHumanApproval, F as AgentIdentity, G as AgentToolCallOptions, H as AgentSessionMetadata, I as AgentIdentityRecord, K as AiLifecycleStage, L as AgentIdentityRegistry, M as AgentDecisionMetadata, N as AgentEventKind, O as AgentActionMetadata, P as AgentHandler, Q as PrivacyProfile, R as AgentIdentityStatus, S as recordInputProvenance, T as recordRenderOutput, U as AgentSessionStatus, V as AgentSessionActionMetadata, W as AgentToolCallActionMetadata, X as PolicyDecision, Y as GovernanceMetadata, Z as PolicyMetadata, _ as deriveActionRiskClass, a as AgentConsentOutcome, at as resolvePrivacyProfile, b as recordControllerId, c as AgentOutputFormat, ct as AgentContext, d as RecordControllerInput, et as ScopedToolDefinition, f as RecordHumanApprovalInput, g as RecordRenderOutputInput, h as RecordPlanStepInput, i as AgentConsentEvidence, it as SanitizationEvidence, j as AgentAuditEventEnvelope, k as AgentActionOptions, l as AgentSecurityRecordOptions, lt as agentContextFromSpan, m as RecordMemoryAccessInput, n as ActionRiskHints, nt as ToolStatus, o as AgentInputProvenance, ot as sanitizeAuditPayload, p as RecordInputProvenanceInput, q as DelegationContext, r as AgentActionRiskClass, rt as PrivacyProfileInput, s as AgentMemoryOperation, st as sanitizeAuditPayloadWithEvidence, t as AGENT_SECURITY_ATTR, tt as ToolCallMetadata, u as RecordActiveScopesInput, v as recordActionRiskClass, w as recordPlanStep, x as recordHumanApproval, y as recordActiveScopes, z as AgentMetadataInput } from "../agent-security-BjM1QOTr.cjs";
1
+ import { $ as withScopedTool, A as TOOL_CALL_ID_LABEL, B as HoneyTokenToolOptions, C as SEQUENCE_RULES, Ct as hashPayload, D as SequenceSecurityEvent, E as SequenceRule, F as spansToSequenceEvents, G as CrossAgentMonitor, H as EVAL_IDENTITY_ATTR, I as EvalIncidentQueryResult, J as CrossAgentEvent, K as CrossAgentMonitorOptions, L as querySpansForEvalIncident, M as detectSequences, N as emitSequenceDetections, O as SequenceSeverity, P as sequenceDetectionsToSecurityEvents, Q as detectCrossAgentPattern, R as spansToCrossAgentEvents, S as POLICY_DECISION_LABEL, St as canonicalizeForHash, T as SequenceEvent, U as RecordEvalRunIdentityInput, V as createHoneyTokenTool, W as recordEvalRunIdentity, X as DetectCrossAgentPatternOptions, Y as CrossAgentSecurityEvent, Z as crossAgentDetectionsToSecurityEvents, _ as sequenceRulesToSigma, _t as recordAgentHandoff, a as AgentPlanRiskVerdict, at as RotateAgentIdentityInput, b as DETECTION_EVENT, bt as createAgentAuditMetadata, c as recordPlanRiskAssessment, ct as defineAgentAction, d as DETECTION_DISPOSITION_EVENT, dt as recordPolicyDecision, et as CreateSignedEventEnvelopeOptions, f as DetectionDispositionStatus, ft as withAgentAction, g as sequenceRuleToSigma, gt as delegateToAgent, h as SigmaDocument, ht as RecordAgentHandoffMetadata, i as AgentPlanClassifierResult, it as RevokeAgentIdentityInput, j as TOOL_NAME_LABEL, k as SequenceSpanLike, l as runAgentPlanClassifier, lt as defineAgentToolCall, m as recordDetectionDisposition, mt as DelegateToAgentInput, n as AgentPlanClassifier, nt as verifyEventEnvelopeHash, o as RecordPlanRiskAssessmentOptions, ot as createAgentIdentityRegistry, p as RecordDetectionDispositionInput, pt as withAgentToolCall, q as CrossAgentDetection, r as AgentPlanClassifierInput, rt as ProvisionAgentIdentityInput, s as heuristicPlanRiskClassifier, st as withAgentSession, t as AGENT_PLAN_RISK_ATTR, tt as createSignedEventEnvelope, u as DETECTION_DISPOSITION_ATTR, ut as recordDecisionBasis, v as AGENT_OUTCOME_LABEL, vt as flattenAgentAttributes, w as SequenceDetection, wt as AGENT_AUDIT_SCHEMA_VERSION, x as EmitSequenceDetectionsOptions, xt as HashPayloadOptions, y as DETECTION_ATTR, yt as setAgentAttributes, z as HoneyTokenToolDefinition } from "../index-DCfPFetp.cjs";
2
+ import { i as ModelPricing, s as TokenUsage } from "../cost-Buyf5nLf.cjs";
3
+ import { $ as PrivacyProfileName, A as AgentAiMetadata, B as AgentOutcome, C as recordMemoryAccess, D as AgentActionFactory, E as tryRecordHumanApproval, F as AgentIdentity, G as AgentToolCallOptions, H as AgentSessionMetadata, I as AgentIdentityRecord, K as AiLifecycleStage, L as AgentIdentityRegistry, M as AgentDecisionMetadata, N as AgentEventKind, O as AgentActionMetadata, P as AgentHandler, Q as PrivacyProfile, R as AgentIdentityStatus, S as recordInputProvenance, T as recordRenderOutput, U as AgentSessionStatus, V as AgentSessionActionMetadata, W as AgentToolCallActionMetadata, X as PolicyDecision, Y as GovernanceMetadata, Z as PolicyMetadata, _ as deriveActionRiskClass, a as AgentConsentOutcome, at as resolvePrivacyProfile, b as recordControllerId, c as AgentOutputFormat, ct as AgentContext, d as RecordControllerInput, et as ScopedToolDefinition, f as RecordHumanApprovalInput, g as RecordRenderOutputInput, h as RecordPlanStepInput, i as AgentConsentEvidence, it as SanitizationEvidence, j as AgentAuditEventEnvelope, k as AgentActionOptions, l as AgentSecurityRecordOptions, lt as agentContextFromSpan, m as RecordMemoryAccessInput, n as ActionRiskHints, nt as ToolStatus, o as AgentInputProvenance, ot as sanitizeAuditPayload, p as RecordInputProvenanceInput, q as DelegationContext, r as AgentActionRiskClass, rt as PrivacyProfileInput, s as AgentMemoryOperation, st as sanitizeAuditPayloadWithEvidence, t as AGENT_SECURITY_ATTR, tt as ToolCallMetadata, u as RecordActiveScopesInput, v as recordActionRiskClass, w as recordPlanStep, x as recordHumanApproval, y as recordActiveScopes, z as AgentMetadataInput } from "../agent-security-DBGQNboD.cjs";
4
4
  export { AGENT_AUDIT_SCHEMA_VERSION, AGENT_OUTCOME_LABEL, AGENT_PLAN_RISK_ATTR, AGENT_SECURITY_ATTR, type ActionRiskHints, type AgentActionFactory, type AgentActionMetadata, type AgentActionOptions, type AgentActionRiskClass, type AgentAiMetadata, type AgentAuditEventEnvelope, type AgentConsentEvidence, type AgentConsentOutcome, type AgentContext, type AgentDecisionMetadata, type AgentEventKind, type AgentHandler, type AgentIdentity, type AgentIdentityRecord, type AgentIdentityRegistry, type AgentIdentityStatus, type AgentInputProvenance, type AgentMemoryOperation, type AgentMetadataInput, type AgentOutcome, type AgentOutputFormat, type AgentPlanClassifier, type AgentPlanClassifierInput, type AgentPlanClassifierResult, type AgentPlanRiskVerdict, type AgentSecurityRecordOptions, type AgentSessionActionMetadata, type AgentSessionMetadata, type AgentSessionStatus, type AgentToolCallActionMetadata, type AgentToolCallOptions, type AiLifecycleStage, type CreateSignedEventEnvelopeOptions, type CrossAgentDetection, type CrossAgentEvent, CrossAgentMonitor, type CrossAgentMonitorOptions, type CrossAgentSecurityEvent, DETECTION_ATTR, DETECTION_DISPOSITION_ATTR, DETECTION_DISPOSITION_EVENT, DETECTION_EVENT, type DelegateToAgentInput, type DelegationContext, type DetectCrossAgentPatternOptions, type DetectionDispositionStatus, EVAL_IDENTITY_ATTR, type EmitSequenceDetectionsOptions, type EvalIncidentQueryResult, type GovernanceMetadata, type HashPayloadOptions, type HoneyTokenToolDefinition, type HoneyTokenToolOptions, type ModelPricing, POLICY_DECISION_LABEL, type PolicyDecision, type PolicyMetadata, type PrivacyProfile, type PrivacyProfileInput, type PrivacyProfileName, type ProvisionAgentIdentityInput, type RecordActiveScopesInput, type RecordAgentHandoffMetadata, type RecordControllerInput, type RecordDetectionDispositionInput, type RecordEvalRunIdentityInput, type RecordHumanApprovalInput, type RecordInputProvenanceInput, type RecordMemoryAccessInput, type RecordPlanRiskAssessmentOptions, type RecordPlanStepInput, type RecordRenderOutputInput, type RevokeAgentIdentityInput, type RotateAgentIdentityInput, SEQUENCE_RULES, type SanitizationEvidence, type ScopedToolDefinition, type SequenceDetection, type SequenceEvent, type SequenceRule, type SequenceSecurityEvent, type SequenceSeverity, type SequenceSpanLike, type SigmaDocument, TOOL_CALL_ID_LABEL, TOOL_NAME_LABEL, type TokenUsage, type ToolCallMetadata, type ToolStatus, agentContextFromSpan, canonicalizeForHash, createAgentAuditMetadata, createAgentIdentityRegistry, createHoneyTokenTool, createSignedEventEnvelope, crossAgentDetectionsToSecurityEvents, defineAgentAction, defineAgentToolCall, delegateToAgent, deriveActionRiskClass, detectCrossAgentPattern, detectSequences, emitSequenceDetections, flattenAgentAttributes, hashPayload, heuristicPlanRiskClassifier, querySpansForEvalIncident, recordActionRiskClass, recordActiveScopes, recordAgentHandoff, recordControllerId, recordDecisionBasis, recordDetectionDisposition, recordEvalRunIdentity, recordHumanApproval, recordInputProvenance, recordMemoryAccess, recordPlanRiskAssessment, recordPlanStep, recordPolicyDecision, recordRenderOutput, resolvePrivacyProfile, runAgentPlanClassifier, sanitizeAuditPayload, sanitizeAuditPayloadWithEvidence, sequenceDetectionsToSecurityEvents, sequenceRuleToSigma, sequenceRulesToSigma, setAgentAttributes, spansToCrossAgentEvents, spansToSequenceEvents, tryRecordHumanApproval, verifyEventEnvelopeHash, withAgentAction, withAgentSession, withAgentToolCall, withScopedTool };
@@ -1,4 +1,4 @@
1
- import { $ as withScopedTool, A as TOOL_CALL_ID_LABEL, B as HoneyTokenToolOptions, C as SEQUENCE_RULES, Ct as hashPayload, D as SequenceSecurityEvent, E as SequenceRule, F as spansToSequenceEvents, G as CrossAgentMonitor, H as EVAL_IDENTITY_ATTR, I as EvalIncidentQueryResult, J as CrossAgentEvent, K as CrossAgentMonitorOptions, L as querySpansForEvalIncident, M as detectSequences, N as emitSequenceDetections, O as SequenceSeverity, P as sequenceDetectionsToSecurityEvents, Q as detectCrossAgentPattern, R as spansToCrossAgentEvents, S as POLICY_DECISION_LABEL, St as canonicalizeForHash, T as SequenceEvent, U as RecordEvalRunIdentityInput, V as createHoneyTokenTool, W as recordEvalRunIdentity, X as DetectCrossAgentPatternOptions, Y as CrossAgentSecurityEvent, Z as crossAgentDetectionsToSecurityEvents, _ as sequenceRulesToSigma, _t as recordAgentHandoff, a as AgentPlanRiskVerdict, at as RotateAgentIdentityInput, b as DETECTION_EVENT, bt as createAgentAuditMetadata, c as recordPlanRiskAssessment, ct as defineAgentAction, d as DETECTION_DISPOSITION_EVENT, dt as recordPolicyDecision, et as CreateSignedEventEnvelopeOptions, f as DetectionDispositionStatus, ft as withAgentAction, g as sequenceRuleToSigma, gt as delegateToAgent, h as SigmaDocument, ht as RecordAgentHandoffMetadata, i as AgentPlanClassifierResult, it as RevokeAgentIdentityInput, j as TOOL_NAME_LABEL, k as SequenceSpanLike, l as runAgentPlanClassifier, lt as defineAgentToolCall, m as recordDetectionDisposition, mt as DelegateToAgentInput, n as AgentPlanClassifier, nt as verifyEventEnvelopeHash, o as RecordPlanRiskAssessmentOptions, ot as createAgentIdentityRegistry, p as RecordDetectionDispositionInput, pt as withAgentToolCall, q as CrossAgentDetection, r as AgentPlanClassifierInput, rt as ProvisionAgentIdentityInput, s as heuristicPlanRiskClassifier, st as withAgentSession, t as AGENT_PLAN_RISK_ATTR, tt as createSignedEventEnvelope, u as DETECTION_DISPOSITION_ATTR, ut as recordDecisionBasis, v as AGENT_OUTCOME_LABEL, vt as flattenAgentAttributes, w as SequenceDetection, wt as AGENT_AUDIT_SCHEMA_VERSION, x as EmitSequenceDetectionsOptions, xt as HashPayloadOptions, y as DETECTION_ATTR, yt as setAgentAttributes, z as HoneyTokenToolDefinition } from "../index-DTPyokIk.js";
2
- import { i as ModelPricing, o as TokenUsage } from "../cost-BcW9kEgp.js";
3
- import { $ as PrivacyProfileName, A as AgentAiMetadata, B as AgentOutcome, C as recordMemoryAccess, D as AgentActionFactory, E as tryRecordHumanApproval, F as AgentIdentity, G as AgentToolCallOptions, H as AgentSessionMetadata, I as AgentIdentityRecord, K as AiLifecycleStage, L as AgentIdentityRegistry, M as AgentDecisionMetadata, N as AgentEventKind, O as AgentActionMetadata, P as AgentHandler, Q as PrivacyProfile, R as AgentIdentityStatus, S as recordInputProvenance, T as recordRenderOutput, U as AgentSessionStatus, V as AgentSessionActionMetadata, W as AgentToolCallActionMetadata, X as PolicyDecision, Y as GovernanceMetadata, Z as PolicyMetadata, _ as deriveActionRiskClass, a as AgentConsentOutcome, at as resolvePrivacyProfile, b as recordControllerId, c as AgentOutputFormat, ct as AgentContext, d as RecordControllerInput, et as ScopedToolDefinition, f as RecordHumanApprovalInput, g as RecordRenderOutputInput, h as RecordPlanStepInput, i as AgentConsentEvidence, it as SanitizationEvidence, j as AgentAuditEventEnvelope, k as AgentActionOptions, l as AgentSecurityRecordOptions, lt as agentContextFromSpan, m as RecordMemoryAccessInput, n as ActionRiskHints, nt as ToolStatus, o as AgentInputProvenance, ot as sanitizeAuditPayload, p as RecordInputProvenanceInput, q as DelegationContext, r as AgentActionRiskClass, rt as PrivacyProfileInput, s as AgentMemoryOperation, st as sanitizeAuditPayloadWithEvidence, t as AGENT_SECURITY_ATTR, tt as ToolCallMetadata, u as RecordActiveScopesInput, v as recordActionRiskClass, w as recordPlanStep, x as recordHumanApproval, y as recordActiveScopes, z as AgentMetadataInput } from "../agent-security-D9NfzH7I.js";
1
+ import { $ as withScopedTool, A as TOOL_CALL_ID_LABEL, B as HoneyTokenToolOptions, C as SEQUENCE_RULES, Ct as hashPayload, D as SequenceSecurityEvent, E as SequenceRule, F as spansToSequenceEvents, G as CrossAgentMonitor, H as EVAL_IDENTITY_ATTR, I as EvalIncidentQueryResult, J as CrossAgentEvent, K as CrossAgentMonitorOptions, L as querySpansForEvalIncident, M as detectSequences, N as emitSequenceDetections, O as SequenceSeverity, P as sequenceDetectionsToSecurityEvents, Q as detectCrossAgentPattern, R as spansToCrossAgentEvents, S as POLICY_DECISION_LABEL, St as canonicalizeForHash, T as SequenceEvent, U as RecordEvalRunIdentityInput, V as createHoneyTokenTool, W as recordEvalRunIdentity, X as DetectCrossAgentPatternOptions, Y as CrossAgentSecurityEvent, Z as crossAgentDetectionsToSecurityEvents, _ as sequenceRulesToSigma, _t as recordAgentHandoff, a as AgentPlanRiskVerdict, at as RotateAgentIdentityInput, b as DETECTION_EVENT, bt as createAgentAuditMetadata, c as recordPlanRiskAssessment, ct as defineAgentAction, d as DETECTION_DISPOSITION_EVENT, dt as recordPolicyDecision, et as CreateSignedEventEnvelopeOptions, f as DetectionDispositionStatus, ft as withAgentAction, g as sequenceRuleToSigma, gt as delegateToAgent, h as SigmaDocument, ht as RecordAgentHandoffMetadata, i as AgentPlanClassifierResult, it as RevokeAgentIdentityInput, j as TOOL_NAME_LABEL, k as SequenceSpanLike, l as runAgentPlanClassifier, lt as defineAgentToolCall, m as recordDetectionDisposition, mt as DelegateToAgentInput, n as AgentPlanClassifier, nt as verifyEventEnvelopeHash, o as RecordPlanRiskAssessmentOptions, ot as createAgentIdentityRegistry, p as RecordDetectionDispositionInput, pt as withAgentToolCall, q as CrossAgentDetection, r as AgentPlanClassifierInput, rt as ProvisionAgentIdentityInput, s as heuristicPlanRiskClassifier, st as withAgentSession, t as AGENT_PLAN_RISK_ATTR, tt as createSignedEventEnvelope, u as DETECTION_DISPOSITION_ATTR, ut as recordDecisionBasis, v as AGENT_OUTCOME_LABEL, vt as flattenAgentAttributes, w as SequenceDetection, wt as AGENT_AUDIT_SCHEMA_VERSION, x as EmitSequenceDetectionsOptions, xt as HashPayloadOptions, y as DETECTION_ATTR, yt as setAgentAttributes, z as HoneyTokenToolDefinition } from "../index-BnTS0guB.js";
2
+ import { i as ModelPricing, s as TokenUsage } from "../cost-Buyf5nLf.js";
3
+ import { $ as PrivacyProfileName, A as AgentAiMetadata, B as AgentOutcome, C as recordMemoryAccess, D as AgentActionFactory, E as tryRecordHumanApproval, F as AgentIdentity, G as AgentToolCallOptions, H as AgentSessionMetadata, I as AgentIdentityRecord, K as AiLifecycleStage, L as AgentIdentityRegistry, M as AgentDecisionMetadata, N as AgentEventKind, O as AgentActionMetadata, P as AgentHandler, Q as PrivacyProfile, R as AgentIdentityStatus, S as recordInputProvenance, T as recordRenderOutput, U as AgentSessionStatus, V as AgentSessionActionMetadata, W as AgentToolCallActionMetadata, X as PolicyDecision, Y as GovernanceMetadata, Z as PolicyMetadata, _ as deriveActionRiskClass, a as AgentConsentOutcome, at as resolvePrivacyProfile, b as recordControllerId, c as AgentOutputFormat, ct as AgentContext, d as RecordControllerInput, et as ScopedToolDefinition, f as RecordHumanApprovalInput, g as RecordRenderOutputInput, h as RecordPlanStepInput, i as AgentConsentEvidence, it as SanitizationEvidence, j as AgentAuditEventEnvelope, k as AgentActionOptions, l as AgentSecurityRecordOptions, lt as agentContextFromSpan, m as RecordMemoryAccessInput, n as ActionRiskHints, nt as ToolStatus, o as AgentInputProvenance, ot as sanitizeAuditPayload, p as RecordInputProvenanceInput, q as DelegationContext, r as AgentActionRiskClass, rt as PrivacyProfileInput, s as AgentMemoryOperation, st as sanitizeAuditPayloadWithEvidence, t as AGENT_SECURITY_ATTR, tt as ToolCallMetadata, u as RecordActiveScopesInput, v as recordActionRiskClass, w as recordPlanStep, x as recordHumanApproval, y as recordActiveScopes, z as AgentMetadataInput } from "../agent-security-DK8_SNfi.js";
4
4
  export { AGENT_AUDIT_SCHEMA_VERSION, AGENT_OUTCOME_LABEL, AGENT_PLAN_RISK_ATTR, AGENT_SECURITY_ATTR, type ActionRiskHints, type AgentActionFactory, type AgentActionMetadata, type AgentActionOptions, type AgentActionRiskClass, type AgentAiMetadata, type AgentAuditEventEnvelope, type AgentConsentEvidence, type AgentConsentOutcome, type AgentContext, type AgentDecisionMetadata, type AgentEventKind, type AgentHandler, type AgentIdentity, type AgentIdentityRecord, type AgentIdentityRegistry, type AgentIdentityStatus, type AgentInputProvenance, type AgentMemoryOperation, type AgentMetadataInput, type AgentOutcome, type AgentOutputFormat, type AgentPlanClassifier, type AgentPlanClassifierInput, type AgentPlanClassifierResult, type AgentPlanRiskVerdict, type AgentSecurityRecordOptions, type AgentSessionActionMetadata, type AgentSessionMetadata, type AgentSessionStatus, type AgentToolCallActionMetadata, type AgentToolCallOptions, type AiLifecycleStage, type CreateSignedEventEnvelopeOptions, type CrossAgentDetection, type CrossAgentEvent, CrossAgentMonitor, type CrossAgentMonitorOptions, type CrossAgentSecurityEvent, DETECTION_ATTR, DETECTION_DISPOSITION_ATTR, DETECTION_DISPOSITION_EVENT, DETECTION_EVENT, type DelegateToAgentInput, type DelegationContext, type DetectCrossAgentPatternOptions, type DetectionDispositionStatus, EVAL_IDENTITY_ATTR, type EmitSequenceDetectionsOptions, type EvalIncidentQueryResult, type GovernanceMetadata, type HashPayloadOptions, type HoneyTokenToolDefinition, type HoneyTokenToolOptions, type ModelPricing, POLICY_DECISION_LABEL, type PolicyDecision, type PolicyMetadata, type PrivacyProfile, type PrivacyProfileInput, type PrivacyProfileName, type ProvisionAgentIdentityInput, type RecordActiveScopesInput, type RecordAgentHandoffMetadata, type RecordControllerInput, type RecordDetectionDispositionInput, type RecordEvalRunIdentityInput, type RecordHumanApprovalInput, type RecordInputProvenanceInput, type RecordMemoryAccessInput, type RecordPlanRiskAssessmentOptions, type RecordPlanStepInput, type RecordRenderOutputInput, type RevokeAgentIdentityInput, type RotateAgentIdentityInput, SEQUENCE_RULES, type SanitizationEvidence, type ScopedToolDefinition, type SequenceDetection, type SequenceEvent, type SequenceRule, type SequenceSecurityEvent, type SequenceSeverity, type SequenceSpanLike, type SigmaDocument, TOOL_CALL_ID_LABEL, TOOL_NAME_LABEL, type TokenUsage, type ToolCallMetadata, type ToolStatus, agentContextFromSpan, canonicalizeForHash, createAgentAuditMetadata, createAgentIdentityRegistry, createHoneyTokenTool, createSignedEventEnvelope, crossAgentDetectionsToSecurityEvents, defineAgentAction, defineAgentToolCall, delegateToAgent, deriveActionRiskClass, detectCrossAgentPattern, detectSequences, emitSequenceDetections, flattenAgentAttributes, hashPayload, heuristicPlanRiskClassifier, querySpansForEvalIncident, recordActionRiskClass, recordActiveScopes, recordAgentHandoff, recordControllerId, recordDecisionBasis, recordDetectionDisposition, recordEvalRunIdentity, recordHumanApproval, recordInputProvenance, recordMemoryAccess, recordPlanRiskAssessment, recordPlanStep, recordPolicyDecision, recordRenderOutput, resolvePrivacyProfile, runAgentPlanClassifier, sanitizeAuditPayload, sanitizeAuditPayloadWithEvidence, sequenceDetectionsToSecurityEvents, sequenceRuleToSigma, sequenceRulesToSigma, setAgentAttributes, spansToCrossAgentEvents, spansToSequenceEvents, tryRecordHumanApproval, verifyEventEnvelopeHash, withAgentAction, withAgentSession, withAgentToolCall, withScopedTool };
@@ -1,4 +1,4 @@
1
- import { i as ModelPricing, o as TokenUsage } from "./cost-BcW9kEgp.cjs";
1
+ import { i as ModelPricing, s as TokenUsage } from "./cost-Buyf5nLf.cjs";
2
2
  import { h as GenAiProviderName } from "./semconv-m_Y-ve_N.cjs";
3
3
  import { RequestLogger } from "autotel";
4
4
  import { OnMissingContext } from "autotel-audit";
@@ -1,4 +1,4 @@
1
- import { i as ModelPricing, o as TokenUsage } from "./cost-BcW9kEgp.js";
1
+ import { i as ModelPricing, s as TokenUsage } from "./cost-Buyf5nLf.js";
2
2
  import { h as GenAiProviderName } from "./semconv-m_Y-ve_N.js";
3
3
  import { RequestLogger } from "autotel";
4
4
  import { OnMissingContext } from "autotel-audit";
@@ -1,4 +1,4 @@
1
- import { o as TokenUsage, t as EstimateCostOptions } from "./cost-BcW9kEgp.cjs";
1
+ import { s as TokenUsage, t as EstimateCostOptions } from "./cost-Buyf5nLf.cjs";
2
2
  import { h as GenAiProviderName } from "./semconv-m_Y-ve_N.cjs";
3
3
  import { n as GenAiAttributeMap } from "./attributes-B8K6NxiM.cjs";
4
4
  import { TraceContext } from "autotel";
@@ -1,4 +1,4 @@
1
- import { o as TokenUsage, t as EstimateCostOptions } from "./cost-BcW9kEgp.js";
1
+ import { s as TokenUsage, t as EstimateCostOptions } from "./cost-Buyf5nLf.js";
2
2
  import { h as GenAiProviderName } from "./semconv-m_Y-ve_N.js";
3
3
  import { n as GenAiAttributeMap } from "./attributes-BNl903D-.js";
4
4
  import { Attributes } from "@opentelemetry/api";
@@ -90,18 +90,36 @@ interface TokenUsage {
90
90
  */
91
91
  tokenSource?: 'observed' | 'estimated';
92
92
  }
93
+ /**
94
+ * Model id → price, keyed the way {@link MODEL_PRICING} is: exact match first,
95
+ * then longest matching prefix after any vendor namespace is stripped.
96
+ *
97
+ * Key by **family**, not by deployed id. One `claude-3-5-haiku` entry covers
98
+ * `anthropic.claude-3-5-haiku-20241022-v1:0`, the `eu.`/`us.` inference
99
+ * profiles, the Vertex `publishers/...` path, and every later date-version.
100
+ */
101
+ type ModelPricingTable = Record<string, ModelPricing>;
93
102
  interface EstimateCostOptions {
94
- /** Override or extend {@link MODEL_PRICING}. Keys are matched first. */
95
- pricing?: Record<string, ModelPricing>;
103
+ /**
104
+ * Prices for this call only, merged over {@link MODEL_PRICING} — an entry
105
+ * here both fills in a model the table lacks and overrides one it has.
106
+ *
107
+ * For prices that apply to the whole process, prefer
108
+ * {@link registerModelPricing} so every entry point sees them without an
109
+ * option threaded through each call.
110
+ */
111
+ pricing?: ModelPricingTable;
96
112
  }
97
113
  /**
98
114
  * Approximate public list prices (USD per 1M tokens) at the time of writing.
99
115
  * Prices change; treat these as convenience defaults, not a billing source of
100
- * truth. Override per call via `options.pricing` or mutate this table at init.
116
+ * truth. Add your own with {@link registerModelPricing}, or per call via
117
+ * `options.pricing`.
101
118
  * Matching is exact first, then by longest key prefix, so versioned model ids
102
119
  * (`claude-sonnet-4-6-20251101`) resolve to a base entry (`claude-sonnet-4-6`).
103
120
  */
104
121
  declare const MODEL_PRICING: Record<string, ModelPricing>;
122
+ declare function registerModelPricing(pricing: ModelPricingTable): () => void;
105
123
  /**
106
124
  * Server-side tools in `usage` that no price table covers, so their charge is
107
125
  * absent from {@link estimateLLMCost}'s figure. Empty when everything priced —
@@ -129,4 +147,4 @@ declare function estimateLLMCost(model: string, usage: TokenUsage, options?: Est
129
147
  */
130
148
  declare function recordLLMCost(ctx: Pick<TraceContext, 'setAttribute'>, model: string, usage: TokenUsage, options?: EstimateCostOptions): number | undefined;
131
149
  //#endregion
132
- export { SERVER_TOOL_PRICING_PER_1K as a, recordLLMCost as c, ModelPricing as i, unpricedServerTools as l, GEN_AI_COST_ATTRIBUTE as n, TokenUsage as o, MODEL_PRICING as r, estimateLLMCost as s, EstimateCostOptions as t };
150
+ export { ModelPricingTable as a, estimateLLMCost as c, unpricedServerTools as d, ModelPricing as i, recordLLMCost as l, GEN_AI_COST_ATTRIBUTE as n, SERVER_TOOL_PRICING_PER_1K as o, MODEL_PRICING as r, TokenUsage as s, EstimateCostOptions as t, registerModelPricing as u };
@@ -90,18 +90,36 @@ interface TokenUsage {
90
90
  */
91
91
  tokenSource?: 'observed' | 'estimated';
92
92
  }
93
+ /**
94
+ * Model id → price, keyed the way {@link MODEL_PRICING} is: exact match first,
95
+ * then longest matching prefix after any vendor namespace is stripped.
96
+ *
97
+ * Key by **family**, not by deployed id. One `claude-3-5-haiku` entry covers
98
+ * `anthropic.claude-3-5-haiku-20241022-v1:0`, the `eu.`/`us.` inference
99
+ * profiles, the Vertex `publishers/...` path, and every later date-version.
100
+ */
101
+ type ModelPricingTable = Record<string, ModelPricing>;
93
102
  interface EstimateCostOptions {
94
- /** Override or extend {@link MODEL_PRICING}. Keys are matched first. */
95
- pricing?: Record<string, ModelPricing>;
103
+ /**
104
+ * Prices for this call only, merged over {@link MODEL_PRICING} — an entry
105
+ * here both fills in a model the table lacks and overrides one it has.
106
+ *
107
+ * For prices that apply to the whole process, prefer
108
+ * {@link registerModelPricing} so every entry point sees them without an
109
+ * option threaded through each call.
110
+ */
111
+ pricing?: ModelPricingTable;
96
112
  }
97
113
  /**
98
114
  * Approximate public list prices (USD per 1M tokens) at the time of writing.
99
115
  * Prices change; treat these as convenience defaults, not a billing source of
100
- * truth. Override per call via `options.pricing` or mutate this table at init.
116
+ * truth. Add your own with {@link registerModelPricing}, or per call via
117
+ * `options.pricing`.
101
118
  * Matching is exact first, then by longest key prefix, so versioned model ids
102
119
  * (`claude-sonnet-4-6-20251101`) resolve to a base entry (`claude-sonnet-4-6`).
103
120
  */
104
121
  declare const MODEL_PRICING: Record<string, ModelPricing>;
122
+ declare function registerModelPricing(pricing: ModelPricingTable): () => void;
105
123
  /**
106
124
  * Server-side tools in `usage` that no price table covers, so their charge is
107
125
  * absent from {@link estimateLLMCost}'s figure. Empty when everything priced —
@@ -129,4 +147,4 @@ declare function estimateLLMCost(model: string, usage: TokenUsage, options?: Est
129
147
  */
130
148
  declare function recordLLMCost(ctx: Pick<TraceContext, 'setAttribute'>, model: string, usage: TokenUsage, options?: EstimateCostOptions): number | undefined;
131
149
  //#endregion
132
- export { SERVER_TOOL_PRICING_PER_1K as a, recordLLMCost as c, ModelPricing as i, unpricedServerTools as l, GEN_AI_COST_ATTRIBUTE as n, TokenUsage as o, MODEL_PRICING as r, estimateLLMCost as s, EstimateCostOptions as t };
150
+ export { ModelPricingTable as a, estimateLLMCost as c, unpricedServerTools as d, ModelPricing as i, recordLLMCost as l, GEN_AI_COST_ATTRIBUTE as n, SERVER_TOOL_PRICING_PER_1K as o, MODEL_PRICING as r, TokenUsage as s, EstimateCostOptions as t, registerModelPricing as u };
package/dist/cost.cjs CHANGED
@@ -30,7 +30,8 @@ const SERVER_TOOL_PRICING_PER_1K = {
30
30
  /**
31
31
  * Approximate public list prices (USD per 1M tokens) at the time of writing.
32
32
  * Prices change; treat these as convenience defaults, not a billing source of
33
- * truth. Override per call via `options.pricing` or mutate this table at init.
33
+ * truth. Add your own with {@link registerModelPricing}, or per call via
34
+ * `options.pricing`.
34
35
  * Matching is exact first, then by longest key prefix, so versioned model ids
35
36
  * (`claude-sonnet-4-6-20251101`) resolve to a base entry (`claude-sonnet-4-6`).
36
37
  */
@@ -110,7 +111,30 @@ const MODEL_PRICING = {
110
111
  outputPer1M: .4
111
112
  }
112
113
  };
113
- function resolvePricing(table, model) {
114
+ /**
115
+ * Strip one leading vendor segment from a hosted model id, or return
116
+ * `undefined` when there is nothing left to strip.
117
+ *
118
+ * Bedrock, Vertex and the cross-region inference profiles all namespace the
119
+ * model rather than rename it: `anthropic.claude-3-5-haiku-20241022-v1:0`,
120
+ * `eu.anthropic.claude-...`, `publishers/anthropic/models/claude-...`. The
121
+ * price table is keyed on the model itself, so the prefix has to come off
122
+ * before a lookup can hit.
123
+ *
124
+ * A segment containing a digit is left alone. Model families carry their
125
+ * version in the name — `gpt-4.1-mini`, `gemini-1.5-pro`, `claude-3-opus` —
126
+ * and stripping `gpt-4` off `gpt-4.1-mini` would turn a real key into `1-mini`.
127
+ */
128
+ function stripVendorPrefix(model) {
129
+ const slash = model.lastIndexOf("/");
130
+ if (slash !== -1) return model.slice(slash + 1);
131
+ const dot = model.indexOf(".");
132
+ if (dot === -1) return undefined;
133
+ const head = model.slice(0, dot);
134
+ if (head.length === 0 || /\d/.test(head)) return undefined;
135
+ return model.slice(dot + 1);
136
+ }
137
+ function matchPricing(table, model) {
114
138
  const exact = table[model];
115
139
  if (exact) return exact;
116
140
  let best;
@@ -123,6 +147,79 @@ function resolvePricing(table, model) {
123
147
  }
124
148
  return best;
125
149
  }
150
+ /**
151
+ * Add prices to {@link MODEL_PRICING} for the whole process, so every cost
152
+ * site sees them — {@link estimateLLMCost}, {@link recordLLMCost},
153
+ * `recordGenAiUsage`, `autotelTelemetry()`, and the agent runtime — with no
154
+ * option threaded through each call.
155
+ *
156
+ * This is the one to reach for with more than a couple of models: prices are a
157
+ * property of the deployment, not of the call. Later registrations win, so a
158
+ * base table can be layered over.
159
+ *
160
+ * Returns a function that restores the previous prices — useful in tests, and
161
+ * the reason to prefer this over mutating {@link MODEL_PRICING} directly.
162
+ *
163
+ * @example
164
+ * ```ts
165
+ * import { registerModelPricing } from 'autotel-genai/cost';
166
+ *
167
+ * // Once at startup. Key by family, not by deployed model id.
168
+ * registerModelPricing({
169
+ * 'glm-4.7-flash': { inputPer1M: 0.6, outputPer1M: 2.2 },
170
+ * 'acme-ft-7b': { inputPer1M: 0.1, outputPer1M: 0.1 },
171
+ * });
172
+ * ```
173
+ */
174
+ /**
175
+ * Registrations in the order they were made, so a model's price is whatever the
176
+ * last live layer says and restoring one never disturbs another. Without the
177
+ * stack, tearing a base table down while a per-tenant override is still live
178
+ * would leave the override's price behind, or the base's - depending only on
179
+ * the order the restores happened to run in.
180
+ */
181
+ const pricingLayers = [];
182
+ /** Each model's price before any layer touched it. */
183
+ const unlayeredPricing = new Map();
184
+ function applyPricingLayers(models) {
185
+ for (const model of models) {
186
+ let price;
187
+ for (const layer of pricingLayers) {
188
+ if (layer.live && layer.table[model]) price = layer.table[model];
189
+ }
190
+ price ??= unlayeredPricing.get(model);
191
+ if (price === undefined) delete MODEL_PRICING[model];
192
+ else MODEL_PRICING[model] = price;
193
+ }
194
+ }
195
+ function registerModelPricing(pricing) {
196
+ const models = Object.keys(pricing);
197
+ for (const model of models) {
198
+ if (!unlayeredPricing.has(model)) {
199
+ unlayeredPricing.set(model, MODEL_PRICING[model]);
200
+ }
201
+ }
202
+ const layer = {
203
+ table: pricing,
204
+ live: true
205
+ };
206
+ pricingLayers.push(layer);
207
+ applyPricingLayers(models);
208
+ return () => {
209
+ if (!layer.live) return;
210
+ layer.live = false;
211
+ applyPricingLayers(models);
212
+ };
213
+ }
214
+ function resolvePricing(table, model) {
215
+ let candidate = model;
216
+ while (candidate !== undefined) {
217
+ const price = matchPricing(table, candidate);
218
+ if (price) return price;
219
+ candidate = stripVendorPrefix(candidate);
220
+ }
221
+ return undefined;
222
+ }
126
223
  /** The table this model's tool prices resolve through, model entry first. */
127
224
  function serverToolRate(price, tool) {
128
225
  return price.serverToolPer1K?.[tool] ?? SERVER_TOOL_PRICING_PER_1K[tool];
@@ -208,4 +305,5 @@ exports.MODEL_PRICING = MODEL_PRICING;
208
305
  exports.SERVER_TOOL_PRICING_PER_1K = SERVER_TOOL_PRICING_PER_1K;
209
306
  exports.estimateLLMCost = estimateLLMCost;
210
307
  exports.recordLLMCost = recordLLMCost;
308
+ exports.registerModelPricing = registerModelPricing;
211
309
  exports.unpricedServerTools = unpricedServerTools;
package/dist/cost.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as SERVER_TOOL_PRICING_PER_1K, c as recordLLMCost, i as ModelPricing, l as unpricedServerTools, n as GEN_AI_COST_ATTRIBUTE, o as TokenUsage, r as MODEL_PRICING, s as estimateLLMCost, t as EstimateCostOptions } from "./cost-BcW9kEgp.cjs";
2
- export { EstimateCostOptions, GEN_AI_COST_ATTRIBUTE, MODEL_PRICING, ModelPricing, SERVER_TOOL_PRICING_PER_1K, TokenUsage, estimateLLMCost, recordLLMCost, unpricedServerTools };
1
+ import { a as ModelPricingTable, c as estimateLLMCost, d as unpricedServerTools, i as ModelPricing, l as recordLLMCost, n as GEN_AI_COST_ATTRIBUTE, o as SERVER_TOOL_PRICING_PER_1K, r as MODEL_PRICING, s as TokenUsage, t as EstimateCostOptions, u as registerModelPricing } from "./cost-Buyf5nLf.cjs";
2
+ export { EstimateCostOptions, GEN_AI_COST_ATTRIBUTE, MODEL_PRICING, ModelPricing, ModelPricingTable, SERVER_TOOL_PRICING_PER_1K, TokenUsage, estimateLLMCost, recordLLMCost, registerModelPricing, unpricedServerTools };
package/dist/cost.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as SERVER_TOOL_PRICING_PER_1K, c as recordLLMCost, i as ModelPricing, l as unpricedServerTools, n as GEN_AI_COST_ATTRIBUTE, o as TokenUsage, r as MODEL_PRICING, s as estimateLLMCost, t as EstimateCostOptions } from "./cost-BcW9kEgp.js";
2
- export { EstimateCostOptions, GEN_AI_COST_ATTRIBUTE, MODEL_PRICING, ModelPricing, SERVER_TOOL_PRICING_PER_1K, TokenUsage, estimateLLMCost, recordLLMCost, unpricedServerTools };
1
+ import { a as ModelPricingTable, c as estimateLLMCost, d as unpricedServerTools, i as ModelPricing, l as recordLLMCost, n as GEN_AI_COST_ATTRIBUTE, o as SERVER_TOOL_PRICING_PER_1K, r as MODEL_PRICING, s as TokenUsage, t as EstimateCostOptions, u as registerModelPricing } from "./cost-Buyf5nLf.js";
2
+ export { EstimateCostOptions, GEN_AI_COST_ATTRIBUTE, MODEL_PRICING, ModelPricing, ModelPricingTable, SERVER_TOOL_PRICING_PER_1K, TokenUsage, estimateLLMCost, recordLLMCost, registerModelPricing, unpricedServerTools };
package/dist/cost.js CHANGED
@@ -29,7 +29,8 @@ const SERVER_TOOL_PRICING_PER_1K = {
29
29
  /**
30
30
  * Approximate public list prices (USD per 1M tokens) at the time of writing.
31
31
  * Prices change; treat these as convenience defaults, not a billing source of
32
- * truth. Override per call via `options.pricing` or mutate this table at init.
32
+ * truth. Add your own with {@link registerModelPricing}, or per call via
33
+ * `options.pricing`.
33
34
  * Matching is exact first, then by longest key prefix, so versioned model ids
34
35
  * (`claude-sonnet-4-6-20251101`) resolve to a base entry (`claude-sonnet-4-6`).
35
36
  */
@@ -109,7 +110,30 @@ const MODEL_PRICING = {
109
110
  outputPer1M: .4
110
111
  }
111
112
  };
112
- function resolvePricing(table, model) {
113
+ /**
114
+ * Strip one leading vendor segment from a hosted model id, or return
115
+ * `undefined` when there is nothing left to strip.
116
+ *
117
+ * Bedrock, Vertex and the cross-region inference profiles all namespace the
118
+ * model rather than rename it: `anthropic.claude-3-5-haiku-20241022-v1:0`,
119
+ * `eu.anthropic.claude-...`, `publishers/anthropic/models/claude-...`. The
120
+ * price table is keyed on the model itself, so the prefix has to come off
121
+ * before a lookup can hit.
122
+ *
123
+ * A segment containing a digit is left alone. Model families carry their
124
+ * version in the name — `gpt-4.1-mini`, `gemini-1.5-pro`, `claude-3-opus` —
125
+ * and stripping `gpt-4` off `gpt-4.1-mini` would turn a real key into `1-mini`.
126
+ */
127
+ function stripVendorPrefix(model) {
128
+ const slash = model.lastIndexOf("/");
129
+ if (slash !== -1) return model.slice(slash + 1);
130
+ const dot = model.indexOf(".");
131
+ if (dot === -1) return undefined;
132
+ const head = model.slice(0, dot);
133
+ if (head.length === 0 || /\d/.test(head)) return undefined;
134
+ return model.slice(dot + 1);
135
+ }
136
+ function matchPricing(table, model) {
113
137
  const exact = table[model];
114
138
  if (exact) return exact;
115
139
  let best;
@@ -122,6 +146,79 @@ function resolvePricing(table, model) {
122
146
  }
123
147
  return best;
124
148
  }
149
+ /**
150
+ * Add prices to {@link MODEL_PRICING} for the whole process, so every cost
151
+ * site sees them — {@link estimateLLMCost}, {@link recordLLMCost},
152
+ * `recordGenAiUsage`, `autotelTelemetry()`, and the agent runtime — with no
153
+ * option threaded through each call.
154
+ *
155
+ * This is the one to reach for with more than a couple of models: prices are a
156
+ * property of the deployment, not of the call. Later registrations win, so a
157
+ * base table can be layered over.
158
+ *
159
+ * Returns a function that restores the previous prices — useful in tests, and
160
+ * the reason to prefer this over mutating {@link MODEL_PRICING} directly.
161
+ *
162
+ * @example
163
+ * ```ts
164
+ * import { registerModelPricing } from 'autotel-genai/cost';
165
+ *
166
+ * // Once at startup. Key by family, not by deployed model id.
167
+ * registerModelPricing({
168
+ * 'glm-4.7-flash': { inputPer1M: 0.6, outputPer1M: 2.2 },
169
+ * 'acme-ft-7b': { inputPer1M: 0.1, outputPer1M: 0.1 },
170
+ * });
171
+ * ```
172
+ */
173
+ /**
174
+ * Registrations in the order they were made, so a model's price is whatever the
175
+ * last live layer says and restoring one never disturbs another. Without the
176
+ * stack, tearing a base table down while a per-tenant override is still live
177
+ * would leave the override's price behind, or the base's - depending only on
178
+ * the order the restores happened to run in.
179
+ */
180
+ const pricingLayers = [];
181
+ /** Each model's price before any layer touched it. */
182
+ const unlayeredPricing = new Map();
183
+ function applyPricingLayers(models) {
184
+ for (const model of models) {
185
+ let price;
186
+ for (const layer of pricingLayers) {
187
+ if (layer.live && layer.table[model]) price = layer.table[model];
188
+ }
189
+ price ??= unlayeredPricing.get(model);
190
+ if (price === undefined) delete MODEL_PRICING[model];
191
+ else MODEL_PRICING[model] = price;
192
+ }
193
+ }
194
+ function registerModelPricing(pricing) {
195
+ const models = Object.keys(pricing);
196
+ for (const model of models) {
197
+ if (!unlayeredPricing.has(model)) {
198
+ unlayeredPricing.set(model, MODEL_PRICING[model]);
199
+ }
200
+ }
201
+ const layer = {
202
+ table: pricing,
203
+ live: true
204
+ };
205
+ pricingLayers.push(layer);
206
+ applyPricingLayers(models);
207
+ return () => {
208
+ if (!layer.live) return;
209
+ layer.live = false;
210
+ applyPricingLayers(models);
211
+ };
212
+ }
213
+ function resolvePricing(table, model) {
214
+ let candidate = model;
215
+ while (candidate !== undefined) {
216
+ const price = matchPricing(table, candidate);
217
+ if (price) return price;
218
+ candidate = stripVendorPrefix(candidate);
219
+ }
220
+ return undefined;
221
+ }
125
222
  /** The table this model's tool prices resolve through, model entry first. */
126
223
  function serverToolRate(price, tool) {
127
224
  return price.serverToolPer1K?.[tool] ?? SERVER_TOOL_PRICING_PER_1K[tool];
@@ -202,4 +299,4 @@ function recordLLMCost(ctx, model, usage, options) {
202
299
  }
203
300
 
204
301
  //#endregion
205
- export { GEN_AI_COST_ATTRIBUTE, MODEL_PRICING, SERVER_TOOL_PRICING_PER_1K, estimateLLMCost, recordLLMCost, unpricedServerTools };
302
+ export { GEN_AI_COST_ATTRIBUTE, MODEL_PRICING, SERVER_TOOL_PRICING_PER_1K, estimateLLMCost, recordLLMCost, registerModelPricing, unpricedServerTools };
@@ -1,8 +1,16 @@
1
1
  import { h as GenAiProviderName, p as GenAiOperationName } from "./semconv-m_Y-ve_N.cjs";
2
2
  import { TraceContext } from "autotel";
3
3
  //#region src/events.d.ts
4
- /** Minimal sink: just what these helpers touch on a trace context. */
5
- type GenAiContentSink = Pick<TraceContext, 'setAttributes' | 'track'>;
4
+ /**
5
+ * Minimal sink: just what these helpers touch on a trace context, and only the
6
+ * scalars they actually set. Narrower than `TraceContext['setAttributes']` on
7
+ * purpose - a real context satisfies it, and a sink backed by a raw span needs
8
+ * no flattener, which would pull the whole `autotel` root into this entry.
9
+ */
10
+ interface GenAiContentSink {
11
+ setAttributes(attrs: Record<string, string | number>): void;
12
+ track: TraceContext['track'];
13
+ }
6
14
  /** A single content part within a message (text, tool_call, tool_call_response, …). */
7
15
  interface GenAiMessagePart {
8
16
  type: string;
@@ -1,8 +1,16 @@
1
1
  import { h as GenAiProviderName, p as GenAiOperationName } from "./semconv-m_Y-ve_N.js";
2
2
  import { TraceContext } from "autotel";
3
3
  //#region src/events.d.ts
4
- /** Minimal sink: just what these helpers touch on a trace context. */
5
- type GenAiContentSink = Pick<TraceContext, 'setAttributes' | 'track'>;
4
+ /**
5
+ * Minimal sink: just what these helpers touch on a trace context, and only the
6
+ * scalars they actually set. Narrower than `TraceContext['setAttributes']` on
7
+ * purpose - a real context satisfies it, and a sink backed by a raw span needs
8
+ * no flattener, which would pull the whole `autotel` root into this entry.
9
+ */
10
+ interface GenAiContentSink {
11
+ setAttributes(attrs: Record<string, string | number>): void;
12
+ track: TraceContext['track'];
13
+ }
6
14
  /** A single content part within a message (text, tool_call, tool_call_response, …). */
7
15
  interface GenAiMessagePart {
8
16
  type: string;
package/dist/events.d.cts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as GenAiMessage, c as GenAiWarning, d as recordInferenceDetails, f as recordModelWarnings, i as GenAiContentSink, l as InferenceDetailsEvent, m as setGenAiContent, n as DEFAULT_MAX_CONTENT_BYTES, o as GenAiMessagePart, p as recordOperationException, r as EvaluationResultEvent, s as GenAiOperationExceptionEvent, t as ContentCaptureSettings, u as recordEvaluationResult } from "./events-B1Kqejbc.cjs";
1
+ import { a as GenAiMessage, c as GenAiWarning, d as recordInferenceDetails, f as recordModelWarnings, i as GenAiContentSink, l as InferenceDetailsEvent, m as setGenAiContent, n as DEFAULT_MAX_CONTENT_BYTES, o as GenAiMessagePart, p as recordOperationException, r as EvaluationResultEvent, s as GenAiOperationExceptionEvent, t as ContentCaptureSettings, u as recordEvaluationResult } from "./events-BMnFqbM3.cjs";
2
2
  export { ContentCaptureSettings, DEFAULT_MAX_CONTENT_BYTES, EvaluationResultEvent, GenAiContentSink, GenAiMessage, GenAiMessagePart, GenAiOperationExceptionEvent, GenAiWarning, InferenceDetailsEvent, recordEvaluationResult, recordInferenceDetails, recordModelWarnings, recordOperationException, setGenAiContent };
package/dist/events.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as GenAiMessage, c as GenAiWarning, d as recordInferenceDetails, f as recordModelWarnings, i as GenAiContentSink, l as InferenceDetailsEvent, m as setGenAiContent, n as DEFAULT_MAX_CONTENT_BYTES, o as GenAiMessagePart, p as recordOperationException, r as EvaluationResultEvent, s as GenAiOperationExceptionEvent, t as ContentCaptureSettings, u as recordEvaluationResult } from "./events-CdjXIatQ.js";
1
+ import { a as GenAiMessage, c as GenAiWarning, d as recordInferenceDetails, f as recordModelWarnings, i as GenAiContentSink, l as InferenceDetailsEvent, m as setGenAiContent, n as DEFAULT_MAX_CONTENT_BYTES, o as GenAiMessagePart, p as recordOperationException, r as EvaluationResultEvent, s as GenAiOperationExceptionEvent, t as ContentCaptureSettings, u as recordEvaluationResult } from "./events-DvDscMOg.js";
2
2
  export { ContentCaptureSettings, DEFAULT_MAX_CONTENT_BYTES, EvaluationResultEvent, GenAiContentSink, GenAiMessage, GenAiMessagePart, GenAiOperationExceptionEvent, GenAiWarning, InferenceDetailsEvent, recordEvaluationResult, recordInferenceDetails, recordModelWarnings, recordOperationException, setGenAiContent };
@@ -1,4 +1,4 @@
1
- import { C as recordMemoryAccess, D as AgentActionFactory, E as tryRecordHumanApproval, F as AgentIdentity, G as AgentToolCallOptions, J as GenAiMetadata, L as AgentIdentityRegistry, N as AgentEventKind, O as AgentActionMetadata, P as AgentHandler, S as recordInputProvenance, T as recordRenderOutput, V as AgentSessionActionMetadata, W as AgentToolCallActionMetadata, Y as GovernanceMetadata, _ as deriveActionRiskClass, b as recordControllerId, ct as AgentContext, et as ScopedToolDefinition, j as AgentAuditEventEnvelope, k as AgentActionOptions, q as DelegationContext, rt as PrivacyProfileInput, t as AGENT_SECURITY_ATTR, tt as ToolCallMetadata, v as recordActionRiskClass, w as recordPlanStep, x as recordHumanApproval, y as recordActiveScopes, z as AgentMetadataInput } from "./agent-security-D9NfzH7I.js";
1
+ import { C as recordMemoryAccess, D as AgentActionFactory, E as tryRecordHumanApproval, F as AgentIdentity, G as AgentToolCallOptions, J as GenAiMetadata, L as AgentIdentityRegistry, N as AgentEventKind, O as AgentActionMetadata, P as AgentHandler, S as recordInputProvenance, T as recordRenderOutput, V as AgentSessionActionMetadata, W as AgentToolCallActionMetadata, Y as GovernanceMetadata, _ as deriveActionRiskClass, b as recordControllerId, ct as AgentContext, et as ScopedToolDefinition, j as AgentAuditEventEnvelope, k as AgentActionOptions, q as DelegationContext, rt as PrivacyProfileInput, t as AGENT_SECURITY_ATTR, tt as ToolCallMetadata, v as recordActionRiskClass, w as recordPlanStep, x as recordHumanApproval, y as recordActiveScopes, z as AgentMetadataInput } from "./agent-security-DK8_SNfi.js";
2
2
  import * as api from "@opentelemetry/api";
3
3
  import { AttributeValue, Attributes, Baggage, BaggageEntry, BaggageEntryMetadata, Context, ContextManager, DiagLogLevel, Exception, HrTime, Link, MeterProvider, Span, SpanContext, SpanKind, SpanOptions, SpanStatus, TextMapGetter, TextMapPropagator, TextMapSetter, TimeInput, TraceState, Tracer, TracerProvider } from "@opentelemetry/api";
4
4
  import { RequestLogger } from "autotel";