@rulvar/core 1.109.0 → 1.110.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.
package/dist/index.d.ts CHANGED
@@ -3713,6 +3713,18 @@ interface ToolBudgetSummary {
3713
3713
  limiter?: "maxToolCalls" | "toolUnits";
3714
3714
  }
3715
3715
  /**
3716
+ * How an event's `costUsd` was folded (RV702). `'per-call'`: the sum of
3717
+ * each provider request priced individually, the same basis the settled
3718
+ * CostReport and invoice use (RV504), so a nonlinear long-context tier
3719
+ * fires per REQUEST. `'aggregate-estimate'`: the aggregate usage priced
3720
+ * in one call, which a tier can inflate past what any single request
3721
+ * cost; emitted only when per-request records cannot cover the number
3722
+ * (a checkpoint written before the reconciliation ledger shipped, or a
3723
+ * terminal entry whose records do not cover its usage). An absent field
3724
+ * on an event stream recorded before RV702 means the aggregate basis.
3725
+ */
3726
+ type CostBasis = "per-call" | "aggregate-estimate";
3727
+ /**
3716
3728
  * Agent lifecycle. One logical agent dispatch emits EXACTLY ONE
3717
3729
  * `agent:start`/`agent:end` pair on its span (the start carries the
3718
3730
  * primary role), and each model invocation phase inside the span
@@ -3762,6 +3774,14 @@ type AgentEvents = {
3762
3774
  durationMs: number; /** The usage this activation added to its (role, model) slices. */
3763
3775
  usage: Usage; /** That usage priced at each serving model's own rate. */
3764
3776
  costUsd: number;
3777
+ /**
3778
+ * The fold behind `costUsd` (RV702). Live phase deltas are always
3779
+ * per-call (every slice a live activation adds is backed by a
3780
+ * recorded provider call); a replayed pair says 'aggregate-estimate'
3781
+ * exactly when its model's records do not cover its usage. Absent
3782
+ * on streams recorded before RV702, which priced the aggregate.
3783
+ */
3784
+ costBasis?: CostBasis;
3765
3785
  outcome: "ok" | "error";
3766
3786
  /**
3767
3787
  * Transport retries inside this activation. Present only when
@@ -3775,6 +3795,16 @@ type AgentEvents = {
3775
3795
  status: string;
3776
3796
  usage: Usage;
3777
3797
  costUsd: number;
3798
+ /**
3799
+ * The fold behind `costUsd` (RV702): 'per-call' when every usage
3800
+ * slice of the invocation (restored included) is covered by
3801
+ * per-request records priced individually, the settled fold's own
3802
+ * basis; 'aggregate-estimate' when it is not (the aggregate number
3803
+ * is kept so restored spend is never silently dropped, and labeled
3804
+ * so it is never mistaken for the per-request fold). Absent on
3805
+ * streams recorded before RV702, which priced the aggregate.
3806
+ */
3807
+ costBasis?: CostBasis;
3778
3808
  entryRef: number;
3779
3809
  /**
3780
3810
  * Present and true when this agent's usage is approximate rather
@@ -4376,6 +4406,15 @@ interface AgentResult<T> {
4376
4406
  output: T | null;
4377
4407
  usage: Usage;
4378
4408
  costUsd: number;
4409
+ /**
4410
+ * The fold behind `costUsd` (RV702): 'per-call' when every usage
4411
+ * slice (restored included) is covered by per-request records priced
4412
+ * individually, exactly the settled fold's basis; 'aggregate-estimate'
4413
+ * when a restored checkpoint left usage no record backs, in which case
4414
+ * the aggregate-priced number is kept (never silently dropped) and
4415
+ * labeled.
4416
+ */
4417
+ costBasis: CostBasis;
4379
4418
  turns: number;
4380
4419
  /**
4381
4420
  * The model that actually served the loop phase at the end (M4-T04):
@@ -10410,6 +10449,12 @@ interface PhaseRow {
10410
10449
  durationMs: number;
10411
10450
  usage: Usage;
10412
10451
  costUsd: number;
10452
+ /**
10453
+ * The fold behind `costUsd` (RV702). An event stream recorded before
10454
+ * the field shipped priced aggregates, so an absent field reduces to
10455
+ * 'aggregate-estimate', never to a per-call claim it cannot back.
10456
+ */
10457
+ costBasis: CostBasis;
10413
10458
  outcome?: "ok" | "error";
10414
10459
  retries: number;
10415
10460
  replayed: boolean;
@@ -10427,6 +10472,12 @@ interface AgentInvocationRow {
10427
10472
  status?: string;
10428
10473
  usage: Usage;
10429
10474
  costUsd: number;
10475
+ /**
10476
+ * The fold behind `costUsd` (RV702), from the span's agent:end; an
10477
+ * absent field (a pre-RV702 stream, or a span still open) reduces to
10478
+ * 'aggregate-estimate', never to a per-call claim it cannot back.
10479
+ */
10480
+ costBasis: CostBasis;
10430
10481
  usageApprox: boolean;
10431
10482
  retryCount: number;
10432
10483
  /**
@@ -10442,10 +10493,15 @@ interface AgentInvocationRow {
10442
10493
  /** The reduced table plus the per-role aggregate across every span. */
10443
10494
  interface InvocationTable {
10444
10495
  agents: AgentInvocationRow[];
10445
- /** Aggregated over COMPLETED phase pairs, keyed by role. */
10496
+ /**
10497
+ * Aggregated over COMPLETED phase pairs, keyed by role. The bucket's
10498
+ * `costBasis` is 'per-call' only while EVERY folded pair carried the
10499
+ * per-call basis; one aggregate-estimate pair degrades the bucket.
10500
+ */
10446
10501
  byRole: Record<string, {
10447
10502
  usage: Usage;
10448
10503
  costUsd: number;
10504
+ costBasis: CostBasis;
10449
10505
  }>;
10450
10506
  /** Sum of agent:end costUsd over settled spans. */
10451
10507
  totalCostUsd: number;
@@ -10557,4 +10613,4 @@ interface SandboxBridge {
10557
10613
  declare const SANDBOX_AGENT_OPT_KEYS: readonly string[];
10558
10614
  declare function createSandboxBridge(ctx: Ctx<never>, options: SandboxBridgeOptions): SandboxBridge;
10559
10615
  //#endregion
10560
- export { AWAIT_SCHEMA, AbandonAttempt, AbandonFold, AbandonPayload, AbandonedSpendView, AbortClass, type AdaptiveEvents, AdmissionController, AdmissionDecision, AdmissionRejectedError, AdmissionStatsBefore, AdmitLineage, AdmitRejectReason, AdmitSpec, AdmitVerdict, AgentCallError, AgentError, type AgentEvents, AgentIdentityInput, type AgentInvocationRow, AgentOpts, AgentProfile, AgentProfilePermissions, AgentProfileTemplateOptions, AgentResult, AgentResultMeta, AgentStatus, type AppliedPricingRow, ApproachSignatureInputs, ApprovalDecision, ApprovalIdentityInput, Artifact, AttemptOutcomeClass, AuditCategory, AuditRecord, AuditRunsOptions, BUDGET_ABORT_REASON, BaseAppend, BriefOpts, BudgetAccountView, BudgetDefaults, BudgetExhaustedError, BudgetExhaustionDiagnostics, BudgetHooks, BudgetReserve, type Bytes, CANCEL_AGENT_SCHEMA, CHECKPOINT_FORMAT_V1, CLAIM_STATEMENT_MAX_CHARS, CLAIM_TTL_DAYS, COMPACTION_SUMMARY_PREFIX, CURRENT_HASH_VERSION, CacheHint, CacheTtl, CanUseTool, CanonicalId, CanonicalIdentity, CanonicalLadderSpec, CanonicalModelSpec, ChatEvent, ChatRequest, CheckpointState, ChildArtifactPage, ChildIdentityInput, ChildResultPage, type ClaimClass, type ClaimOp, type ClaimStatus, ClaimValidationOptions, CollectOpts, CollectedTurn, CompactionConfig, CompiledPermissionChain, CompiledWorkflow, ConfigError, type CoreEvents, CostAttribution, CostAttributionFacts, CostReport, CreateEngineOptions, type CriticalPath, Ctx, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_CITATION_SAMPLE, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_CALLS_PER_ENTRY, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_EVIDENCE_OVERHEAD_CALLS, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_DEPTH, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_REVISIONS_PER_RUN, DEFAULT_MAX_TOTAL_SPAWNS, DEFAULT_MAX_TURNS, DEFAULT_MODEL_RETRY_ATTEMPTS, DEFAULT_NO_PROGRESS_TURNS, DEFAULT_PER_RUN_CONCURRENCY, DEFAULT_RETRY_POLICY, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DEFAULT_SYNTHESIS_MAX_TURNS, DEFAULT_SYNTHESIS_NOTE_MAX_TURNS, DataKeyProvider, DebitResult, DeclaredLadder, DedupIndex, DedupNote, DedupedClaims, DerivedKey, DeriverRegistry, type DeterminismConfig, DeterminismError, type DeterminismEvents, type DeterminismMode, DispositionRule, DispositionTable, DonorCandidate, DonorRef, DroppedItem, EMIT_RESULT_TOOL, EMPTY_SCHEMA_HASH, EMPTY_TOOLSET_HASH, ESCALATE_TOOL_NAME, ESCALATION_REPORT_SCHEMA, ESCALATION_REQUEST_SCHEMA, EVENT_SEGMENT_STRIDE, EffectiveUsageLimits, Effort, Engine, EngineDefaults, EngineQuotaConfig, EngineQuotaRuntime, EntryBillingFold, EntryBillingUnit, EntryKind, EntryRef, EntryStatus, EnvelopeEncryption, EnvelopeEncryptionOptions, ErrorClass, ErrorCode, ErrorPolicy, EscalatedResult, EscalationDecision, EscalationDecisionAbortedError, EscalationDigest, EscalationKind, EscalationLimits, EscalationOptions, EscalationReport, EscalationRequest, EventBus, EvidenceContract, type EvidenceRef, type ExecKeyDerivation, type ExecutorRegistry, type ExplorationSummary, ExtensionAppendInput, ExtensionDispatchSpec, ExternalIdentityInput, ExternalRegistry, ExtractNecessityInput, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_TOOL_NAME, FailRunError, FailoverTarget, FailoverTrigger, FallbackField, FallbackTrigger, FencedCodeMode, FileModelKnowledgeStore, FileModelKnowledgeStoreOptions, FileTranscriptStore, type FinalizationWindowBudget, FinishContract, FinishContractCitations, FinishContractGoldenReject, FinishContractManifest, FinishInfo, FinishSelfTestFailure, FinishSelfTestFixtures, FinishSelfTestReport, FinishValidationChild, FinishValidationInput, FinishValidationSpec, FinishValidationVerdict, FinishValidator, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, Gate, GateAudit, type GateRecord, GitWorktreeProvider, GitWorktreeProviderOptions, GraftBoot, HashVersion, HookVerdict, IMPLEMENTATION_PROFILE_LIMITS, INBOX_PROPOSAL_TTL_DAYS, IdentityInput, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, IncrementalSynthesisResult, InvalidResolutionError, InvocationRole, type InvocationTable, InvoiceExport, InvoicePricingProvenance, InvoiceReconciliation, InvoiceRow, type IsolatedExecContext, type IsolatedExecRequest, type IsolatedExecutorTag, type IsolationProvider, type IsolationSpec, Issue$1 as Issue, JOURNAL_ENVELOPE_MARKER, JournalCompatSubCode, JournalCompatibilityError, JournalEntry, JournalMatcher, JournalMissError, JournalOperation, JournalOrderViolation, type JournalPricingSnapshot, JournalSerializationContext, JournalSerializationHook, type JournalStore, type Json, JsonSchema, JsonlFileStore, KB_ACTIVE_CLAIMS_CAP, KB_CARD_RENDER_BUDGET_CHARS, type KbProposal, type KbProposalTrigger, KeyDeriver, KeyRing, KeyedLimiter, KnowledgeCasError, type KnowledgeSnapshot, LARGE_VALUE_WARN_BYTES, LEGACY_LTID_PREFIX, LEGACY_SIGNATURE_INPUTS, LINEAGE_SIG_VERSION, LadderSpec, type LeasableStore, type Lease, LeaseHeldError, Ledger, LineageCounters, LineageIndex, LineageRef, LineageRelation, LineageStats, LogicalTaskId, MASKED_SECRET, MAX_CHILD_RESULT_PAGE_CHARS, MAX_DEPTH_CEILING, MAX_TIMER_DELAY_MS, MatchResult, McpConfig, McpToolSource, MechanicalGateProfile, MechanicalGateVerdict, MemoryQuotaLimiter, type MetaLookupStore, type ModelCaps, ModelChoice, type ModelClaim, ModelEpochInputs, type ModelKnowledgeHandle, type ModelKnowledgeStore, ModelListConstraint, ModelRef, ModelRetry, ModelSpec, Msg, NoProgressDetector, NodeId, NodeLinkValue, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OnEscalation, OperationDisposition, OrchestrateAcceptance, OrchestrateOptions, OrchestrateSynthesis, OrchestrateSynthesisSkipReason, OrchestratorBudgetSpec, OrchestratorCapConfigError, OrchestratorExtension, OrchestratorExtensionIO, OrchestratorRuntime, Out, PARALLEL_AGENTS_SCHEMA, PROGRESS_REPORT_TOOL_NAME, ParallelSiteCounter, Part, PendingExternal, PendingToolTurn, PermissionConfig, PermissionGate, PermissionHook, PermissionPreset, PermissionRule, PermissionVerdict, type PhaseRow, PhaseTarget, type PinnedPricingSegment, PipelineCollected, PipelineOpts, PlanInvariantError, PreflightAdmissionRow, PreflightFinding, PreflightInput, PreflightOrchestratorSpec, PreflightReport, PreflightSpawnReport, PreflightSpawnSpec, PreflightToolCeiling, PriceTable, PricedUsage, type Pricing, type PricingTier, ProgressReport, type ProviderAdapter, ProviderCallRecord, QUOTA_WINDOW_MS, QualityFloors, QuotaCounters, type QuotaDecision, type QuotaEstimate, type QuotaLimiter, type QuotaReservationRequest, QuotaRule, QuotaWindowSnapshot, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, RESEARCH_PROFILE_LIMITS, REVIEW_PROFILE_LIMITS, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, RandIdentityInput, RandPayload, RateLimitObservation, ReconcileOptions, ReconcileResult, RefEntryAppender, RefEntryClassification, RefusalInfo, RepeatedClaim, ReplayDisposition, ReplayMode, ReplayPlanHashMismatch, Replayer, RepositoryResearchToolset, RepositoryResearchToolsetOptions, ResearchAgentProfileOptions, ResearchAgentProfileResult, ResearchEvidenceEntry, ResolutionArbiter, ResolutionAttempt, ResolutionBy, ResolutionFold, ResolutionLayer, ResolutionOutcome, ResolutionPayload, ResolvedInvocation, ResolvedToolset, ResumeHandle, ResumeOptions, ResumePreview, ResumeReport, RetryClass, RetryPolicy, ReuseConfig, RiskRuleValue, Role, RulvarError, RulvarErrorCode, RunAgentOptions, RunAuditVerdict, RunBudget, RunEventSink, RunExport, type RunFilter, RunHandle, RunInternals, type RunMeta, RunOptions, RunOutcome, RunProfile, RunStateAudit, RunStatus, RuntimeEventSink, SANDBOX_AGENT_OPT_KEYS, SPAWN_AGENT_SCHEMA, SandboxBridge, SandboxBridgeOptions, SandboxError, SandboxHostToWorker, SandboxMethod, SandboxWorkerToHost, SchemaPair, SchemaSpec, SchemaValidationResult, ScopeSegment, ScriptRejected, ScriptRunner, ScrubNote, SecretMasker, SectionMatchMode, Semaphore, SerializationHook, Settled, SettlementError, ShellPatternRules, ShellSegment, ShellVerdict, SinglePhaseAppend, SpanMinter, SpanRegistry, SpawnAdmissionValue, SpawnAgentParams, SpawnKey, SpawnLineage, SpawnLineageOpt, SpawnOrigin, SpawnRecord, Spend, Stage, type StandardJSONSchemaV1, type StandardSchemaV1, StepIdentityInput, StructuredOutputTier, SuspendedAppend, SuspensionState, TOOL_NAME_PATTERN, type TaskClass, TaskDigest, TaskSpec, TerminalPatch, TerminationAccount, TerminationAccountSnapshot, TerminationDeniedValue, TerminationDeniedWriter, TerminationInitValue, TerminationLimits, TerminationResource, type ToolBudgetSummary, ToolCallRequest, ToolChoice, type ToolContext, ToolContextSeed, ToolContract, type ToolDef, type ToolEvents, type ToolExecutor, type ToolExecutorProvider, ToolInit, type ToolRisk, ToolRuntime, type ToolSource, type ToolSourceSession, ToolsOption, TranscriptSerializationHook, type TranscriptStore, TriggerClass, TtlState, Usage, UsageLimits, UsageSlice, VerifiedRecommendation, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, WakeBudgetBlock, WakeDigest, WakeTrigger, WireError, Workflow, WorkflowCallOpts, type WorkflowEvent, type WorkflowEventBody, WorkflowRegistry, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, atCompactionThreshold, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compilePermissionChain, compilePermissionPreset, compileSecretMasker, compileVerifiedLayer, constantTimeEqual, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createEnvelopeEncryption, createSandboxBridge, currentOnlyKeyRing, decodeCheckpoint, dedupeRepeatedClaims, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispatchProjectionReserveUsd, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidencePreservedValidator, executeWorkflow, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, finishContract, foldTermination, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, headingStructureValidator, identityJcs, implementationAgentProfile, invoiceFromJournal, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, journalPricingSnapshot, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, latestProgressReport, lexShellCommand, liftRetainedParts, lineageWeightOf, localKeyProvider, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, memoryQuotaLimiter, mergeQuotaDenial, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, orchestratorAdmissionEstCostUsd, parallelScope, parseModelRef, parseScopePath, phiInitialOf, pipelineScope, planNodeScope, preflightEstimate, priceEntryBilling, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, progressReportTool, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, quotaActualTokens, quotaEstimateTokens, quotaRuleAdmission, quotaRuleKey, quotaRuleMatches, readRunMeta, readTerminationInit, reconcileRunMeta, reduceAuditTrail, reduceCriticalPath, reduceInvocationTable, registryKeyRing, remeasureQueue, replayDisposition, repositoryResearchToolset, requiredFieldsValidator, requiredSectionsValidator, researchAgentProfile, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, reviewAgentProfile, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, sectionCitationsValidator, selectStructuredOutputTier, selfTestFinishValidation, shouldCompact, snapshotQuotaRules, snapshotUsage, spawnDepthOf, stripFencedBlocks, summarizeInstruction, summarizeOutput, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolsetHash, ttlState, usageViolations, validateEditorialCommit, validateEngineQuotaConfig, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateQuotaRules, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateUsageLimits, wordCountValidator, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
10616
+ export { AWAIT_SCHEMA, AbandonAttempt, AbandonFold, AbandonPayload, AbandonedSpendView, AbortClass, type AdaptiveEvents, AdmissionController, AdmissionDecision, AdmissionRejectedError, AdmissionStatsBefore, AdmitLineage, AdmitRejectReason, AdmitSpec, AdmitVerdict, AgentCallError, AgentError, type AgentEvents, AgentIdentityInput, type AgentInvocationRow, AgentOpts, AgentProfile, AgentProfilePermissions, AgentProfileTemplateOptions, AgentResult, AgentResultMeta, AgentStatus, type AppliedPricingRow, ApproachSignatureInputs, ApprovalDecision, ApprovalIdentityInput, Artifact, AttemptOutcomeClass, AuditCategory, AuditRecord, AuditRunsOptions, BUDGET_ABORT_REASON, BaseAppend, BriefOpts, BudgetAccountView, BudgetDefaults, BudgetExhaustedError, BudgetExhaustionDiagnostics, BudgetHooks, BudgetReserve, type Bytes, CANCEL_AGENT_SCHEMA, CHECKPOINT_FORMAT_V1, CLAIM_STATEMENT_MAX_CHARS, CLAIM_TTL_DAYS, COMPACTION_SUMMARY_PREFIX, CURRENT_HASH_VERSION, CacheHint, CacheTtl, CanUseTool, CanonicalId, CanonicalIdentity, CanonicalLadderSpec, CanonicalModelSpec, ChatEvent, ChatRequest, CheckpointState, ChildArtifactPage, ChildIdentityInput, ChildResultPage, type ClaimClass, type ClaimOp, type ClaimStatus, ClaimValidationOptions, CollectOpts, CollectedTurn, CompactionConfig, CompiledPermissionChain, CompiledWorkflow, ConfigError, type CoreEvents, CostAttribution, CostAttributionFacts, type CostBasis, CostReport, CreateEngineOptions, type CriticalPath, Ctx, DEFAULT_CHILD_BUDGET_FRACTION, DEFAULT_CHILD_RESULT_PAGE_CHARS, DEFAULT_CITATION_PATTERN, DEFAULT_CITATION_SAMPLE, DEFAULT_COMPACTION_THRESHOLD, DEFAULT_ESCALATION_LIMITS, DEFAULT_EVIDENCE_CALLS_PER_ENTRY, DEFAULT_EVIDENCE_MIN_SHARE, DEFAULT_EVIDENCE_OVERHEAD_CALLS, DEFAULT_FINISH_MAX_REPAIRS, DEFAULT_FLAT_RESERVE_USD, DEFAULT_MAX_CHILDREN_PER_NODE, DEFAULT_MAX_DEPTH, DEFAULT_MAX_OSCILLATIONS_PER_KEY, DEFAULT_MAX_PINNED_WORKTREES, DEFAULT_MAX_REVISIONS_PER_RUN, DEFAULT_MAX_TOTAL_SPAWNS, DEFAULT_MAX_TURNS, DEFAULT_MODEL_RETRY_ATTEMPTS, DEFAULT_NO_PROGRESS_TURNS, DEFAULT_PER_RUN_CONCURRENCY, DEFAULT_RETRY_POLICY, DEFAULT_STREAM_IDLE_TIMEOUT_MS, DEFAULT_SYNTHESIS_MAX_TURNS, DEFAULT_SYNTHESIS_NOTE_MAX_TURNS, DataKeyProvider, DebitResult, DeclaredLadder, DedupIndex, DedupNote, DedupedClaims, DerivedKey, DeriverRegistry, type DeterminismConfig, DeterminismError, type DeterminismEvents, type DeterminismMode, DispositionRule, DispositionTable, DonorCandidate, DonorRef, DroppedItem, EMIT_RESULT_TOOL, EMPTY_SCHEMA_HASH, EMPTY_TOOLSET_HASH, ESCALATE_TOOL_NAME, ESCALATION_REPORT_SCHEMA, ESCALATION_REQUEST_SCHEMA, EVENT_SEGMENT_STRIDE, EffectiveUsageLimits, Effort, Engine, EngineDefaults, EngineQuotaConfig, EngineQuotaRuntime, EntryBillingFold, EntryBillingUnit, EntryKind, EntryRef, EntryStatus, EnvelopeEncryption, EnvelopeEncryptionOptions, ErrorClass, ErrorCode, ErrorPolicy, EscalatedResult, EscalationDecision, EscalationDecisionAbortedError, EscalationDigest, EscalationKind, EscalationLimits, EscalationOptions, EscalationReport, EscalationRequest, EventBus, EvidenceContract, type EvidenceRef, type ExecKeyDerivation, type ExecutorRegistry, type ExplorationSummary, ExtensionAppendInput, ExtensionDispatchSpec, ExternalIdentityInput, ExternalRegistry, ExtractNecessityInput, FINALIZE_SYNTHESIS_INSTRUCTION, FINISH_SCHEMA, FINISH_TOOL_NAME, FailRunError, FailoverTarget, FailoverTrigger, FallbackField, FallbackTrigger, FencedCodeMode, FileModelKnowledgeStore, FileModelKnowledgeStoreOptions, FileTranscriptStore, type FinalizationWindowBudget, FinishContract, FinishContractCitations, FinishContractGoldenReject, FinishContractManifest, FinishInfo, FinishSelfTestFailure, FinishSelfTestFixtures, FinishSelfTestReport, FinishValidationChild, FinishValidationInput, FinishValidationSpec, FinishValidationVerdict, FinishValidator, GET_CHILD_RESULT_SCHEMA, GET_CHILD_RESULT_TOOL_NAME, Gate, GateAudit, type GateRecord, GitWorktreeProvider, GitWorktreeProviderOptions, GraftBoot, HashVersion, HookVerdict, IMPLEMENTATION_PROFILE_LIMITS, INBOX_PROPOSAL_TTL_DAYS, IdentityInput, InMemoryStore, InMemoryTranscriptStore, InProcessRunner, IncrementalSynthesisResult, InvalidResolutionError, InvocationRole, type InvocationTable, InvoiceExport, InvoicePricingProvenance, InvoiceReconciliation, InvoiceRow, type IsolatedExecContext, type IsolatedExecRequest, type IsolatedExecutorTag, type IsolationProvider, type IsolationSpec, Issue$1 as Issue, JOURNAL_ENVELOPE_MARKER, JournalCompatSubCode, JournalCompatibilityError, JournalEntry, JournalMatcher, JournalMissError, JournalOperation, JournalOrderViolation, type JournalPricingSnapshot, JournalSerializationContext, JournalSerializationHook, type JournalStore, type Json, JsonSchema, JsonlFileStore, KB_ACTIVE_CLAIMS_CAP, KB_CARD_RENDER_BUDGET_CHARS, type KbProposal, type KbProposalTrigger, KeyDeriver, KeyRing, KeyedLimiter, KnowledgeCasError, type KnowledgeSnapshot, LARGE_VALUE_WARN_BYTES, LEGACY_LTID_PREFIX, LEGACY_SIGNATURE_INPUTS, LINEAGE_SIG_VERSION, LadderSpec, type LeasableStore, type Lease, LeaseHeldError, Ledger, LineageCounters, LineageIndex, LineageRef, LineageRelation, LineageStats, LogicalTaskId, MASKED_SECRET, MAX_CHILD_RESULT_PAGE_CHARS, MAX_DEPTH_CEILING, MAX_TIMER_DELAY_MS, MatchResult, McpConfig, McpToolSource, MechanicalGateProfile, MechanicalGateVerdict, MemoryQuotaLimiter, type MetaLookupStore, type ModelCaps, ModelChoice, type ModelClaim, ModelEpochInputs, type ModelKnowledgeHandle, type ModelKnowledgeStore, ModelListConstraint, ModelRef, ModelRetry, ModelSpec, Msg, NoProgressDetector, NodeId, NodeLinkValue, NonSerializableValueError, ORCHESTRATE_WORKFLOW_NAME, OnEscalation, OperationDisposition, OrchestrateAcceptance, OrchestrateOptions, OrchestrateSynthesis, OrchestrateSynthesisSkipReason, OrchestratorBudgetSpec, OrchestratorCapConfigError, OrchestratorExtension, OrchestratorExtensionIO, OrchestratorRuntime, Out, PARALLEL_AGENTS_SCHEMA, PROGRESS_REPORT_TOOL_NAME, ParallelSiteCounter, Part, PendingExternal, PendingToolTurn, PermissionConfig, PermissionGate, PermissionHook, PermissionPreset, PermissionRule, PermissionVerdict, type PhaseRow, PhaseTarget, type PinnedPricingSegment, PipelineCollected, PipelineOpts, PlanInvariantError, PreflightAdmissionRow, PreflightFinding, PreflightInput, PreflightOrchestratorSpec, PreflightReport, PreflightSpawnReport, PreflightSpawnSpec, PreflightToolCeiling, PriceTable, PricedUsage, type Pricing, type PricingTier, ProgressReport, type ProviderAdapter, ProviderCallRecord, QUOTA_WINDOW_MS, QualityFloors, QuotaCounters, type QuotaDecision, type QuotaEstimate, type QuotaLimiter, type QuotaReservationRequest, QuotaRule, QuotaWindowSnapshot, READ_CHILD_ARTIFACT_SCHEMA, READ_CHILD_ARTIFACT_TOOL_NAME, RESEARCH_PROFILE_LIMITS, REVIEW_PROFILE_LIMITS, ROLE_EFFORT_DEFAULTS, ROOT_ACCOUNT, ROOT_SCOPE, RUN_PROFILES, RUN_SETTLE_DECISION_TYPE, RandIdentityInput, RandPayload, RateLimitObservation, ReconcileOptions, ReconcileResult, RefEntryAppender, RefEntryClassification, RefusalInfo, RepeatedClaim, ReplayDisposition, ReplayMode, ReplayPlanHashMismatch, Replayer, RepositoryResearchToolset, RepositoryResearchToolsetOptions, ResearchAgentProfileOptions, ResearchAgentProfileResult, ResearchEvidenceEntry, ResolutionArbiter, ResolutionAttempt, ResolutionBy, ResolutionFold, ResolutionLayer, ResolutionOutcome, ResolutionPayload, ResolvedInvocation, ResolvedToolset, ResumeHandle, ResumeOptions, ResumePreview, ResumeReport, RetryClass, RetryPolicy, ReuseConfig, RiskRuleValue, Role, RulvarError, RulvarErrorCode, RunAgentOptions, RunAuditVerdict, RunBudget, RunEventSink, RunExport, type RunFilter, RunHandle, RunInternals, type RunMeta, RunOptions, RunOutcome, RunProfile, RunStateAudit, RunStatus, RuntimeEventSink, SANDBOX_AGENT_OPT_KEYS, SPAWN_AGENT_SCHEMA, SandboxBridge, SandboxBridgeOptions, SandboxError, SandboxHostToWorker, SandboxMethod, SandboxWorkerToHost, SchemaPair, SchemaSpec, SchemaValidationResult, ScopeSegment, ScriptRejected, ScriptRunner, ScrubNote, SecretMasker, SectionMatchMode, Semaphore, SerializationHook, Settled, SettlementError, ShellPatternRules, ShellSegment, ShellVerdict, SinglePhaseAppend, SpanMinter, SpanRegistry, SpawnAdmissionValue, SpawnAgentParams, SpawnKey, SpawnLineage, SpawnLineageOpt, SpawnOrigin, SpawnRecord, Spend, Stage, type StandardJSONSchemaV1, type StandardSchemaV1, StepIdentityInput, StructuredOutputTier, SuspendedAppend, SuspensionState, TOOL_NAME_PATTERN, type TaskClass, TaskDigest, TaskSpec, TerminalPatch, TerminationAccount, TerminationAccountSnapshot, TerminationDeniedValue, TerminationDeniedWriter, TerminationInitValue, TerminationLimits, TerminationResource, type ToolBudgetSummary, ToolCallRequest, ToolChoice, type ToolContext, ToolContextSeed, ToolContract, type ToolDef, type ToolEvents, type ToolExecutor, type ToolExecutorProvider, ToolInit, type ToolRisk, ToolRuntime, type ToolSource, type ToolSourceSession, ToolsOption, TranscriptSerializationHook, type TranscriptStore, TriggerClass, TtlState, Usage, UsageLimits, UsageSlice, VerifiedRecommendation, WAIT_FOR_EVENTS_SCHEMA, WAIT_FOR_EVENTS_TOOL_NAME, WAKE_SUMMARY_RENDER_BUDGET_CHARS, WakeBudgetBlock, WakeDigest, WakeTrigger, WireError, Workflow, WorkflowCallOpts, type WorkflowEvent, type WorkflowEventBody, WorkflowRegistry, admissionReserveUsd, affordableOutputTokens, agentErrorFromWire, agentErrorToWire, agentResultWire, agentScope, applyClaimOps, applyStructuredOutputTier, approachSigCoarse, approachSigOf, archiveDeprecatedModelOps, assertFencedWrites, atCompactionThreshold, auditRun, auditRuns, buildAbandonFold, buildAdapterRegistry, buildCostReport, buildDeriverRegistry, buildOrchestratorTools, buildTerminationInitValue, buildToolContext, canRideLoopTurn, canonicalIsolationTag, canonicalizeLadder, canonicalizeSchema, capIssues, capsHashOf, checkFloors, checkpointRefFor, childCoveragePrefix, claimExpired, claimExpiry, claimIssues, claimOpIssues, classifyAgentError, classifyAttemptOutcome, collectDeclaredLadders, compactMessages, compilePermissionChain, compilePermissionPreset, compileSecretMasker, compileVerifiedLayer, constantTimeEqual, costReportFromJournal, countsAgainstLimit, createCanonicalIdMinter, createCtx, createEngine, createEnvelopeEncryption, createSandboxBridge, currentOnlyKeyRing, decodeCheckpoint, dedupeRepeatedClaims, defineWorkflow, deriveContentKey, deriverV1, deriverV2, digestOf, dispatchProjectionReserveUsd, dispositionHook, emptyDigestBlocks, emptyToolset, encodeCheckpoint, entryUsageSlices, escalateTool, evaluatePermission, evaluateReuse, evidencePreservedValidator, executeWorkflow, exhaustionCodeOf, extractCandidate, failoverTriggerOf, fallbackTriggerOf, filterClaimsForRun, finalizeFires, finishContract, foldTermination, formatRePrompt, formatScopePath, hasFencedWrites, hasMetaLookup, hashRunArgs, hashRunOutput, hashWorkflowBody, hashWorkflowSource, headingStructureValidator, identityJcs, implementationAgentProfile, invoiceFromJournal, isEscalated, isSchemaPairSpec, isStandardSchemaSpec, isStrictCompatibleSchema, journalPricingSnapshot, kMaxOf, knowledgeHash, ladderLengthOf, ladderRungChoice, lastRunSettle, latestProgressReport, lexShellCommand, liftRetainedParts, lineageWeightOf, localKeyProvider, makeOrchestratorWorkflow, maskSecrets, maskSecretsDeep, maskSecretsJson, matchArgvPattern, matchShellCommand, mcp, memoryQuotaLimiter, mergeQuotaDenial, mergeUsageLimits, metaMatchesFilter, minMatchesValidator, modelEpochOf, modelKnowledgeCard, modelSpecIdentity, needsSeparateExtract, nextFailover, nodeLinkKey, normalizeApproachTag, normalizeEntry, normalizeFallbacks, orchestrate, orchestratorAdmissionEstCostUsd, parallelScope, parseModelRef, parseScopePath, phiInitialOf, pipelineScope, planNodeScope, preflightEstimate, priceEntryBilling, priceEntryUsage, priceUsdOf, profileCard, profileRegistrySnapshotHash, progressReportTool, projectHistory, projectIdentity, projectToJsonSchema, proposalStatement, providerOf, quotaActualTokens, quotaEstimateTokens, quotaRuleAdmission, quotaRuleKey, quotaRuleMatches, readRunMeta, readTerminationInit, reconcileRunMeta, reduceAuditTrail, reduceCriticalPath, reduceInvocationTable, registryKeyRing, remeasureQueue, replayDisposition, repositoryResearchToolset, requiredFieldsValidator, requiredSectionsValidator, researchAgentProfile, resolveModelInvocation, resolvePricing, resolveToolset, retryClassOf, retryDelayMs, reviewAgentProfile, roleConfiguredInRouting, roundOneDisposition, runAgent, runProfile, sanitizeTerminalText, sanitizeTokenCount, sanitizeUsage, sanitizeUsageDelta, scanJournalCompatibility, schemaHash, schemaHashOfSpec, sectionCitationsValidator, selectStructuredOutputTier, selfTestFinishValidation, shouldCompact, snapshotQuotaRules, snapshotUsage, spawnDepthOf, stripFencedBlocks, summarizeInstruction, summarizeOutput, terminationConfigDrift, tierWithinCaps, toApprovalDecision, toJournalValue, tool, toolContract, toolsetHash, ttlState, usageViolations, validateEditorialCommit, validateEngineQuotaConfig, validateEntryShape, validateEscalationLimits, validateEscalationReport, validateQuotaRules, validateRetryPolicy, validateSchemaSpec, validateTerminationLimits, validateUsageLimits, wordCountValidator, workflowScope, workflowSourceRef, wrapJournalStore, wrapTranscriptStore };
package/dist/index.js CHANGED
@@ -11067,6 +11067,18 @@ async function runAgent(options) {
11067
11067
  });
11068
11068
  };
11069
11069
  const providerCalls = [];
11070
+ const usdByPhaseModel = /* @__PURE__ */ new Map();
11071
+ const addCallUsd = (role, ref, usage) => {
11072
+ const priced = options.priceUsd?.(ref, usage) ?? 0;
11073
+ const usd = Number.isFinite(priced) && priced > 0 ? priced : 0;
11074
+ const key = `${role}\u0000${ref}`;
11075
+ const prior = usdByPhaseModel.get(key);
11076
+ usdByPhaseModel.set(key, {
11077
+ role,
11078
+ usd: (prior?.usd ?? 0) + usd
11079
+ });
11080
+ };
11081
+ let perCallCoverage = true;
11070
11082
  let invocationCounter = 0;
11071
11083
  let transportRetries = 0;
11072
11084
  let schemaRecoveredTerminalExchanges = 0;
@@ -11076,6 +11088,11 @@ async function runAgent(options) {
11076
11088
  for (const [key, slice] of usageByPhaseModel) if (slice.role === role) snapshot.set(key, slice.usage);
11077
11089
  return snapshot;
11078
11090
  };
11091
+ const roleUsdSnapshot = (role) => {
11092
+ const snapshot = /* @__PURE__ */ new Map();
11093
+ for (const [key, cell] of usdByPhaseModel) if (cell.role === role) snapshot.set(key, cell.usd);
11094
+ return snapshot;
11095
+ };
11079
11096
  const usageDelta = (after, before) => {
11080
11097
  const base = before ?? ZERO_USAGE$1;
11081
11098
  const delta = {
@@ -11103,19 +11120,22 @@ async function runAgent(options) {
11103
11120
  role,
11104
11121
  model,
11105
11122
  before: roleUsageSnapshot(role),
11123
+ beforeUsd: roleUsdSnapshot(role),
11106
11124
  startedAtMs: now(),
11107
11125
  retriesBefore: transportRetries
11108
11126
  };
11109
11127
  };
11110
11128
  const endPhase = (phase, outcome, servedModel) => {
11111
11129
  let phaseUsage = ZERO_USAGE$1;
11112
- let phaseUsd = 0;
11113
11130
  for (const [key, slice] of usageByPhaseModel) {
11114
11131
  if (slice.role !== phase.role) continue;
11115
11132
  const delta = usageDelta(slice.usage, phase.before.get(key));
11116
11133
  phaseUsage = addUsage$1(phaseUsage, delta);
11117
- const priced = options.priceUsd?.(slice.servedBy, delta) ?? 0;
11118
- if (Number.isFinite(priced) && priced > 0) phaseUsd += priced;
11134
+ }
11135
+ let phaseUsd = 0;
11136
+ for (const [key, cell] of usdByPhaseModel) {
11137
+ if (cell.role !== phase.role) continue;
11138
+ phaseUsd += cell.usd - (phase.beforeUsd.get(key) ?? 0);
11119
11139
  }
11120
11140
  const retries = transportRetries - phase.retriesBefore;
11121
11141
  events?.emit({
@@ -11128,6 +11148,7 @@ async function runAgent(options) {
11128
11148
  durationMs: Math.max(0, now() - phase.startedAtMs),
11129
11149
  usage: phaseUsage,
11130
11150
  costUsd: phaseUsd,
11151
+ costBasis: "per-call",
11131
11152
  outcome,
11132
11153
  ...retries > 0 ? { retries } : {}
11133
11154
  });
@@ -11376,15 +11397,28 @@ async function runAgent(options) {
11376
11397
  servedBy,
11377
11398
  usage: totalUsage
11378
11399
  }];
11400
+ const restoredSliceSums = /* @__PURE__ */ new Map();
11379
11401
  for (const slice of restoredSlices) {
11380
11402
  const sliceUsage = usageViolations(slice.usage).length === 0 ? slice.usage : sanitizeUsage(slice.usage);
11381
11403
  addPhaseUsage(slice.role ?? primaryRole, slice.servedBy, sliceUsage);
11382
11404
  options.budget?.onUsage(sliceUsage, slice.servedBy);
11383
- }
11384
- for (const record of restored.providerCalls ?? []) providerCalls.push(usageViolations(record.usage).length === 0 ? record : {
11385
- ...record,
11386
- usage: sanitizeUsage(record.usage)
11387
- });
11405
+ const key = `${slice.role ?? primaryRole} ${slice.servedBy}`;
11406
+ restoredSliceSums.set(key, addUsage$1(restoredSliceSums.get(key) ?? ZERO_USAGE$1, sliceUsage));
11407
+ }
11408
+ const restoredRecordSums = /* @__PURE__ */ new Map();
11409
+ for (const record of restored.providerCalls ?? []) {
11410
+ const sane = usageViolations(record.usage).length === 0 ? record : {
11411
+ ...record,
11412
+ usage: sanitizeUsage(record.usage)
11413
+ };
11414
+ providerCalls.push(sane);
11415
+ addCallUsd(sane.role ?? primaryRole, sane.servedBy, sane.usage);
11416
+ const key = `${sane.role ?? primaryRole} ${sane.servedBy}`;
11417
+ restoredRecordSums.set(key, addUsage$1(restoredRecordSums.get(key) ?? ZERO_USAGE$1, sane.usage));
11418
+ }
11419
+ const usageEquals = (a, b) => a.inputTokens === b.inputTokens && a.outputTokens === b.outputTokens && a.cacheReadTokens === b.cacheReadTokens && a.cacheWriteTokens === b.cacheWriteTokens && (a.reasoningTokens ?? 0) === (b.reasoningTokens ?? 0);
11420
+ for (const [key, sliceSum] of restoredSliceSums) if (!usageEquals(sliceSum, restoredRecordSums.get(key) ?? ZERO_USAGE$1)) perCallCoverage = false;
11421
+ for (const key of restoredRecordSums.keys()) if (!restoredSliceSums.has(key)) perCallCoverage = false;
11388
11422
  guard?.restore(messages);
11389
11423
  if (limits.toolBudgetNotices === true && limits.maxToolCalls !== void 0) for (const threshold of crossedNoticeThresholds(toolCallsUsed, limits.maxToolCalls)) firedNotices.add(threshold);
11390
11424
  if (extension !== void 0 && limits.maxToolCalls !== void 0 && toolCallsUsed > limits.maxToolCalls) {
@@ -11435,6 +11469,25 @@ async function runAgent(options) {
11435
11469
  }
11436
11470
  return usd;
11437
11471
  };
11472
+ /**
11473
+ * The invocation's recorded spend (RV702): the per-call accumulator
11474
+ * when every slice is covered by records, the settled fold's own
11475
+ * basis; the labeled aggregate estimate when a restored checkpoint
11476
+ * left usage no record backs, so restored spend is never silently
11477
+ * dropped and an estimate never poses as the per-request fold.
11478
+ */
11479
+ const recordedSpend = () => {
11480
+ if (!perCallCoverage) return {
11481
+ usd: priceRecordedUsage(),
11482
+ basis: "aggregate-estimate"
11483
+ };
11484
+ let usd = 0;
11485
+ for (const cell of usdByPhaseModel.values()) usd += cell.usd;
11486
+ return {
11487
+ usd,
11488
+ basis: "per-call"
11489
+ };
11490
+ };
11438
11491
  const saveBoundary = async (pending) => {
11439
11492
  if (options.checkpoint === void 0) return;
11440
11493
  await options.checkpoint.save({
@@ -11608,7 +11661,7 @@ async function runAgent(options) {
11608
11661
  continue;
11609
11662
  }
11610
11663
  const request = validation.value;
11611
- const spentSoFar = priceRecordedUsage();
11664
+ const spentSoFar = recordedSpend().usd;
11612
11665
  if (countsAgainstLimit(request.kind) && spentSoFar < options.escalation.minSpendUsd) {
11613
11666
  events?.emit({
11614
11667
  type: "tool:end",
@@ -12016,6 +12069,7 @@ async function runAgent(options) {
12016
12069
  if (outcome.aborted !== void 0) record.aborted = outcome.aborted;
12017
12070
  else if (outcome.wireError !== void 0) record.errorCode = outcome.wireError.code;
12018
12071
  providerCalls.push(record);
12072
+ addCallUsd(site.role, target.resolved.ref, accounted);
12019
12073
  const limited = outcome.wireError?.data;
12020
12074
  if (limited?.kind === "rate-limit" && typeof limited.reportedLimits === "object" && limited.reportedLimits !== null) rateLimitObservations.set(`${target.adapter.id}:${target.resolved.model}`, {
12021
12075
  provider: target.adapter.id,
@@ -12846,12 +12900,13 @@ async function runAgent(options) {
12846
12900
  const blob = new TextEncoder().encode(JSON.stringify({ messages }));
12847
12901
  await options.transcript.put(transcriptRef, blob);
12848
12902
  }
12849
- const costUsd = priceRecordedUsage();
12903
+ const spend = recordedSpend();
12850
12904
  const result = {
12851
12905
  status,
12852
12906
  output: status === "ok" ? output : output ?? null,
12853
12907
  usage: totalUsage,
12854
- costUsd,
12908
+ costUsd: spend.usd,
12909
+ costBasis: spend.basis,
12855
12910
  turns,
12856
12911
  servedBy,
12857
12912
  transcriptRef
@@ -14667,13 +14722,15 @@ function createCtx(internals, rootWorkflow) {
14667
14722
  cacheReadTokens: 0,
14668
14723
  cacheWriteTokens: 0
14669
14724
  };
14670
- const replayPriced = terminal === void 0 ? void 0 : priceEntryUsage(terminal, (ref, sliceUsage) => internals.priceUsd(ref, sliceUsage));
14725
+ const replayPriced = terminal === void 0 ? void 0 : priceEntryBilling(terminal, (ref, sliceUsage) => internals.priceUsd(ref, sliceUsage));
14671
14726
  const costUsd = replayPriced?.usd ?? 0;
14727
+ const replayBasis = replayPriced === void 0 || replayPriced.fullyAttributed ? "per-call" : "aggregate-estimate";
14672
14728
  const result = {
14673
14729
  status: matched.kind === "skip" ? "skipped" : terminal?.status ?? "ok",
14674
14730
  output: matched.kind === "skip" ? null : terminal?.value ?? null,
14675
14731
  usage,
14676
14732
  costUsd,
14733
+ costBasis: replayBasis,
14677
14734
  servedBy: terminal?.servedBy ?? loopResolved.ref,
14678
14735
  turns: 0,
14679
14736
  transcriptRef: terminal?.transcriptRef ?? ""
@@ -14737,29 +14794,37 @@ function createCtx(internals, rootWorkflow) {
14737
14794
  durationMs: 0
14738
14795
  }, spanId, true);
14739
14796
  }
14740
- if (terminal !== void 0) entryUsageSlices(terminal).forEach((slice, index) => {
14741
- const priced = internals.priceUsd(slice.servedBy, slice.usage) ?? 0;
14742
- const sliceUsd = Number.isFinite(priced) && priced > 0 ? priced : 0;
14743
- const common = {
14744
- agentType,
14745
- label: opts.label,
14746
- role: slice.role ?? primaryRole,
14747
- model: slice.servedBy,
14748
- invocation: index + 1
14749
- };
14750
- internals.events.emit({
14751
- type: "agent:phase:start",
14752
- ...common
14753
- }, spanId, true);
14754
- internals.events.emit({
14755
- type: "agent:phase:end",
14756
- ...common,
14757
- durationMs: 0,
14758
- usage: slice.usage,
14759
- costUsd: sliceUsd,
14760
- outcome: terminal.status === "error" || terminal.status === "cancelled" ? "error" : "ok"
14761
- }, spanId, true);
14762
- });
14797
+ if (terminal !== void 0) {
14798
+ const usdByRoleModel = /* @__PURE__ */ new Map();
14799
+ const perCallModels = /* @__PURE__ */ new Set();
14800
+ for (const unit of replayPriced?.units ?? []) {
14801
+ const key = `${unit.role ?? primaryRole} ${unit.servedBy}`;
14802
+ usdByRoleModel.set(key, (usdByRoleModel.get(key) ?? 0) + unit.usd);
14803
+ if (unit.source === "call") perCallModels.add(unit.servedBy);
14804
+ }
14805
+ entryUsageSlices(terminal).forEach((slice, index) => {
14806
+ const common = {
14807
+ agentType,
14808
+ label: opts.label,
14809
+ role: slice.role ?? primaryRole,
14810
+ model: slice.servedBy,
14811
+ invocation: index + 1
14812
+ };
14813
+ internals.events.emit({
14814
+ type: "agent:phase:start",
14815
+ ...common
14816
+ }, spanId, true);
14817
+ internals.events.emit({
14818
+ type: "agent:phase:end",
14819
+ ...common,
14820
+ durationMs: 0,
14821
+ usage: slice.usage,
14822
+ costUsd: usdByRoleModel.get(`${slice.role ?? primaryRole} ${slice.servedBy}`) ?? 0,
14823
+ costBasis: perCallModels.has(slice.servedBy) ? "per-call" : "aggregate-estimate",
14824
+ outcome: terminal.status === "error" || terminal.status === "cancelled" ? "error" : "ok"
14825
+ }, spanId, true);
14826
+ });
14827
+ }
14763
14828
  internals.events.emit({
14764
14829
  type: "agent:end",
14765
14830
  agentType,
@@ -14767,12 +14832,13 @@ function createCtx(internals, rootWorkflow) {
14767
14832
  status: result.status,
14768
14833
  usage,
14769
14834
  costUsd,
14835
+ costBasis: replayBasis,
14770
14836
  entryRef: terminal?.seq ?? matched.running.seq,
14771
14837
  ...terminal?.usageApprox === true ? { usageApprox: true } : {},
14772
14838
  ...result.exploration === void 0 ? {} : { exploration: result.exploration },
14773
14839
  ...result.toolBudget === void 0 ? {} : { toolBudget: result.toolBudget }
14774
14840
  }, spanId, true);
14775
- for (const slice of replayPriced?.priced ?? []) bump(internals.cost.byModel, slice.servedBy, slice.usd);
14841
+ for (const unit of replayPriced?.units ?? []) bump(internals.cost.byModel, unit.servedBy, unit.usd);
14776
14842
  for (const slice of replayPriced?.unpriced ?? []) internals.cost.unpriced.push({
14777
14843
  model: slice.servedBy,
14778
14844
  usage: slice.usage
@@ -15404,6 +15470,7 @@ function createCtx(internals, rootWorkflow) {
15404
15470
  status: result.status,
15405
15471
  usage: result.usage,
15406
15472
  costUsd: result.costUsd,
15473
+ costBasis: result.costBasis,
15407
15474
  entryRef: terminal.seq,
15408
15475
  ...resultUsageApprox ? { usageApprox: true } : {},
15409
15476
  ...result.transportRetries !== void 0 && result.transportRetries > 0 ? { retryCount: result.transportRetries } : {},
@@ -17606,6 +17673,7 @@ function makeOrchestratorWorkflow(goal, opts) {
17606
17673
  cacheWriteTokens: 0
17607
17674
  },
17608
17675
  costUsd: 0,
17676
+ costBasis: "per-call",
17609
17677
  turns: 0,
17610
17678
  servedBy: "unknown:unknown",
17611
17679
  transcriptRef: "",
@@ -18583,6 +18651,7 @@ function makeOrchestratorWorkflow(goal, opts) {
18583
18651
  cacheWriteTokens: 0
18584
18652
  },
18585
18653
  costUsd: 0,
18654
+ costBasis: "per-call",
18586
18655
  turns: 0,
18587
18656
  servedBy: "unknown:unknown",
18588
18657
  transcriptRef: "",
@@ -20355,6 +20424,7 @@ function reduceInvocationTable(events) {
20355
20424
  ...event.label === void 0 ? {} : { label: event.label },
20356
20425
  usage: ZERO,
20357
20426
  costUsd: 0,
20427
+ costBasis: "aggregate-estimate",
20358
20428
  usageApprox: false,
20359
20429
  retryCount: 0,
20360
20430
  replayed: event.replayed === true,
@@ -20381,6 +20451,7 @@ function reduceInvocationTable(events) {
20381
20451
  durationMs: 0,
20382
20452
  usage: ZERO,
20383
20453
  costUsd: 0,
20454
+ costBasis: "aggregate-estimate",
20384
20455
  retries: 0,
20385
20456
  replayed: event.replayed === true,
20386
20457
  open: true
@@ -20400,6 +20471,7 @@ function reduceInvocationTable(events) {
20400
20471
  durationMs: 0,
20401
20472
  usage: ZERO,
20402
20473
  costUsd: 0,
20474
+ costBasis: "aggregate-estimate",
20403
20475
  retries: 0,
20404
20476
  replayed: event.replayed === true,
20405
20477
  open: true
@@ -20413,14 +20485,17 @@ function reduceInvocationTable(events) {
20413
20485
  phase.durationMs = event.durationMs;
20414
20486
  phase.usage = event.usage;
20415
20487
  phase.costUsd = event.costUsd;
20488
+ phase.costBasis = event.costBasis ?? "aggregate-estimate";
20416
20489
  phase.outcome = event.outcome;
20417
20490
  phase.retries = event.retries ?? 0;
20418
20491
  const bucket = byRole[event.role] ??= {
20419
20492
  usage: ZERO,
20420
- costUsd: 0
20493
+ costUsd: 0,
20494
+ costBasis: "per-call"
20421
20495
  };
20422
20496
  bucket.usage = addUsage(bucket.usage, event.usage);
20423
20497
  bucket.costUsd += event.costUsd;
20498
+ if (phase.costBasis === "aggregate-estimate") bucket.costBasis = "aggregate-estimate";
20424
20499
  break;
20425
20500
  }
20426
20501
  case "agent:end": {
@@ -20429,6 +20504,7 @@ function reduceInvocationTable(events) {
20429
20504
  row.status = event.status;
20430
20505
  row.usage = event.usage;
20431
20506
  row.costUsd = event.costUsd;
20507
+ row.costBasis = event.costBasis ?? "aggregate-estimate";
20432
20508
  row.usageApprox = event.usageApprox === true;
20433
20509
  row.retryCount = event.retryCount ?? 0;
20434
20510
  if (event.toolBudget !== void 0) row.toolBudget = event.toolBudget;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rulvar/core",
3
- "version": "1.109.0",
3
+ "version": "1.110.0",
4
4
  "description": "Rulvar core: L0 contracts, journal kernel, ctx primitives, agent runtime, model router, tool system, dynamic orchestrator, InMemory and JSONL stores, event stream.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",