import type {
CanonicalModelEvent,
CanonicalModelRequest,
CanonicalModelResponse,
ModelConfig,
} from "./protocol/canonical.js";
import type { ModelCapabilities } from "./protocol/capabilities.js";
import { ModelRequestError } from "./protocol/errors.js";
import type { MultimodalConstraints } from "./protocol/multimodal.js";
import { complete, streamModel, type ModelRuntimeOptions } from "./streaming/streamModel.js";
export interface ModelRuntime {
stream(request: CanonicalModelRequest, options?: ModelRuntimeOptions): AsyncIterable<CanonicalModelEvent>;
complete(request: CanonicalModelRequest, options?: ModelRuntimeOptions): Promise<CanonicalModelResponse>;
getCapabilities(providerId: string, modelId: string): ModelCapabilities;
getMultimodal(providerId: string, modelId: string): MultimodalConstraints;
}
export function createModelRuntime(
config: ModelConfig,
options: ModelRuntimeOptions = {},
): ModelRuntime {
const getModel = (providerId: string, modelId: string) => {
const provider = config.providers[providerId];
if (!provider) {
throw new ModelRequestError("provider_not_found", `Provider ${providerId} does not exist.`);
}
const model = provider.models[modelId];
if (!model) {
throw new ModelRequestError(
"model_not_found",
`Model ${modelId} does not exist in provider ${providerId}.`,
);
}
return model;
};
return {
stream: (request, callOptions) => streamModel(request, config, { ...options, ...callOptions }),
complete: (request, callOptions) => complete(request, config, { ...options, ...callOptions }),
getCapabilities: (providerId, modelId) => getModel(providerId, modelId).capabilities,
getMultimodal: (providerId, modelId) => getModel(providerId, modelId).multimodal,
};
}