@agentskit/adapters 0.7.0 → 0.9.1
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 +23 -5
- package/dist/index.cjs +281 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +199 -2
- package/dist/index.d.ts +199 -2
- package/dist/index.js +269 -1
- package/dist/index.js.map +1 -1
- package/package.json +14 -3
package/dist/index.js
CHANGED
|
@@ -775,6 +775,274 @@ function vercelAI(config) {
|
|
|
775
775
|
};
|
|
776
776
|
}
|
|
777
777
|
|
|
778
|
+
// src/mistral.ts
|
|
779
|
+
var mistral = createOpenAICompatibleAdapter("https://api.mistral.ai/v1");
|
|
780
|
+
|
|
781
|
+
// src/cohere.ts
|
|
782
|
+
var cohere = createOpenAICompatibleAdapter("https://api.cohere.com/compatibility/v1");
|
|
783
|
+
|
|
784
|
+
// src/together.ts
|
|
785
|
+
var together = createOpenAICompatibleAdapter("https://api.together.xyz/v1");
|
|
786
|
+
|
|
787
|
+
// src/groq.ts
|
|
788
|
+
var groq = createOpenAICompatibleAdapter("https://api.groq.com/openai/v1");
|
|
789
|
+
|
|
790
|
+
// src/fireworks.ts
|
|
791
|
+
var fireworks = createOpenAICompatibleAdapter("https://api.fireworks.ai/inference/v1");
|
|
792
|
+
|
|
793
|
+
// src/openrouter.ts
|
|
794
|
+
var openrouter = createOpenAICompatibleAdapter("https://openrouter.ai/api/v1");
|
|
795
|
+
|
|
796
|
+
// src/huggingface.ts
|
|
797
|
+
var huggingface = createOpenAICompatibleAdapter("https://router.huggingface.co/v1");
|
|
798
|
+
|
|
799
|
+
// src/lmstudio.ts
|
|
800
|
+
var lmstudio = createOpenAICompatibleAdapter("http://localhost:1234/v1");
|
|
801
|
+
|
|
802
|
+
// src/vllm.ts
|
|
803
|
+
var vllm = createOpenAICompatibleAdapter("http://localhost:8000/v1");
|
|
804
|
+
|
|
805
|
+
// src/llamacpp.ts
|
|
806
|
+
var llamacpp = createOpenAICompatibleAdapter("http://localhost:8080/v1");
|
|
807
|
+
|
|
808
|
+
// src/router.ts
|
|
809
|
+
function requireCapabilities(request) {
|
|
810
|
+
const needs = {};
|
|
811
|
+
if (request.context?.tools && request.context.tools.length > 0) needs.tools = true;
|
|
812
|
+
return needs;
|
|
813
|
+
}
|
|
814
|
+
function matchesCapabilities(need, have) {
|
|
815
|
+
if (!have) return true;
|
|
816
|
+
for (const key of Object.keys(need)) {
|
|
817
|
+
if (key === "extensions") continue;
|
|
818
|
+
if (need[key] && have[key] === false) return false;
|
|
819
|
+
}
|
|
820
|
+
return true;
|
|
821
|
+
}
|
|
822
|
+
function pickSyncPolicy(pool, policy) {
|
|
823
|
+
if (policy === "cheapest") {
|
|
824
|
+
const c = pool.reduce((best, x) => (x.cost ?? Infinity) < (best.cost ?? Infinity) ? x : best, pool[0]);
|
|
825
|
+
return { c, reason: "cheapest" };
|
|
826
|
+
}
|
|
827
|
+
if (policy === "fastest") {
|
|
828
|
+
const c = pool.reduce((best, x) => (x.latencyMs ?? Infinity) < (best.latencyMs ?? Infinity) ? x : best, pool[0]);
|
|
829
|
+
return { c, reason: "fastest" };
|
|
830
|
+
}
|
|
831
|
+
return { c: pool[0], reason: "capability-match" };
|
|
832
|
+
}
|
|
833
|
+
function createRouter(options) {
|
|
834
|
+
const { candidates } = options;
|
|
835
|
+
if (candidates.length === 0) throw new Error("createRouter requires at least one candidate");
|
|
836
|
+
const policy = options.policy ?? "cheapest";
|
|
837
|
+
return {
|
|
838
|
+
createSource: (request) => {
|
|
839
|
+
const need = requireCapabilities(request);
|
|
840
|
+
const capable = candidates.filter((c2) => matchesCapabilities(need, c2.capabilities ?? c2.adapter.capabilities));
|
|
841
|
+
const classified = options.classify?.(request);
|
|
842
|
+
if (typeof classified === "string") {
|
|
843
|
+
const c2 = capable.find((x) => x.id === classified);
|
|
844
|
+
if (c2) {
|
|
845
|
+
options.onRoute?.({ id: c2.id, reason: "classify:id", request });
|
|
846
|
+
return c2.adapter.createSource(request);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
let pool = capable;
|
|
850
|
+
let pickedBy;
|
|
851
|
+
if (Array.isArray(classified) && classified.length > 0) {
|
|
852
|
+
const filtered = capable.filter((c2) => c2.tags && classified.every((t) => c2.tags.includes(t)));
|
|
853
|
+
if (filtered.length > 0) {
|
|
854
|
+
pool = filtered;
|
|
855
|
+
pickedBy = "classify:tags";
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
if (pool.length === 0) throw new Error("no candidate satisfies the request");
|
|
859
|
+
if (typeof policy === "function") {
|
|
860
|
+
const maybe = policy({ request, candidates: pool });
|
|
861
|
+
if (maybe instanceof Promise) {
|
|
862
|
+
return {
|
|
863
|
+
abort: () => {
|
|
864
|
+
},
|
|
865
|
+
stream: async function* () {
|
|
866
|
+
const id = await maybe;
|
|
867
|
+
const c3 = pool.find((x) => x.id === id);
|
|
868
|
+
if (!c3) throw new Error(`policy returned unknown id: ${id}`);
|
|
869
|
+
options.onRoute?.({ id: c3.id, reason: pickedBy ?? "custom policy", request });
|
|
870
|
+
for await (const chunk of c3.adapter.createSource(request).stream()) yield chunk;
|
|
871
|
+
}
|
|
872
|
+
};
|
|
873
|
+
}
|
|
874
|
+
const c2 = pool.find((x) => x.id === maybe);
|
|
875
|
+
if (!c2) throw new Error(`policy returned unknown id: ${maybe}`);
|
|
876
|
+
options.onRoute?.({ id: c2.id, reason: pickedBy ?? "custom policy", request });
|
|
877
|
+
return c2.adapter.createSource(request);
|
|
878
|
+
}
|
|
879
|
+
const { c, reason } = pickSyncPolicy(pool, policy);
|
|
880
|
+
options.onRoute?.({ id: c.id, reason: pickedBy ?? reason, request });
|
|
881
|
+
return c.adapter.createSource(request);
|
|
882
|
+
}
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
// src/ensemble.ts
|
|
887
|
+
async function drain(source, timeoutMs) {
|
|
888
|
+
const chunks = [];
|
|
889
|
+
let text = "";
|
|
890
|
+
let timer;
|
|
891
|
+
let timedOut = false;
|
|
892
|
+
let error;
|
|
893
|
+
if (timeoutMs !== void 0) {
|
|
894
|
+
timer = setTimeout(() => {
|
|
895
|
+
timedOut = true;
|
|
896
|
+
source.abort();
|
|
897
|
+
}, timeoutMs);
|
|
898
|
+
}
|
|
899
|
+
try {
|
|
900
|
+
for await (const chunk of source.stream()) {
|
|
901
|
+
chunks.push(chunk);
|
|
902
|
+
if (chunk.type === "text" && typeof chunk.content === "string") text += chunk.content;
|
|
903
|
+
}
|
|
904
|
+
} catch (err) {
|
|
905
|
+
error = err instanceof Error ? err : new Error(String(err));
|
|
906
|
+
} finally {
|
|
907
|
+
if (timer) clearTimeout(timer);
|
|
908
|
+
}
|
|
909
|
+
if (timedOut) error = new Error(`timeout after ${timeoutMs}ms`);
|
|
910
|
+
return { chunks, text, error };
|
|
911
|
+
}
|
|
912
|
+
function majorityVote(branches, candidates) {
|
|
913
|
+
const counts = /* @__PURE__ */ new Map();
|
|
914
|
+
const weightById = new Map(candidates.map((c) => [c.id, c.weight ?? 1]));
|
|
915
|
+
for (const b of branches) {
|
|
916
|
+
if (b.error) continue;
|
|
917
|
+
counts.set(b.text, (counts.get(b.text) ?? 0) + (weightById.get(b.id) ?? 1));
|
|
918
|
+
}
|
|
919
|
+
let best = "";
|
|
920
|
+
let bestScore = -1;
|
|
921
|
+
for (const [text, score] of counts) {
|
|
922
|
+
if (score > bestScore) {
|
|
923
|
+
bestScore = score;
|
|
924
|
+
best = text;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
return best;
|
|
928
|
+
}
|
|
929
|
+
function createEnsembleAdapter(options) {
|
|
930
|
+
if (options.candidates.length === 0) {
|
|
931
|
+
throw new Error("createEnsembleAdapter requires at least one candidate");
|
|
932
|
+
}
|
|
933
|
+
const aggregate = options.aggregate ?? "majority-vote";
|
|
934
|
+
return {
|
|
935
|
+
createSource: (request) => {
|
|
936
|
+
let aborted = false;
|
|
937
|
+
const sources = [];
|
|
938
|
+
const run = async () => {
|
|
939
|
+
const tasks = options.candidates.map(async (c, i) => {
|
|
940
|
+
const source = c.adapter.createSource(request);
|
|
941
|
+
sources[i] = source;
|
|
942
|
+
const { chunks, text, error } = await drain(source, options.timeoutMs);
|
|
943
|
+
return { id: c.id, chunks, text, error };
|
|
944
|
+
});
|
|
945
|
+
return Promise.all(tasks);
|
|
946
|
+
};
|
|
947
|
+
const finalText = async (branches) => {
|
|
948
|
+
if (typeof aggregate === "function") return aggregate(branches);
|
|
949
|
+
if (aggregate === "concat") {
|
|
950
|
+
return branches.filter((b) => !b.error).map((b) => b.text).join("\n---\n");
|
|
951
|
+
}
|
|
952
|
+
if (aggregate === "longest") {
|
|
953
|
+
return branches.filter((b) => !b.error).reduce(
|
|
954
|
+
(best, b) => b.text.length > best.length ? b.text : best,
|
|
955
|
+
""
|
|
956
|
+
);
|
|
957
|
+
}
|
|
958
|
+
return majorityVote(branches, options.candidates);
|
|
959
|
+
};
|
|
960
|
+
return {
|
|
961
|
+
abort: () => {
|
|
962
|
+
aborted = true;
|
|
963
|
+
for (const s of sources) s?.abort();
|
|
964
|
+
},
|
|
965
|
+
stream: async function* () {
|
|
966
|
+
const branches = await run();
|
|
967
|
+
options.onBranches?.(branches);
|
|
968
|
+
if (aborted) return;
|
|
969
|
+
const text = await finalText(branches);
|
|
970
|
+
if (!text && branches.every((b) => b.error)) {
|
|
971
|
+
throw new Error("all ensemble branches failed");
|
|
972
|
+
}
|
|
973
|
+
yield { type: "text", content: text, metadata: { ensemble: branches.map((b) => ({ id: b.id, bytes: b.text.length, error: b.error?.message })) } };
|
|
974
|
+
yield { type: "done" };
|
|
975
|
+
}
|
|
976
|
+
};
|
|
977
|
+
}
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
// src/fallback.ts
|
|
982
|
+
function createFallbackAdapter(candidates, options = {}) {
|
|
983
|
+
if (candidates.length === 0) {
|
|
984
|
+
throw new Error("createFallbackAdapter requires at least one candidate");
|
|
985
|
+
}
|
|
986
|
+
return {
|
|
987
|
+
createSource: (request) => {
|
|
988
|
+
let active;
|
|
989
|
+
let aborted = false;
|
|
990
|
+
return {
|
|
991
|
+
abort: () => {
|
|
992
|
+
aborted = true;
|
|
993
|
+
active?.abort();
|
|
994
|
+
},
|
|
995
|
+
stream: async function* () {
|
|
996
|
+
const errors = [];
|
|
997
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
998
|
+
if (aborted) return;
|
|
999
|
+
const candidate = candidates[i];
|
|
1000
|
+
let source;
|
|
1001
|
+
try {
|
|
1002
|
+
source = candidate.adapter.createSource(request);
|
|
1003
|
+
} catch (err) {
|
|
1004
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1005
|
+
errors.push({ id: candidate.id, error });
|
|
1006
|
+
options.onFallback?.({ id: candidate.id, index: i, error });
|
|
1007
|
+
if (options.shouldRetry && !options.shouldRetry(error, i)) throw error;
|
|
1008
|
+
continue;
|
|
1009
|
+
}
|
|
1010
|
+
active = source;
|
|
1011
|
+
const iter = source.stream()[Symbol.asyncIterator]();
|
|
1012
|
+
let first;
|
|
1013
|
+
try {
|
|
1014
|
+
first = await iter.next();
|
|
1015
|
+
} catch (err) {
|
|
1016
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
1017
|
+
errors.push({ id: candidate.id, error });
|
|
1018
|
+
options.onFallback?.({ id: candidate.id, index: i, error });
|
|
1019
|
+
if (options.shouldRetry && !options.shouldRetry(error, i)) throw error;
|
|
1020
|
+
active = void 0;
|
|
1021
|
+
continue;
|
|
1022
|
+
}
|
|
1023
|
+
if (first.done) {
|
|
1024
|
+
const error = new Error(`candidate ${candidate.id} emitted no chunks`);
|
|
1025
|
+
errors.push({ id: candidate.id, error });
|
|
1026
|
+
options.onFallback?.({ id: candidate.id, index: i, error });
|
|
1027
|
+
if (options.shouldRetry && !options.shouldRetry(error, i)) throw error;
|
|
1028
|
+
active = void 0;
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
yield first.value;
|
|
1032
|
+
while (true) {
|
|
1033
|
+
const next = await iter.next();
|
|
1034
|
+
if (next.done) return;
|
|
1035
|
+
yield next.value;
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
const summary = errors.map((e) => `${e.id}: ${e.error.message}`).join("; ");
|
|
1039
|
+
throw new Error(`all fallback candidates failed (${summary})`);
|
|
1040
|
+
}
|
|
1041
|
+
};
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
|
|
778
1046
|
// src/mock.ts
|
|
779
1047
|
function mockAdapter(options) {
|
|
780
1048
|
const { response, delayMs = 0, history } = options;
|
|
@@ -1061,6 +1329,6 @@ var grokEmbedder = createOpenAICompatibleEmbedder("Grok", "https://api.x.ai");
|
|
|
1061
1329
|
// src/embedders/kimi.ts
|
|
1062
1330
|
var kimiEmbedder = createOpenAICompatibleEmbedder("Kimi", "https://api.moonshot.ai");
|
|
1063
1331
|
|
|
1064
|
-
export { anthropic, chunkText, createAdapter, createOpenAICompatibleEmbedder, deepseek, deepseekEmbedder, fetchWithRetry, gemini, geminiEmbedder, generic, grok, grokEmbedder, inMemorySink, kimi, kimiEmbedder, langchain, langgraph, mockAdapter, ollama, ollamaEmbedder, openai, openaiEmbedder, recordingAdapter, replayAdapter, simulateStream, vercelAI };
|
|
1332
|
+
export { anthropic, chunkText, cohere, createAdapter, createEnsembleAdapter, createFallbackAdapter, createOpenAICompatibleEmbedder, createRouter, deepseek, deepseekEmbedder, fetchWithRetry, fireworks, gemini, geminiEmbedder, generic, grok, grokEmbedder, groq, huggingface, inMemorySink, kimi, kimiEmbedder, langchain, langgraph, llamacpp, lmstudio, mistral, mockAdapter, ollama, ollamaEmbedder, openai, openaiEmbedder, openrouter, recordingAdapter, replayAdapter, simulateStream, together, vercelAI, vllm };
|
|
1065
1333
|
//# sourceMappingURL=index.js.map
|
|
1066
1334
|
//# sourceMappingURL=index.js.map
|