diff --git a/crates/node/model_pricing.d.ts b/crates/node/model_pricing.d.ts
index e1932a469..f0e971f24 100644
--- a/crates/node/model_pricing.d.ts
+++ b/crates/node/model_pricing.d.ts
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import type { Json, JsonObject } from './index';
-import type { ComponentSpec as PluginComponentSpec, ConfigReport } from './plugin';
+import type { ComponentSpecFor, ConfigReport } from './plugin';
/** Plugin kind used by the model pricing component. */
export declare const PRICING_PLUGIN_KIND = 'pricing';
@@ -111,12 +111,14 @@ export declare function fileSource(path: string): FileSource;
export declare function pricingConfig(sources?: PricingSource[]): PricingConfig;
/** Wrap model pricing config as a top-level plugin component. */
export declare function ComponentSpec(
- config: PricingConfig | JsonObject,
+ config: PricingConfig,
options?: {
enabled?: boolean;
},
-): PluginComponentSpec;
+): ComponentSpecFor<'pricing'>;
/** Validate a model pricing config document without activating it. */
export declare function validateConfig(config: PricingConfig | JsonObject): ConfigReport;
+/** Validate an untyped model pricing document and return it as a config; throws on error diagnostics. */
+export declare function parseConfig(document: JsonObject): PricingConfig;
export type { Json };
diff --git a/crates/node/model_pricing.js b/crates/node/model_pricing.js
index 06ff48034..d73eb30ba 100644
--- a/crates/node/model_pricing.js
+++ b/crates/node/model_pricing.js
@@ -171,6 +171,22 @@ function validateConfig(config) {
}).config;
}
+/**
+ * Validate an untyped model pricing document and return it as a config.
+ *
+ * @param {object} document - Model pricing component configuration document.
+ * @returns {object} The same document once validation reports no errors.
+ */
+function parseConfig(document) {
+ const errors = validateConfig(document).diagnostics.filter((diagnostic) => diagnostic.level === 'error');
+ if (errors.length > 0) {
+ throw new Error(`invalid model pricing config: ${errors.map((diagnostic) => diagnostic.message).join('; ')}`, {
+ cause: errors,
+ });
+ }
+ return document;
+}
+
module.exports = {
PRICING_PLUGIN_KIND,
defaultConfig,
@@ -185,4 +201,5 @@ module.exports = {
pricingConfig,
ComponentSpec,
validateConfig,
+ parseConfig,
};
diff --git a/crates/node/pii_redaction.d.ts b/crates/node/pii_redaction.d.ts
index 5b98d2407..ed67c85f4 100644
--- a/crates/node/pii_redaction.d.ts
+++ b/crates/node/pii_redaction.d.ts
@@ -69,4 +69,4 @@ export declare function ComponentSpec(
options?: {
enabled?: boolean;
},
-): import('./plugin.js').ComponentSpec;
+): ComponentSpec;
diff --git a/crates/node/plugin.d.ts b/crates/node/plugin.d.ts
index de7f7ce92..0ab14d0fc 100644
--- a/crates/node/plugin.d.ts
+++ b/crates/node/plugin.d.ts
@@ -4,7 +4,14 @@
///
import type { AdaptivePluginConfig } from './adaptive';
-import type { ConfigDiagnostic, Json, JsonObject, JsonObjectCompatible, PluginContext, ResourceMetricsConfig } from './index';
+import type {
+ ConfigDiagnostic,
+ Json,
+ JsonObject,
+ JsonObjectCompatible,
+ PluginContext,
+ ResourceMetricsConfig,
+} from './index';
import type { PricingConfig } from './model_pricing';
import type { Config as ObservabilityConfig } from './observability';
import type { Config as PiiRedactionConfig } from './pii_redaction';
@@ -71,23 +78,33 @@ export type KnownComponentSpec = {
[K in ComponentKind]: { kind: K; enabled?: boolean; config?: ComponentConfigs[K] };
}[ComponentKind];
-/** One top-level plugin component. */
-export interface ComponentSpec {
+declare const openComponent: unique symbol;
+
+/** Config of a component created with `ComponentSpec` for a kind registered through `registerPlugin`. */
+export type OpenComponentConfig = {
+ readonly [openComponent]: true;
+};
+
+/** Component for a kind registered through `registerPlugin`; create one with `ComponentSpec`. */
+export interface OpenComponentSpec {
kind: string;
enabled?: boolean;
- config?: JsonObject;
+ config?: C & OpenComponentConfig;
}
export type ComponentConfigFor = K extends ComponentKind ? ComponentConfigs[K] : JsonObject;
export type ComponentSpecFor = K extends ComponentKind
? Extract
- : ComponentSpec;
+ : OpenComponentSpec;
+
+/** One top-level plugin component. */
+export type ComponentSpec = KnownComponentSpec | OpenComponentSpec