@ax-llm/ax 11.0.21 → 11.0.23
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/index.cjs +290 -99
- package/index.cjs.map +1 -1
- package/index.d.cts +125 -36
- package/index.d.ts +125 -36
- package/index.js +287 -97
- package/index.js.map +1 -1
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -95,14 +95,15 @@ __export(index_exports, {
|
|
|
95
95
|
AxLLMRequestTypeValues: () => AxLLMRequestTypeValues,
|
|
96
96
|
AxMemory: () => AxMemory,
|
|
97
97
|
AxMockAIService: () => AxMockAIService,
|
|
98
|
+
AxMultiServiceRouter: () => AxMultiServiceRouter,
|
|
98
99
|
AxProgram: () => AxProgram,
|
|
99
100
|
AxProgramWithSignature: () => AxProgramWithSignature,
|
|
100
101
|
AxPromptTemplate: () => AxPromptTemplate,
|
|
101
102
|
AxRAG: () => AxRAG,
|
|
102
103
|
AxRateLimiterTokenUsage: () => AxRateLimiterTokenUsage,
|
|
103
|
-
AxRoute: () => AxRoute,
|
|
104
|
-
AxRouter: () => AxRouter,
|
|
105
104
|
AxSignature: () => AxSignature,
|
|
105
|
+
AxSimpleClassifier: () => AxSimpleClassifier,
|
|
106
|
+
AxSimpleClassifierClass: () => AxSimpleClassifierClass,
|
|
106
107
|
AxSpanKindValues: () => AxSpanKindValues,
|
|
107
108
|
AxTestPrompt: () => AxTestPrompt
|
|
108
109
|
});
|
|
@@ -111,26 +112,6 @@ module.exports = __toCommonJS(index_exports);
|
|
|
111
112
|
// ai/base.ts
|
|
112
113
|
var import_api2 = require("@opentelemetry/api");
|
|
113
114
|
|
|
114
|
-
// dsp/modelinfo.ts
|
|
115
|
-
function getModelInfo({
|
|
116
|
-
model,
|
|
117
|
-
modelInfo,
|
|
118
|
-
models
|
|
119
|
-
}) {
|
|
120
|
-
const mappedModel = models?.find((v) => v.key === model)?.model ?? model;
|
|
121
|
-
const exactMatch = modelInfo.find((v) => v.name === model);
|
|
122
|
-
if (exactMatch) return exactMatch;
|
|
123
|
-
const normalizedName = mappedModel.replace(/^(anthropic\.|openai\.)/, "").replace(/-latest$/, "").replace(/-\d{8}$/, "").replace(/-v\d+:\d+$/, "").replace(/@\d{8}$/, "").replace(/-\d{2,}(-[a-zA-Z0-9-]+)?$/, "").replace(/-v\d+@\d{8}$/, "").replace(/-v\d+$/, "");
|
|
124
|
-
const normalizedMatch = modelInfo.find((v) => v.name === normalizedName);
|
|
125
|
-
if (normalizedMatch) return normalizedMatch;
|
|
126
|
-
return {
|
|
127
|
-
name: model,
|
|
128
|
-
currency: "usd",
|
|
129
|
-
promptTokenCostPer1M: 0,
|
|
130
|
-
completionTokenCostPer1M: 0
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
|
|
134
115
|
// trace/trace.ts
|
|
135
116
|
var axSpanAttributes = {
|
|
136
117
|
// LLM
|
|
@@ -848,6 +829,9 @@ var AxBaseAI = class {
|
|
|
848
829
|
throw new Error("No model defined");
|
|
849
830
|
}
|
|
850
831
|
this.setOptions(options);
|
|
832
|
+
if (models) {
|
|
833
|
+
validateModels(models);
|
|
834
|
+
}
|
|
851
835
|
}
|
|
852
836
|
debug = false;
|
|
853
837
|
rt;
|
|
@@ -926,33 +910,19 @@ var AxBaseAI = class {
|
|
|
926
910
|
tracer: this.tracer
|
|
927
911
|
};
|
|
928
912
|
}
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
});
|
|
935
|
-
return {
|
|
936
|
-
...mi,
|
|
937
|
-
provider: this.name
|
|
938
|
-
};
|
|
913
|
+
getModelList() {
|
|
914
|
+
return this.models?.filter((model) => !model.isInternal)?.map((model) => ({
|
|
915
|
+
key: model.key,
|
|
916
|
+
description: model.description,
|
|
917
|
+
model: model.model
|
|
918
|
+
}));
|
|
939
919
|
}
|
|
940
|
-
|
|
941
|
-
if (!this.defaults.embedModel) {
|
|
942
|
-
return;
|
|
943
|
-
}
|
|
944
|
-
const mi = getModelInfo({
|
|
945
|
-
model: this.defaults.embedModel,
|
|
946
|
-
modelInfo: this.modelInfo
|
|
947
|
-
});
|
|
920
|
+
getDefaultModels() {
|
|
948
921
|
return {
|
|
949
|
-
|
|
950
|
-
|
|
922
|
+
model: this.defaults.model,
|
|
923
|
+
embedModel: this.defaults.embedModel
|
|
951
924
|
};
|
|
952
925
|
}
|
|
953
|
-
getModelList() {
|
|
954
|
-
return this.models;
|
|
955
|
-
}
|
|
956
926
|
getName() {
|
|
957
927
|
return this.name;
|
|
958
928
|
}
|
|
@@ -1238,14 +1208,25 @@ var AxBaseAI = class {
|
|
|
1238
1208
|
return { ...headers, ...await this.headers() };
|
|
1239
1209
|
}
|
|
1240
1210
|
};
|
|
1241
|
-
|
|
1211
|
+
function setResponseAttr(res, span) {
|
|
1242
1212
|
if (res.modelUsage) {
|
|
1243
1213
|
span.setAttributes({
|
|
1244
1214
|
[axSpanAttributes.LLM_USAGE_COMPLETION_TOKENS]: res.modelUsage.completionTokens ?? 0,
|
|
1245
1215
|
[axSpanAttributes.LLM_USAGE_PROMPT_TOKENS]: res.modelUsage.promptTokens
|
|
1246
1216
|
});
|
|
1247
1217
|
}
|
|
1248
|
-
}
|
|
1218
|
+
}
|
|
1219
|
+
function validateModels(models) {
|
|
1220
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1221
|
+
for (const model of models) {
|
|
1222
|
+
if (keys.has(model.key)) {
|
|
1223
|
+
throw new Error(
|
|
1224
|
+
`Duplicate model key detected: "${model.key}". Each model key must be unique.`
|
|
1225
|
+
);
|
|
1226
|
+
}
|
|
1227
|
+
keys.add(model.key);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1249
1230
|
|
|
1250
1231
|
// ai/google-vertex/auth.ts
|
|
1251
1232
|
var import_google_auth_library = require("google-auth-library");
|
|
@@ -1276,6 +1257,7 @@ var GoogleVertexAuth = class {
|
|
|
1276
1257
|
|
|
1277
1258
|
// ai/anthropic/types.ts
|
|
1278
1259
|
var AxAIAnthropicModel = /* @__PURE__ */ ((AxAIAnthropicModel2) => {
|
|
1260
|
+
AxAIAnthropicModel2["Claude37Sonnet"] = "claude-3-7-sonnet-latest";
|
|
1279
1261
|
AxAIAnthropicModel2["Claude35Sonnet"] = "claude-3-5-sonnet-latest";
|
|
1280
1262
|
AxAIAnthropicModel2["Claude35Haiku"] = "claude-3-5-haiku-latest";
|
|
1281
1263
|
AxAIAnthropicModel2["Claude3Opus"] = "claude-3-opus-latest";
|
|
@@ -1286,6 +1268,7 @@ var AxAIAnthropicModel = /* @__PURE__ */ ((AxAIAnthropicModel2) => {
|
|
|
1286
1268
|
return AxAIAnthropicModel2;
|
|
1287
1269
|
})(AxAIAnthropicModel || {});
|
|
1288
1270
|
var AxAIAnthropicVertexModel = /* @__PURE__ */ ((AxAIAnthropicVertexModel3) => {
|
|
1271
|
+
AxAIAnthropicVertexModel3["Claude37Sonnet"] = "claude-3-7-sonnet";
|
|
1289
1272
|
AxAIAnthropicVertexModel3["Claude35Haiku"] = "claude-3-5-haiku";
|
|
1290
1273
|
AxAIAnthropicVertexModel3["Claude35Sonnet"] = "claude-3-5-sonnet";
|
|
1291
1274
|
AxAIAnthropicVertexModel3["Claude35SonnetV2"] = "claude-3-5-sonnet-v2";
|
|
@@ -1901,7 +1884,7 @@ var AxAIOpenAIImpl = class {
|
|
|
1901
1884
|
response_format: this.config?.responseFormat ? { type: this.config?.responseFormat } : void 0,
|
|
1902
1885
|
tools,
|
|
1903
1886
|
tool_choice: toolsChoice,
|
|
1904
|
-
|
|
1887
|
+
max_completion_tokens: req.modelConfig?.maxTokens ?? this.config.maxTokens ?? 500,
|
|
1905
1888
|
temperature: req.modelConfig?.temperature ?? this.config.temperature,
|
|
1906
1889
|
top_p: req.modelConfig?.topP ?? this.config.topP ?? 1,
|
|
1907
1890
|
n: req.modelConfig?.n ?? this.config.n,
|
|
@@ -3753,18 +3736,15 @@ var AxAI = class {
|
|
|
3753
3736
|
getId() {
|
|
3754
3737
|
return this.ai.getId();
|
|
3755
3738
|
}
|
|
3756
|
-
getModelInfo() {
|
|
3757
|
-
return this.ai.getModelInfo();
|
|
3758
|
-
}
|
|
3759
|
-
getEmbedModelInfo() {
|
|
3760
|
-
return this.ai.getEmbedModelInfo();
|
|
3761
|
-
}
|
|
3762
3739
|
getFeatures(model) {
|
|
3763
3740
|
return this.ai.getFeatures(model);
|
|
3764
3741
|
}
|
|
3765
3742
|
getModelList() {
|
|
3766
3743
|
return this.ai.getModelList();
|
|
3767
3744
|
}
|
|
3745
|
+
getDefaultModels() {
|
|
3746
|
+
return this.ai.getDefaultModels();
|
|
3747
|
+
}
|
|
3768
3748
|
getMetrics() {
|
|
3769
3749
|
return this.ai.getMetrics();
|
|
3770
3750
|
}
|
|
@@ -4001,10 +3981,11 @@ var AxAssertionError = class extends Error {
|
|
|
4001
3981
|
}
|
|
4002
3982
|
getFixingInstructions = () => {
|
|
4003
3983
|
const extraFields = [];
|
|
3984
|
+
const message = this.message.trim();
|
|
4004
3985
|
extraFields.push({
|
|
4005
3986
|
name: "error",
|
|
4006
|
-
title: "
|
|
4007
|
-
description:
|
|
3987
|
+
title: "Follow these instructions",
|
|
3988
|
+
description: message + (message.endsWith(".") ? "" : ".")
|
|
4008
3989
|
});
|
|
4009
3990
|
return extraFields;
|
|
4010
3991
|
};
|
|
@@ -5741,7 +5722,8 @@ async function processFieldProcessors(fieldProcessors, values, mem, sessionId) {
|
|
|
5741
5722
|
if (values[processor.field.name] === void 0) {
|
|
5742
5723
|
continue;
|
|
5743
5724
|
}
|
|
5744
|
-
const
|
|
5725
|
+
const processFn = processor.process;
|
|
5726
|
+
const result = await processFn(values[processor.field.name], {
|
|
5745
5727
|
sessionId,
|
|
5746
5728
|
values,
|
|
5747
5729
|
done: true
|
|
@@ -5759,7 +5741,8 @@ async function processStreamingFieldProcessors(fieldProcessors, content, xstate,
|
|
|
5759
5741
|
value = value.replace(/^[ ]*```[a-zA-Z0-9]*\n\s*/, "");
|
|
5760
5742
|
value = value.replace(/\s*```\s*$/, "");
|
|
5761
5743
|
}
|
|
5762
|
-
const
|
|
5744
|
+
const processFn = processor.process;
|
|
5745
|
+
const result = await processFn(value, {
|
|
5763
5746
|
sessionId,
|
|
5764
5747
|
values,
|
|
5765
5748
|
done
|
|
@@ -6029,7 +6012,7 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
6029
6012
|
addStreamingAssert = (fieldName, fn, message) => {
|
|
6030
6013
|
this.streamingAsserts.push({ fieldName, fn, message });
|
|
6031
6014
|
};
|
|
6032
|
-
|
|
6015
|
+
addFieldProcessorInternal = (fieldName, fn, streaming = false) => {
|
|
6033
6016
|
const field = this.signature.getOutputFields().find((f) => f.name === fieldName);
|
|
6034
6017
|
if (!field) {
|
|
6035
6018
|
throw new Error(`addFieldProcessor: field ${fieldName} not found`);
|
|
@@ -6047,6 +6030,12 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
6047
6030
|
this.fieldProcessors.push({ field, process: fn });
|
|
6048
6031
|
}
|
|
6049
6032
|
};
|
|
6033
|
+
addStreamingFieldProcessor = (fieldName, fn) => {
|
|
6034
|
+
this.addFieldProcessorInternal(fieldName, fn, true);
|
|
6035
|
+
};
|
|
6036
|
+
addFieldProcessor = (fieldName, fn) => {
|
|
6037
|
+
this.addFieldProcessorInternal(fieldName, fn, false);
|
|
6038
|
+
};
|
|
6050
6039
|
async forwardSendRequest({
|
|
6051
6040
|
ai,
|
|
6052
6041
|
mem,
|
|
@@ -6092,9 +6081,10 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
6092
6081
|
}) {
|
|
6093
6082
|
const { sessionId, traceId, model, functions } = options ?? {};
|
|
6094
6083
|
const fastFail = options?.fastFail ?? this.options?.fastFail;
|
|
6084
|
+
const modelName = model ?? ai.getDefaultModels().model;
|
|
6095
6085
|
const usageInfo = {
|
|
6096
6086
|
ai: ai.getName(),
|
|
6097
|
-
model:
|
|
6087
|
+
model: modelName
|
|
6098
6088
|
};
|
|
6099
6089
|
const res = await this.forwardSendRequest({
|
|
6100
6090
|
ai,
|
|
@@ -6178,7 +6168,9 @@ var AxGen = class extends AxProgramWithSignature {
|
|
|
6178
6168
|
content,
|
|
6179
6169
|
streamingValidation
|
|
6180
6170
|
);
|
|
6181
|
-
|
|
6171
|
+
if (this.streamingAsserts.length !== 0) {
|
|
6172
|
+
assertStreamingAssertions(this.streamingAsserts, xstate, content);
|
|
6173
|
+
}
|
|
6182
6174
|
if (this.streamingFieldProcessors.length !== 0) {
|
|
6183
6175
|
await processStreamingFieldProcessors(
|
|
6184
6176
|
this.streamingFieldProcessors,
|
|
@@ -6804,8 +6796,9 @@ var AxBalancer = class _AxBalancer {
|
|
|
6804
6796
|
if (services.length === 0) {
|
|
6805
6797
|
throw new Error("No AI services provided.");
|
|
6806
6798
|
}
|
|
6799
|
+
validateModels2(services);
|
|
6807
6800
|
this.services = [...services].sort(
|
|
6808
|
-
options?.comparator ?? _AxBalancer.
|
|
6801
|
+
options?.comparator ?? _AxBalancer.metricComparator
|
|
6809
6802
|
);
|
|
6810
6803
|
const cs = this.services[this.currentServiceIndex];
|
|
6811
6804
|
if (cs === void 0) {
|
|
@@ -6824,16 +6817,31 @@ var AxBalancer = class _AxBalancer {
|
|
|
6824
6817
|
/**
|
|
6825
6818
|
* Service comparator that sorts services by cost.
|
|
6826
6819
|
*/
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
|
|
6832
|
-
|
|
6820
|
+
// Requires a rethink
|
|
6821
|
+
/*
|
|
6822
|
+
public static costComparator = (a: AxAIService, b: AxAIService) => {
|
|
6823
|
+
const aInfo = a.getModelInfo()
|
|
6824
|
+
const bInfo = b.getModelInfo()
|
|
6825
|
+
const aTotalCost =
|
|
6826
|
+
(aInfo.promptTokenCostPer1M || Infinity) +
|
|
6827
|
+
(aInfo.completionTokenCostPer1M || Infinity)
|
|
6828
|
+
const bTotalCost =
|
|
6829
|
+
(bInfo.promptTokenCostPer1M || Infinity) +
|
|
6830
|
+
(bInfo.completionTokenCostPer1M || Infinity)
|
|
6831
|
+
return aTotalCost - bTotalCost
|
|
6832
|
+
}
|
|
6833
|
+
*/
|
|
6834
|
+
static metricComparator = (a, b) => {
|
|
6835
|
+
const aMetrics = a.getMetrics();
|
|
6836
|
+
const bMetrics = b.getMetrics();
|
|
6837
|
+
return aMetrics.latency.chat.mean - bMetrics.latency.chat.mean;
|
|
6833
6838
|
};
|
|
6834
6839
|
getModelList() {
|
|
6835
6840
|
return this.currentService.getModelList();
|
|
6836
6841
|
}
|
|
6842
|
+
getDefaultModels() {
|
|
6843
|
+
return this.currentService.getDefaultModels();
|
|
6844
|
+
}
|
|
6837
6845
|
getNextService() {
|
|
6838
6846
|
const cs = this.services[++this.currentServiceIndex];
|
|
6839
6847
|
if (cs === void 0) {
|
|
@@ -6856,12 +6864,6 @@ var AxBalancer = class _AxBalancer {
|
|
|
6856
6864
|
getId() {
|
|
6857
6865
|
return this.currentService.getId();
|
|
6858
6866
|
}
|
|
6859
|
-
getModelInfo() {
|
|
6860
|
-
return this.currentService.getModelInfo();
|
|
6861
|
-
}
|
|
6862
|
-
getEmbedModelInfo() {
|
|
6863
|
-
return this.currentService.getEmbedModelInfo();
|
|
6864
|
-
}
|
|
6865
6867
|
getFeatures(model) {
|
|
6866
6868
|
return this.currentService.getFeatures(model);
|
|
6867
6869
|
}
|
|
@@ -6971,6 +6973,46 @@ var AxBalancer = class _AxBalancer {
|
|
|
6971
6973
|
return this.currentService.getOptions();
|
|
6972
6974
|
}
|
|
6973
6975
|
};
|
|
6976
|
+
function validateModels2(services) {
|
|
6977
|
+
const serviceWithModel = services.find(
|
|
6978
|
+
(service) => service.getModelList() !== void 0
|
|
6979
|
+
);
|
|
6980
|
+
if (!serviceWithModel) {
|
|
6981
|
+
return;
|
|
6982
|
+
}
|
|
6983
|
+
const referenceModelList = serviceWithModel.getModelList();
|
|
6984
|
+
if (!referenceModelList) {
|
|
6985
|
+
throw new Error("No model list found in any service.");
|
|
6986
|
+
}
|
|
6987
|
+
const referenceKeys = new Set(referenceModelList.map((model) => model.key));
|
|
6988
|
+
for (let i = 0; i < services.length; i++) {
|
|
6989
|
+
const service = services[i];
|
|
6990
|
+
if (!service) {
|
|
6991
|
+
throw new Error(`Service at index ${i} is undefined`);
|
|
6992
|
+
}
|
|
6993
|
+
const modelList = service.getModelList();
|
|
6994
|
+
if (!modelList) {
|
|
6995
|
+
throw new Error(
|
|
6996
|
+
`Service at index ${i} (${service.getName()}) has no model list while another service does.`
|
|
6997
|
+
);
|
|
6998
|
+
}
|
|
6999
|
+
const serviceKeys = new Set(modelList.map((model) => model.key));
|
|
7000
|
+
for (const key of referenceKeys) {
|
|
7001
|
+
if (!serviceKeys.has(key)) {
|
|
7002
|
+
throw new Error(
|
|
7003
|
+
`Service at index ${i} (${service.getName()}) is missing model "${key}"`
|
|
7004
|
+
);
|
|
7005
|
+
}
|
|
7006
|
+
}
|
|
7007
|
+
for (const key of serviceKeys) {
|
|
7008
|
+
if (!referenceKeys.has(key)) {
|
|
7009
|
+
throw new Error(
|
|
7010
|
+
`Service at index ${i} (${service.getName()}) has extra model "${key}"`
|
|
7011
|
+
);
|
|
7012
|
+
}
|
|
7013
|
+
}
|
|
7014
|
+
}
|
|
7015
|
+
}
|
|
6974
7016
|
|
|
6975
7017
|
// dsp/optimize.ts
|
|
6976
7018
|
var AxBootstrapFewShot = class {
|
|
@@ -8202,18 +8244,6 @@ var AxMockAIService = class {
|
|
|
8202
8244
|
getId() {
|
|
8203
8245
|
return this.config.id ?? "mock-ai-service-id";
|
|
8204
8246
|
}
|
|
8205
|
-
getModelInfo() {
|
|
8206
|
-
return {
|
|
8207
|
-
name: "mock-model",
|
|
8208
|
-
provider: "mock-provider",
|
|
8209
|
-
promptTokenCostPer1M: 100,
|
|
8210
|
-
completionTokenCostPer1M: 100,
|
|
8211
|
-
...this.config.modelInfo
|
|
8212
|
-
};
|
|
8213
|
-
}
|
|
8214
|
-
getEmbedModelInfo() {
|
|
8215
|
-
return this.config.embedModelInfo;
|
|
8216
|
-
}
|
|
8217
8247
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
8218
8248
|
getFeatures(_model) {
|
|
8219
8249
|
return {
|
|
@@ -8224,6 +8254,12 @@ var AxMockAIService = class {
|
|
|
8224
8254
|
getModelList() {
|
|
8225
8255
|
return this.config.models;
|
|
8226
8256
|
}
|
|
8257
|
+
getDefaultModels() {
|
|
8258
|
+
return {
|
|
8259
|
+
model: this.config.modelInfo?.name ?? "mock-model",
|
|
8260
|
+
embedModel: this.config.embedModelInfo?.name
|
|
8261
|
+
};
|
|
8262
|
+
}
|
|
8227
8263
|
getMetrics() {
|
|
8228
8264
|
return this.metrics;
|
|
8229
8265
|
}
|
|
@@ -8301,7 +8337,7 @@ var AxMockAIService = class {
|
|
|
8301
8337
|
|
|
8302
8338
|
// dsp/router.ts
|
|
8303
8339
|
var colorLog6 = new ColorLog();
|
|
8304
|
-
var
|
|
8340
|
+
var AxSimpleClassifierClass = class {
|
|
8305
8341
|
name;
|
|
8306
8342
|
context;
|
|
8307
8343
|
constructor(name, context) {
|
|
@@ -8315,7 +8351,7 @@ var AxRoute = class {
|
|
|
8315
8351
|
return this.context;
|
|
8316
8352
|
}
|
|
8317
8353
|
};
|
|
8318
|
-
var
|
|
8354
|
+
var AxSimpleClassifier = class {
|
|
8319
8355
|
ai;
|
|
8320
8356
|
db;
|
|
8321
8357
|
debug;
|
|
@@ -8329,12 +8365,12 @@ var AxRouter = class {
|
|
|
8329
8365
|
setState(state) {
|
|
8330
8366
|
this.db.setDB(state);
|
|
8331
8367
|
}
|
|
8332
|
-
|
|
8333
|
-
for (const
|
|
8334
|
-
const ret = await this.ai.embed({ texts:
|
|
8368
|
+
setClasses = async (classes) => {
|
|
8369
|
+
for (const c of classes) {
|
|
8370
|
+
const ret = await this.ai.embed({ texts: c.getContext() });
|
|
8335
8371
|
await this.db.upsert({
|
|
8336
|
-
id:
|
|
8337
|
-
table: "
|
|
8372
|
+
id: c.getName(),
|
|
8373
|
+
table: "classes",
|
|
8338
8374
|
values: ret.embeddings[0]
|
|
8339
8375
|
});
|
|
8340
8376
|
}
|
|
@@ -8342,7 +8378,7 @@ var AxRouter = class {
|
|
|
8342
8378
|
async forward(text, options) {
|
|
8343
8379
|
const { embeddings } = await this.ai.embed({ texts: [text] });
|
|
8344
8380
|
const matches = await this.db.query({
|
|
8345
|
-
table: "
|
|
8381
|
+
table: "classes",
|
|
8346
8382
|
values: embeddings[0]
|
|
8347
8383
|
});
|
|
8348
8384
|
let m = matches.matches;
|
|
@@ -8357,11 +8393,11 @@ var AxRouter = class {
|
|
|
8357
8393
|
)
|
|
8358
8394
|
);
|
|
8359
8395
|
}
|
|
8360
|
-
const
|
|
8361
|
-
if (!
|
|
8396
|
+
const matchedClass = m.at(0);
|
|
8397
|
+
if (!matchedClass) {
|
|
8362
8398
|
return "";
|
|
8363
8399
|
}
|
|
8364
|
-
return
|
|
8400
|
+
return matchedClass.id;
|
|
8365
8401
|
}
|
|
8366
8402
|
setOptions(options) {
|
|
8367
8403
|
if (typeof options.debug === "boolean") {
|
|
@@ -8568,6 +8604,160 @@ var AxEmbeddingAdapter = class {
|
|
|
8568
8604
|
}
|
|
8569
8605
|
};
|
|
8570
8606
|
|
|
8607
|
+
// ai/multiservice.ts
|
|
8608
|
+
var AxMultiServiceRouter = class {
|
|
8609
|
+
services = /* @__PURE__ */ new Map();
|
|
8610
|
+
/**
|
|
8611
|
+
* Constructs a new multi-service router.
|
|
8612
|
+
* It validates that each service provides a unique set of model keys,
|
|
8613
|
+
* then builds a lookup (map) for routing the chat/embed requests.
|
|
8614
|
+
*/
|
|
8615
|
+
constructor(services) {
|
|
8616
|
+
if (services.length === 0) {
|
|
8617
|
+
throw new Error("No AI services provided.");
|
|
8618
|
+
}
|
|
8619
|
+
for (const [index, item] of services.entries()) {
|
|
8620
|
+
const isKeyBased = "key" in item;
|
|
8621
|
+
if (isKeyBased) {
|
|
8622
|
+
if (this.services.has(item.key)) {
|
|
8623
|
+
throw new Error(`Duplicate model key: ${item.key}`);
|
|
8624
|
+
}
|
|
8625
|
+
const { service, description, isInternal } = item;
|
|
8626
|
+
this.services.set(item.key, {
|
|
8627
|
+
service,
|
|
8628
|
+
description,
|
|
8629
|
+
isInternal,
|
|
8630
|
+
model: item.service.getDefaultModels().model,
|
|
8631
|
+
useDefaultModel: true
|
|
8632
|
+
});
|
|
8633
|
+
} else {
|
|
8634
|
+
const modelList = item.getModelList();
|
|
8635
|
+
if (!modelList) {
|
|
8636
|
+
throw new Error(
|
|
8637
|
+
`Service ${index} \`${item.getName()}\` has no model list.`
|
|
8638
|
+
);
|
|
8639
|
+
}
|
|
8640
|
+
for (const { key, description, model } of modelList ?? []) {
|
|
8641
|
+
if (this.services.has(key)) {
|
|
8642
|
+
const otherService = this.services.get(key)?.service;
|
|
8643
|
+
throw new Error(
|
|
8644
|
+
`Service ${index} \`${item.getName()}\` has duplicate model key: ${key} as service ${otherService?.getName()}`
|
|
8645
|
+
);
|
|
8646
|
+
}
|
|
8647
|
+
this.services.set(key, {
|
|
8648
|
+
description,
|
|
8649
|
+
service: item,
|
|
8650
|
+
model
|
|
8651
|
+
});
|
|
8652
|
+
}
|
|
8653
|
+
}
|
|
8654
|
+
}
|
|
8655
|
+
}
|
|
8656
|
+
/**
|
|
8657
|
+
* Delegates the chat call to the service matching the provided model key.
|
|
8658
|
+
*/
|
|
8659
|
+
async chat(req, options) {
|
|
8660
|
+
const modelKey = req.model;
|
|
8661
|
+
if (!modelKey) {
|
|
8662
|
+
throw new Error("Model key must be specified for multi-service");
|
|
8663
|
+
}
|
|
8664
|
+
const item = this.services.get(modelKey);
|
|
8665
|
+
if (!item) {
|
|
8666
|
+
throw new Error(`No service found for model key: ${modelKey}`);
|
|
8667
|
+
}
|
|
8668
|
+
const service = item.service;
|
|
8669
|
+
const model = item.useDefaultModel ? req.model : modelKey;
|
|
8670
|
+
return await service.chat({ model, ...req }, options);
|
|
8671
|
+
}
|
|
8672
|
+
/**
|
|
8673
|
+
* Delegates the embed call to the service matching the provided embed model key.
|
|
8674
|
+
*/
|
|
8675
|
+
async embed(req, options) {
|
|
8676
|
+
const modelKey = req.embedModel;
|
|
8677
|
+
if (!modelKey) {
|
|
8678
|
+
throw new Error("Embed model key must be specified for multi-service");
|
|
8679
|
+
}
|
|
8680
|
+
const item = this.services.get(modelKey);
|
|
8681
|
+
if (!item) {
|
|
8682
|
+
throw new Error(`No service found for embed model key: ${modelKey}`);
|
|
8683
|
+
}
|
|
8684
|
+
const service = item.service;
|
|
8685
|
+
const embedModel = item.useDefaultModel ? req.embedModel : modelKey;
|
|
8686
|
+
return await service.embed({ embedModel, ...req }, options);
|
|
8687
|
+
}
|
|
8688
|
+
/**
|
|
8689
|
+
* Returns a composite ID built from the IDs of the underlying services.
|
|
8690
|
+
*/
|
|
8691
|
+
getId() {
|
|
8692
|
+
return "MultiServiceRouter:" + Array.from(this.services.values()).map((s) => s.service.getId()).join(",");
|
|
8693
|
+
}
|
|
8694
|
+
/**
|
|
8695
|
+
* Returns the name of this router.
|
|
8696
|
+
*/
|
|
8697
|
+
getName() {
|
|
8698
|
+
return "MultiServiceRouter";
|
|
8699
|
+
}
|
|
8700
|
+
/**
|
|
8701
|
+
* Aggregates all available models across the underlying services.
|
|
8702
|
+
*/
|
|
8703
|
+
getModelList() {
|
|
8704
|
+
return Array.from(this.services).filter(([, value]) => !value.isInternal).map(([key, { description, model }]) => ({
|
|
8705
|
+
key,
|
|
8706
|
+
description,
|
|
8707
|
+
model
|
|
8708
|
+
}));
|
|
8709
|
+
}
|
|
8710
|
+
getDefaultModels() {
|
|
8711
|
+
throw new Error(
|
|
8712
|
+
"getDefaultModels is not supported for multi-service router."
|
|
8713
|
+
);
|
|
8714
|
+
}
|
|
8715
|
+
/**
|
|
8716
|
+
* If a model key is provided, delegate to the corresponding service's features.
|
|
8717
|
+
* Otherwise, returns a default feature set.
|
|
8718
|
+
*/
|
|
8719
|
+
getFeatures(model) {
|
|
8720
|
+
if (model) {
|
|
8721
|
+
const service = this.services.get(model);
|
|
8722
|
+
if (service) {
|
|
8723
|
+
return service.service.getFeatures(model);
|
|
8724
|
+
}
|
|
8725
|
+
}
|
|
8726
|
+
return { functions: false, streaming: false };
|
|
8727
|
+
}
|
|
8728
|
+
/**
|
|
8729
|
+
* Returns aggregated metrics from the underlying service.
|
|
8730
|
+
* Uses the metrics from the last service that was used,
|
|
8731
|
+
* or falls back to the first service if none has been used.
|
|
8732
|
+
*/
|
|
8733
|
+
getMetrics() {
|
|
8734
|
+
const service = this.services.values().next().value;
|
|
8735
|
+
if (!service) {
|
|
8736
|
+
throw new Error("No service available to get metrics.");
|
|
8737
|
+
}
|
|
8738
|
+
return service.service.getMetrics();
|
|
8739
|
+
}
|
|
8740
|
+
/**
|
|
8741
|
+
* Sets options on all underlying services.
|
|
8742
|
+
*/
|
|
8743
|
+
setOptions(options) {
|
|
8744
|
+
for (const service of this.services.values()) {
|
|
8745
|
+
service.service.setOptions(options);
|
|
8746
|
+
}
|
|
8747
|
+
}
|
|
8748
|
+
/**
|
|
8749
|
+
* Returns the options from the last used service,
|
|
8750
|
+
* or falls back to the first service if none has been used.
|
|
8751
|
+
*/
|
|
8752
|
+
getOptions() {
|
|
8753
|
+
const service = this.services.values().next().value;
|
|
8754
|
+
if (!service) {
|
|
8755
|
+
throw new Error("No service available to get options.");
|
|
8756
|
+
}
|
|
8757
|
+
return service.service.getOptions();
|
|
8758
|
+
}
|
|
8759
|
+
};
|
|
8760
|
+
|
|
8571
8761
|
// prompts/rag.ts
|
|
8572
8762
|
var AxRAG = class extends AxChainOfThought {
|
|
8573
8763
|
genQuery;
|
|
@@ -8668,14 +8858,15 @@ var AxRAG = class extends AxChainOfThought {
|
|
|
8668
8858
|
AxLLMRequestTypeValues,
|
|
8669
8859
|
AxMemory,
|
|
8670
8860
|
AxMockAIService,
|
|
8861
|
+
AxMultiServiceRouter,
|
|
8671
8862
|
AxProgram,
|
|
8672
8863
|
AxProgramWithSignature,
|
|
8673
8864
|
AxPromptTemplate,
|
|
8674
8865
|
AxRAG,
|
|
8675
8866
|
AxRateLimiterTokenUsage,
|
|
8676
|
-
AxRoute,
|
|
8677
|
-
AxRouter,
|
|
8678
8867
|
AxSignature,
|
|
8868
|
+
AxSimpleClassifier,
|
|
8869
|
+
AxSimpleClassifierClass,
|
|
8679
8870
|
AxSpanKindValues,
|
|
8680
8871
|
AxTestPrompt
|
|
8681
8872
|
});
|