@hebo-ai/gateway 0.6.2-rc0 → 0.6.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.
- package/README.md +3 -3
- package/dist/endpoints/chat-completions/converters.js +26 -21
- package/dist/endpoints/chat-completions/handler.js +2 -0
- package/dist/endpoints/chat-completions/otel.js +1 -1
- package/dist/endpoints/chat-completions/schema.d.ts +4 -18
- package/dist/endpoints/chat-completions/schema.js +14 -17
- package/dist/endpoints/embeddings/handler.js +2 -0
- package/dist/endpoints/embeddings/otel.js +5 -0
- package/dist/endpoints/embeddings/schema.d.ts +6 -0
- package/dist/endpoints/embeddings/schema.js +4 -1
- package/dist/endpoints/models/converters.js +3 -3
- package/dist/lifecycle.js +2 -2
- package/dist/logger/default.js +3 -3
- package/dist/logger/index.d.ts +2 -5
- package/dist/middleware/common.js +1 -0
- package/dist/middleware/utils.js +0 -3
- package/dist/models/amazon/middleware.js +8 -5
- package/dist/models/anthropic/middleware.js +13 -13
- package/dist/models/catalog.js +5 -1
- package/dist/models/cohere/middleware.js +7 -5
- package/dist/models/google/middleware.d.ts +1 -1
- package/dist/models/google/middleware.js +29 -25
- package/dist/models/openai/middleware.js +13 -9
- package/dist/models/voyage/middleware.js +2 -1
- package/dist/providers/bedrock/middleware.js +21 -23
- package/dist/providers/registry.js +3 -0
- package/dist/telemetry/fetch.js +7 -2
- package/dist/telemetry/gen-ai.js +15 -12
- package/dist/telemetry/memory.d.ts +1 -1
- package/dist/telemetry/memory.js +30 -14
- package/dist/telemetry/span.js +1 -1
- package/dist/telemetry/stream.js +30 -23
- package/dist/utils/env.js +4 -2
- package/dist/utils/preset.js +1 -0
- package/dist/utils/response.js +3 -1
- package/package.json +36 -50
- package/src/config.ts +0 -98
- package/src/endpoints/chat-completions/converters.test.ts +0 -631
- package/src/endpoints/chat-completions/converters.ts +0 -899
- package/src/endpoints/chat-completions/handler.test.ts +0 -391
- package/src/endpoints/chat-completions/handler.ts +0 -201
- package/src/endpoints/chat-completions/index.ts +0 -4
- package/src/endpoints/chat-completions/otel.test.ts +0 -315
- package/src/endpoints/chat-completions/otel.ts +0 -214
- package/src/endpoints/chat-completions/schema.ts +0 -364
- package/src/endpoints/embeddings/converters.ts +0 -51
- package/src/endpoints/embeddings/handler.test.ts +0 -133
- package/src/endpoints/embeddings/handler.ts +0 -137
- package/src/endpoints/embeddings/index.ts +0 -4
- package/src/endpoints/embeddings/otel.ts +0 -40
- package/src/endpoints/embeddings/schema.ts +0 -36
- package/src/endpoints/models/converters.ts +0 -56
- package/src/endpoints/models/handler.test.ts +0 -122
- package/src/endpoints/models/handler.ts +0 -37
- package/src/endpoints/models/index.ts +0 -3
- package/src/endpoints/models/schema.ts +0 -37
- package/src/errors/ai-sdk.ts +0 -99
- package/src/errors/gateway.ts +0 -17
- package/src/errors/openai.ts +0 -57
- package/src/errors/utils.ts +0 -47
- package/src/gateway.ts +0 -50
- package/src/index.ts +0 -19
- package/src/lifecycle.ts +0 -135
- package/src/logger/default.ts +0 -105
- package/src/logger/index.ts +0 -42
- package/src/middleware/common.test.ts +0 -215
- package/src/middleware/common.ts +0 -163
- package/src/middleware/debug.ts +0 -37
- package/src/middleware/matcher.ts +0 -161
- package/src/middleware/utils.ts +0 -34
- package/src/models/amazon/index.ts +0 -2
- package/src/models/amazon/middleware.test.ts +0 -133
- package/src/models/amazon/middleware.ts +0 -79
- package/src/models/amazon/presets.ts +0 -104
- package/src/models/anthropic/index.ts +0 -2
- package/src/models/anthropic/middleware.test.ts +0 -643
- package/src/models/anthropic/middleware.ts +0 -148
- package/src/models/anthropic/presets.ts +0 -191
- package/src/models/catalog.ts +0 -13
- package/src/models/cohere/index.ts +0 -2
- package/src/models/cohere/middleware.test.ts +0 -138
- package/src/models/cohere/middleware.ts +0 -76
- package/src/models/cohere/presets.ts +0 -186
- package/src/models/google/index.ts +0 -2
- package/src/models/google/middleware.test.ts +0 -298
- package/src/models/google/middleware.ts +0 -137
- package/src/models/google/presets.ts +0 -118
- package/src/models/meta/index.ts +0 -1
- package/src/models/meta/presets.ts +0 -143
- package/src/models/openai/index.ts +0 -2
- package/src/models/openai/middleware.test.ts +0 -189
- package/src/models/openai/middleware.ts +0 -103
- package/src/models/openai/presets.ts +0 -280
- package/src/models/types.ts +0 -114
- package/src/models/voyage/index.ts +0 -2
- package/src/models/voyage/middleware.test.ts +0 -28
- package/src/models/voyage/middleware.ts +0 -23
- package/src/models/voyage/presets.ts +0 -126
- package/src/providers/anthropic/canonical.ts +0 -17
- package/src/providers/anthropic/index.ts +0 -1
- package/src/providers/bedrock/canonical.ts +0 -87
- package/src/providers/bedrock/index.ts +0 -2
- package/src/providers/bedrock/middleware.test.ts +0 -303
- package/src/providers/bedrock/middleware.ts +0 -128
- package/src/providers/cohere/canonical.ts +0 -26
- package/src/providers/cohere/index.ts +0 -1
- package/src/providers/groq/canonical.ts +0 -21
- package/src/providers/groq/index.ts +0 -1
- package/src/providers/openai/canonical.ts +0 -16
- package/src/providers/openai/index.ts +0 -1
- package/src/providers/registry.test.ts +0 -44
- package/src/providers/registry.ts +0 -165
- package/src/providers/types.ts +0 -20
- package/src/providers/vertex/canonical.ts +0 -17
- package/src/providers/vertex/index.ts +0 -1
- package/src/providers/voyage/canonical.ts +0 -16
- package/src/providers/voyage/index.ts +0 -1
- package/src/telemetry/ai-sdk.ts +0 -46
- package/src/telemetry/baggage.ts +0 -27
- package/src/telemetry/fetch.ts +0 -62
- package/src/telemetry/gen-ai.ts +0 -113
- package/src/telemetry/http.ts +0 -62
- package/src/telemetry/index.ts +0 -1
- package/src/telemetry/memory.ts +0 -36
- package/src/telemetry/span.ts +0 -85
- package/src/telemetry/stream.ts +0 -64
- package/src/types.ts +0 -223
- package/src/utils/env.ts +0 -7
- package/src/utils/headers.ts +0 -27
- package/src/utils/preset.ts +0 -65
- package/src/utils/request.test.ts +0 -75
- package/src/utils/request.ts +0 -52
- package/src/utils/response.ts +0 -84
- package/src/utils/url.ts +0 -26
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import type { EmbeddingModelMiddleware, LanguageModelMiddleware } from "ai";
|
|
2
|
-
|
|
3
|
-
import type { ModelId } from "../models/types";
|
|
4
|
-
import type { ProviderId } from "../providers/types";
|
|
5
|
-
|
|
6
|
-
import { logger } from "../logger";
|
|
7
|
-
import { addSpanEvent } from "../telemetry/span";
|
|
8
|
-
import { forwardParamsEmbeddingMiddleware, forwardParamsMiddleware } from "./common";
|
|
9
|
-
import { debugEmbeddingFinalParamsMiddleware, debugFinalParamsMiddleware } from "./debug";
|
|
10
|
-
|
|
11
|
-
type MiddlewareEntries = {
|
|
12
|
-
language?: LanguageModelMiddleware[];
|
|
13
|
-
embedding?: EmbeddingModelMiddleware[];
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
type Rule = {
|
|
17
|
-
pattern: string;
|
|
18
|
-
test: (key: string) => boolean;
|
|
19
|
-
stored: MiddlewareEntries;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
type ModelMiddleware = LanguageModelMiddleware | EmbeddingModelMiddleware;
|
|
23
|
-
|
|
24
|
-
class SimpleMatcher {
|
|
25
|
-
private rules: Rule[] = [];
|
|
26
|
-
|
|
27
|
-
use(pattern: string, entry: MiddlewareEntries) {
|
|
28
|
-
const stored: MiddlewareEntries = {
|
|
29
|
-
language: entry.language ? [...entry.language] : undefined,
|
|
30
|
-
embedding: entry.embedding ? [...entry.embedding] : undefined,
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
this.rules.push({ pattern, test: compilePattern(pattern), stored });
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
match(key: string): MiddlewareEntries[] {
|
|
37
|
-
const out: MiddlewareEntries[] = [];
|
|
38
|
-
const matched: string[] = [];
|
|
39
|
-
for (const r of this.rules) {
|
|
40
|
-
if (!r.test(key)) continue;
|
|
41
|
-
out.push(r.stored);
|
|
42
|
-
matched.push(r.pattern);
|
|
43
|
-
}
|
|
44
|
-
const matchedSummary = matched.length > 0 ? matched.join(",") : "none";
|
|
45
|
-
logger.debug(`[middleware] matched ${key} to [${matchedSummary}]`);
|
|
46
|
-
return out;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
class ModelMiddlewareMatcher {
|
|
51
|
-
private model = new SimpleMatcher();
|
|
52
|
-
private provider = new SimpleMatcher();
|
|
53
|
-
|
|
54
|
-
private static readonly MAX_CACHE = 500;
|
|
55
|
-
private cache = new Map<string, ModelMiddleware[]>();
|
|
56
|
-
|
|
57
|
-
useForModel(patterns: ModelId | readonly ModelId[], entry: MiddlewareEntries) {
|
|
58
|
-
this.cache.clear();
|
|
59
|
-
for (const pattern of toArray(patterns)) {
|
|
60
|
-
this.model.use(pattern, entry);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
useForProvider(patterns: ProviderId | readonly ProviderId[], entry: MiddlewareEntries) {
|
|
65
|
-
this.cache.clear();
|
|
66
|
-
for (const pattern of toArray(patterns)) {
|
|
67
|
-
this.provider.use(pattern, entry);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
for(modelId: ModelId, providerId: ProviderId): LanguageModelMiddleware[] {
|
|
72
|
-
return this.resolve({
|
|
73
|
-
kind: "text",
|
|
74
|
-
modelId,
|
|
75
|
-
providerId,
|
|
76
|
-
forward: () => forwardParamsMiddleware(providerId),
|
|
77
|
-
debug: debugFinalParamsMiddleware,
|
|
78
|
-
}) as LanguageModelMiddleware[];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
forEmbedding(modelId: ModelId, providerId: ProviderId): EmbeddingModelMiddleware[] {
|
|
82
|
-
return this.resolve({
|
|
83
|
-
kind: "embedding",
|
|
84
|
-
modelId,
|
|
85
|
-
providerId,
|
|
86
|
-
forward: () => forwardParamsEmbeddingMiddleware(providerId),
|
|
87
|
-
debug: debugEmbeddingFinalParamsMiddleware,
|
|
88
|
-
}) as EmbeddingModelMiddleware[];
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
resolve(options: {
|
|
92
|
-
kind: "text" | "embedding";
|
|
93
|
-
modelId?: ModelId;
|
|
94
|
-
providerId?: ProviderId;
|
|
95
|
-
forward?: ModelMiddleware | (() => ModelMiddleware);
|
|
96
|
-
debug?: ModelMiddleware;
|
|
97
|
-
}): ModelMiddleware[] {
|
|
98
|
-
const { kind, modelId, providerId, forward, debug } = options;
|
|
99
|
-
|
|
100
|
-
const key = `${kind}-${modelId}:${providerId}`;
|
|
101
|
-
const cached = this.cache.get(key);
|
|
102
|
-
if (cached) {
|
|
103
|
-
logger.debug(`[middleware] cache hit for ${modelId}:${providerId}`);
|
|
104
|
-
return cached;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const out: ModelMiddleware[] = [];
|
|
108
|
-
if (modelId) {
|
|
109
|
-
out.push(...this.collect(this.model.match(modelId), kind));
|
|
110
|
-
}
|
|
111
|
-
if (forward) {
|
|
112
|
-
out.push(typeof forward === "function" ? forward() : forward);
|
|
113
|
-
}
|
|
114
|
-
if (providerId) {
|
|
115
|
-
out.push(...this.collect(this.provider.match(providerId), kind));
|
|
116
|
-
}
|
|
117
|
-
if (debug) {
|
|
118
|
-
out.push(debug);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (this.cache.size >= ModelMiddlewareMatcher.MAX_CACHE) {
|
|
122
|
-
let n = Math.ceil(ModelMiddlewareMatcher.MAX_CACHE * 0.2);
|
|
123
|
-
for (const cacheKey of this.cache.keys()) {
|
|
124
|
-
this.cache.delete(cacheKey);
|
|
125
|
-
if (--n === 0) break;
|
|
126
|
-
}
|
|
127
|
-
logger.warn(`[middleware] cache eviction`);
|
|
128
|
-
addSpanEvent("hebo.middleware.cache.evicted");
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
this.cache.set(key, out);
|
|
132
|
-
return out;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
private collect(entries: MiddlewareEntries[], kind: "text" | "embedding"): ModelMiddleware[] {
|
|
136
|
-
const out: ModelMiddleware[] = [];
|
|
137
|
-
for (const s of entries) {
|
|
138
|
-
if (kind === "text") out.push(...(s.language ?? []));
|
|
139
|
-
else out.push(...(s.embedding ?? []));
|
|
140
|
-
}
|
|
141
|
-
return out;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export const modelMiddlewareMatcher = new ModelMiddlewareMatcher();
|
|
146
|
-
export type { ModelMiddlewareMatcher };
|
|
147
|
-
|
|
148
|
-
const toArray = <T>(v: T | readonly T[]) => (Array.isArray(v) ? v : [v]);
|
|
149
|
-
|
|
150
|
-
function compilePattern(pattern: string): (key: string) => boolean {
|
|
151
|
-
if (!pattern.includes("*")) return (key) => key === pattern;
|
|
152
|
-
|
|
153
|
-
const re = new RegExp(
|
|
154
|
-
`^${pattern
|
|
155
|
-
.split("*")
|
|
156
|
-
.map((p) => p.replaceAll(/[-\\^$+?.()|[\]{}]/g, "\\$&"))
|
|
157
|
-
.join(".*")}$`,
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
return (key) => re.test(key);
|
|
161
|
-
}
|
package/src/middleware/utils.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { ChatCompletionsReasoningEffort } from "../endpoints/chat-completions/schema";
|
|
2
|
-
|
|
3
|
-
export function calculateReasoningBudgetFromEffort(
|
|
4
|
-
effort: ChatCompletionsReasoningEffort,
|
|
5
|
-
maxTokens: number,
|
|
6
|
-
minTokens: number = 1024,
|
|
7
|
-
): number {
|
|
8
|
-
let percentage = 0;
|
|
9
|
-
switch (effort) {
|
|
10
|
-
case "none":
|
|
11
|
-
percentage = 0;
|
|
12
|
-
break;
|
|
13
|
-
case "minimal":
|
|
14
|
-
percentage = 0.1;
|
|
15
|
-
break;
|
|
16
|
-
case "low":
|
|
17
|
-
percentage = 0.2;
|
|
18
|
-
break;
|
|
19
|
-
case "medium":
|
|
20
|
-
percentage = 0.5;
|
|
21
|
-
break;
|
|
22
|
-
case "high":
|
|
23
|
-
percentage = 0.8;
|
|
24
|
-
break;
|
|
25
|
-
case "xhigh":
|
|
26
|
-
case "max":
|
|
27
|
-
percentage = 0.95;
|
|
28
|
-
break;
|
|
29
|
-
default:
|
|
30
|
-
return 0;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return Math.max(minTokens, Math.floor(maxTokens * percentage));
|
|
34
|
-
}
|
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { MockLanguageModelV3 } from "ai/test";
|
|
2
|
-
import { expect, test } from "bun:test";
|
|
3
|
-
|
|
4
|
-
import { modelMiddlewareMatcher } from "../../middleware/matcher";
|
|
5
|
-
import { CANONICAL_MODEL_IDS } from "../../models/types";
|
|
6
|
-
import { novaDimensionsMiddleware, novaReasoningMiddleware } from "./middleware";
|
|
7
|
-
|
|
8
|
-
test("nova middleware > matching patterns", () => {
|
|
9
|
-
const languageMatching = ["amazon/nova-2-lite"] satisfies (typeof CANONICAL_MODEL_IDS)[number][];
|
|
10
|
-
|
|
11
|
-
const languageNonMatching = [
|
|
12
|
-
"amazon/nova-micro",
|
|
13
|
-
"amazon/nova-lite",
|
|
14
|
-
"amazon/nova-pro",
|
|
15
|
-
"amazon/nova-premier",
|
|
16
|
-
] satisfies (typeof CANONICAL_MODEL_IDS)[number][];
|
|
17
|
-
|
|
18
|
-
for (const id of languageMatching) {
|
|
19
|
-
const middleware = modelMiddlewareMatcher.resolve({ kind: "text", modelId: id });
|
|
20
|
-
expect(middleware).toContain(novaReasoningMiddleware);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
for (const id of languageNonMatching) {
|
|
24
|
-
const middleware = modelMiddlewareMatcher.resolve({ kind: "text", modelId: id });
|
|
25
|
-
expect(middleware).not.toContain(novaReasoningMiddleware);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const embeddingMatching = [
|
|
29
|
-
"amazon/nova-2-multimodal-embeddings",
|
|
30
|
-
] satisfies (typeof CANONICAL_MODEL_IDS)[number][];
|
|
31
|
-
|
|
32
|
-
const embeddingNonMatching = [
|
|
33
|
-
"amazon/nova-2-lite",
|
|
34
|
-
] satisfies (typeof CANONICAL_MODEL_IDS)[number][];
|
|
35
|
-
|
|
36
|
-
for (const id of embeddingMatching) {
|
|
37
|
-
const middleware = modelMiddlewareMatcher.resolve({ kind: "embedding", modelId: id });
|
|
38
|
-
expect(middleware).toContain(novaDimensionsMiddleware);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
for (const id of embeddingNonMatching) {
|
|
42
|
-
const middleware = modelMiddlewareMatcher.resolve({ kind: "embedding", modelId: id });
|
|
43
|
-
expect(middleware).not.toContain(novaDimensionsMiddleware);
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
test("novaReasoningMiddleware > should map effort to Bedrock reasoning config", async () => {
|
|
48
|
-
const params = {
|
|
49
|
-
prompt: [],
|
|
50
|
-
providerOptions: {
|
|
51
|
-
unknown: {
|
|
52
|
-
reasoning: { enabled: true, effort: "low" },
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const result = await novaReasoningMiddleware.transformParams!({
|
|
58
|
-
type: "generate",
|
|
59
|
-
params,
|
|
60
|
-
model: new MockLanguageModelV3(),
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
expect(result).toEqual({
|
|
64
|
-
prompt: [],
|
|
65
|
-
providerOptions: {
|
|
66
|
-
amazon: {
|
|
67
|
-
reasoningConfig: {
|
|
68
|
-
type: "enabled",
|
|
69
|
-
maxReasoningEffort: "low",
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
unknown: {},
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
test("novaReasoningMiddleware > should disable reasoning when requested", async () => {
|
|
78
|
-
const params = {
|
|
79
|
-
prompt: [],
|
|
80
|
-
providerOptions: {
|
|
81
|
-
unknown: {
|
|
82
|
-
reasoning: { enabled: false },
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
const result = await novaReasoningMiddleware.transformParams!({
|
|
88
|
-
type: "generate",
|
|
89
|
-
params,
|
|
90
|
-
model: new MockLanguageModelV3(),
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
expect(result).toEqual({
|
|
94
|
-
prompt: [],
|
|
95
|
-
providerOptions: {
|
|
96
|
-
amazon: {
|
|
97
|
-
reasoningConfig: {
|
|
98
|
-
type: "disabled",
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
unknown: {},
|
|
102
|
-
},
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
test("novaReasoningMiddleware > should default reasoning effort when enabled without effort", async () => {
|
|
107
|
-
const params = {
|
|
108
|
-
prompt: [],
|
|
109
|
-
providerOptions: {
|
|
110
|
-
unknown: {
|
|
111
|
-
reasoning: { enabled: true },
|
|
112
|
-
},
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const result = await novaReasoningMiddleware.transformParams!({
|
|
117
|
-
type: "generate",
|
|
118
|
-
params,
|
|
119
|
-
model: new MockLanguageModelV3(),
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
expect(result).toEqual({
|
|
123
|
-
prompt: [],
|
|
124
|
-
providerOptions: {
|
|
125
|
-
amazon: {
|
|
126
|
-
reasoningConfig: {
|
|
127
|
-
type: "enabled",
|
|
128
|
-
},
|
|
129
|
-
},
|
|
130
|
-
unknown: {},
|
|
131
|
-
},
|
|
132
|
-
});
|
|
133
|
-
});
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import type { EmbeddingModelMiddleware, LanguageModelMiddleware } from "ai";
|
|
2
|
-
|
|
3
|
-
import type {
|
|
4
|
-
ChatCompletionsReasoningConfig,
|
|
5
|
-
ChatCompletionsReasoningEffort,
|
|
6
|
-
} from "../../endpoints/chat-completions/schema";
|
|
7
|
-
|
|
8
|
-
import { modelMiddlewareMatcher } from "../../middleware/matcher";
|
|
9
|
-
|
|
10
|
-
// Convert `dimensions` (OpenAI) to `embeddingDimension` (Nova)
|
|
11
|
-
export const novaDimensionsMiddleware: EmbeddingModelMiddleware = {
|
|
12
|
-
specificationVersion: "v3",
|
|
13
|
-
// oxlint-disable-next-line require-await
|
|
14
|
-
transformParams: async ({ params }) => {
|
|
15
|
-
const unknown = params.providerOptions?.["unknown"];
|
|
16
|
-
if (!unknown) return params;
|
|
17
|
-
|
|
18
|
-
const dimensions = unknown["dimensions"] as number;
|
|
19
|
-
if (!dimensions) return params;
|
|
20
|
-
|
|
21
|
-
(params.providerOptions!["nova"] ??= {})["embeddingDimension"] = dimensions;
|
|
22
|
-
delete unknown["dimensions"];
|
|
23
|
-
|
|
24
|
-
return params;
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
function mapNovaEffort(effort: ChatCompletionsReasoningEffort) {
|
|
29
|
-
switch (effort) {
|
|
30
|
-
case "minimal":
|
|
31
|
-
case "low":
|
|
32
|
-
return "low";
|
|
33
|
-
case "medium":
|
|
34
|
-
return "medium";
|
|
35
|
-
case "high":
|
|
36
|
-
case "xhigh":
|
|
37
|
-
case "max":
|
|
38
|
-
return "high";
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export const novaReasoningMiddleware: LanguageModelMiddleware = {
|
|
43
|
-
specificationVersion: "v3",
|
|
44
|
-
// oxlint-disable-next-line require-await
|
|
45
|
-
transformParams: async ({ params }) => {
|
|
46
|
-
const unknown = params.providerOptions?.["unknown"];
|
|
47
|
-
if (!unknown) return params;
|
|
48
|
-
|
|
49
|
-
const reasoning = unknown["reasoning"] as ChatCompletionsReasoningConfig;
|
|
50
|
-
if (!reasoning) return params;
|
|
51
|
-
|
|
52
|
-
const target = (params.providerOptions!["amazon"] ??= {});
|
|
53
|
-
|
|
54
|
-
if (!reasoning.enabled) {
|
|
55
|
-
target["reasoningConfig"] = { type: "disabled" };
|
|
56
|
-
} else if (reasoning.effort) {
|
|
57
|
-
// FUTURE: warn if mapNovaEffort modified the effort
|
|
58
|
-
target["reasoningConfig"] = {
|
|
59
|
-
type: "enabled",
|
|
60
|
-
maxReasoningEffort: mapNovaEffort(reasoning.effort),
|
|
61
|
-
};
|
|
62
|
-
} else {
|
|
63
|
-
// FUTURE: warn if reasoning.max_tokens (unsupported) was ignored
|
|
64
|
-
target["reasoningConfig"] = { type: "enabled" };
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
delete unknown["reasoning"];
|
|
68
|
-
|
|
69
|
-
return params;
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
modelMiddlewareMatcher.useForModel("amazon/nova-*embeddings*", {
|
|
74
|
-
embedding: [novaDimensionsMiddleware],
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
modelMiddlewareMatcher.useForModel("amazon/nova-2-*", {
|
|
78
|
-
language: [novaReasoningMiddleware],
|
|
79
|
-
});
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import type { CanonicalProviderId } from "../../providers/types";
|
|
2
|
-
import type { CanonicalModelId, CatalogModel } from "../types";
|
|
3
|
-
|
|
4
|
-
import { presetFor, type DeepPartial } from "../../utils/preset";
|
|
5
|
-
|
|
6
|
-
const NOVA_TEXT_BASE = {
|
|
7
|
-
modalities: {
|
|
8
|
-
input: ["text"] as const,
|
|
9
|
-
output: ["text"] as const,
|
|
10
|
-
},
|
|
11
|
-
capabilities: ["tool_call", "temperature"] as const,
|
|
12
|
-
providers: ["bedrock"] as const satisfies readonly CanonicalProviderId[],
|
|
13
|
-
} satisfies DeepPartial<CatalogModel>;
|
|
14
|
-
|
|
15
|
-
const NOVA_MULTIMODAL_BASE = {
|
|
16
|
-
modalities: {
|
|
17
|
-
input: ["text", "image", "video", "pdf"] as const,
|
|
18
|
-
output: ["text"] as const,
|
|
19
|
-
},
|
|
20
|
-
capabilities: ["attachments", "tool_call", "temperature"] as const,
|
|
21
|
-
providers: ["bedrock"] as const satisfies readonly CanonicalProviderId[],
|
|
22
|
-
} satisfies DeepPartial<CatalogModel>;
|
|
23
|
-
|
|
24
|
-
const NOVA_EMBEDDINGS_BASE = {
|
|
25
|
-
modalities: {
|
|
26
|
-
input: ["text", "image", "audio", "video", "pdf"] as const,
|
|
27
|
-
output: ["embedding"] as const,
|
|
28
|
-
},
|
|
29
|
-
providers: ["bedrock"] as const satisfies readonly CanonicalProviderId[],
|
|
30
|
-
} satisfies DeepPartial<CatalogModel>;
|
|
31
|
-
|
|
32
|
-
export const novaMicro = presetFor<CanonicalModelId, CatalogModel>()("amazon/nova-micro" as const, {
|
|
33
|
-
...NOVA_TEXT_BASE,
|
|
34
|
-
name: "Amazon Nova Micro",
|
|
35
|
-
created: "2024-12-03",
|
|
36
|
-
knowledge: "2024-10",
|
|
37
|
-
context: 128000,
|
|
38
|
-
} satisfies CatalogModel);
|
|
39
|
-
|
|
40
|
-
export const novaLite = presetFor<CanonicalModelId, CatalogModel>()("amazon/nova-lite" as const, {
|
|
41
|
-
...NOVA_MULTIMODAL_BASE,
|
|
42
|
-
name: "Amazon Nova Lite",
|
|
43
|
-
created: "2024-12-03",
|
|
44
|
-
knowledge: "2024-10",
|
|
45
|
-
context: 300000,
|
|
46
|
-
} satisfies CatalogModel);
|
|
47
|
-
|
|
48
|
-
export const novaPro = presetFor<CanonicalModelId, CatalogModel>()("amazon/nova-pro" as const, {
|
|
49
|
-
...NOVA_MULTIMODAL_BASE,
|
|
50
|
-
name: "Amazon Nova Pro",
|
|
51
|
-
created: "2024-12-03",
|
|
52
|
-
knowledge: "2024-10",
|
|
53
|
-
context: 300000,
|
|
54
|
-
} satisfies CatalogModel);
|
|
55
|
-
|
|
56
|
-
export const novaPremier = presetFor<CanonicalModelId, CatalogModel>()(
|
|
57
|
-
"amazon/nova-premier" as const,
|
|
58
|
-
{
|
|
59
|
-
...NOVA_MULTIMODAL_BASE,
|
|
60
|
-
name: "Amazon Nova Premier",
|
|
61
|
-
created: "2024-12-03",
|
|
62
|
-
knowledge: "2024-10",
|
|
63
|
-
context: 1000000,
|
|
64
|
-
} satisfies CatalogModel,
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
export const nova2Lite = presetFor<CanonicalModelId, CatalogModel>()(
|
|
68
|
-
"amazon/nova-2-lite" as const,
|
|
69
|
-
{
|
|
70
|
-
...NOVA_TEXT_BASE,
|
|
71
|
-
name: "Amazon Nova 2 Lite",
|
|
72
|
-
created: "2025-12-01",
|
|
73
|
-
knowledge: "2024-10",
|
|
74
|
-
context: 128000,
|
|
75
|
-
} satisfies CatalogModel,
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
export const nova2MultimodalEmbeddings = presetFor<CanonicalModelId, CatalogModel>()(
|
|
79
|
-
"amazon/nova-2-multimodal-embeddings" as const,
|
|
80
|
-
{
|
|
81
|
-
...NOVA_EMBEDDINGS_BASE,
|
|
82
|
-
name: "Amazon Nova Multimodal Embeddings",
|
|
83
|
-
created: "2025-10-28",
|
|
84
|
-
context: 8000,
|
|
85
|
-
} satisfies CatalogModel,
|
|
86
|
-
);
|
|
87
|
-
|
|
88
|
-
const novaAtomic = {
|
|
89
|
-
v1: [novaMicro, novaLite, novaPro, novaPremier],
|
|
90
|
-
v2: [nova2Lite, nova2MultimodalEmbeddings],
|
|
91
|
-
} as const;
|
|
92
|
-
|
|
93
|
-
const novaGroups = {
|
|
94
|
-
"v1.x": [...novaAtomic["v1"]],
|
|
95
|
-
"v2.x": [...novaAtomic["v2"]],
|
|
96
|
-
} as const;
|
|
97
|
-
|
|
98
|
-
export const nova = {
|
|
99
|
-
...novaAtomic,
|
|
100
|
-
...novaGroups,
|
|
101
|
-
latest: [...novaAtomic["v1"], ...novaAtomic["v2"]],
|
|
102
|
-
embeddings: [nova2MultimodalEmbeddings],
|
|
103
|
-
all: Object.values(novaAtomic).flat(),
|
|
104
|
-
} as const;
|