@omnicross/contracts 0.1.1 → 0.1.2

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.
@@ -25,6 +25,18 @@ type SubscriptionLevel = 'Free' | 'Pro' | 'Max';
25
25
  * Token configuration status
26
26
  */
27
27
  type TokenStatus = 'unconfigured' | 'authorized' | 'configured' | 'expired' | 'error';
28
+ /**
29
+ * Machine-readable credential-sync warning code (external-cli-sync).
30
+ *
31
+ * - `external-divergent`: the external CLI's native credential file (e.g.
32
+ * `~/.claude/.credentials.json`) holds a DIFFERENT, fresher credential than
33
+ * the stored account — the stored refresh token may have been rotated out.
34
+ * - `external-not-rotated`: a refresh failed and the external file holds the
35
+ * SAME dead credential — a genuine revocation, re-login is required.
36
+ * - `duplicate-token`: two accounts of one provider share the same credential —
37
+ * refreshing one will invalidate the other (single-use refresh tokens).
38
+ */
39
+ type SyncWarningCode = 'external-divergent' | 'external-not-rotated' | 'duplicate-token';
28
40
  /**
29
41
  * Claude token configuration
30
42
  */
@@ -40,6 +52,9 @@ type ClaudeTokenConfig = {
40
52
  setupTokenExpiresAt?: string;
41
53
  lastRefreshedAt?: string;
42
54
  errorMessage?: string;
55
+ /** Persisted credential-sync warning (external-cli-sync); cleared on a
56
+ * successful refresh / import. */
57
+ syncWarning?: SyncWarningCode;
43
58
  };
44
59
  /**
45
60
  * Codex (OpenAI) token configuration
@@ -56,6 +71,9 @@ type CodexTokenConfig = {
56
71
  organizationId?: string;
57
72
  lastRefreshedAt?: string;
58
73
  errorMessage?: string;
74
+ /** Persisted credential-sync warning (external-cli-sync); cleared on a
75
+ * successful refresh / import. */
76
+ syncWarning?: SyncWarningCode;
59
77
  };
60
78
  /**
61
79
  * Gemini token configuration
@@ -125,6 +143,12 @@ type SubscriptionAccountSanitized = {
125
143
  isSetupToken?: boolean;
126
144
  hasAccessToken: boolean;
127
145
  isActive: boolean;
146
+ /**
147
+ * Credential-sync warning for this account (external-cli-sync). Carries the
148
+ * persisted code when one was recorded by a failed refresh, plus the
149
+ * list-time computed codes (`external-divergent` / `duplicate-token`).
150
+ */
151
+ syncWarning?: SyncWarningCode;
128
152
  };
129
153
  /**
130
154
  * OAuth authorization parameters
@@ -143,4 +167,4 @@ type TokenExchangeRequest = {
143
167
  state: string;
144
168
  };
145
169
 
146
- export type { AccountTokensConfig, AuthMethod, ClaudeAuthMethod, ClaudeTokenConfig, CodexTokenConfig, GeminiTokenConfig, OAuthParams, SubscriptionAccountEntry, SubscriptionAccountSanitized, SubscriptionLevel, TokenExchangeRequest, TokenStatus };
170
+ export type { AccountTokensConfig, AuthMethod, ClaudeAuthMethod, ClaudeTokenConfig, CodexTokenConfig, GeminiTokenConfig, OAuthParams, SubscriptionAccountEntry, SubscriptionAccountSanitized, SubscriptionLevel, SyncWarningCode, TokenExchangeRequest, TokenStatus };
@@ -25,6 +25,18 @@ type SubscriptionLevel = 'Free' | 'Pro' | 'Max';
25
25
  * Token configuration status
26
26
  */
27
27
  type TokenStatus = 'unconfigured' | 'authorized' | 'configured' | 'expired' | 'error';
28
+ /**
29
+ * Machine-readable credential-sync warning code (external-cli-sync).
30
+ *
31
+ * - `external-divergent`: the external CLI's native credential file (e.g.
32
+ * `~/.claude/.credentials.json`) holds a DIFFERENT, fresher credential than
33
+ * the stored account — the stored refresh token may have been rotated out.
34
+ * - `external-not-rotated`: a refresh failed and the external file holds the
35
+ * SAME dead credential — a genuine revocation, re-login is required.
36
+ * - `duplicate-token`: two accounts of one provider share the same credential —
37
+ * refreshing one will invalidate the other (single-use refresh tokens).
38
+ */
39
+ type SyncWarningCode = 'external-divergent' | 'external-not-rotated' | 'duplicate-token';
28
40
  /**
29
41
  * Claude token configuration
30
42
  */
@@ -40,6 +52,9 @@ type ClaudeTokenConfig = {
40
52
  setupTokenExpiresAt?: string;
41
53
  lastRefreshedAt?: string;
42
54
  errorMessage?: string;
55
+ /** Persisted credential-sync warning (external-cli-sync); cleared on a
56
+ * successful refresh / import. */
57
+ syncWarning?: SyncWarningCode;
43
58
  };
44
59
  /**
45
60
  * Codex (OpenAI) token configuration
@@ -56,6 +71,9 @@ type CodexTokenConfig = {
56
71
  organizationId?: string;
57
72
  lastRefreshedAt?: string;
58
73
  errorMessage?: string;
74
+ /** Persisted credential-sync warning (external-cli-sync); cleared on a
75
+ * successful refresh / import. */
76
+ syncWarning?: SyncWarningCode;
59
77
  };
60
78
  /**
61
79
  * Gemini token configuration
@@ -125,6 +143,12 @@ type SubscriptionAccountSanitized = {
125
143
  isSetupToken?: boolean;
126
144
  hasAccessToken: boolean;
127
145
  isActive: boolean;
146
+ /**
147
+ * Credential-sync warning for this account (external-cli-sync). Carries the
148
+ * persisted code when one was recorded by a failed refresh, plus the
149
+ * list-time computed codes (`external-divergent` / `duplicate-token`).
150
+ */
151
+ syncWarning?: SyncWarningCode;
128
152
  };
129
153
  /**
130
154
  * OAuth authorization parameters
@@ -143,4 +167,4 @@ type TokenExchangeRequest = {
143
167
  state: string;
144
168
  };
145
169
 
146
- export type { AccountTokensConfig, AuthMethod, ClaudeAuthMethod, ClaudeTokenConfig, CodexTokenConfig, GeminiTokenConfig, OAuthParams, SubscriptionAccountEntry, SubscriptionAccountSanitized, SubscriptionLevel, TokenExchangeRequest, TokenStatus };
170
+ export type { AccountTokensConfig, AuthMethod, ClaudeAuthMethod, ClaudeTokenConfig, CodexTokenConfig, GeminiTokenConfig, OAuthParams, SubscriptionAccountEntry, SubscriptionAccountSanitized, SubscriptionLevel, SyncWarningCode, TokenExchangeRequest, TokenStatus };
package/dist/index.cjs CHANGED
@@ -24,6 +24,7 @@ __export(index_exports, {
24
24
  CANNOT_DISABLE_THINKING_PATTERNS: () => CANNOT_DISABLE_THINKING_PATTERNS,
25
25
  CATALOG_VERSION: () => CATALOG_VERSION,
26
26
  CODING_PLAN_URL_PRESETS: () => CODING_PLAN_URL_PRESETS,
27
+ DEFAULT_LITELLM_PRICING_URL: () => DEFAULT_LITELLM_PRICING_URL,
27
28
  DEFAULT_MAX_TOKENS: () => DEFAULT_MAX_TOKENS,
28
29
  DEFAULT_MCP_SESSION_CONFIG: () => DEFAULT_MCP_SESSION_CONFIG,
29
30
  DEFAULT_SEED_PRESET_IDS: () => DEFAULT_SEED_PRESET_IDS,
@@ -333,6 +334,9 @@ var DEFAULT_MCP_SESSION_CONFIG = {
333
334
  selectedServers: []
334
335
  };
335
336
 
337
+ // src/pricing-types.ts
338
+ var DEFAULT_LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
339
+
336
340
  // src/provider-presets/catalog.json
337
341
  var catalog_default = {
338
342
  version: 1,
@@ -2683,6 +2687,7 @@ function isLocalProvider(id) {
2683
2687
  CANNOT_DISABLE_THINKING_PATTERNS,
2684
2688
  CATALOG_VERSION,
2685
2689
  CODING_PLAN_URL_PRESETS,
2690
+ DEFAULT_LITELLM_PRICING_URL,
2686
2691
  DEFAULT_MAX_TOKENS,
2687
2692
  DEFAULT_MCP_SESSION_CONFIG,
2688
2693
  DEFAULT_SEED_PRESET_IDS,
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- export { AccountTokensConfig, AuthMethod, ClaudeAuthMethod, ClaudeTokenConfig, CodexTokenConfig, GeminiTokenConfig, OAuthParams, SubscriptionAccountEntry, SubscriptionAccountSanitized, SubscriptionLevel, TokenExchangeRequest, TokenStatus } from './account-tokens-types.cjs';
1
+ export { AccountTokensConfig, AuthMethod, ClaudeAuthMethod, ClaudeTokenConfig, CodexTokenConfig, GeminiTokenConfig, OAuthParams, SubscriptionAccountEntry, SubscriptionAccountSanitized, SubscriptionLevel, SyncWarningCode, TokenExchangeRequest, TokenStatus } from './account-tokens-types.cjs';
2
2
  export { KNOWN_MODELS, KnownModelCapabilities, MODEL_ALIASES, ResolvedModelCapabilities, applyAlias, lookupCanonicalCapabilities, normalizeModelId, resolveModelCapabilities } from './canonical-models.cjs';
3
3
  export { AnthropicAudioContent, AnthropicChatRequest, AnthropicChatResponse, AnthropicContentPart, AnthropicImageContent, AnthropicMessage, AnthropicSystemContent, AnthropicTextContent, AnthropicThinkingContent, AnthropicTool, AnthropicToolResultContent, AnthropicToolUseContent, AnthropicVideoContent, ConversionConfig, OpenAIChatRequest, OpenAIChatResponse, OpenAIContentPart, OpenAIMessage, OpenAIStreamChunk, OpenAITool, OpenAIToolCall, SimpleChatAudio, SimpleChatImage, SimpleChatMessage, SimpleChatSession, SimpleChatVideo } from './completion-types.cjs';
4
4
  export { R as ReasoningConfig, T as ThinkLevel, a as ThinkingContent } from './thinking-CBWSLel8.cjs';
@@ -7,8 +7,10 @@ export { EXTENDED_CONTEXT_CAPABLE_MODELS, isExtendedContextCapable } from './ext
7
7
  export { A as API_MODE_IDS, a as AgentDefaultModels, b as ApiFormat, c as ApiKeyEntry, d as ApiMode, e as ApiModeId, C as ChatApiFormat, f as CodingPlanConfig, g as CompletionSettings, G as GlobalModelParameters, L as LLMProvider, M as ModelConfig, h as ModelGroup, i as ModelParameter, j as ModelRef, O as OpenRouterDataCollection, k as OpenRouterMaxPrice, l as OpenRouterProviderRouting, m as OpenRouterProviderSort, n as OpenRouterQuantization, P as PresetProviderTemplate, o as ProviderApiType, p as ProviderModelMapping, q as ProviderSearchConfig, r as ProviderTemplate, S as SearchCapability, T as TransformerConfig, s as TransformerEntry } from './llm-config-CQjOimv2.cjs';
8
8
  export { DEFAULT_MCP_SESSION_CONFIG, MCPCallToolResponse, MCPTool, MCPToolResponseContent, McpActionResult, McpDiscoverResult, McpMode, McpServerConfig, McpServerInput, McpServerJsonInput, McpServerList, McpServerRecord, McpServerRemoveInput, McpServerScope, McpServerTransport, McpSessionConfig, McpTestResult, McpToolInfo } from './mcp-types.cjs';
9
9
  export { MessageBlock, MessageBlockBase, MessageBlockType, TextBlock, ThinkingBlock, ToolResultBlock, ToolUseBlock } from './message-blocks.cjs';
10
+ export { DEFAULT_LITELLM_PRICING_URL, PricingConflict, PricingConflictDecision, PricingEntry, PricingEntryInput, PricingFetchResult, PricingResolution, PricingSource } from './pricing-types.cjs';
10
11
  export { CATALOG_VERSION, CODING_PLAN_URL_PRESETS, DEFAULT_SEED_PRESET_IDS, LLM_PROVIDER_PRESETS, MAX_CONCURRENCY_DEFAULTS, PROVIDER_MODEL_MAPPINGS, PROVIDER_SEARCH_CONFIGS, getAllProviderPresets, getCodingPlanBaseUrl, getPresetById, getPresetRevision, getProviderSearchConfig, resolveFollowProviderModel } from './provider-presets/index.cjs';
11
12
  export { OpenCodeGoModelEntry, OpenCodeGoScenario, OpenCodeGoTokenConfig, OpenCodeGoTokenSanitized, ProviderChannel, SubscriptionListEntry, SubscriptionProviderId, SubscriptionStatusEntry, legacyCliBackendToSubscriptionProvider, subscriptionTargetForSession } from './subscription-types.cjs';
12
13
  export { CANNOT_DISABLE_THINKING_PATTERNS, DEFAULT_MAX_TOKENS, EFFORT_RATIO, REASONING_MODEL_PATTERNS, THINKING_TOKEN_MAP, buildAnthropicThinking, buildGeminiThinkingConfig, buildQwenThinkingConfig, calculateThinkingBudget, canDisableThinking, findTokenLimit, getClaudeMaxTokens, getOpenAIReasoningEffort, isReasoningModel } from './thinking-config.cjs';
14
+ export { ApiKeyUsageRow, MessageUsageRow, ModelUsageRow, SessionCacheStats, UsageDateRange, UsageEventInput, UsageEventRecord, UsageQueryParams, UsageTotals } from './usage-stats-types.cjs';
13
15
  export { UsageEngineOrigin, UsageTokens } from './usage-types.cjs';
14
16
  export { JinaReaderResponse, WebSearchOptions, WebSearchProviderConfig, WebSearchProviderId, WebSearchProviderType, WebSearchResponse, WebSearchResult, isApiProvider, isLocalProvider } from './websearch-types.cjs';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { AccountTokensConfig, AuthMethod, ClaudeAuthMethod, ClaudeTokenConfig, CodexTokenConfig, GeminiTokenConfig, OAuthParams, SubscriptionAccountEntry, SubscriptionAccountSanitized, SubscriptionLevel, TokenExchangeRequest, TokenStatus } from './account-tokens-types.js';
1
+ export { AccountTokensConfig, AuthMethod, ClaudeAuthMethod, ClaudeTokenConfig, CodexTokenConfig, GeminiTokenConfig, OAuthParams, SubscriptionAccountEntry, SubscriptionAccountSanitized, SubscriptionLevel, SyncWarningCode, TokenExchangeRequest, TokenStatus } from './account-tokens-types.js';
2
2
  export { KNOWN_MODELS, KnownModelCapabilities, MODEL_ALIASES, ResolvedModelCapabilities, applyAlias, lookupCanonicalCapabilities, normalizeModelId, resolveModelCapabilities } from './canonical-models.js';
3
3
  export { AnthropicAudioContent, AnthropicChatRequest, AnthropicChatResponse, AnthropicContentPart, AnthropicImageContent, AnthropicMessage, AnthropicSystemContent, AnthropicTextContent, AnthropicThinkingContent, AnthropicTool, AnthropicToolResultContent, AnthropicToolUseContent, AnthropicVideoContent, ConversionConfig, OpenAIChatRequest, OpenAIChatResponse, OpenAIContentPart, OpenAIMessage, OpenAIStreamChunk, OpenAITool, OpenAIToolCall, SimpleChatAudio, SimpleChatImage, SimpleChatMessage, SimpleChatSession, SimpleChatVideo } from './completion-types.js';
4
4
  export { R as ReasoningConfig, T as ThinkLevel, a as ThinkingContent } from './thinking-CBWSLel8.js';
@@ -7,8 +7,10 @@ export { EXTENDED_CONTEXT_CAPABLE_MODELS, isExtendedContextCapable } from './ext
7
7
  export { A as API_MODE_IDS, a as AgentDefaultModels, b as ApiFormat, c as ApiKeyEntry, d as ApiMode, e as ApiModeId, C as ChatApiFormat, f as CodingPlanConfig, g as CompletionSettings, G as GlobalModelParameters, L as LLMProvider, M as ModelConfig, h as ModelGroup, i as ModelParameter, j as ModelRef, O as OpenRouterDataCollection, k as OpenRouterMaxPrice, l as OpenRouterProviderRouting, m as OpenRouterProviderSort, n as OpenRouterQuantization, P as PresetProviderTemplate, o as ProviderApiType, p as ProviderModelMapping, q as ProviderSearchConfig, r as ProviderTemplate, S as SearchCapability, T as TransformerConfig, s as TransformerEntry } from './llm-config-D1jKQLVp.js';
8
8
  export { DEFAULT_MCP_SESSION_CONFIG, MCPCallToolResponse, MCPTool, MCPToolResponseContent, McpActionResult, McpDiscoverResult, McpMode, McpServerConfig, McpServerInput, McpServerJsonInput, McpServerList, McpServerRecord, McpServerRemoveInput, McpServerScope, McpServerTransport, McpSessionConfig, McpTestResult, McpToolInfo } from './mcp-types.js';
9
9
  export { MessageBlock, MessageBlockBase, MessageBlockType, TextBlock, ThinkingBlock, ToolResultBlock, ToolUseBlock } from './message-blocks.js';
10
+ export { DEFAULT_LITELLM_PRICING_URL, PricingConflict, PricingConflictDecision, PricingEntry, PricingEntryInput, PricingFetchResult, PricingResolution, PricingSource } from './pricing-types.js';
10
11
  export { CATALOG_VERSION, CODING_PLAN_URL_PRESETS, DEFAULT_SEED_PRESET_IDS, LLM_PROVIDER_PRESETS, MAX_CONCURRENCY_DEFAULTS, PROVIDER_MODEL_MAPPINGS, PROVIDER_SEARCH_CONFIGS, getAllProviderPresets, getCodingPlanBaseUrl, getPresetById, getPresetRevision, getProviderSearchConfig, resolveFollowProviderModel } from './provider-presets/index.js';
11
12
  export { OpenCodeGoModelEntry, OpenCodeGoScenario, OpenCodeGoTokenConfig, OpenCodeGoTokenSanitized, ProviderChannel, SubscriptionListEntry, SubscriptionProviderId, SubscriptionStatusEntry, legacyCliBackendToSubscriptionProvider, subscriptionTargetForSession } from './subscription-types.js';
12
13
  export { CANNOT_DISABLE_THINKING_PATTERNS, DEFAULT_MAX_TOKENS, EFFORT_RATIO, REASONING_MODEL_PATTERNS, THINKING_TOKEN_MAP, buildAnthropicThinking, buildGeminiThinkingConfig, buildQwenThinkingConfig, calculateThinkingBudget, canDisableThinking, findTokenLimit, getClaudeMaxTokens, getOpenAIReasoningEffort, isReasoningModel } from './thinking-config.js';
14
+ export { ApiKeyUsageRow, MessageUsageRow, ModelUsageRow, SessionCacheStats, UsageDateRange, UsageEventInput, UsageEventRecord, UsageQueryParams, UsageTotals } from './usage-stats-types.js';
13
15
  export { UsageEngineOrigin, UsageTokens } from './usage-types.js';
14
16
  export { JinaReaderResponse, WebSearchOptions, WebSearchProviderConfig, WebSearchProviderId, WebSearchProviderType, WebSearchResponse, WebSearchResult, isApiProvider, isLocalProvider } from './websearch-types.js';
package/dist/index.js CHANGED
@@ -266,6 +266,9 @@ var DEFAULT_MCP_SESSION_CONFIG = {
266
266
  selectedServers: []
267
267
  };
268
268
 
269
+ // src/pricing-types.ts
270
+ var DEFAULT_LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
271
+
269
272
  // src/provider-presets/catalog.json
270
273
  var catalog_default = {
271
274
  version: 1,
@@ -2615,6 +2618,7 @@ export {
2615
2618
  CANNOT_DISABLE_THINKING_PATTERNS,
2616
2619
  CATALOG_VERSION,
2617
2620
  CODING_PLAN_URL_PRESETS,
2621
+ DEFAULT_LITELLM_PRICING_URL,
2618
2622
  DEFAULT_MAX_TOKENS,
2619
2623
  DEFAULT_MCP_SESSION_CONFIG,
2620
2624
  DEFAULT_SEED_PRESET_IDS,
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/pricing-types.ts
21
+ var pricing_types_exports = {};
22
+ __export(pricing_types_exports, {
23
+ DEFAULT_LITELLM_PRICING_URL: () => DEFAULT_LITELLM_PRICING_URL
24
+ });
25
+ module.exports = __toCommonJS(pricing_types_exports);
26
+ var DEFAULT_LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
27
+ // Annotate the CommonJS export names for ESM import in node:
28
+ 0 && (module.exports = {
29
+ DEFAULT_LITELLM_PRICING_URL
30
+ });
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Model pricing types — provider-generic pricing-table contracts.
3
+ *
4
+ * Pricing rows are keyed by (providerId, modelId) and persisted by the
5
+ * embedding host's own store. The serving core's pricing engine uses them to
6
+ * derive `costUsd` for each captured usage event; hosts may also surface the
7
+ * rows in their own pricing-management UI.
8
+ *
9
+ * @module pricing-types
10
+ */
11
+ /** Where this pricing entry came from. */
12
+ type PricingSource =
13
+ /** Built-in fallback shipped by the host, seeded on first run. */
14
+ 'builtin'
15
+ /** Auto-fetched from the LiteLLM JSON URL. */
16
+ | 'litellm'
17
+ /** Hand-edited by the user; protected from auto-overwrite. */
18
+ | 'user';
19
+ /**
20
+ * Per-model pricing row keyed by (providerId, modelId). Prices are in USD per
21
+ * 1,000,000 tokens. `cache_read` / `cache_write` are optional — providers
22
+ * without prompt caching leave them null.
23
+ */
24
+ interface PricingEntry {
25
+ providerId: string;
26
+ modelId: string;
27
+ inputPricePer1m: number;
28
+ outputPricePer1m: number;
29
+ cacheReadPricePer1m: number | null;
30
+ cacheWritePricePer1m: number | null;
31
+ source: PricingSource;
32
+ /** True when the row has been hand-edited. Protects it from auto-overwrite during a source refresh. */
33
+ userEdited: boolean;
34
+ /** Unix-millis of the most recent user edit, or null if never. */
35
+ editedAt: number | null;
36
+ /** Unix-millis of the most recent write of any kind. */
37
+ updatedAt: number;
38
+ }
39
+ /** Upsert input shape (manual edits and parsed source entries). */
40
+ type PricingEntryInput = {
41
+ providerId: string;
42
+ modelId: string;
43
+ inputPricePer1m: number;
44
+ outputPricePer1m: number;
45
+ cacheReadPricePer1m?: number | null;
46
+ cacheWritePricePer1m?: number | null;
47
+ };
48
+ /** Conflict reported during a source refresh — local row was user-edited. */
49
+ interface PricingConflict {
50
+ providerId: string;
51
+ modelId: string;
52
+ /** Existing row in the local store (before any change). */
53
+ current: PricingEntry;
54
+ /** Incoming row from the pricing source. */
55
+ incoming: PricingEntryInput;
56
+ }
57
+ /** Result of a source refresh. The auto-applied entries are already written. */
58
+ interface PricingFetchResult {
59
+ /** Rows that were upserted automatically (new or non-userEdited). */
60
+ applied: PricingEntry[];
61
+ /** Rows where the local copy is userEdited — surfaced to the UI for resolution. */
62
+ conflicts: PricingConflict[];
63
+ /** When the fetch started (unix-millis). */
64
+ fetchedAt: number;
65
+ /** Source URL that was fetched. */
66
+ sourceUrl: string;
67
+ }
68
+ /** Per-row decision passed back from the host's conflict-resolution UI. */
69
+ interface PricingConflictDecision {
70
+ providerId: string;
71
+ modelId: string;
72
+ action: 'overwrite' | 'skip';
73
+ }
74
+ /** Outcome of resolving a list of conflict decisions. */
75
+ interface PricingResolution {
76
+ /** Number of rows overwritten with the incoming source values. */
77
+ overwrittenCount: number;
78
+ /** Number of rows left unchanged (skipped). */
79
+ skippedCount: number;
80
+ }
81
+ /** Default LiteLLM source URL — public model_prices_and_context_window.json. */
82
+ declare const DEFAULT_LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
83
+
84
+ export { DEFAULT_LITELLM_PRICING_URL, type PricingConflict, type PricingConflictDecision, type PricingEntry, type PricingEntryInput, type PricingFetchResult, type PricingResolution, type PricingSource };
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Model pricing types — provider-generic pricing-table contracts.
3
+ *
4
+ * Pricing rows are keyed by (providerId, modelId) and persisted by the
5
+ * embedding host's own store. The serving core's pricing engine uses them to
6
+ * derive `costUsd` for each captured usage event; hosts may also surface the
7
+ * rows in their own pricing-management UI.
8
+ *
9
+ * @module pricing-types
10
+ */
11
+ /** Where this pricing entry came from. */
12
+ type PricingSource =
13
+ /** Built-in fallback shipped by the host, seeded on first run. */
14
+ 'builtin'
15
+ /** Auto-fetched from the LiteLLM JSON URL. */
16
+ | 'litellm'
17
+ /** Hand-edited by the user; protected from auto-overwrite. */
18
+ | 'user';
19
+ /**
20
+ * Per-model pricing row keyed by (providerId, modelId). Prices are in USD per
21
+ * 1,000,000 tokens. `cache_read` / `cache_write` are optional — providers
22
+ * without prompt caching leave them null.
23
+ */
24
+ interface PricingEntry {
25
+ providerId: string;
26
+ modelId: string;
27
+ inputPricePer1m: number;
28
+ outputPricePer1m: number;
29
+ cacheReadPricePer1m: number | null;
30
+ cacheWritePricePer1m: number | null;
31
+ source: PricingSource;
32
+ /** True when the row has been hand-edited. Protects it from auto-overwrite during a source refresh. */
33
+ userEdited: boolean;
34
+ /** Unix-millis of the most recent user edit, or null if never. */
35
+ editedAt: number | null;
36
+ /** Unix-millis of the most recent write of any kind. */
37
+ updatedAt: number;
38
+ }
39
+ /** Upsert input shape (manual edits and parsed source entries). */
40
+ type PricingEntryInput = {
41
+ providerId: string;
42
+ modelId: string;
43
+ inputPricePer1m: number;
44
+ outputPricePer1m: number;
45
+ cacheReadPricePer1m?: number | null;
46
+ cacheWritePricePer1m?: number | null;
47
+ };
48
+ /** Conflict reported during a source refresh — local row was user-edited. */
49
+ interface PricingConflict {
50
+ providerId: string;
51
+ modelId: string;
52
+ /** Existing row in the local store (before any change). */
53
+ current: PricingEntry;
54
+ /** Incoming row from the pricing source. */
55
+ incoming: PricingEntryInput;
56
+ }
57
+ /** Result of a source refresh. The auto-applied entries are already written. */
58
+ interface PricingFetchResult {
59
+ /** Rows that were upserted automatically (new or non-userEdited). */
60
+ applied: PricingEntry[];
61
+ /** Rows where the local copy is userEdited — surfaced to the UI for resolution. */
62
+ conflicts: PricingConflict[];
63
+ /** When the fetch started (unix-millis). */
64
+ fetchedAt: number;
65
+ /** Source URL that was fetched. */
66
+ sourceUrl: string;
67
+ }
68
+ /** Per-row decision passed back from the host's conflict-resolution UI. */
69
+ interface PricingConflictDecision {
70
+ providerId: string;
71
+ modelId: string;
72
+ action: 'overwrite' | 'skip';
73
+ }
74
+ /** Outcome of resolving a list of conflict decisions. */
75
+ interface PricingResolution {
76
+ /** Number of rows overwritten with the incoming source values. */
77
+ overwrittenCount: number;
78
+ /** Number of rows left unchanged (skipped). */
79
+ skippedCount: number;
80
+ }
81
+ /** Default LiteLLM source URL — public model_prices_and_context_window.json. */
82
+ declare const DEFAULT_LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
83
+
84
+ export { DEFAULT_LITELLM_PRICING_URL, type PricingConflict, type PricingConflictDecision, type PricingEntry, type PricingEntryInput, type PricingFetchResult, type PricingResolution, type PricingSource };
@@ -0,0 +1,5 @@
1
+ // src/pricing-types.ts
2
+ var DEFAULT_LITELLM_PRICING_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
3
+ export {
4
+ DEFAULT_LITELLM_PRICING_URL
5
+ };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/usage-stats-types.ts
17
+ var usage_stats_types_exports = {};
18
+ module.exports = __toCommonJS(usage_stats_types_exports);
@@ -0,0 +1,143 @@
1
+ import { UsageEngineOrigin } from './usage-types.cjs';
2
+
3
+ /**
4
+ * Usage-statistics DTOs — provider-generic stats row + aggregation views.
5
+ *
6
+ * The persisted usage-event row shape and the aggregate query views shared by
7
+ * embedders that record per-request usage. Storage itself is host-owned (the
8
+ * serving core only defines the seam); `engineOrigin` uses the OPEN
9
+ * `UsageEngineOrigin` union from `usage-types` so hosts may narrow it to their
10
+ * own closed engine list at their boundary.
11
+ *
12
+ * @module usage-stats-types
13
+ */
14
+
15
+ /**
16
+ * One captured LLM request, as persisted by the host store.
17
+ *
18
+ * `messageId` is nullable because indirect call paths (e.g. subagent-internal
19
+ * requests) may not map to a host message row. `parentMessageId` is
20
+ * best-effort — populated when the caller knows the parent, NULL otherwise.
21
+ */
22
+ interface UsageEventRecord {
23
+ id: string;
24
+ ts: number;
25
+ messageId: string | null;
26
+ parentMessageId: string | null;
27
+ sessionId: string | null;
28
+ providerId: string;
29
+ model: string;
30
+ apiKeyId: string | null;
31
+ engineOrigin: UsageEngineOrigin;
32
+ inputTokens: number;
33
+ outputTokens: number;
34
+ cacheReadTokens: number;
35
+ cacheCreationTokens: number;
36
+ reasoningTokens: number;
37
+ costUsd: number;
38
+ /** Hypothetical-input-cost − actual-cost difference attributable to cache_read tokens. */
39
+ costSavedByCacheUsd: number;
40
+ /** JSON-serialised raw provider usage object. Kept for forensics. */
41
+ rawUsage: string | null;
42
+ /** Host run-correlation id (owning agent-run, when the host has one). Additive / nullable. */
43
+ runId?: string | null;
44
+ /** Host event-correlation id for this LLM call. NULL when unknown. Additive / nullable. */
45
+ eventId?: string | null;
46
+ }
47
+ /** Input shape for inserting a new event. `id` and `ts` are filled by the recorder/store. */
48
+ type UsageEventInput = Omit<UsageEventRecord, 'id' | 'ts'> & {
49
+ ts?: number;
50
+ };
51
+ /** Date range for queries. Both bounds are unix-millis; `endTs` is exclusive. */
52
+ interface UsageDateRange {
53
+ startTs: number;
54
+ endTs: number;
55
+ }
56
+ interface UsageQueryParams {
57
+ range: UsageDateRange;
58
+ /** Optional filter — restrict to a particular session. */
59
+ sessionId?: string;
60
+ }
61
+ /** Aggregated totals over a date range. */
62
+ interface UsageTotals {
63
+ inputTokens: number;
64
+ outputTokens: number;
65
+ cacheReadTokens: number;
66
+ cacheCreationTokens: number;
67
+ reasoningTokens: number;
68
+ costUsd: number;
69
+ costSavedByCacheUsd: number;
70
+ /** Number of events contributing to these totals. */
71
+ eventCount: number;
72
+ }
73
+ /** One row of the per-model breakdown. */
74
+ interface ModelUsageRow {
75
+ providerId: string;
76
+ model: string;
77
+ eventCount: number;
78
+ inputTokens: number;
79
+ outputTokens: number;
80
+ cacheReadTokens: number;
81
+ cacheCreationTokens: number;
82
+ costUsd: number;
83
+ costSavedByCacheUsd: number;
84
+ /** True when no pricing row exists for (providerId, model) — UIs may show an "unpriced" badge. */
85
+ unpriced: boolean;
86
+ }
87
+ /** One row of the per-API-key breakdown. NULL apiKeyId is mapped to a sentinel. */
88
+ interface ApiKeyUsageRow {
89
+ /** `null` represents the unattributed sentinel group. */
90
+ apiKeyId: string | null;
91
+ /** Display label resolved by the host store (its key registry, or an "unattributed" fallback). */
92
+ label: string;
93
+ providerId: string | null;
94
+ eventCount: number;
95
+ inputTokens: number;
96
+ outputTokens: number;
97
+ costUsd: number;
98
+ }
99
+ /**
100
+ * Cumulative cache stats for ONE session — a SUM over the session's usage
101
+ * events. `hitRate` is the cost-oriented aggregate `ΣcacheRead / Σ(prompt-side
102
+ * tokens)` where the prompt-side total is `input + cacheRead + cacheCreation`
103
+ * (output excluded).
104
+ */
105
+ interface SessionCacheStats {
106
+ sessionId: string;
107
+ /** Σ uncached prompt tokens (cache miss). */
108
+ inputTokens: number;
109
+ /** Σ cache-read (hit) tokens. */
110
+ cacheReadTokens: number;
111
+ /** Σ cache-creation (write) tokens — Anthropic; 0 for auto-caching providers. */
112
+ cacheCreationTokens: number;
113
+ /** Σ output tokens (not part of the hit-rate denominator). */
114
+ outputTokens: number;
115
+ /** Number of usage-event rows for the session. */
116
+ eventCount: number;
117
+ /**
118
+ * ΣcacheRead / Σ(input + cacheRead + cacheCreation), in [0, 1]. 0 when the
119
+ * session has no prompt-side tokens yet (avoids divide-by-zero).
120
+ */
121
+ hitRate: number;
122
+ }
123
+ /** One row in the message-level list (used by message-drilldown UI components). */
124
+ interface MessageUsageRow {
125
+ id: string;
126
+ ts: number;
127
+ messageId: string | null;
128
+ parentMessageId: string | null;
129
+ sessionId: string | null;
130
+ providerId: string;
131
+ model: string;
132
+ apiKeyId: string | null;
133
+ engineOrigin: UsageEngineOrigin;
134
+ inputTokens: number;
135
+ outputTokens: number;
136
+ cacheReadTokens: number;
137
+ cacheCreationTokens: number;
138
+ reasoningTokens: number;
139
+ costUsd: number;
140
+ costSavedByCacheUsd: number;
141
+ }
142
+
143
+ export type { ApiKeyUsageRow, MessageUsageRow, ModelUsageRow, SessionCacheStats, UsageDateRange, UsageEventInput, UsageEventRecord, UsageQueryParams, UsageTotals };
@@ -0,0 +1,143 @@
1
+ import { UsageEngineOrigin } from './usage-types.js';
2
+
3
+ /**
4
+ * Usage-statistics DTOs — provider-generic stats row + aggregation views.
5
+ *
6
+ * The persisted usage-event row shape and the aggregate query views shared by
7
+ * embedders that record per-request usage. Storage itself is host-owned (the
8
+ * serving core only defines the seam); `engineOrigin` uses the OPEN
9
+ * `UsageEngineOrigin` union from `usage-types` so hosts may narrow it to their
10
+ * own closed engine list at their boundary.
11
+ *
12
+ * @module usage-stats-types
13
+ */
14
+
15
+ /**
16
+ * One captured LLM request, as persisted by the host store.
17
+ *
18
+ * `messageId` is nullable because indirect call paths (e.g. subagent-internal
19
+ * requests) may not map to a host message row. `parentMessageId` is
20
+ * best-effort — populated when the caller knows the parent, NULL otherwise.
21
+ */
22
+ interface UsageEventRecord {
23
+ id: string;
24
+ ts: number;
25
+ messageId: string | null;
26
+ parentMessageId: string | null;
27
+ sessionId: string | null;
28
+ providerId: string;
29
+ model: string;
30
+ apiKeyId: string | null;
31
+ engineOrigin: UsageEngineOrigin;
32
+ inputTokens: number;
33
+ outputTokens: number;
34
+ cacheReadTokens: number;
35
+ cacheCreationTokens: number;
36
+ reasoningTokens: number;
37
+ costUsd: number;
38
+ /** Hypothetical-input-cost − actual-cost difference attributable to cache_read tokens. */
39
+ costSavedByCacheUsd: number;
40
+ /** JSON-serialised raw provider usage object. Kept for forensics. */
41
+ rawUsage: string | null;
42
+ /** Host run-correlation id (owning agent-run, when the host has one). Additive / nullable. */
43
+ runId?: string | null;
44
+ /** Host event-correlation id for this LLM call. NULL when unknown. Additive / nullable. */
45
+ eventId?: string | null;
46
+ }
47
+ /** Input shape for inserting a new event. `id` and `ts` are filled by the recorder/store. */
48
+ type UsageEventInput = Omit<UsageEventRecord, 'id' | 'ts'> & {
49
+ ts?: number;
50
+ };
51
+ /** Date range for queries. Both bounds are unix-millis; `endTs` is exclusive. */
52
+ interface UsageDateRange {
53
+ startTs: number;
54
+ endTs: number;
55
+ }
56
+ interface UsageQueryParams {
57
+ range: UsageDateRange;
58
+ /** Optional filter — restrict to a particular session. */
59
+ sessionId?: string;
60
+ }
61
+ /** Aggregated totals over a date range. */
62
+ interface UsageTotals {
63
+ inputTokens: number;
64
+ outputTokens: number;
65
+ cacheReadTokens: number;
66
+ cacheCreationTokens: number;
67
+ reasoningTokens: number;
68
+ costUsd: number;
69
+ costSavedByCacheUsd: number;
70
+ /** Number of events contributing to these totals. */
71
+ eventCount: number;
72
+ }
73
+ /** One row of the per-model breakdown. */
74
+ interface ModelUsageRow {
75
+ providerId: string;
76
+ model: string;
77
+ eventCount: number;
78
+ inputTokens: number;
79
+ outputTokens: number;
80
+ cacheReadTokens: number;
81
+ cacheCreationTokens: number;
82
+ costUsd: number;
83
+ costSavedByCacheUsd: number;
84
+ /** True when no pricing row exists for (providerId, model) — UIs may show an "unpriced" badge. */
85
+ unpriced: boolean;
86
+ }
87
+ /** One row of the per-API-key breakdown. NULL apiKeyId is mapped to a sentinel. */
88
+ interface ApiKeyUsageRow {
89
+ /** `null` represents the unattributed sentinel group. */
90
+ apiKeyId: string | null;
91
+ /** Display label resolved by the host store (its key registry, or an "unattributed" fallback). */
92
+ label: string;
93
+ providerId: string | null;
94
+ eventCount: number;
95
+ inputTokens: number;
96
+ outputTokens: number;
97
+ costUsd: number;
98
+ }
99
+ /**
100
+ * Cumulative cache stats for ONE session — a SUM over the session's usage
101
+ * events. `hitRate` is the cost-oriented aggregate `ΣcacheRead / Σ(prompt-side
102
+ * tokens)` where the prompt-side total is `input + cacheRead + cacheCreation`
103
+ * (output excluded).
104
+ */
105
+ interface SessionCacheStats {
106
+ sessionId: string;
107
+ /** Σ uncached prompt tokens (cache miss). */
108
+ inputTokens: number;
109
+ /** Σ cache-read (hit) tokens. */
110
+ cacheReadTokens: number;
111
+ /** Σ cache-creation (write) tokens — Anthropic; 0 for auto-caching providers. */
112
+ cacheCreationTokens: number;
113
+ /** Σ output tokens (not part of the hit-rate denominator). */
114
+ outputTokens: number;
115
+ /** Number of usage-event rows for the session. */
116
+ eventCount: number;
117
+ /**
118
+ * ΣcacheRead / Σ(input + cacheRead + cacheCreation), in [0, 1]. 0 when the
119
+ * session has no prompt-side tokens yet (avoids divide-by-zero).
120
+ */
121
+ hitRate: number;
122
+ }
123
+ /** One row in the message-level list (used by message-drilldown UI components). */
124
+ interface MessageUsageRow {
125
+ id: string;
126
+ ts: number;
127
+ messageId: string | null;
128
+ parentMessageId: string | null;
129
+ sessionId: string | null;
130
+ providerId: string;
131
+ model: string;
132
+ apiKeyId: string | null;
133
+ engineOrigin: UsageEngineOrigin;
134
+ inputTokens: number;
135
+ outputTokens: number;
136
+ cacheReadTokens: number;
137
+ cacheCreationTokens: number;
138
+ reasoningTokens: number;
139
+ costUsd: number;
140
+ costSavedByCacheUsd: number;
141
+ }
142
+
143
+ export type { ApiKeyUsageRow, MessageUsageRow, ModelUsageRow, SessionCacheStats, UsageDateRange, UsageEventInput, UsageEventRecord, UsageQueryParams, UsageTotals };
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omnicross/contracts",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Dependency-light, host-agnostic contract types + runtime-value helpers shared by the @omnicross/* packages.",
5
5
  "license": "MIT",
6
6
  "author": "Sayo (https://github.com/Dumoedss)",
@@ -75,6 +75,11 @@
75
75
  "import": "./dist/message-blocks.js",
76
76
  "require": "./dist/message-blocks.cjs"
77
77
  },
78
+ "./pricing-types": {
79
+ "types": "./dist/pricing-types.d.ts",
80
+ "import": "./dist/pricing-types.js",
81
+ "require": "./dist/pricing-types.cjs"
82
+ },
78
83
  "./provider-presets": {
79
84
  "types": "./dist/provider-presets/index.d.ts",
80
85
  "import": "./dist/provider-presets/index.js",
@@ -90,6 +95,11 @@
90
95
  "import": "./dist/thinking-config.js",
91
96
  "require": "./dist/thinking-config.cjs"
92
97
  },
98
+ "./usage-stats-types": {
99
+ "types": "./dist/usage-stats-types.d.ts",
100
+ "import": "./dist/usage-stats-types.js",
101
+ "require": "./dist/usage-stats-types.cjs"
102
+ },
93
103
  "./usage-types": {
94
104
  "types": "./dist/usage-types.d.ts",
95
105
  "import": "./dist/usage-types.js",