octaflow 0.22.0 → 0.24.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/ai/index.d.ts +9 -2
- package/dist/ai/index.js +14 -2
- package/dist/ai/providers/index.d.ts +78 -1
- package/dist/ai/providers/index.js +86 -4
- package/dist/ai/registry.d.ts +2 -2
- package/dist/ai/registry.js +2 -2
- package/dist/pg-boss/index.js +3 -3
- package/dist/provider-registry-BRwjC6_3.js +181 -0
- package/dist/provider-registry-BvXBqJDR.d.ts +134 -0
- package/package.json +6 -1
- package/dist/provider-registry-DcRDsjtT.js +0 -121
- package/dist/provider-registry-bXGOmyeh.d.ts +0 -81
package/dist/ai/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { E as RetryPolicy, g as TypedWorkflow, h as TypedStepContext, m as TypedStep, nt as Result, tt as FlowErrorShape } from "../index-BURAYZui.js";
|
|
2
2
|
import { n as Logger } from "../logger-BCus3AOa.js";
|
|
3
3
|
import { i as BuildStepContextArgs, o as WorkflowHooks } from "../hooks-BdxIcc92.js";
|
|
4
|
-
import { a as
|
|
4
|
+
import { C as isSubprocessorResidency, S as embeddingDimensionsFor, _ as EmbeddingProviderMeta, a as AiProcessingRegion, b as OpenAiCompatibleProviderId, c as AiProviderModelOption, d as AiVendorResidency, f as DEFAULT_AI_PROVIDER, g as EmbeddingProviderId, h as EMBEDDING_PROVIDER_IDS, i as AiEndpointResidency, l as AiResidencyError, m as EMBEDDING_PROVIDERS, n as AI_PROVIDER_IDS, o as AiProviderId, p as DEFAULT_EMBEDDING_PROVIDER, r as AiEndpointRegion, s as AiProviderMeta, t as AI_PROVIDERS, u as AiResidencyResult, v as OPENAI_COMPATIBLE_PROVIDER, w as resolveEndpointResidency, x as OpenAiCompatibleProviderMeta, y as OPENAI_COMPATIBLE_PROVIDER_ID } from "../provider-registry-BvXBqJDR.js";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { EmbeddingModelV4, LanguageModelV4, SharedV4ProviderMetadata } from "@ai-sdk/provider";
|
|
7
7
|
//#region src/ai/instrumented-model.d.ts
|
|
@@ -82,6 +82,13 @@ export interface TokenUsage {
|
|
|
82
82
|
* pinned ids (`mistral-medium-2508`) fall to the fallback.
|
|
83
83
|
*/
|
|
84
84
|
export declare const DEFAULT_MODEL_PRICING: Record<string, ModelPricing>;
|
|
85
|
+
/**
|
|
86
|
+
* A zero row for a model that costs nothing per token, such as one on a server
|
|
87
|
+
* you run. Add it per model id: `{ ...DEFAULT_MODEL_PRICING, 'qwen3-32b': ZERO_MODEL_PRICING }`.
|
|
88
|
+
* An id missing from the table prices at the priciest row, which is safe for a
|
|
89
|
+
* vendor and makes quota refuse a free model long before it should.
|
|
90
|
+
*/
|
|
91
|
+
export declare const ZERO_MODEL_PRICING: ModelPricing;
|
|
85
92
|
export interface CostEstimatorOptions {
|
|
86
93
|
/** Pricing table keyed by model id. Defaults to `DEFAULT_MODEL_PRICING`. */
|
|
87
94
|
pricing?: Record<string, ModelPricing>;
|
|
@@ -543,4 +550,4 @@ export declare function thinkingSettingsFor(providerId: string, modelId: string,
|
|
|
543
550
|
budgetTokens: number;
|
|
544
551
|
}): ThinkingSettings;
|
|
545
552
|
//#endregion
|
|
546
|
-
export { AI_PROVIDERS, AI_PROVIDER_IDS, AiProcessingRegion, AiProviderId, AiProviderMeta, AiProviderModelOption, AiVendorResidency, DEFAULT_AI_PROVIDER, DEFAULT_EMBEDDING_PROVIDER, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, EmbeddingProviderId, EmbeddingProviderMeta, embeddingDimensionsFor };
|
|
553
|
+
export { AI_PROVIDERS, AI_PROVIDER_IDS, AiEndpointRegion, AiEndpointResidency, AiProcessingRegion, AiProviderId, AiProviderMeta, AiProviderModelOption, AiResidencyError, AiResidencyResult, AiVendorResidency, DEFAULT_AI_PROVIDER, DEFAULT_EMBEDDING_PROVIDER, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, EmbeddingProviderId, EmbeddingProviderMeta, OPENAI_COMPATIBLE_PROVIDER, OPENAI_COMPATIBLE_PROVIDER_ID, OpenAiCompatibleProviderId, OpenAiCompatibleProviderMeta, embeddingDimensionsFor, isSubprocessorResidency, resolveEndpointResidency };
|
package/dist/ai/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { S as ok, b as noopLogger, f as defineStep, l as buildWorkflow, x as err } from "../core-DNWPwFaE.js";
|
|
2
2
|
import { a as readRefusalDetails, i as isAiRefusalError, n as REFUSAL_FINISH_REASON, r as createRefusalAwareModel, t as AiRefusalError } from "../refusal-BsL2HPDb.js";
|
|
3
|
-
import { a as EMBEDDING_PROVIDERS, i as DEFAULT_EMBEDDING_PROVIDER, n as AI_PROVIDER_IDS, o as EMBEDDING_PROVIDER_IDS, r as DEFAULT_AI_PROVIDER, s as
|
|
3
|
+
import { a as EMBEDDING_PROVIDERS, c as OPENAI_COMPATIBLE_PROVIDER_ID, d as resolveEndpointResidency, i as DEFAULT_EMBEDDING_PROVIDER, l as embeddingDimensionsFor, n as AI_PROVIDER_IDS, o as EMBEDDING_PROVIDER_IDS, r as DEFAULT_AI_PROVIDER, s as OPENAI_COMPATIBLE_PROVIDER, t as AI_PROVIDERS, u as isSubprocessorResidency } from "../provider-registry-BRwjC6_3.js";
|
|
4
4
|
import { wrapEmbeddingModel, wrapLanguageModel } from "ai";
|
|
5
5
|
//#region src/ai/instrumented-model.ts
|
|
6
6
|
function createUsageAccumulator() {
|
|
@@ -266,6 +266,18 @@ const DEFAULT_MODEL_PRICING = {
|
|
|
266
266
|
cacheWritePerMillion: 0
|
|
267
267
|
}
|
|
268
268
|
};
|
|
269
|
+
/**
|
|
270
|
+
* A zero row for a model that costs nothing per token, such as one on a server
|
|
271
|
+
* you run. Add it per model id: `{ ...DEFAULT_MODEL_PRICING, 'qwen3-32b': ZERO_MODEL_PRICING }`.
|
|
272
|
+
* An id missing from the table prices at the priciest row, which is safe for a
|
|
273
|
+
* vendor and makes quota refuse a free model long before it should.
|
|
274
|
+
*/
|
|
275
|
+
const ZERO_MODEL_PRICING = Object.freeze({
|
|
276
|
+
inputPerMillion: 0,
|
|
277
|
+
outputPerMillion: 0,
|
|
278
|
+
cacheReadPerMillion: 0,
|
|
279
|
+
cacheWritePerMillion: 0
|
|
280
|
+
});
|
|
269
281
|
function priciest(pricing) {
|
|
270
282
|
let best;
|
|
271
283
|
for (const p of Object.values(pricing)) if (!best || p.outputPerMillion > best.outputPerMillion) best = p;
|
|
@@ -650,4 +662,4 @@ function thinkingSettingsFor(providerId, modelId, opts) {
|
|
|
650
662
|
return { temperature: opts.temperature };
|
|
651
663
|
}
|
|
652
664
|
//#endregion
|
|
653
|
-
export { AI_PROVIDERS, AI_PROVIDER_IDS, AiRefusalError, DEFAULT_AI_PROVIDER, DEFAULT_AI_QUOTA, DEFAULT_EMBEDDING_PROVIDER, DEFAULT_MODEL_PRICING, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, REFUSAL_FINISH_REASON, anthropicThinkingSettings, buildAiWorkflow, createAiQuotaService, createAiUsageAggregationService, createAiWorkflowHooks, createCostEstimator, createEmbeddingUsageAccumulator, createInstrumentedEmbeddingModel, createInstrumentedModel, createRefusalAwareModel, createUsageAccumulator, defineAiStep, embeddingDimensionsFor, estimateCostMicros, isAiRefusalError, readRefusalDetails, supportsAdaptiveThinking, supportsToolSearch, thinkingSettingsFor };
|
|
665
|
+
export { AI_PROVIDERS, AI_PROVIDER_IDS, AiRefusalError, DEFAULT_AI_PROVIDER, DEFAULT_AI_QUOTA, DEFAULT_EMBEDDING_PROVIDER, DEFAULT_MODEL_PRICING, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, OPENAI_COMPATIBLE_PROVIDER, OPENAI_COMPATIBLE_PROVIDER_ID, REFUSAL_FINISH_REASON, ZERO_MODEL_PRICING, anthropicThinkingSettings, buildAiWorkflow, createAiQuotaService, createAiUsageAggregationService, createAiWorkflowHooks, createCostEstimator, createEmbeddingUsageAccumulator, createInstrumentedEmbeddingModel, createInstrumentedModel, createRefusalAwareModel, createUsageAccumulator, defineAiStep, embeddingDimensionsFor, estimateCostMicros, isAiRefusalError, isSubprocessorResidency, readRefusalDetails, resolveEndpointResidency, supportsAdaptiveThinking, supportsToolSearch, thinkingSettingsFor };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { b as OpenAiCompatibleProviderId, g as EmbeddingProviderId, i as AiEndpointResidency, o as AiProviderId } from "../../provider-registry-BvXBqJDR.js";
|
|
2
2
|
import { EmbeddingModelV4, LanguageModelV4 } from "@ai-sdk/provider";
|
|
3
3
|
//#region src/ai/providers/index.d.ts
|
|
4
4
|
export type LanguageModelFactory = (modelId: string) => LanguageModelV4;
|
|
@@ -66,4 +66,81 @@ export interface LazyEmbeddingModelMeta {
|
|
|
66
66
|
* next call rather than cached.
|
|
67
67
|
*/
|
|
68
68
|
export declare function createLazyEmbeddingModel(meta: LazyEmbeddingModelMeta, load: () => Promise<EmbeddingModelV4>): EmbeddingModelV4;
|
|
69
|
+
export type AiProviderConfigErrorKey = 'ai_residency_undeclared' | 'ai_residency_invalid' | 'ai_base_url_invalid' | 'ai_model_required' | 'ai_embedding_dimensions_invalid';
|
|
70
|
+
/**
|
|
71
|
+
* A provider configuration that cannot work. Thrown before any SDK is loaded
|
|
72
|
+
* or any request is made: it is a deployment mistake, found at wiring time.
|
|
73
|
+
*/
|
|
74
|
+
export declare class AiProviderConfigError extends Error {
|
|
75
|
+
readonly key: AiProviderConfigErrorKey;
|
|
76
|
+
constructor(key: AiProviderConfigErrorKey, message: string);
|
|
77
|
+
}
|
|
78
|
+
export interface OpenAiCompatibleEndpointConfig {
|
|
79
|
+
/** The API root including its version segment, e.g. `http://vllm.ai.svc:8000/v1`. Required: there is no default host. */
|
|
80
|
+
baseUrl: string;
|
|
81
|
+
/** Sent as `Authorization: Bearer …` when set. Most self-hosted servers need none. */
|
|
82
|
+
apiKey?: string;
|
|
83
|
+
/** Where the endpoint processes payloads. Required, validated by `resolveEndpointResidency`. */
|
|
84
|
+
residency: AiEndpointResidency;
|
|
85
|
+
/** Reported as the model's `provider`. Defaults to `openai-compatible`. */
|
|
86
|
+
name?: string;
|
|
87
|
+
headers?: Record<string, string>;
|
|
88
|
+
/** A fetch implementation, for middleware or tests. Defaults to the global `fetch`. */
|
|
89
|
+
fetch?: typeof globalThis.fetch;
|
|
90
|
+
}
|
|
91
|
+
export interface OpenAiCompatibleModelProviderConfig extends OpenAiCompatibleEndpointConfig {
|
|
92
|
+
/** The model a call without an id uses. Required: a server you run has no registry default. */
|
|
93
|
+
defaultModel: string;
|
|
94
|
+
/** Cheap model for classifier-style passes. Defaults to `defaultModel`. */
|
|
95
|
+
classifierModel?: string;
|
|
96
|
+
/** Set when the server enforces a JSON schema on output (vLLM does); otherwise `generateObject` uses JSON mode. */
|
|
97
|
+
structuredOutputs?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Ask for token usage on streamed responses. Defaults to `true`, because the
|
|
100
|
+
* instrumented model meters what the stream reports and a stream without it
|
|
101
|
+
* reports zero tokens. Turn it off only for a server that rejects the option.
|
|
102
|
+
*/
|
|
103
|
+
includeUsage?: boolean;
|
|
104
|
+
}
|
|
105
|
+
export interface OpenAiCompatibleModelProvider {
|
|
106
|
+
providerId: OpenAiCompatibleProviderId;
|
|
107
|
+
/** The declared residency, validated — what a badge or an audit record shows. */
|
|
108
|
+
residency: AiEndpointResidency;
|
|
109
|
+
classifierModelId: string;
|
|
110
|
+
/** A Chat Completions model, wrapped for refusal detection like the vendor ones. */
|
|
111
|
+
languageModel(modelId?: string): LanguageModelV4;
|
|
112
|
+
}
|
|
113
|
+
export interface OpenAiCompatibleEmbeddingProviderConfig extends OpenAiCompatibleEndpointConfig {
|
|
114
|
+
model: string;
|
|
115
|
+
/**
|
|
116
|
+
* The model's vector width, which must match your `vector(N)` column.
|
|
117
|
+
* Required: a guessed width, such as the registry's 1536 fallback, silently
|
|
118
|
+
* breaks a 1024-wide model like `bge-m3` at the first insert.
|
|
119
|
+
*/
|
|
120
|
+
dimensions: number;
|
|
121
|
+
}
|
|
122
|
+
export interface OpenAiCompatibleEmbeddingProvider {
|
|
123
|
+
providerId: OpenAiCompatibleProviderId;
|
|
124
|
+
residency: AiEndpointResidency;
|
|
125
|
+
modelId: string;
|
|
126
|
+
dimensions: number;
|
|
127
|
+
embeddingModel(): EmbeddingModelV4;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* A model server you run, or any host with the OpenAI-compatible API, as
|
|
131
|
+
* refusal-aware models. Language models go through **Chat Completions**, which
|
|
132
|
+
* is what vLLM, Ollama and llama.cpp speak — not the Responses API that
|
|
133
|
+
* `@ai-sdk/openai` defaults to.
|
|
134
|
+
*
|
|
135
|
+
* ```ts
|
|
136
|
+
* const models = await createOpenAiCompatibleModelProvider({
|
|
137
|
+
* baseUrl: 'http://vllm.ai.svc:8000/v1',
|
|
138
|
+
* residency: { region: 'self-hosted' },
|
|
139
|
+
* defaultModel: 'qwen3-32b',
|
|
140
|
+
* });
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
export declare function createOpenAiCompatibleModelProvider(config: OpenAiCompatibleModelProviderConfig): Promise<OpenAiCompatibleModelProvider>;
|
|
144
|
+
/** An embedding model on an OpenAI-compatible endpoint, with its declared width. */
|
|
145
|
+
export declare function createOpenAiCompatibleEmbeddingProvider(config: OpenAiCompatibleEmbeddingProviderConfig): Promise<OpenAiCompatibleEmbeddingProvider>;
|
|
69
146
|
//#endregion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as createRefusalAwareModel } from "../../refusal-BsL2HPDb.js";
|
|
2
|
-
import { a as EMBEDDING_PROVIDERS, t as AI_PROVIDERS } from "../../provider-registry-
|
|
2
|
+
import { a as EMBEDDING_PROVIDERS, c as OPENAI_COMPATIBLE_PROVIDER_ID, d as resolveEndpointResidency, t as AI_PROVIDERS } from "../../provider-registry-BRwjC6_3.js";
|
|
3
3
|
//#region src/ai/providers/index.ts
|
|
4
4
|
const LLM_LOADERS = {
|
|
5
5
|
anthropic: async (apiKey, baseURL) => {
|
|
@@ -52,7 +52,7 @@ function createEmbeddingModelFactory(providerId, apiKey, baseURL) {
|
|
|
52
52
|
* ```
|
|
53
53
|
*/
|
|
54
54
|
async function createLanguageModelProvider(config) {
|
|
55
|
-
const providerId = config.provider ?? "
|
|
55
|
+
const providerId = config.provider ?? "mistral";
|
|
56
56
|
const meta = AI_PROVIDERS[providerId];
|
|
57
57
|
const factory = await createLanguageModelFactory(providerId, config.apiKey, config.baseUrl);
|
|
58
58
|
const defaultModel = config.defaultModel ?? meta.defaultModel;
|
|
@@ -63,7 +63,7 @@ async function createLanguageModelProvider(config) {
|
|
|
63
63
|
};
|
|
64
64
|
}
|
|
65
65
|
async function createEmbeddingModelProvider(config) {
|
|
66
|
-
const providerId = config.provider ?? "
|
|
66
|
+
const providerId = config.provider ?? "mistral";
|
|
67
67
|
const factory = await createEmbeddingModelFactory(providerId, config.apiKey, config.baseUrl);
|
|
68
68
|
const modelId = config.model ?? EMBEDDING_PROVIDERS[providerId].defaultModel;
|
|
69
69
|
return {
|
|
@@ -103,5 +103,87 @@ function createLazyEmbeddingModel(meta, load) {
|
|
|
103
103
|
doEmbed: (options) => model().then((m) => m.doEmbed(options))
|
|
104
104
|
};
|
|
105
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* A provider configuration that cannot work. Thrown before any SDK is loaded
|
|
108
|
+
* or any request is made: it is a deployment mistake, found at wiring time.
|
|
109
|
+
*/
|
|
110
|
+
var AiProviderConfigError = class extends Error {
|
|
111
|
+
key;
|
|
112
|
+
constructor(key, message) {
|
|
113
|
+
super(message);
|
|
114
|
+
this.name = "AiProviderConfigError";
|
|
115
|
+
this.key = key;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
function checkEndpoint(config) {
|
|
119
|
+
const residency = resolveEndpointResidency(config.residency);
|
|
120
|
+
if (!residency.ok) throw new AiProviderConfigError(residency.error.key, residency.error.message);
|
|
121
|
+
let url;
|
|
122
|
+
try {
|
|
123
|
+
url = new URL(config.baseUrl);
|
|
124
|
+
} catch {
|
|
125
|
+
url = void 0;
|
|
126
|
+
}
|
|
127
|
+
if (url === void 0 || url.protocol !== "http:" && url.protocol !== "https:") throw new AiProviderConfigError("ai_base_url_invalid", `baseUrl must be an absolute http(s) URL, got ${JSON.stringify(config.baseUrl)}`);
|
|
128
|
+
return residency.value;
|
|
129
|
+
}
|
|
130
|
+
function requireModel(modelId, field) {
|
|
131
|
+
if (typeof modelId !== "string" || modelId.trim() === "") throw new AiProviderConfigError("ai_model_required", `${field} is required for an OpenAI-compatible endpoint`);
|
|
132
|
+
return modelId;
|
|
133
|
+
}
|
|
134
|
+
async function loadOpenAiCompatible(config, options = {}) {
|
|
135
|
+
const { createOpenAICompatible } = await import("@ai-sdk/openai-compatible");
|
|
136
|
+
return createOpenAICompatible({
|
|
137
|
+
name: config.name ?? "openai-compatible",
|
|
138
|
+
baseURL: config.baseUrl.replace(/\/+$/, ""),
|
|
139
|
+
apiKey: config.apiKey,
|
|
140
|
+
headers: config.headers,
|
|
141
|
+
fetch: config.fetch,
|
|
142
|
+
includeUsage: options.includeUsage ?? true,
|
|
143
|
+
supportsStructuredOutputs: options.structuredOutputs
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* A model server you run, or any host with the OpenAI-compatible API, as
|
|
148
|
+
* refusal-aware models. Language models go through **Chat Completions**, which
|
|
149
|
+
* is what vLLM, Ollama and llama.cpp speak — not the Responses API that
|
|
150
|
+
* `@ai-sdk/openai` defaults to.
|
|
151
|
+
*
|
|
152
|
+
* ```ts
|
|
153
|
+
* const models = await createOpenAiCompatibleModelProvider({
|
|
154
|
+
* baseUrl: 'http://vllm.ai.svc:8000/v1',
|
|
155
|
+
* residency: { region: 'self-hosted' },
|
|
156
|
+
* defaultModel: 'qwen3-32b',
|
|
157
|
+
* });
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
async function createOpenAiCompatibleModelProvider(config) {
|
|
161
|
+
const residency = checkEndpoint(config);
|
|
162
|
+
const defaultModel = requireModel(config.defaultModel, "defaultModel");
|
|
163
|
+
const provider = await loadOpenAiCompatible(config, {
|
|
164
|
+
structuredOutputs: config.structuredOutputs,
|
|
165
|
+
includeUsage: config.includeUsage
|
|
166
|
+
});
|
|
167
|
+
return {
|
|
168
|
+
providerId: OPENAI_COMPATIBLE_PROVIDER_ID,
|
|
169
|
+
residency,
|
|
170
|
+
classifierModelId: config.classifierModel ?? defaultModel,
|
|
171
|
+
languageModel: (modelId) => createRefusalAwareModel(provider.chatModel(modelId ?? defaultModel))
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/** An embedding model on an OpenAI-compatible endpoint, with its declared width. */
|
|
175
|
+
async function createOpenAiCompatibleEmbeddingProvider(config) {
|
|
176
|
+
const residency = checkEndpoint(config);
|
|
177
|
+
const modelId = requireModel(config.model, "model");
|
|
178
|
+
if (!Number.isInteger(config.dimensions) || config.dimensions <= 0) throw new AiProviderConfigError("ai_embedding_dimensions_invalid", `dimensions must be a positive integer matching your vector column, got ${JSON.stringify(config.dimensions)}`);
|
|
179
|
+
const provider = await loadOpenAiCompatible(config);
|
|
180
|
+
return {
|
|
181
|
+
providerId: OPENAI_COMPATIBLE_PROVIDER_ID,
|
|
182
|
+
residency,
|
|
183
|
+
modelId,
|
|
184
|
+
dimensions: config.dimensions,
|
|
185
|
+
embeddingModel: () => provider.embeddingModel(modelId)
|
|
186
|
+
};
|
|
187
|
+
}
|
|
106
188
|
//#endregion
|
|
107
|
-
export { createEmbeddingModelFactory, createEmbeddingModelProvider, createLanguageModelFactory, createLanguageModelProvider, createLazyEmbeddingModel };
|
|
189
|
+
export { AiProviderConfigError, createEmbeddingModelFactory, createEmbeddingModelProvider, createLanguageModelFactory, createLanguageModelProvider, createLazyEmbeddingModel, createOpenAiCompatibleEmbeddingProvider, createOpenAiCompatibleModelProvider };
|
package/dist/ai/registry.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { AI_PROVIDERS, AI_PROVIDER_IDS, AiProcessingRegion, AiProviderId, AiProviderMeta, AiProviderModelOption, AiVendorResidency, DEFAULT_AI_PROVIDER, DEFAULT_EMBEDDING_PROVIDER, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, EmbeddingProviderId, EmbeddingProviderMeta, embeddingDimensionsFor };
|
|
1
|
+
import { C as isSubprocessorResidency, S as embeddingDimensionsFor, _ as EmbeddingProviderMeta, a as AiProcessingRegion, b as OpenAiCompatibleProviderId, c as AiProviderModelOption, d as AiVendorResidency, f as DEFAULT_AI_PROVIDER, g as EmbeddingProviderId, h as EMBEDDING_PROVIDER_IDS, i as AiEndpointResidency, l as AiResidencyError, m as EMBEDDING_PROVIDERS, n as AI_PROVIDER_IDS, o as AiProviderId, p as DEFAULT_EMBEDDING_PROVIDER, r as AiEndpointRegion, s as AiProviderMeta, t as AI_PROVIDERS, u as AiResidencyResult, v as OPENAI_COMPATIBLE_PROVIDER, w as resolveEndpointResidency, x as OpenAiCompatibleProviderMeta, y as OPENAI_COMPATIBLE_PROVIDER_ID } from "../provider-registry-BvXBqJDR.js";
|
|
2
|
+
export { AI_PROVIDERS, AI_PROVIDER_IDS, AiEndpointRegion, AiEndpointResidency, AiProcessingRegion, AiProviderId, AiProviderMeta, AiProviderModelOption, AiResidencyError, AiResidencyResult, AiVendorResidency, DEFAULT_AI_PROVIDER, DEFAULT_EMBEDDING_PROVIDER, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, EmbeddingProviderId, EmbeddingProviderMeta, OPENAI_COMPATIBLE_PROVIDER, OPENAI_COMPATIBLE_PROVIDER_ID, OpenAiCompatibleProviderId, OpenAiCompatibleProviderMeta, embeddingDimensionsFor, isSubprocessorResidency, resolveEndpointResidency };
|
package/dist/ai/registry.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as EMBEDDING_PROVIDERS, i as DEFAULT_EMBEDDING_PROVIDER, n as AI_PROVIDER_IDS, o as EMBEDDING_PROVIDER_IDS, r as DEFAULT_AI_PROVIDER, s as
|
|
2
|
-
export { AI_PROVIDERS, AI_PROVIDER_IDS, DEFAULT_AI_PROVIDER, DEFAULT_EMBEDDING_PROVIDER, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, embeddingDimensionsFor };
|
|
1
|
+
import { a as EMBEDDING_PROVIDERS, c as OPENAI_COMPATIBLE_PROVIDER_ID, d as resolveEndpointResidency, i as DEFAULT_EMBEDDING_PROVIDER, l as embeddingDimensionsFor, n as AI_PROVIDER_IDS, o as EMBEDDING_PROVIDER_IDS, r as DEFAULT_AI_PROVIDER, s as OPENAI_COMPATIBLE_PROVIDER, t as AI_PROVIDERS, u as isSubprocessorResidency } from "../provider-registry-BRwjC6_3.js";
|
|
2
|
+
export { AI_PROVIDERS, AI_PROVIDER_IDS, DEFAULT_AI_PROVIDER, DEFAULT_EMBEDDING_PROVIDER, EMBEDDING_PROVIDERS, EMBEDDING_PROVIDER_IDS, OPENAI_COMPATIBLE_PROVIDER, OPENAI_COMPATIBLE_PROVIDER_ID, embeddingDimensionsFor, isSubprocessorResidency, resolveEndpointResidency };
|
package/dist/pg-boss/index.js
CHANGED
|
@@ -276,7 +276,7 @@ function createPgBossStepWorker(deps) {
|
|
|
276
276
|
}
|
|
277
277
|
async function stop() {
|
|
278
278
|
if (workerId) {
|
|
279
|
-
await boss.offWork(workerId);
|
|
279
|
+
await boss.offWork(queueName, { id: workerId });
|
|
280
280
|
workerId = null;
|
|
281
281
|
}
|
|
282
282
|
}
|
|
@@ -314,7 +314,7 @@ function createPgBossDlqWorker(deps) {
|
|
|
314
314
|
}
|
|
315
315
|
async function stop() {
|
|
316
316
|
if (workerId) {
|
|
317
|
-
await boss.offWork(workerId);
|
|
317
|
+
await boss.offWork(dlq, { id: workerId });
|
|
318
318
|
workerId = null;
|
|
319
319
|
}
|
|
320
320
|
}
|
|
@@ -398,7 +398,7 @@ function createPgBossStartWorker(deps) {
|
|
|
398
398
|
}
|
|
399
399
|
async function stop() {
|
|
400
400
|
if (workerId) {
|
|
401
|
-
await boss.offWork(workerId);
|
|
401
|
+
await boss.offWork(queueName, { id: workerId });
|
|
402
402
|
workerId = null;
|
|
403
403
|
}
|
|
404
404
|
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
//#region src/ai/provider-registry.ts
|
|
2
|
+
/**
|
|
3
|
+
* The provider registry — pure metadata about the vendors a BYOK deployment
|
|
4
|
+
* can point at: ids, default and cheap models, where a key is created, and
|
|
5
|
+
* **where the vendor processes what you send it**. Dependency-free, so a
|
|
6
|
+
* browser bundle (a provider/model picker, a residency badge) can import it;
|
|
7
|
+
* the SDK factories that need `@ai-sdk/*` live in `octaflow/ai/providers`.
|
|
8
|
+
*
|
|
9
|
+
* Adding a provider: an id here with its metadata, a factory in
|
|
10
|
+
* `providers/`, and pricing rows in `cost.ts`.
|
|
11
|
+
*/
|
|
12
|
+
const AI_PROVIDER_IDS = ["anthropic", "mistral"];
|
|
13
|
+
const EMBEDDING_PROVIDER_IDS = ["openai", "mistral"];
|
|
14
|
+
/**
|
|
15
|
+
* What an unset provider resolves to: the EU-established vendor, so a deployment
|
|
16
|
+
* that names no provider adds no third-country transfer to its annex. Choosing
|
|
17
|
+
* a third-country vendor is a decision the caller writes down. The embedding
|
|
18
|
+
* default is 1024-dimensional (`mistral-embed`); a `vector(N)` column sized for
|
|
19
|
+
* another model names its provider explicitly.
|
|
20
|
+
*/
|
|
21
|
+
const DEFAULT_AI_PROVIDER = "mistral";
|
|
22
|
+
const DEFAULT_EMBEDDING_PROVIDER = "mistral";
|
|
23
|
+
const AI_PROVIDERS = {
|
|
24
|
+
anthropic: {
|
|
25
|
+
id: "anthropic",
|
|
26
|
+
label: "Anthropic",
|
|
27
|
+
residency: {
|
|
28
|
+
region: "third-country",
|
|
29
|
+
legalName: "Anthropic PBC",
|
|
30
|
+
country: "US"
|
|
31
|
+
},
|
|
32
|
+
defaultModel: "claude-sonnet-5",
|
|
33
|
+
classifierModel: "claude-haiku-4-5",
|
|
34
|
+
testModel: "claude-haiku-4-5",
|
|
35
|
+
keyPrefix: "sk-ant-",
|
|
36
|
+
consoleKeyUrl: "https://console.anthropic.com/settings/keys",
|
|
37
|
+
modelOptions: [
|
|
38
|
+
{
|
|
39
|
+
label: "Claude Opus 5",
|
|
40
|
+
value: "claude-opus-5"
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
label: "Claude Opus 4.8",
|
|
44
|
+
value: "claude-opus-4-8"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
label: "Claude Sonnet 5",
|
|
48
|
+
value: "claude-sonnet-5"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
label: "Claude Haiku 4.5",
|
|
52
|
+
value: "claude-haiku-4-5"
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
},
|
|
56
|
+
mistral: {
|
|
57
|
+
id: "mistral",
|
|
58
|
+
label: "Mistral",
|
|
59
|
+
residency: {
|
|
60
|
+
region: "eu",
|
|
61
|
+
legalName: "Mistral AI SAS",
|
|
62
|
+
country: "FR"
|
|
63
|
+
},
|
|
64
|
+
defaultModel: "mistral-medium-latest",
|
|
65
|
+
classifierModel: "mistral-small-latest",
|
|
66
|
+
testModel: "mistral-small-latest",
|
|
67
|
+
keyPrefix: null,
|
|
68
|
+
consoleKeyUrl: "https://console.mistral.ai/api-keys",
|
|
69
|
+
modelOptions: [
|
|
70
|
+
{
|
|
71
|
+
label: "Mistral Medium 3.5",
|
|
72
|
+
value: "mistral-medium-latest"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
label: "Mistral Large 3",
|
|
76
|
+
value: "mistral-large-latest"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
label: "Mistral Small 4",
|
|
80
|
+
value: "mistral-small-latest"
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const EMBEDDING_PROVIDERS = {
|
|
86
|
+
openai: {
|
|
87
|
+
id: "openai",
|
|
88
|
+
label: "OpenAI",
|
|
89
|
+
residency: {
|
|
90
|
+
region: "third-country",
|
|
91
|
+
legalName: "OpenAI, L.L.C.",
|
|
92
|
+
country: "US"
|
|
93
|
+
},
|
|
94
|
+
defaultModel: "text-embedding-3-small",
|
|
95
|
+
consoleKeyUrl: "https://platform.openai.com/api-keys",
|
|
96
|
+
dimensionsByModel: {
|
|
97
|
+
"text-embedding-3-small": 1536,
|
|
98
|
+
"text-embedding-3-large": 3072
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
mistral: {
|
|
102
|
+
id: "mistral",
|
|
103
|
+
label: "Mistral",
|
|
104
|
+
residency: {
|
|
105
|
+
region: "eu",
|
|
106
|
+
legalName: "Mistral AI SAS",
|
|
107
|
+
country: "FR"
|
|
108
|
+
},
|
|
109
|
+
defaultModel: "mistral-embed",
|
|
110
|
+
consoleKeyUrl: "https://console.mistral.ai/api-keys",
|
|
111
|
+
dimensionsByModel: { "mistral-embed": 1024 }
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Vector dimensions for an embedding model id in the vendor lists above.
|
|
116
|
+
* Unknown ids fall back to `fallback` (default 1536) so free-form vendor model
|
|
117
|
+
* ids keep a working column. A self-hosted model never goes through this
|
|
118
|
+
* guess: its width is declared (`createOpenAiCompatibleEmbeddingProvider`'s
|
|
119
|
+
* `dimensions`), because a wrong one fails at the first `vector(N)` insert.
|
|
120
|
+
*/
|
|
121
|
+
function embeddingDimensionsFor(modelId, fallback = 1536) {
|
|
122
|
+
for (const meta of Object.values(EMBEDDING_PROVIDERS)) {
|
|
123
|
+
const dims = meta.dimensionsByModel[modelId];
|
|
124
|
+
if (dims !== void 0) return dims;
|
|
125
|
+
}
|
|
126
|
+
return fallback;
|
|
127
|
+
}
|
|
128
|
+
const OPENAI_COMPATIBLE_PROVIDER_ID = "openai-compatible";
|
|
129
|
+
const OPENAI_COMPATIBLE_PROVIDER = {
|
|
130
|
+
id: OPENAI_COMPATIBLE_PROVIDER_ID,
|
|
131
|
+
label: "OpenAI-compatible endpoint",
|
|
132
|
+
residency: "declared-by-deployment"
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Validates a residency declared by a deployment — from config, an env file, a
|
|
136
|
+
* database row — before any call is made. A missing one is
|
|
137
|
+
* `ai_residency_undeclared`: an endpoint whose data location nobody stated is
|
|
138
|
+
* refused, never assumed to be local. A vendor region needs the legal name and
|
|
139
|
+
* the ISO country a subprocessor annex prints.
|
|
140
|
+
*/
|
|
141
|
+
function resolveEndpointResidency(declared) {
|
|
142
|
+
if (declared === void 0 || declared === null) return {
|
|
143
|
+
ok: false,
|
|
144
|
+
error: {
|
|
145
|
+
key: "ai_residency_undeclared",
|
|
146
|
+
message: "an OpenAI-compatible endpoint needs a declared residency: { region: \"self-hosted\" }, or a vendor region with its legalName and country"
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
if (typeof declared !== "object") return invalidResidency("residency must be an object");
|
|
150
|
+
const { region, legalName, country } = declared;
|
|
151
|
+
if (region === "self-hosted") return {
|
|
152
|
+
ok: true,
|
|
153
|
+
value: { region: "self-hosted" }
|
|
154
|
+
};
|
|
155
|
+
if (region !== "eu" && region !== "third-country") return invalidResidency(`unknown region ${JSON.stringify(region)}; expected "self-hosted", "eu" or "third-country"`);
|
|
156
|
+
if (typeof legalName !== "string" || legalName.trim() === "") return invalidResidency(`region "${region}" names a vendor, so legalName is required`);
|
|
157
|
+
if (typeof country !== "string" || !/^[A-Z]{2}$/.test(country)) return invalidResidency(`region "${region}" needs country as an ISO 3166-1 alpha-2 code`);
|
|
158
|
+
return {
|
|
159
|
+
ok: true,
|
|
160
|
+
value: {
|
|
161
|
+
region,
|
|
162
|
+
legalName,
|
|
163
|
+
country
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
function invalidResidency(message) {
|
|
168
|
+
return {
|
|
169
|
+
ok: false,
|
|
170
|
+
error: {
|
|
171
|
+
key: "ai_residency_invalid",
|
|
172
|
+
message
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
/** Whether calling an endpoint with this residency makes its operator a subprocessor. A self-hosted endpoint does not. */
|
|
177
|
+
function isSubprocessorResidency(residency) {
|
|
178
|
+
return residency.region !== "self-hosted";
|
|
179
|
+
}
|
|
180
|
+
//#endregion
|
|
181
|
+
export { EMBEDDING_PROVIDERS as a, OPENAI_COMPATIBLE_PROVIDER_ID as c, resolveEndpointResidency as d, DEFAULT_EMBEDDING_PROVIDER as i, embeddingDimensionsFor as l, AI_PROVIDER_IDS as n, EMBEDDING_PROVIDER_IDS as o, DEFAULT_AI_PROVIDER as r, OPENAI_COMPATIBLE_PROVIDER as s, AI_PROVIDERS as t, isSubprocessorResidency as u };
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
//#region src/ai/provider-registry.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* The provider registry — pure metadata about the vendors a BYOK deployment
|
|
4
|
+
* can point at: ids, default and cheap models, where a key is created, and
|
|
5
|
+
* **where the vendor processes what you send it**. Dependency-free, so a
|
|
6
|
+
* browser bundle (a provider/model picker, a residency badge) can import it;
|
|
7
|
+
* the SDK factories that need `@ai-sdk/*` live in `octaflow/ai/providers`.
|
|
8
|
+
*
|
|
9
|
+
* Adding a provider: an id here with its metadata, a factory in
|
|
10
|
+
* `providers/`, and pricing rows in `cost.ts`.
|
|
11
|
+
*/
|
|
12
|
+
declare const AI_PROVIDER_IDS: readonly ['anthropic', 'mistral'];
|
|
13
|
+
type AiProviderId = (typeof AI_PROVIDER_IDS)[number];
|
|
14
|
+
declare const EMBEDDING_PROVIDER_IDS: readonly ['openai', 'mistral'];
|
|
15
|
+
type EmbeddingProviderId = (typeof EMBEDDING_PROVIDER_IDS)[number];
|
|
16
|
+
/**
|
|
17
|
+
* What an unset provider resolves to: the EU-established vendor, so a deployment
|
|
18
|
+
* that names no provider adds no third-country transfer to its annex. Choosing
|
|
19
|
+
* a third-country vendor is a decision the caller writes down. The embedding
|
|
20
|
+
* default is 1024-dimensional (`mistral-embed`); a `vector(N)` column sized for
|
|
21
|
+
* another model names its provider explicitly.
|
|
22
|
+
*/
|
|
23
|
+
declare const DEFAULT_AI_PROVIDER: AiProviderId;
|
|
24
|
+
declare const DEFAULT_EMBEDDING_PROVIDER: EmbeddingProviderId;
|
|
25
|
+
/**
|
|
26
|
+
* Where a provider processes the payloads you send it.
|
|
27
|
+
*
|
|
28
|
+
* `'eu'` means the vendor is established in the EU/EEA and serves the API from
|
|
29
|
+
* there, so a call carries no third-country transfer under Art. 44 ff. GDPR.
|
|
30
|
+
* `'third-country'` means it does — your data-processing agreement then has
|
|
31
|
+
* to carry a transfer mechanism for that vendor.
|
|
32
|
+
*
|
|
33
|
+
* This is metadata about the *vendor endpoint called*, not a promise about a
|
|
34
|
+
* customer's own BYOK key: a customer who brings their own key contracts with
|
|
35
|
+
* the vendor directly.
|
|
36
|
+
*/
|
|
37
|
+
type AiProcessingRegion = 'eu' | 'third-country';
|
|
38
|
+
interface AiVendorResidency {
|
|
39
|
+
region: AiProcessingRegion;
|
|
40
|
+
/** Legal entity, as it appears in a subprocessor annex. */
|
|
41
|
+
legalName: string;
|
|
42
|
+
/** Country of establishment, ISO 3166-1 alpha-2. */
|
|
43
|
+
country: string;
|
|
44
|
+
}
|
|
45
|
+
interface AiProviderModelOption {
|
|
46
|
+
label: string;
|
|
47
|
+
value: string;
|
|
48
|
+
}
|
|
49
|
+
interface AiProviderMeta {
|
|
50
|
+
id: AiProviderId;
|
|
51
|
+
label: string;
|
|
52
|
+
/** Where calls to this provider are processed — drives a residency badge and the subprocessor analysis. */
|
|
53
|
+
residency: AiVendorResidency;
|
|
54
|
+
/** Default chat/workflow model when nothing sets one. */
|
|
55
|
+
defaultModel: string;
|
|
56
|
+
/** Cheap model for classifier-style passes. */
|
|
57
|
+
classifierModel: string;
|
|
58
|
+
/** Cheap model for a "test connection" ping. */
|
|
59
|
+
testModel: string;
|
|
60
|
+
/** Well-known API key prefix for a soft format hint, or null when the provider has none. */
|
|
61
|
+
keyPrefix: string | null;
|
|
62
|
+
/** Where the operator creates an API key. */
|
|
63
|
+
consoleKeyUrl: string;
|
|
64
|
+
/** Curated model choices for a picker (free-form custom ids stay allowed). */
|
|
65
|
+
modelOptions: AiProviderModelOption[];
|
|
66
|
+
}
|
|
67
|
+
declare const AI_PROVIDERS: Record<AiProviderId, AiProviderMeta>;
|
|
68
|
+
interface EmbeddingProviderMeta {
|
|
69
|
+
id: EmbeddingProviderId;
|
|
70
|
+
label: string;
|
|
71
|
+
/** See {@link AiProviderMeta.residency}. */
|
|
72
|
+
residency: AiVendorResidency;
|
|
73
|
+
defaultModel: string;
|
|
74
|
+
/** Where the operator creates an API key. */
|
|
75
|
+
consoleKeyUrl: string;
|
|
76
|
+
/** Vector dimensions per known model id — must match the `vector(N)` column in your schema. */
|
|
77
|
+
dimensionsByModel: Record<string, number>;
|
|
78
|
+
}
|
|
79
|
+
declare const EMBEDDING_PROVIDERS: Record<EmbeddingProviderId, EmbeddingProviderMeta>;
|
|
80
|
+
/**
|
|
81
|
+
* Vector dimensions for an embedding model id in the vendor lists above.
|
|
82
|
+
* Unknown ids fall back to `fallback` (default 1536) so free-form vendor model
|
|
83
|
+
* ids keep a working column. A self-hosted model never goes through this
|
|
84
|
+
* guess: its width is declared (`createOpenAiCompatibleEmbeddingProvider`'s
|
|
85
|
+
* `dimensions`), because a wrong one fails at the first `vector(N)` insert.
|
|
86
|
+
*/
|
|
87
|
+
declare function embeddingDimensionsFor(modelId: string, fallback?: number): number;
|
|
88
|
+
/**
|
|
89
|
+
* Where a model endpoint the *deployment* names processes payloads. A vendor in
|
|
90
|
+
* the lists above has a fixed residency; an OpenAI-compatible endpoint does not:
|
|
91
|
+
* the same client talks to vLLM in your own cluster, to Ollama on a workstation,
|
|
92
|
+
* or to a hosted inference vendor. So whoever deploys it declares the residency,
|
|
93
|
+
* and `'self-hosted'` is the value that adds no subprocessor.
|
|
94
|
+
*
|
|
95
|
+
* Kept apart from {@link AiProcessingRegion} on purpose: that union describes the
|
|
96
|
+
* vendors above, and a picker that iterates `AI_PROVIDERS` keeps working unchanged.
|
|
97
|
+
*/
|
|
98
|
+
type AiEndpointRegion = AiProcessingRegion | 'self-hosted';
|
|
99
|
+
/** `{ region: 'self-hosted' }` for infrastructure you operate; a vendor's full residency otherwise. */
|
|
100
|
+
type AiEndpointResidency = {
|
|
101
|
+
region: 'self-hosted';
|
|
102
|
+
} | AiVendorResidency;
|
|
103
|
+
declare const OPENAI_COMPATIBLE_PROVIDER_ID = "openai-compatible";
|
|
104
|
+
type OpenAiCompatibleProviderId = typeof OPENAI_COMPATIBLE_PROVIDER_ID;
|
|
105
|
+
interface OpenAiCompatibleProviderMeta {
|
|
106
|
+
id: OpenAiCompatibleProviderId;
|
|
107
|
+
label: string;
|
|
108
|
+
/** Never fixed in the registry — see {@link resolveEndpointResidency}. */
|
|
109
|
+
residency: 'declared-by-deployment';
|
|
110
|
+
}
|
|
111
|
+
declare const OPENAI_COMPATIBLE_PROVIDER: OpenAiCompatibleProviderMeta;
|
|
112
|
+
interface AiResidencyError {
|
|
113
|
+
key: 'ai_residency_undeclared' | 'ai_residency_invalid';
|
|
114
|
+
message: string;
|
|
115
|
+
}
|
|
116
|
+
type AiResidencyResult = {
|
|
117
|
+
ok: true;
|
|
118
|
+
value: AiEndpointResidency;
|
|
119
|
+
} | {
|
|
120
|
+
ok: false;
|
|
121
|
+
error: AiResidencyError;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Validates a residency declared by a deployment — from config, an env file, a
|
|
125
|
+
* database row — before any call is made. A missing one is
|
|
126
|
+
* `ai_residency_undeclared`: an endpoint whose data location nobody stated is
|
|
127
|
+
* refused, never assumed to be local. A vendor region needs the legal name and
|
|
128
|
+
* the ISO country a subprocessor annex prints.
|
|
129
|
+
*/
|
|
130
|
+
declare function resolveEndpointResidency(declared: unknown): AiResidencyResult;
|
|
131
|
+
/** Whether calling an endpoint with this residency makes its operator a subprocessor. A self-hosted endpoint does not. */
|
|
132
|
+
declare function isSubprocessorResidency(residency: AiEndpointResidency): boolean;
|
|
133
|
+
//#endregion
|
|
134
|
+
export { isSubprocessorResidency as C, embeddingDimensionsFor as S, EmbeddingProviderMeta as _, AiProcessingRegion as a, OpenAiCompatibleProviderId as b, AiProviderModelOption as c, AiVendorResidency as d, DEFAULT_AI_PROVIDER as f, EmbeddingProviderId as g, EMBEDDING_PROVIDER_IDS as h, AiEndpointResidency as i, AiResidencyError as l, EMBEDDING_PROVIDERS as m, AI_PROVIDER_IDS as n, AiProviderId as o, DEFAULT_EMBEDDING_PROVIDER as p, AiEndpointRegion as r, AiProviderMeta as s, AI_PROVIDERS as t, AiResidencyResult as u, OPENAI_COMPATIBLE_PROVIDER as v, resolveEndpointResidency as w, OpenAiCompatibleProviderMeta as x, OPENAI_COMPATIBLE_PROVIDER_ID as y };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "octaflow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.24.0",
|
|
4
4
|
"description": "Durable DAG workflow engine: Zod-typed steps over Postgres + pg-boss, with an optional AI add-on (token/cost/quota). Layered single package.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -71,6 +71,7 @@
|
|
|
71
71
|
"@ai-sdk/anthropic": "^4.0.0",
|
|
72
72
|
"@ai-sdk/mistral": "^4.0.0",
|
|
73
73
|
"@ai-sdk/openai": "^4.0.0",
|
|
74
|
+
"@ai-sdk/openai-compatible": "^3.0.0",
|
|
74
75
|
"@ai-sdk/provider": "^4.0.0",
|
|
75
76
|
"ai": "^7.0.0",
|
|
76
77
|
"pg": "^8.0.0",
|
|
@@ -88,6 +89,9 @@
|
|
|
88
89
|
"@ai-sdk/openai": {
|
|
89
90
|
"optional": true
|
|
90
91
|
},
|
|
92
|
+
"@ai-sdk/openai-compatible": {
|
|
93
|
+
"optional": true
|
|
94
|
+
},
|
|
91
95
|
"@ai-sdk/provider": {
|
|
92
96
|
"optional": true
|
|
93
97
|
},
|
|
@@ -105,6 +109,7 @@
|
|
|
105
109
|
"@ai-sdk/anthropic": "^4.0.52",
|
|
106
110
|
"@ai-sdk/mistral": "^4.0.42",
|
|
107
111
|
"@ai-sdk/openai": "^4.0.65",
|
|
112
|
+
"@ai-sdk/openai-compatible": "^3.0.48",
|
|
108
113
|
"@ai-sdk/provider": "^4.0.13",
|
|
109
114
|
"@testcontainers/postgresql": "^12.1.0",
|
|
110
115
|
"@types/node": "^26.5.1",
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
//#region src/ai/provider-registry.ts
|
|
2
|
-
/**
|
|
3
|
-
* The provider registry — pure metadata about the vendors a BYOK deployment
|
|
4
|
-
* can point at: ids, default and cheap models, where a key is created, and
|
|
5
|
-
* **where the vendor processes what you send it**. Dependency-free, so a
|
|
6
|
-
* browser bundle (a provider/model picker, a residency badge) can import it;
|
|
7
|
-
* the SDK factories that need `@ai-sdk/*` live in `octaflow/ai/providers`.
|
|
8
|
-
*
|
|
9
|
-
* Adding a provider: an id here with its metadata, a factory in
|
|
10
|
-
* `providers/`, and pricing rows in `cost.ts`.
|
|
11
|
-
*/
|
|
12
|
-
const AI_PROVIDER_IDS = ["anthropic", "mistral"];
|
|
13
|
-
const EMBEDDING_PROVIDER_IDS = ["openai", "mistral"];
|
|
14
|
-
/** What an unset provider resolves to. */
|
|
15
|
-
const DEFAULT_AI_PROVIDER = "anthropic";
|
|
16
|
-
const DEFAULT_EMBEDDING_PROVIDER = "openai";
|
|
17
|
-
const AI_PROVIDERS = {
|
|
18
|
-
anthropic: {
|
|
19
|
-
id: "anthropic",
|
|
20
|
-
label: "Anthropic",
|
|
21
|
-
residency: {
|
|
22
|
-
region: "third-country",
|
|
23
|
-
legalName: "Anthropic PBC",
|
|
24
|
-
country: "US"
|
|
25
|
-
},
|
|
26
|
-
defaultModel: "claude-sonnet-5",
|
|
27
|
-
classifierModel: "claude-haiku-4-5",
|
|
28
|
-
testModel: "claude-haiku-4-5",
|
|
29
|
-
keyPrefix: "sk-ant-",
|
|
30
|
-
consoleKeyUrl: "https://console.anthropic.com/settings/keys",
|
|
31
|
-
modelOptions: [
|
|
32
|
-
{
|
|
33
|
-
label: "Claude Opus 5",
|
|
34
|
-
value: "claude-opus-5"
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
label: "Claude Opus 4.8",
|
|
38
|
-
value: "claude-opus-4-8"
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
label: "Claude Sonnet 5",
|
|
42
|
-
value: "claude-sonnet-5"
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
label: "Claude Haiku 4.5",
|
|
46
|
-
value: "claude-haiku-4-5"
|
|
47
|
-
}
|
|
48
|
-
]
|
|
49
|
-
},
|
|
50
|
-
mistral: {
|
|
51
|
-
id: "mistral",
|
|
52
|
-
label: "Mistral",
|
|
53
|
-
residency: {
|
|
54
|
-
region: "eu",
|
|
55
|
-
legalName: "Mistral AI SAS",
|
|
56
|
-
country: "FR"
|
|
57
|
-
},
|
|
58
|
-
defaultModel: "mistral-medium-latest",
|
|
59
|
-
classifierModel: "mistral-small-latest",
|
|
60
|
-
testModel: "mistral-small-latest",
|
|
61
|
-
keyPrefix: null,
|
|
62
|
-
consoleKeyUrl: "https://console.mistral.ai/api-keys",
|
|
63
|
-
modelOptions: [
|
|
64
|
-
{
|
|
65
|
-
label: "Mistral Medium 3.5",
|
|
66
|
-
value: "mistral-medium-latest"
|
|
67
|
-
},
|
|
68
|
-
{
|
|
69
|
-
label: "Mistral Large 3",
|
|
70
|
-
value: "mistral-large-latest"
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
label: "Mistral Small 4",
|
|
74
|
-
value: "mistral-small-latest"
|
|
75
|
-
}
|
|
76
|
-
]
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
const EMBEDDING_PROVIDERS = {
|
|
80
|
-
openai: {
|
|
81
|
-
id: "openai",
|
|
82
|
-
label: "OpenAI",
|
|
83
|
-
residency: {
|
|
84
|
-
region: "third-country",
|
|
85
|
-
legalName: "OpenAI, L.L.C.",
|
|
86
|
-
country: "US"
|
|
87
|
-
},
|
|
88
|
-
defaultModel: "text-embedding-3-small",
|
|
89
|
-
consoleKeyUrl: "https://platform.openai.com/api-keys",
|
|
90
|
-
dimensionsByModel: {
|
|
91
|
-
"text-embedding-3-small": 1536,
|
|
92
|
-
"text-embedding-3-large": 3072
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
mistral: {
|
|
96
|
-
id: "mistral",
|
|
97
|
-
label: "Mistral",
|
|
98
|
-
residency: {
|
|
99
|
-
region: "eu",
|
|
100
|
-
legalName: "Mistral AI SAS",
|
|
101
|
-
country: "FR"
|
|
102
|
-
},
|
|
103
|
-
defaultModel: "mistral-embed",
|
|
104
|
-
consoleKeyUrl: "https://console.mistral.ai/api-keys",
|
|
105
|
-
dimensionsByModel: { "mistral-embed": 1024 }
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
/**
|
|
109
|
-
* Vector dimensions for an embedding model id. Unknown ids fall back to
|
|
110
|
-
* `fallback` (default 1536, the common OpenAI-compatible dimension) so
|
|
111
|
-
* free-form model ids keep a working column.
|
|
112
|
-
*/
|
|
113
|
-
function embeddingDimensionsFor(modelId, fallback = 1536) {
|
|
114
|
-
for (const meta of Object.values(EMBEDDING_PROVIDERS)) {
|
|
115
|
-
const dims = meta.dimensionsByModel[modelId];
|
|
116
|
-
if (dims !== void 0) return dims;
|
|
117
|
-
}
|
|
118
|
-
return fallback;
|
|
119
|
-
}
|
|
120
|
-
//#endregion
|
|
121
|
-
export { EMBEDDING_PROVIDERS as a, DEFAULT_EMBEDDING_PROVIDER as i, AI_PROVIDER_IDS as n, EMBEDDING_PROVIDER_IDS as o, DEFAULT_AI_PROVIDER as r, embeddingDimensionsFor as s, AI_PROVIDERS as t };
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
//#region src/ai/provider-registry.d.ts
|
|
2
|
-
/**
|
|
3
|
-
* The provider registry — pure metadata about the vendors a BYOK deployment
|
|
4
|
-
* can point at: ids, default and cheap models, where a key is created, and
|
|
5
|
-
* **where the vendor processes what you send it**. Dependency-free, so a
|
|
6
|
-
* browser bundle (a provider/model picker, a residency badge) can import it;
|
|
7
|
-
* the SDK factories that need `@ai-sdk/*` live in `octaflow/ai/providers`.
|
|
8
|
-
*
|
|
9
|
-
* Adding a provider: an id here with its metadata, a factory in
|
|
10
|
-
* `providers/`, and pricing rows in `cost.ts`.
|
|
11
|
-
*/
|
|
12
|
-
declare const AI_PROVIDER_IDS: readonly ['anthropic', 'mistral'];
|
|
13
|
-
type AiProviderId = (typeof AI_PROVIDER_IDS)[number];
|
|
14
|
-
declare const EMBEDDING_PROVIDER_IDS: readonly ['openai', 'mistral'];
|
|
15
|
-
type EmbeddingProviderId = (typeof EMBEDDING_PROVIDER_IDS)[number];
|
|
16
|
-
/** What an unset provider resolves to. */
|
|
17
|
-
declare const DEFAULT_AI_PROVIDER: AiProviderId;
|
|
18
|
-
declare const DEFAULT_EMBEDDING_PROVIDER: EmbeddingProviderId;
|
|
19
|
-
/**
|
|
20
|
-
* Where a provider processes the payloads you send it.
|
|
21
|
-
*
|
|
22
|
-
* `'eu'` means the vendor is established in the EU/EEA and serves the API from
|
|
23
|
-
* there, so a call carries no third-country transfer under Art. 44 ff. GDPR.
|
|
24
|
-
* `'third-country'` means it does — your data-processing agreement then has
|
|
25
|
-
* to carry a transfer mechanism for that vendor.
|
|
26
|
-
*
|
|
27
|
-
* This is metadata about the *vendor endpoint called*, not a promise about a
|
|
28
|
-
* customer's own BYOK key: a customer who brings their own key contracts with
|
|
29
|
-
* the vendor directly.
|
|
30
|
-
*/
|
|
31
|
-
type AiProcessingRegion = 'eu' | 'third-country';
|
|
32
|
-
interface AiVendorResidency {
|
|
33
|
-
region: AiProcessingRegion;
|
|
34
|
-
/** Legal entity, as it appears in a subprocessor annex. */
|
|
35
|
-
legalName: string;
|
|
36
|
-
/** Country of establishment, ISO 3166-1 alpha-2. */
|
|
37
|
-
country: string;
|
|
38
|
-
}
|
|
39
|
-
interface AiProviderModelOption {
|
|
40
|
-
label: string;
|
|
41
|
-
value: string;
|
|
42
|
-
}
|
|
43
|
-
interface AiProviderMeta {
|
|
44
|
-
id: AiProviderId;
|
|
45
|
-
label: string;
|
|
46
|
-
/** Where calls to this provider are processed — drives a residency badge and the subprocessor analysis. */
|
|
47
|
-
residency: AiVendorResidency;
|
|
48
|
-
/** Default chat/workflow model when nothing sets one. */
|
|
49
|
-
defaultModel: string;
|
|
50
|
-
/** Cheap model for classifier-style passes. */
|
|
51
|
-
classifierModel: string;
|
|
52
|
-
/** Cheap model for a "test connection" ping. */
|
|
53
|
-
testModel: string;
|
|
54
|
-
/** Well-known API key prefix for a soft format hint, or null when the provider has none. */
|
|
55
|
-
keyPrefix: string | null;
|
|
56
|
-
/** Where the operator creates an API key. */
|
|
57
|
-
consoleKeyUrl: string;
|
|
58
|
-
/** Curated model choices for a picker (free-form custom ids stay allowed). */
|
|
59
|
-
modelOptions: AiProviderModelOption[];
|
|
60
|
-
}
|
|
61
|
-
declare const AI_PROVIDERS: Record<AiProviderId, AiProviderMeta>;
|
|
62
|
-
interface EmbeddingProviderMeta {
|
|
63
|
-
id: EmbeddingProviderId;
|
|
64
|
-
label: string;
|
|
65
|
-
/** See {@link AiProviderMeta.residency}. */
|
|
66
|
-
residency: AiVendorResidency;
|
|
67
|
-
defaultModel: string;
|
|
68
|
-
/** Where the operator creates an API key. */
|
|
69
|
-
consoleKeyUrl: string;
|
|
70
|
-
/** Vector dimensions per known model id — must match the `vector(N)` column in your schema. */
|
|
71
|
-
dimensionsByModel: Record<string, number>;
|
|
72
|
-
}
|
|
73
|
-
declare const EMBEDDING_PROVIDERS: Record<EmbeddingProviderId, EmbeddingProviderMeta>;
|
|
74
|
-
/**
|
|
75
|
-
* Vector dimensions for an embedding model id. Unknown ids fall back to
|
|
76
|
-
* `fallback` (default 1536, the common OpenAI-compatible dimension) so
|
|
77
|
-
* free-form model ids keep a working column.
|
|
78
|
-
*/
|
|
79
|
-
declare function embeddingDimensionsFor(modelId: string, fallback?: number): number;
|
|
80
|
-
//#endregion
|
|
81
|
-
export { AiProviderMeta as a, DEFAULT_AI_PROVIDER as c, EMBEDDING_PROVIDER_IDS as d, EmbeddingProviderId as f, AiProviderId as i, DEFAULT_EMBEDDING_PROVIDER as l, embeddingDimensionsFor as m, AI_PROVIDER_IDS as n, AiProviderModelOption as o, EmbeddingProviderMeta as p, AiProcessingRegion as r, AiVendorResidency as s, AI_PROVIDERS as t, EMBEDDING_PROVIDERS as u };
|