graphile-llm 0.7.3 → 0.9.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/__tests__/graphile-llm.test.js +87 -71
- package/chat.d.ts +5 -5
- package/chat.js +45 -43
- package/config-cache.d.ts +77 -0
- package/config-cache.js +148 -0
- package/embedder.d.ts +5 -5
- package/embedder.js +11 -17
- package/env.d.ts +31 -0
- package/env.js +52 -0
- package/esm/__tests__/graphile-llm.test.js +87 -71
- package/esm/chat.d.ts +5 -5
- package/esm/chat.js +45 -40
- package/esm/config-cache.d.ts +77 -0
- package/esm/config-cache.js +143 -0
- package/esm/embedder.d.ts +5 -5
- package/esm/embedder.js +11 -17
- package/esm/env.d.ts +31 -0
- package/esm/env.js +49 -0
- package/esm/index.d.ts +14 -5
- package/esm/index.js +11 -5
- package/esm/metering.d.ts +114 -0
- package/esm/metering.js +352 -0
- package/esm/plugins/agent-discovery-plugin.d.ts +29 -0
- package/esm/plugins/agent-discovery-plugin.js +65 -0
- package/esm/plugins/llm-module-plugin.d.ts +11 -2
- package/esm/plugins/llm-module-plugin.js +15 -7
- package/esm/plugins/metering-plugin.d.ts +42 -0
- package/esm/plugins/metering-plugin.js +175 -0
- package/esm/plugins/rag-plugin.js +20 -20
- package/esm/plugins/text-mutation-plugin.d.ts +4 -0
- package/esm/plugins/text-mutation-plugin.js +23 -13
- package/esm/plugins/text-search-plugin.d.ts +4 -0
- package/esm/plugins/text-search-plugin.js +23 -11
- package/esm/preset.d.ts +21 -1
- package/esm/preset.js +33 -6
- package/esm/types.d.ts +86 -10
- package/index.d.ts +14 -5
- package/index.js +25 -8
- package/metering.d.ts +114 -0
- package/metering.js +359 -0
- package/package.json +15 -15
- package/plugins/agent-discovery-plugin.d.ts +29 -0
- package/plugins/agent-discovery-plugin.js +69 -0
- package/plugins/llm-module-plugin.d.ts +11 -2
- package/plugins/llm-module-plugin.js +15 -7
- package/plugins/metering-plugin.d.ts +42 -0
- package/plugins/metering-plugin.js +178 -0
- package/plugins/rag-plugin.js +20 -20
- package/plugins/text-mutation-plugin.d.ts +4 -0
- package/plugins/text-mutation-plugin.js +23 -13
- package/plugins/text-search-plugin.d.ts +4 -0
- package/plugins/text-search-plugin.js +23 -11
- package/preset.d.ts +21 -1
- package/preset.js +33 -6
- package/types.d.ts +86 -10
package/esm/types.d.ts
CHANGED
|
@@ -4,9 +4,18 @@
|
|
|
4
4
|
* Shared type definitions for the LLM plugin.
|
|
5
5
|
*/
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
7
|
+
* Result from an embedding call, including real token usage from the provider.
|
|
8
8
|
*/
|
|
9
|
-
export
|
|
9
|
+
export interface EmbeddingResult {
|
|
10
|
+
/** The vector embedding */
|
|
11
|
+
embedding: number[];
|
|
12
|
+
/** Number of prompt tokens consumed (from provider; 0 if unavailable) */
|
|
13
|
+
promptTokens: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A function that converts text into a vector embedding with token usage.
|
|
17
|
+
*/
|
|
18
|
+
export type EmbedderFunction = (text: string) => Promise<EmbeddingResult>;
|
|
10
19
|
/**
|
|
11
20
|
* Configuration for an embedding provider.
|
|
12
21
|
*/
|
|
@@ -17,8 +26,24 @@ export interface EmbedderConfig {
|
|
|
17
26
|
model?: string;
|
|
18
27
|
/** Base URL for the provider (e.g. 'http://localhost:11434' for Ollama) */
|
|
19
28
|
baseUrl?: string;
|
|
20
|
-
|
|
21
|
-
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Token usage metadata returned by LLM providers.
|
|
32
|
+
* Maps to the billing schema's inference_log columns.
|
|
33
|
+
*/
|
|
34
|
+
export interface LlmUsage {
|
|
35
|
+
/** Prompt / input tokens consumed */
|
|
36
|
+
input: number;
|
|
37
|
+
/** Completion / output tokens generated (includes reasoning for providers that count it) */
|
|
38
|
+
output: number;
|
|
39
|
+
/** Reasoning tokens (subset of output — not additive) */
|
|
40
|
+
reasoning: number;
|
|
41
|
+
/** Tokens served from prompt cache (zero cost) */
|
|
42
|
+
cacheRead: number;
|
|
43
|
+
/** Tokens written to prompt cache */
|
|
44
|
+
cacheWrite: number;
|
|
45
|
+
/** input + output + cacheRead + cacheWrite */
|
|
46
|
+
totalTokens: number;
|
|
22
47
|
}
|
|
23
48
|
/**
|
|
24
49
|
* A single message in a chat conversation.
|
|
@@ -37,9 +62,17 @@ export interface ChatOptions {
|
|
|
37
62
|
temperature?: number;
|
|
38
63
|
}
|
|
39
64
|
/**
|
|
40
|
-
*
|
|
65
|
+
* Result from a chat completion call, including real token usage.
|
|
41
66
|
*/
|
|
42
|
-
export
|
|
67
|
+
export interface ChatResult {
|
|
68
|
+
content: string;
|
|
69
|
+
usage: LlmUsage;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* A function that sends messages to a chat completion provider
|
|
73
|
+
* and returns the response with token usage metadata.
|
|
74
|
+
*/
|
|
75
|
+
export type ChatFunction = (messages: ChatMessage[], options?: ChatOptions) => Promise<ChatResult>;
|
|
43
76
|
/**
|
|
44
77
|
* Configuration for a chat completion provider.
|
|
45
78
|
*/
|
|
@@ -50,8 +83,6 @@ export interface ChatConfig {
|
|
|
50
83
|
model?: string;
|
|
51
84
|
/** Base URL for the provider */
|
|
52
85
|
baseUrl?: string;
|
|
53
|
-
/** API key for providers that require authentication */
|
|
54
|
-
apiKey?: string;
|
|
55
86
|
}
|
|
56
87
|
/**
|
|
57
88
|
* The shape of the `llm_module` data stored in `services_public.api_modules`.
|
|
@@ -74,8 +105,6 @@ export interface LlmModuleData {
|
|
|
74
105
|
chat_model?: string;
|
|
75
106
|
/** Base URL for the chat provider */
|
|
76
107
|
chat_base_url?: string;
|
|
77
|
-
/** API key reference (e.g. 'vault://openai-key' or env var name) */
|
|
78
|
-
api_key_ref?: string;
|
|
79
108
|
/** Rate limit: requests per minute */
|
|
80
109
|
rate_limit_rpm?: number;
|
|
81
110
|
/** Maximum tokens per request */
|
|
@@ -131,6 +160,41 @@ export interface ChunkTableInfo {
|
|
|
131
160
|
/** Text content column on chunks table (the actual chunk text) */
|
|
132
161
|
contentField: string;
|
|
133
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Configuration for billing/metering integration.
|
|
165
|
+
* When provided, embedding and chat calls are wrapped with quota checks
|
|
166
|
+
* and usage recording via the billing_module functions.
|
|
167
|
+
*/
|
|
168
|
+
export interface MeteringConfig {
|
|
169
|
+
/**
|
|
170
|
+
* Meter slug for embedding operations.
|
|
171
|
+
* Must match a slug in the billing_module meters table.
|
|
172
|
+
*
|
|
173
|
+
* @default the embedding model name (e.g. 'text-embedding-3-small')
|
|
174
|
+
* — meter slug = model name, so each model has its own meter
|
|
175
|
+
* in the three-level waterfall (per-model → inference pool → universal).
|
|
176
|
+
*/
|
|
177
|
+
embeddingMeterSlug?: string;
|
|
178
|
+
/**
|
|
179
|
+
* Meter slug for chat completion operations.
|
|
180
|
+
*
|
|
181
|
+
* @default the chat model name (e.g. 'gpt-4o-mini')
|
|
182
|
+
*/
|
|
183
|
+
chatMeterSlug?: string;
|
|
184
|
+
/**
|
|
185
|
+
* Disable metering entirely (e.g. for local dev).
|
|
186
|
+
* When true, billing functions are never called.
|
|
187
|
+
* @default false
|
|
188
|
+
*/
|
|
189
|
+
skipMetering?: boolean;
|
|
190
|
+
/**
|
|
191
|
+
* Resolve the billing entity_id from pgSettings.
|
|
192
|
+
* The entity_id identifies who gets billed (user, org, etc.).
|
|
193
|
+
*
|
|
194
|
+
* @default reads jwt.claims.user_id
|
|
195
|
+
*/
|
|
196
|
+
resolveEntityId?: (pgSettings: Record<string, string>) => string | null;
|
|
197
|
+
}
|
|
134
198
|
/**
|
|
135
199
|
* Options for the GraphileLlmPreset.
|
|
136
200
|
*/
|
|
@@ -170,4 +234,16 @@ export interface GraphileLlmOptions {
|
|
|
170
234
|
* Individual queries can override these values.
|
|
171
235
|
*/
|
|
172
236
|
ragDefaults?: RagDefaults;
|
|
237
|
+
/**
|
|
238
|
+
* Billing/metering configuration (opt-in).
|
|
239
|
+
* When truthy, loads the LlmMeteringPlugin which wraps the embedder
|
|
240
|
+
* with billing quota checks + usage recording.
|
|
241
|
+
*
|
|
242
|
+
* Set to `true` to enable metering with defaults (entity_id from jwt.claims.user_id).
|
|
243
|
+
* Provide a MeteringConfig object for fine-grained control (custom entity_id, meter slugs).
|
|
244
|
+
* Set to `false` or omit to disable metering entirely.
|
|
245
|
+
*
|
|
246
|
+
* @default undefined (metering disabled)
|
|
247
|
+
*/
|
|
248
|
+
metering?: boolean | MeteringConfig;
|
|
173
249
|
}
|
package/index.d.ts
CHANGED
|
@@ -29,11 +29,20 @@
|
|
|
29
29
|
* };
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
|
+
export type { LlmEnvOptions, LlmProviderConfig } from './env';
|
|
33
|
+
export { getLlmEnvOptions } from './env';
|
|
32
34
|
export { GraphileLlmPreset } from './preset';
|
|
33
35
|
export { createLlmModulePlugin } from './plugins/llm-module-plugin';
|
|
34
|
-
export { createLlmTextSearchPlugin } from './plugins/text-search-plugin';
|
|
35
|
-
export { createLlmTextMutationPlugin } from './plugins/text-mutation-plugin';
|
|
36
36
|
export { createLlmRagPlugin } from './plugins/rag-plugin';
|
|
37
|
-
export {
|
|
38
|
-
export {
|
|
39
|
-
export
|
|
37
|
+
export { createLlmTextMutationPlugin } from './plugins/text-mutation-plugin';
|
|
38
|
+
export { createLlmTextSearchPlugin } from './plugins/text-search-plugin';
|
|
39
|
+
export { createLlmMeteringPlugin } from './plugins/metering-plugin';
|
|
40
|
+
export type { AgentDiscovery, AgentTableInfo } from './plugins/agent-discovery-plugin';
|
|
41
|
+
export { clearAgentDiscoveryCache, getAgentDiscovery } from './plugins/agent-discovery-plugin';
|
|
42
|
+
export { buildEmbedder, buildEmbedderFromEnv, buildEmbedderFromModule } from './embedder';
|
|
43
|
+
export { buildChatCompleter, buildChatCompleterFromEnv, buildChatCompleterFromModule } from './chat';
|
|
44
|
+
export type { InferenceLogEntry, MeteringContext, MeteringOptions, MeterResult, WithPgClient } from './metering';
|
|
45
|
+
export { logInferenceUsage, meteredChat, meteredEmbed, QuotaExceededError } from './metering';
|
|
46
|
+
export type { BillingConfig, InferenceLogConfig, LlmBillingCacheEntry, PgClient } from './config-cache';
|
|
47
|
+
export { getLlmBillingCacheStats, getLlmBillingConfig, invalidateLlmBillingConfig } from './config-cache';
|
|
48
|
+
export type { ChatConfig, ChatFunction, ChatMessage, ChatOptions, ChatResult, ChunkTableInfo, EmbedderConfig, EmbedderFunction, EmbeddingResult, GraphileLlmOptions, LlmModuleData, LlmUsage, MeteringConfig, RagDefaults } from './types';
|
package/index.js
CHANGED
|
@@ -31,26 +31,43 @@
|
|
|
31
31
|
* ```
|
|
32
32
|
*/
|
|
33
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
-
exports.
|
|
34
|
+
exports.invalidateLlmBillingConfig = exports.getLlmBillingConfig = exports.getLlmBillingCacheStats = exports.QuotaExceededError = exports.meteredEmbed = exports.meteredChat = exports.logInferenceUsage = exports.buildChatCompleterFromModule = exports.buildChatCompleterFromEnv = exports.buildChatCompleter = exports.buildEmbedderFromModule = exports.buildEmbedderFromEnv = exports.buildEmbedder = exports.getAgentDiscovery = exports.clearAgentDiscoveryCache = exports.createLlmMeteringPlugin = exports.createLlmTextSearchPlugin = exports.createLlmTextMutationPlugin = exports.createLlmRagPlugin = exports.createLlmModulePlugin = exports.GraphileLlmPreset = exports.getLlmEnvOptions = void 0;
|
|
35
|
+
var env_1 = require("./env");
|
|
36
|
+
Object.defineProperty(exports, "getLlmEnvOptions", { enumerable: true, get: function () { return env_1.getLlmEnvOptions; } });
|
|
35
37
|
// Preset (recommended entry point)
|
|
36
38
|
var preset_1 = require("./preset");
|
|
37
39
|
Object.defineProperty(exports, "GraphileLlmPreset", { enumerable: true, get: function () { return preset_1.GraphileLlmPreset; } });
|
|
38
|
-
// Individual plugins
|
|
40
|
+
// Individual plugins (pure — no billing dependency)
|
|
39
41
|
var llm_module_plugin_1 = require("./plugins/llm-module-plugin");
|
|
40
42
|
Object.defineProperty(exports, "createLlmModulePlugin", { enumerable: true, get: function () { return llm_module_plugin_1.createLlmModulePlugin; } });
|
|
41
|
-
var text_search_plugin_1 = require("./plugins/text-search-plugin");
|
|
42
|
-
Object.defineProperty(exports, "createLlmTextSearchPlugin", { enumerable: true, get: function () { return text_search_plugin_1.createLlmTextSearchPlugin; } });
|
|
43
|
-
var text_mutation_plugin_1 = require("./plugins/text-mutation-plugin");
|
|
44
|
-
Object.defineProperty(exports, "createLlmTextMutationPlugin", { enumerable: true, get: function () { return text_mutation_plugin_1.createLlmTextMutationPlugin; } });
|
|
45
43
|
var rag_plugin_1 = require("./plugins/rag-plugin");
|
|
46
44
|
Object.defineProperty(exports, "createLlmRagPlugin", { enumerable: true, get: function () { return rag_plugin_1.createLlmRagPlugin; } });
|
|
45
|
+
var text_mutation_plugin_1 = require("./plugins/text-mutation-plugin");
|
|
46
|
+
Object.defineProperty(exports, "createLlmTextMutationPlugin", { enumerable: true, get: function () { return text_mutation_plugin_1.createLlmTextMutationPlugin; } });
|
|
47
|
+
var text_search_plugin_1 = require("./plugins/text-search-plugin");
|
|
48
|
+
Object.defineProperty(exports, "createLlmTextSearchPlugin", { enumerable: true, get: function () { return text_search_plugin_1.createLlmTextSearchPlugin; } });
|
|
49
|
+
// Metering plugin (opt-in billing integration)
|
|
50
|
+
var metering_plugin_1 = require("./plugins/metering-plugin");
|
|
51
|
+
Object.defineProperty(exports, "createLlmMeteringPlugin", { enumerable: true, get: function () { return metering_plugin_1.createLlmMeteringPlugin; } });
|
|
52
|
+
var agent_discovery_plugin_1 = require("./plugins/agent-discovery-plugin");
|
|
53
|
+
Object.defineProperty(exports, "clearAgentDiscoveryCache", { enumerable: true, get: function () { return agent_discovery_plugin_1.clearAgentDiscoveryCache; } });
|
|
54
|
+
Object.defineProperty(exports, "getAgentDiscovery", { enumerable: true, get: function () { return agent_discovery_plugin_1.getAgentDiscovery; } });
|
|
47
55
|
// Embedder utilities
|
|
48
56
|
var embedder_1 = require("./embedder");
|
|
49
57
|
Object.defineProperty(exports, "buildEmbedder", { enumerable: true, get: function () { return embedder_1.buildEmbedder; } });
|
|
50
|
-
Object.defineProperty(exports, "buildEmbedderFromModule", { enumerable: true, get: function () { return embedder_1.buildEmbedderFromModule; } });
|
|
51
58
|
Object.defineProperty(exports, "buildEmbedderFromEnv", { enumerable: true, get: function () { return embedder_1.buildEmbedderFromEnv; } });
|
|
59
|
+
Object.defineProperty(exports, "buildEmbedderFromModule", { enumerable: true, get: function () { return embedder_1.buildEmbedderFromModule; } });
|
|
52
60
|
// Chat completion utilities
|
|
53
61
|
var chat_1 = require("./chat");
|
|
54
62
|
Object.defineProperty(exports, "buildChatCompleter", { enumerable: true, get: function () { return chat_1.buildChatCompleter; } });
|
|
55
|
-
Object.defineProperty(exports, "buildChatCompleterFromModule", { enumerable: true, get: function () { return chat_1.buildChatCompleterFromModule; } });
|
|
56
63
|
Object.defineProperty(exports, "buildChatCompleterFromEnv", { enumerable: true, get: function () { return chat_1.buildChatCompleterFromEnv; } });
|
|
64
|
+
Object.defineProperty(exports, "buildChatCompleterFromModule", { enumerable: true, get: function () { return chat_1.buildChatCompleterFromModule; } });
|
|
65
|
+
var metering_1 = require("./metering");
|
|
66
|
+
Object.defineProperty(exports, "logInferenceUsage", { enumerable: true, get: function () { return metering_1.logInferenceUsage; } });
|
|
67
|
+
Object.defineProperty(exports, "meteredChat", { enumerable: true, get: function () { return metering_1.meteredChat; } });
|
|
68
|
+
Object.defineProperty(exports, "meteredEmbed", { enumerable: true, get: function () { return metering_1.meteredEmbed; } });
|
|
69
|
+
Object.defineProperty(exports, "QuotaExceededError", { enumerable: true, get: function () { return metering_1.QuotaExceededError; } });
|
|
70
|
+
var config_cache_1 = require("./config-cache");
|
|
71
|
+
Object.defineProperty(exports, "getLlmBillingCacheStats", { enumerable: true, get: function () { return config_cache_1.getLlmBillingCacheStats; } });
|
|
72
|
+
Object.defineProperty(exports, "getLlmBillingConfig", { enumerable: true, get: function () { return config_cache_1.getLlmBillingConfig; } });
|
|
73
|
+
Object.defineProperty(exports, "invalidateLlmBillingConfig", { enumerable: true, get: function () { return config_cache_1.invalidateLlmBillingConfig; } });
|
package/metering.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* metering — Billing-aware wrappers for embedder and chat functions
|
|
3
|
+
*
|
|
4
|
+
* Wraps EmbedderFunction and ChatFunction with:
|
|
5
|
+
* 1. Pre-check: `check_billing_quota(meter_slug, entity_id, estimated_amount)`
|
|
6
|
+
* 2. Execute the underlying function
|
|
7
|
+
* 3. Post-record: `record_usage(meter_slug, entity_id, actual_amount)`
|
|
8
|
+
*
|
|
9
|
+
* When the quota check fails, the wrapper returns null (graceful degradation)
|
|
10
|
+
* instead of throwing, so the search pipeline can fall back to text-only.
|
|
11
|
+
*
|
|
12
|
+
* Token counts:
|
|
13
|
+
* - Chat: real provider counts via ChatResult.usage (from OllamaAdapter.stream())
|
|
14
|
+
* - Embedding: real provider counts via EmbeddingResult.promptTokens (from /api/embed)
|
|
15
|
+
*
|
|
16
|
+
* The billing functions live in the tenant database and are called via the
|
|
17
|
+
* Graphile `withPgClient` callback. Function locations (schema, names) are
|
|
18
|
+
* resolved from `billing_module` metaschema and cached by `config-cache.ts`.
|
|
19
|
+
*/
|
|
20
|
+
import type { BillingConfig, InferenceLogConfig, PgClient } from './config-cache';
|
|
21
|
+
import type { ChatFunction, ChatMessage, ChatOptions, EmbedderFunction } from './types';
|
|
22
|
+
/**
|
|
23
|
+
* Callback matching Graphile's withPgClient signature.
|
|
24
|
+
* Acquires a pg client, calls the callback, then releases the client.
|
|
25
|
+
*/
|
|
26
|
+
export type WithPgClient = (pgSettings: Record<string, string>, callback: (pgClient: PgClient) => Promise<void>) => Promise<void>;
|
|
27
|
+
export interface MeteringContext {
|
|
28
|
+
/** Callback to acquire a tenant database client */
|
|
29
|
+
withPgClient: WithPgClient;
|
|
30
|
+
/** pgSettings from the GraphQL context (for role/claims) */
|
|
31
|
+
pgSettings: Record<string, string>;
|
|
32
|
+
/** Billing function references from the billing_module */
|
|
33
|
+
billing: BillingConfig;
|
|
34
|
+
/** Entity ID to meter against (from JWT claims) */
|
|
35
|
+
entityId: string;
|
|
36
|
+
/** Per-request correlation ID (from request.id pgSetting) */
|
|
37
|
+
requestId: string | null;
|
|
38
|
+
/** Database UUID from JWT claims */
|
|
39
|
+
databaseId: string;
|
|
40
|
+
/** Actor (user) ID from JWT claims */
|
|
41
|
+
actorId: string | null;
|
|
42
|
+
/** Inference log table config (null if inference_log_module not provisioned) */
|
|
43
|
+
inferenceLog: InferenceLogConfig | null;
|
|
44
|
+
}
|
|
45
|
+
export interface MeteringOptions {
|
|
46
|
+
/** Meter slug for embedding operations (default: model name from build config) */
|
|
47
|
+
embeddingMeterSlug?: string;
|
|
48
|
+
/** Meter slug for chat completion operations (default: model name from build config) */
|
|
49
|
+
chatMeterSlug?: string;
|
|
50
|
+
/** Whether to skip metering entirely (e.g. for local dev). Default: false */
|
|
51
|
+
skipMetering?: boolean;
|
|
52
|
+
/** Embedding model name (for inference log) */
|
|
53
|
+
embeddingModel?: string;
|
|
54
|
+
/** Chat model name (for inference log) */
|
|
55
|
+
chatModel?: string;
|
|
56
|
+
/** Provider name (for inference log) */
|
|
57
|
+
provider?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface MeterResult<T> {
|
|
60
|
+
/** The result from the underlying function, or null if quota exceeded */
|
|
61
|
+
result: T | null;
|
|
62
|
+
/** Whether the call was metered */
|
|
63
|
+
metered: boolean;
|
|
64
|
+
/** Whether the call was skipped due to quota limits */
|
|
65
|
+
quotaExceeded: boolean;
|
|
66
|
+
/** Latency of the underlying function call in ms */
|
|
67
|
+
latencyMs: number;
|
|
68
|
+
}
|
|
69
|
+
export interface InferenceLogEntry {
|
|
70
|
+
databaseId: string;
|
|
71
|
+
entityId: string;
|
|
72
|
+
actorId: string | null;
|
|
73
|
+
model: string;
|
|
74
|
+
provider: string | null;
|
|
75
|
+
service: 'llm' | 'embedding' | 'tts' | 'stt' | 'ocr' | 'image_gen' | 'search' | 'compute';
|
|
76
|
+
operation: string;
|
|
77
|
+
inputTokens: number;
|
|
78
|
+
outputTokens: number;
|
|
79
|
+
totalTokens: number;
|
|
80
|
+
cacheReadTokens: number | null;
|
|
81
|
+
cacheWriteTokens: number | null;
|
|
82
|
+
latencyMs: number;
|
|
83
|
+
ragEnabled: boolean;
|
|
84
|
+
chunksRetrieved: number | null;
|
|
85
|
+
embeddingModel: string | null;
|
|
86
|
+
embeddingLatencyMs: number | null;
|
|
87
|
+
status: 'success' | 'quota_exceeded' | 'provider_error' | 'timeout';
|
|
88
|
+
errorType: string | null;
|
|
89
|
+
rawUsage: Record<string, unknown> | null;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Write a row to the usage_log_inference table.
|
|
93
|
+
* Gracefully skips if the inference_log_module is not provisioned.
|
|
94
|
+
*
|
|
95
|
+
* TODO: Also write to child (generated) database when dual-write is needed.
|
|
96
|
+
*/
|
|
97
|
+
export declare function logInferenceUsage(ctx: MeteringContext, entry: InferenceLogEntry): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Wrap an embedder with billing quota check + usage recording.
|
|
100
|
+
*
|
|
101
|
+
* The returned MeterResult contains `quotaExceeded: true` when the pre-check
|
|
102
|
+
* fails, enabling the caller to fall back to text-only search.
|
|
103
|
+
*/
|
|
104
|
+
export declare function meteredEmbed(embedder: EmbedderFunction, text: string, ctx: MeteringContext | null, options?: MeteringOptions): Promise<MeterResult<number[]>>;
|
|
105
|
+
/**
|
|
106
|
+
* Wrap a chat completion call with billing quota check + usage recording.
|
|
107
|
+
*/
|
|
108
|
+
export declare function meteredChat(chat: ChatFunction, messages: ChatMessage[], ctx: MeteringContext | null, chatOptions?: ChatOptions, meteringOptions?: MeteringOptions): Promise<MeterResult<string>>;
|
|
109
|
+
export declare class QuotaExceededError extends Error {
|
|
110
|
+
readonly code = "QUOTA_EXCEEDED";
|
|
111
|
+
readonly meterSlug: string;
|
|
112
|
+
readonly entityId: string;
|
|
113
|
+
constructor(meterSlug: string, entityId: string);
|
|
114
|
+
}
|