@fallom/trace 0.1.3 → 0.1.4
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 +120 -1
- package/dist/chunk-IGJD7GBO.mjs +248 -0
- package/dist/chunk-VNUUS74T.mjs +242 -0
- package/dist/index.d.mts +132 -10
- package/dist/index.d.ts +132 -10
- package/dist/index.js +447 -116
- package/dist/index.mjs +115 -32
- package/dist/prompts-67DJ33I4.mjs +14 -0
- package/dist/prompts-ODF4KO2E.mjs +14 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,6 +3,9 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __esm = (fn, res) => function __init() {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
};
|
|
6
9
|
var __export = (target, all) => {
|
|
7
10
|
for (var name in all)
|
|
8
11
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -17,12 +20,252 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
20
|
};
|
|
18
21
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
22
|
|
|
23
|
+
// src/prompts.ts
|
|
24
|
+
var prompts_exports = {};
|
|
25
|
+
__export(prompts_exports, {
|
|
26
|
+
clearPromptContext: () => clearPromptContext,
|
|
27
|
+
get: () => get,
|
|
28
|
+
getAB: () => getAB,
|
|
29
|
+
getPromptContext: () => getPromptContext,
|
|
30
|
+
init: () => init
|
|
31
|
+
});
|
|
32
|
+
function log(msg) {
|
|
33
|
+
if (debugMode) {
|
|
34
|
+
console.log(`[Fallom Prompts] ${msg}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function init(options = {}) {
|
|
38
|
+
apiKey = options.apiKey || process.env.FALLOM_API_KEY || null;
|
|
39
|
+
baseUrl = options.baseUrl || process.env.FALLOM_BASE_URL || "https://spans.fallom.com";
|
|
40
|
+
initialized = true;
|
|
41
|
+
if (!apiKey) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
fetchAll().catch(() => {
|
|
45
|
+
});
|
|
46
|
+
if (!syncInterval) {
|
|
47
|
+
syncInterval = setInterval(() => {
|
|
48
|
+
fetchAll().catch(() => {
|
|
49
|
+
});
|
|
50
|
+
}, 3e4);
|
|
51
|
+
syncInterval.unref();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function ensureInit() {
|
|
55
|
+
if (!initialized) {
|
|
56
|
+
try {
|
|
57
|
+
init();
|
|
58
|
+
} catch {
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function fetchAll() {
|
|
63
|
+
await Promise.all([fetchPrompts(), fetchPromptABTests()]);
|
|
64
|
+
}
|
|
65
|
+
async function fetchPrompts(timeout = SYNC_TIMEOUT) {
|
|
66
|
+
if (!apiKey) return;
|
|
67
|
+
try {
|
|
68
|
+
const controller = new AbortController();
|
|
69
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
70
|
+
const resp = await fetch(`${baseUrl}/prompts`, {
|
|
71
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
72
|
+
signal: controller.signal
|
|
73
|
+
});
|
|
74
|
+
clearTimeout(timeoutId);
|
|
75
|
+
if (resp.ok) {
|
|
76
|
+
const data = await resp.json();
|
|
77
|
+
for (const p of data.prompts || []) {
|
|
78
|
+
if (!promptCache.has(p.key)) {
|
|
79
|
+
promptCache.set(p.key, { versions: /* @__PURE__ */ new Map(), current: null });
|
|
80
|
+
}
|
|
81
|
+
const cached = promptCache.get(p.key);
|
|
82
|
+
cached.versions.set(p.version, {
|
|
83
|
+
systemPrompt: p.system_prompt,
|
|
84
|
+
userTemplate: p.user_template
|
|
85
|
+
});
|
|
86
|
+
cached.current = p.version;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
} catch {
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function fetchPromptABTests(timeout = SYNC_TIMEOUT) {
|
|
93
|
+
if (!apiKey) return;
|
|
94
|
+
try {
|
|
95
|
+
const controller = new AbortController();
|
|
96
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
97
|
+
const resp = await fetch(`${baseUrl}/prompt-ab-tests`, {
|
|
98
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
99
|
+
signal: controller.signal
|
|
100
|
+
});
|
|
101
|
+
clearTimeout(timeoutId);
|
|
102
|
+
if (resp.ok) {
|
|
103
|
+
const data = await resp.json();
|
|
104
|
+
for (const t of data.prompt_ab_tests || []) {
|
|
105
|
+
if (!promptABCache.has(t.key)) {
|
|
106
|
+
promptABCache.set(t.key, { versions: /* @__PURE__ */ new Map(), current: null });
|
|
107
|
+
}
|
|
108
|
+
const cached = promptABCache.get(t.key);
|
|
109
|
+
cached.versions.set(t.version, { variants: t.variants });
|
|
110
|
+
cached.current = t.version;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} catch {
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function replaceVariables(template, variables) {
|
|
117
|
+
if (!variables) return template;
|
|
118
|
+
return template.replace(/\{\{(\s*\w+\s*)\}\}/g, (match, varName) => {
|
|
119
|
+
const key = varName.trim();
|
|
120
|
+
return key in variables ? String(variables[key]) : match;
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
function setPromptContext(ctx) {
|
|
124
|
+
promptContext = ctx;
|
|
125
|
+
}
|
|
126
|
+
function getPromptContext() {
|
|
127
|
+
const ctx = promptContext;
|
|
128
|
+
promptContext = null;
|
|
129
|
+
return ctx;
|
|
130
|
+
}
|
|
131
|
+
async function get(promptKey, options = {}) {
|
|
132
|
+
const { variables, version, debug = false } = options;
|
|
133
|
+
debugMode = debug;
|
|
134
|
+
ensureInit();
|
|
135
|
+
log(`get() called: promptKey=${promptKey}`);
|
|
136
|
+
let promptData = promptCache.get(promptKey);
|
|
137
|
+
if (!promptData) {
|
|
138
|
+
log("Not in cache, fetching...");
|
|
139
|
+
await fetchPrompts(SYNC_TIMEOUT);
|
|
140
|
+
promptData = promptCache.get(promptKey);
|
|
141
|
+
}
|
|
142
|
+
if (!promptData) {
|
|
143
|
+
throw new Error(
|
|
144
|
+
`Prompt '${promptKey}' not found. Check that it exists in your Fallom dashboard.`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
const targetVersion = version ?? promptData.current;
|
|
148
|
+
const content = promptData.versions.get(targetVersion);
|
|
149
|
+
if (!content) {
|
|
150
|
+
throw new Error(
|
|
151
|
+
`Prompt '${promptKey}' version ${targetVersion} not found.`
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
const system = replaceVariables(content.systemPrompt, variables);
|
|
155
|
+
const user = replaceVariables(content.userTemplate, variables);
|
|
156
|
+
setPromptContext({
|
|
157
|
+
promptKey,
|
|
158
|
+
promptVersion: targetVersion
|
|
159
|
+
});
|
|
160
|
+
log(`\u2705 Got prompt: ${promptKey} v${targetVersion}`);
|
|
161
|
+
return {
|
|
162
|
+
key: promptKey,
|
|
163
|
+
version: targetVersion,
|
|
164
|
+
system,
|
|
165
|
+
user
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
async function getAB(abTestKey, sessionId, options = {}) {
|
|
169
|
+
const { variables, debug = false } = options;
|
|
170
|
+
debugMode = debug;
|
|
171
|
+
ensureInit();
|
|
172
|
+
log(`getAB() called: abTestKey=${abTestKey}, sessionId=${sessionId}`);
|
|
173
|
+
let abData = promptABCache.get(abTestKey);
|
|
174
|
+
if (!abData) {
|
|
175
|
+
log("Not in cache, fetching...");
|
|
176
|
+
await fetchPromptABTests(SYNC_TIMEOUT);
|
|
177
|
+
abData = promptABCache.get(abTestKey);
|
|
178
|
+
}
|
|
179
|
+
if (!abData) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
`Prompt A/B test '${abTestKey}' not found. Check that it exists in your Fallom dashboard.`
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
const currentVersion = abData.current;
|
|
185
|
+
const versionData = abData.versions.get(currentVersion);
|
|
186
|
+
if (!versionData) {
|
|
187
|
+
throw new Error(`Prompt A/B test '${abTestKey}' has no current version.`);
|
|
188
|
+
}
|
|
189
|
+
const { variants } = versionData;
|
|
190
|
+
const hashBytes = (0, import_crypto.createHash)("md5").update(sessionId).digest();
|
|
191
|
+
const hashVal = hashBytes.readUInt32BE(0) % 1e6;
|
|
192
|
+
let cumulative = 0;
|
|
193
|
+
let selectedVariant = variants[variants.length - 1];
|
|
194
|
+
let selectedIndex = variants.length - 1;
|
|
195
|
+
for (let i = 0; i < variants.length; i++) {
|
|
196
|
+
cumulative += variants[i].weight * 1e4;
|
|
197
|
+
if (hashVal < cumulative) {
|
|
198
|
+
selectedVariant = variants[i];
|
|
199
|
+
selectedIndex = i;
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const promptKey = selectedVariant.prompt_key;
|
|
204
|
+
const promptVersion = selectedVariant.prompt_version;
|
|
205
|
+
let promptData = promptCache.get(promptKey);
|
|
206
|
+
if (!promptData) {
|
|
207
|
+
await fetchPrompts(SYNC_TIMEOUT);
|
|
208
|
+
promptData = promptCache.get(promptKey);
|
|
209
|
+
}
|
|
210
|
+
if (!promptData) {
|
|
211
|
+
throw new Error(
|
|
212
|
+
`Prompt '${promptKey}' (from A/B test '${abTestKey}') not found.`
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
const targetVersion = promptVersion ?? promptData.current;
|
|
216
|
+
const content = promptData.versions.get(targetVersion);
|
|
217
|
+
if (!content) {
|
|
218
|
+
throw new Error(
|
|
219
|
+
`Prompt '${promptKey}' version ${targetVersion} not found.`
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
const system = replaceVariables(content.systemPrompt, variables);
|
|
223
|
+
const user = replaceVariables(content.userTemplate, variables);
|
|
224
|
+
setPromptContext({
|
|
225
|
+
promptKey,
|
|
226
|
+
promptVersion: targetVersion,
|
|
227
|
+
abTestKey,
|
|
228
|
+
variantIndex: selectedIndex
|
|
229
|
+
});
|
|
230
|
+
log(
|
|
231
|
+
`\u2705 Got prompt from A/B: ${promptKey} v${targetVersion} (variant ${selectedIndex})`
|
|
232
|
+
);
|
|
233
|
+
return {
|
|
234
|
+
key: promptKey,
|
|
235
|
+
version: targetVersion,
|
|
236
|
+
system,
|
|
237
|
+
user,
|
|
238
|
+
abTestKey,
|
|
239
|
+
variantIndex: selectedIndex
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function clearPromptContext() {
|
|
243
|
+
promptContext = null;
|
|
244
|
+
}
|
|
245
|
+
var import_crypto, apiKey, baseUrl, initialized, syncInterval, debugMode, promptCache, promptABCache, promptContext, SYNC_TIMEOUT;
|
|
246
|
+
var init_prompts = __esm({
|
|
247
|
+
"src/prompts.ts"() {
|
|
248
|
+
"use strict";
|
|
249
|
+
import_crypto = require("crypto");
|
|
250
|
+
apiKey = null;
|
|
251
|
+
baseUrl = "https://spans.fallom.com";
|
|
252
|
+
initialized = false;
|
|
253
|
+
syncInterval = null;
|
|
254
|
+
debugMode = false;
|
|
255
|
+
promptCache = /* @__PURE__ */ new Map();
|
|
256
|
+
promptABCache = /* @__PURE__ */ new Map();
|
|
257
|
+
promptContext = null;
|
|
258
|
+
SYNC_TIMEOUT = 2e3;
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
|
|
20
262
|
// src/index.ts
|
|
21
263
|
var index_exports = {};
|
|
22
264
|
__export(index_exports, {
|
|
23
265
|
default: () => index_default,
|
|
24
|
-
init: () =>
|
|
266
|
+
init: () => init4,
|
|
25
267
|
models: () => models_exports,
|
|
268
|
+
prompts: () => prompts_exports,
|
|
26
269
|
trace: () => trace_exports
|
|
27
270
|
});
|
|
28
271
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -32,7 +275,7 @@ var trace_exports = {};
|
|
|
32
275
|
__export(trace_exports, {
|
|
33
276
|
clearSession: () => clearSession,
|
|
34
277
|
getSession: () => getSession,
|
|
35
|
-
init: () =>
|
|
278
|
+
init: () => init2,
|
|
36
279
|
runWithSession: () => runWithSession,
|
|
37
280
|
setSession: () => setSession,
|
|
38
281
|
shutdown: () => shutdown,
|
|
@@ -671,29 +914,29 @@ var Resource = (
|
|
|
671
914
|
// src/trace.ts
|
|
672
915
|
var sessionStorage = new import_async_hooks.AsyncLocalStorage();
|
|
673
916
|
var fallbackSession = null;
|
|
674
|
-
var
|
|
675
|
-
var
|
|
676
|
-
var
|
|
917
|
+
var apiKey2 = null;
|
|
918
|
+
var baseUrl2 = "https://spans.fallom.com";
|
|
919
|
+
var initialized2 = false;
|
|
677
920
|
var captureContent = true;
|
|
678
|
-
var
|
|
921
|
+
var debugMode2 = false;
|
|
679
922
|
var sdk = null;
|
|
680
|
-
function
|
|
681
|
-
if (
|
|
923
|
+
function log2(...args) {
|
|
924
|
+
if (debugMode2) console.log("[Fallom]", ...args);
|
|
682
925
|
}
|
|
683
926
|
var fallomSpanProcessor = {
|
|
684
927
|
onStart(span2, _parentContext) {
|
|
685
|
-
|
|
928
|
+
log2("\u{1F4CD} Span started:", span2.name || "unknown");
|
|
686
929
|
const ctx = sessionStorage.getStore() || fallbackSession;
|
|
687
930
|
if (ctx) {
|
|
688
931
|
span2.setAttribute("fallom.config_key", ctx.configKey);
|
|
689
932
|
span2.setAttribute("fallom.session_id", ctx.sessionId);
|
|
690
|
-
|
|
933
|
+
log2(" Added session context:", ctx.configKey, ctx.sessionId);
|
|
691
934
|
} else {
|
|
692
|
-
|
|
935
|
+
log2(" No session context available");
|
|
693
936
|
}
|
|
694
937
|
},
|
|
695
938
|
onEnd(span2) {
|
|
696
|
-
|
|
939
|
+
log2("\u2705 Span ended:", span2.name, "duration:", span2.duration);
|
|
697
940
|
},
|
|
698
941
|
shutdown() {
|
|
699
942
|
return Promise.resolve();
|
|
@@ -702,33 +945,33 @@ var fallomSpanProcessor = {
|
|
|
702
945
|
return Promise.resolve();
|
|
703
946
|
}
|
|
704
947
|
};
|
|
705
|
-
async function
|
|
706
|
-
if (
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
948
|
+
async function init2(options = {}) {
|
|
949
|
+
if (initialized2) return;
|
|
950
|
+
debugMode2 = options.debug ?? false;
|
|
951
|
+
log2("\u{1F680} Initializing Fallom tracing...");
|
|
952
|
+
apiKey2 = options.apiKey || process.env.FALLOM_API_KEY || null;
|
|
953
|
+
baseUrl2 = options.baseUrl || process.env.FALLOM_BASE_URL || "https://spans.fallom.com";
|
|
711
954
|
const envCapture = process.env.FALLOM_CAPTURE_CONTENT?.toLowerCase();
|
|
712
955
|
if (envCapture === "false" || envCapture === "0" || envCapture === "no") {
|
|
713
956
|
captureContent = false;
|
|
714
957
|
} else {
|
|
715
958
|
captureContent = options.captureContent ?? true;
|
|
716
959
|
}
|
|
717
|
-
if (!
|
|
960
|
+
if (!apiKey2) {
|
|
718
961
|
throw new Error(
|
|
719
962
|
"No API key provided. Set FALLOM_API_KEY environment variable or pass apiKey parameter."
|
|
720
963
|
);
|
|
721
964
|
}
|
|
722
|
-
|
|
723
|
-
|
|
965
|
+
initialized2 = true;
|
|
966
|
+
log2("\u{1F4E1} Exporter URL:", `${baseUrl2}/v1/traces`);
|
|
724
967
|
const exporter = new import_exporter_trace_otlp_http.OTLPTraceExporter({
|
|
725
|
-
url: `${
|
|
968
|
+
url: `${baseUrl2}/v1/traces`,
|
|
726
969
|
headers: {
|
|
727
|
-
Authorization: `Bearer ${
|
|
970
|
+
Authorization: `Bearer ${apiKey2}`
|
|
728
971
|
}
|
|
729
972
|
});
|
|
730
973
|
const instrumentations = await getInstrumentations();
|
|
731
|
-
|
|
974
|
+
log2("\u{1F527} Loaded instrumentations:", instrumentations.length);
|
|
732
975
|
sdk = new import_sdk_node.NodeSDK({
|
|
733
976
|
resource: new Resource({
|
|
734
977
|
"service.name": "fallom-traced-app"
|
|
@@ -738,20 +981,48 @@ async function init(options = {}) {
|
|
|
738
981
|
instrumentations
|
|
739
982
|
});
|
|
740
983
|
sdk.start();
|
|
741
|
-
|
|
984
|
+
log2("\u2705 SDK started");
|
|
742
985
|
process.on("SIGTERM", () => {
|
|
743
986
|
sdk?.shutdown().catch(console.error);
|
|
744
987
|
});
|
|
745
988
|
}
|
|
746
989
|
async function getInstrumentations() {
|
|
747
990
|
const instrumentations = [];
|
|
748
|
-
await tryAddInstrumentation(
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
await tryAddInstrumentation(
|
|
754
|
-
|
|
991
|
+
await tryAddInstrumentation(
|
|
992
|
+
instrumentations,
|
|
993
|
+
"@traceloop/instrumentation-openai",
|
|
994
|
+
"OpenAIInstrumentation"
|
|
995
|
+
);
|
|
996
|
+
await tryAddInstrumentation(
|
|
997
|
+
instrumentations,
|
|
998
|
+
"@traceloop/instrumentation-anthropic",
|
|
999
|
+
"AnthropicInstrumentation"
|
|
1000
|
+
);
|
|
1001
|
+
await tryAddInstrumentation(
|
|
1002
|
+
instrumentations,
|
|
1003
|
+
"@traceloop/instrumentation-cohere",
|
|
1004
|
+
"CohereInstrumentation"
|
|
1005
|
+
);
|
|
1006
|
+
await tryAddInstrumentation(
|
|
1007
|
+
instrumentations,
|
|
1008
|
+
"@traceloop/instrumentation-bedrock",
|
|
1009
|
+
"BedrockInstrumentation"
|
|
1010
|
+
);
|
|
1011
|
+
await tryAddInstrumentation(
|
|
1012
|
+
instrumentations,
|
|
1013
|
+
"@traceloop/instrumentation-google-generativeai",
|
|
1014
|
+
"GoogleGenerativeAIInstrumentation"
|
|
1015
|
+
);
|
|
1016
|
+
await tryAddInstrumentation(
|
|
1017
|
+
instrumentations,
|
|
1018
|
+
"@traceloop/instrumentation-azure",
|
|
1019
|
+
"AzureOpenAIInstrumentation"
|
|
1020
|
+
);
|
|
1021
|
+
await tryAddInstrumentation(
|
|
1022
|
+
instrumentations,
|
|
1023
|
+
"@traceloop/instrumentation-vertexai",
|
|
1024
|
+
"VertexAIInstrumentation"
|
|
1025
|
+
);
|
|
755
1026
|
return instrumentations;
|
|
756
1027
|
}
|
|
757
1028
|
async function tryAddInstrumentation(instrumentations, pkg, className) {
|
|
@@ -759,13 +1030,18 @@ async function tryAddInstrumentation(instrumentations, pkg, className) {
|
|
|
759
1030
|
const mod = await import(pkg);
|
|
760
1031
|
const InstrumentationClass = mod[className] || mod.default?.[className];
|
|
761
1032
|
if (InstrumentationClass) {
|
|
762
|
-
instrumentations.push(
|
|
763
|
-
|
|
1033
|
+
instrumentations.push(
|
|
1034
|
+
new InstrumentationClass({ traceContent: captureContent })
|
|
1035
|
+
);
|
|
1036
|
+
log2(` \u2705 Loaded ${pkg}`);
|
|
764
1037
|
} else {
|
|
765
|
-
|
|
1038
|
+
log2(
|
|
1039
|
+
` \u26A0\uFE0F ${pkg} loaded but ${className} not found. Available:`,
|
|
1040
|
+
Object.keys(mod)
|
|
1041
|
+
);
|
|
766
1042
|
}
|
|
767
1043
|
} catch (e) {
|
|
768
|
-
|
|
1044
|
+
log2(` \u274C ${pkg} not installed`);
|
|
769
1045
|
}
|
|
770
1046
|
}
|
|
771
1047
|
function setSession(configKey, sessionId) {
|
|
@@ -786,7 +1062,7 @@ function clearSession() {
|
|
|
786
1062
|
fallbackSession = null;
|
|
787
1063
|
}
|
|
788
1064
|
function span(data, options = {}) {
|
|
789
|
-
if (!
|
|
1065
|
+
if (!initialized2) {
|
|
790
1066
|
throw new Error("Fallom not initialized. Call trace.init() first.");
|
|
791
1067
|
}
|
|
792
1068
|
const ctx = sessionStorage.getStore() || fallbackSession;
|
|
@@ -804,10 +1080,10 @@ async function sendSpan(configKey, sessionId, data) {
|
|
|
804
1080
|
try {
|
|
805
1081
|
const controller = new AbortController();
|
|
806
1082
|
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
807
|
-
await fetch(`${
|
|
1083
|
+
await fetch(`${baseUrl2}/spans`, {
|
|
808
1084
|
method: "POST",
|
|
809
1085
|
headers: {
|
|
810
|
-
Authorization: `Bearer ${
|
|
1086
|
+
Authorization: `Bearer ${apiKey2}`,
|
|
811
1087
|
"Content-Type": "application/json"
|
|
812
1088
|
},
|
|
813
1089
|
body: JSON.stringify({
|
|
@@ -824,34 +1100,42 @@ async function sendSpan(configKey, sessionId, data) {
|
|
|
824
1100
|
async function shutdown() {
|
|
825
1101
|
if (sdk) {
|
|
826
1102
|
await sdk.shutdown();
|
|
827
|
-
|
|
1103
|
+
initialized2 = false;
|
|
828
1104
|
}
|
|
829
1105
|
}
|
|
830
1106
|
async function sendTrace(trace) {
|
|
831
1107
|
try {
|
|
832
1108
|
const controller = new AbortController();
|
|
833
1109
|
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
834
|
-
await fetch(`${
|
|
1110
|
+
await fetch(`${baseUrl2}/v1/traces`, {
|
|
835
1111
|
method: "POST",
|
|
836
1112
|
headers: {
|
|
837
|
-
Authorization: `Bearer ${
|
|
1113
|
+
Authorization: `Bearer ${apiKey2}`,
|
|
838
1114
|
"Content-Type": "application/json"
|
|
839
1115
|
},
|
|
840
1116
|
body: JSON.stringify(trace),
|
|
841
1117
|
signal: controller.signal
|
|
842
1118
|
});
|
|
843
1119
|
clearTimeout(timeoutId);
|
|
844
|
-
|
|
1120
|
+
log2("\u{1F4E4} Trace sent:", trace.name, trace.model);
|
|
845
1121
|
} catch {
|
|
846
1122
|
}
|
|
847
1123
|
}
|
|
848
1124
|
function wrapOpenAI(client) {
|
|
849
|
-
const originalCreate = client.chat.completions.create.bind(
|
|
1125
|
+
const originalCreate = client.chat.completions.create.bind(
|
|
1126
|
+
client.chat.completions
|
|
1127
|
+
);
|
|
850
1128
|
client.chat.completions.create = async function(...args) {
|
|
851
1129
|
const ctx = sessionStorage.getStore() || fallbackSession;
|
|
852
|
-
if (!ctx || !
|
|
1130
|
+
if (!ctx || !initialized2) {
|
|
853
1131
|
return originalCreate(...args);
|
|
854
1132
|
}
|
|
1133
|
+
let promptCtx = null;
|
|
1134
|
+
try {
|
|
1135
|
+
const { getPromptContext: getPromptContext2 } = await Promise.resolve().then(() => (init_prompts(), prompts_exports));
|
|
1136
|
+
promptCtx = getPromptContext2();
|
|
1137
|
+
} catch {
|
|
1138
|
+
}
|
|
855
1139
|
const params = args[0] || {};
|
|
856
1140
|
const startTime = Date.now();
|
|
857
1141
|
try {
|
|
@@ -870,7 +1154,11 @@ function wrapOpenAI(client) {
|
|
|
870
1154
|
completion_tokens: response?.usage?.completion_tokens,
|
|
871
1155
|
total_tokens: response?.usage?.total_tokens,
|
|
872
1156
|
input: captureContent ? JSON.stringify(params?.messages) : void 0,
|
|
873
|
-
output: captureContent ? response?.choices?.[0]?.message?.content : void 0
|
|
1157
|
+
output: captureContent ? response?.choices?.[0]?.message?.content : void 0,
|
|
1158
|
+
prompt_key: promptCtx?.promptKey,
|
|
1159
|
+
prompt_version: promptCtx?.promptVersion,
|
|
1160
|
+
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1161
|
+
prompt_variant_index: promptCtx?.variantIndex
|
|
874
1162
|
}).catch(() => {
|
|
875
1163
|
});
|
|
876
1164
|
return response;
|
|
@@ -885,7 +1173,11 @@ function wrapOpenAI(client) {
|
|
|
885
1173
|
end_time: new Date(endTime).toISOString(),
|
|
886
1174
|
duration_ms: endTime - startTime,
|
|
887
1175
|
status: "ERROR",
|
|
888
|
-
error_message: error?.message
|
|
1176
|
+
error_message: error?.message,
|
|
1177
|
+
prompt_key: promptCtx?.promptKey,
|
|
1178
|
+
prompt_version: promptCtx?.promptVersion,
|
|
1179
|
+
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1180
|
+
prompt_variant_index: promptCtx?.variantIndex
|
|
889
1181
|
}).catch(() => {
|
|
890
1182
|
});
|
|
891
1183
|
throw error;
|
|
@@ -897,9 +1189,15 @@ function wrapAnthropic(client) {
|
|
|
897
1189
|
const originalCreate = client.messages.create.bind(client.messages);
|
|
898
1190
|
client.messages.create = async function(...args) {
|
|
899
1191
|
const ctx = sessionStorage.getStore() || fallbackSession;
|
|
900
|
-
if (!ctx || !
|
|
1192
|
+
if (!ctx || !initialized2) {
|
|
901
1193
|
return originalCreate(...args);
|
|
902
1194
|
}
|
|
1195
|
+
let promptCtx = null;
|
|
1196
|
+
try {
|
|
1197
|
+
const { getPromptContext: getPromptContext2 } = await Promise.resolve().then(() => (init_prompts(), prompts_exports));
|
|
1198
|
+
promptCtx = getPromptContext2();
|
|
1199
|
+
} catch {
|
|
1200
|
+
}
|
|
903
1201
|
const params = args[0] || {};
|
|
904
1202
|
const startTime = Date.now();
|
|
905
1203
|
try {
|
|
@@ -918,7 +1216,11 @@ function wrapAnthropic(client) {
|
|
|
918
1216
|
completion_tokens: response?.usage?.output_tokens,
|
|
919
1217
|
total_tokens: (response?.usage?.input_tokens || 0) + (response?.usage?.output_tokens || 0),
|
|
920
1218
|
input: captureContent ? JSON.stringify(params?.messages) : void 0,
|
|
921
|
-
output: captureContent ? response?.content?.[0]?.text : void 0
|
|
1219
|
+
output: captureContent ? response?.content?.[0]?.text : void 0,
|
|
1220
|
+
prompt_key: promptCtx?.promptKey,
|
|
1221
|
+
prompt_version: promptCtx?.promptVersion,
|
|
1222
|
+
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1223
|
+
prompt_variant_index: promptCtx?.variantIndex
|
|
922
1224
|
}).catch(() => {
|
|
923
1225
|
});
|
|
924
1226
|
return response;
|
|
@@ -933,7 +1235,11 @@ function wrapAnthropic(client) {
|
|
|
933
1235
|
end_time: new Date(endTime).toISOString(),
|
|
934
1236
|
duration_ms: endTime - startTime,
|
|
935
1237
|
status: "ERROR",
|
|
936
|
-
error_message: error?.message
|
|
1238
|
+
error_message: error?.message,
|
|
1239
|
+
prompt_key: promptCtx?.promptKey,
|
|
1240
|
+
prompt_version: promptCtx?.promptVersion,
|
|
1241
|
+
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1242
|
+
prompt_variant_index: promptCtx?.variantIndex
|
|
937
1243
|
}).catch(() => {
|
|
938
1244
|
});
|
|
939
1245
|
throw error;
|
|
@@ -945,9 +1251,15 @@ function wrapGoogleAI(model) {
|
|
|
945
1251
|
const originalGenerate = model.generateContent.bind(model);
|
|
946
1252
|
model.generateContent = async function(...args) {
|
|
947
1253
|
const ctx = sessionStorage.getStore() || fallbackSession;
|
|
948
|
-
if (!ctx || !
|
|
1254
|
+
if (!ctx || !initialized2) {
|
|
949
1255
|
return originalGenerate(...args);
|
|
950
1256
|
}
|
|
1257
|
+
let promptCtx = null;
|
|
1258
|
+
try {
|
|
1259
|
+
const { getPromptContext: getPromptContext2 } = await Promise.resolve().then(() => (init_prompts(), prompts_exports));
|
|
1260
|
+
promptCtx = getPromptContext2();
|
|
1261
|
+
} catch {
|
|
1262
|
+
}
|
|
951
1263
|
const startTime = Date.now();
|
|
952
1264
|
try {
|
|
953
1265
|
const response = await originalGenerate(...args);
|
|
@@ -967,7 +1279,11 @@ function wrapGoogleAI(model) {
|
|
|
967
1279
|
completion_tokens: usage?.candidatesTokenCount,
|
|
968
1280
|
total_tokens: usage?.totalTokenCount,
|
|
969
1281
|
input: captureContent ? JSON.stringify(args[0]) : void 0,
|
|
970
|
-
output: captureContent ? result?.text?.() : void 0
|
|
1282
|
+
output: captureContent ? result?.text?.() : void 0,
|
|
1283
|
+
prompt_key: promptCtx?.promptKey,
|
|
1284
|
+
prompt_version: promptCtx?.promptVersion,
|
|
1285
|
+
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1286
|
+
prompt_variant_index: promptCtx?.variantIndex
|
|
971
1287
|
}).catch(() => {
|
|
972
1288
|
});
|
|
973
1289
|
return response;
|
|
@@ -982,7 +1298,11 @@ function wrapGoogleAI(model) {
|
|
|
982
1298
|
end_time: new Date(endTime).toISOString(),
|
|
983
1299
|
duration_ms: endTime - startTime,
|
|
984
1300
|
status: "ERROR",
|
|
985
|
-
error_message: error?.message
|
|
1301
|
+
error_message: error?.message,
|
|
1302
|
+
prompt_key: promptCtx?.promptKey,
|
|
1303
|
+
prompt_version: promptCtx?.promptVersion,
|
|
1304
|
+
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1305
|
+
prompt_variant_index: promptCtx?.variantIndex
|
|
986
1306
|
}).catch(() => {
|
|
987
1307
|
});
|
|
988
1308
|
throw error;
|
|
@@ -994,71 +1314,71 @@ function wrapGoogleAI(model) {
|
|
|
994
1314
|
// src/models.ts
|
|
995
1315
|
var models_exports = {};
|
|
996
1316
|
__export(models_exports, {
|
|
997
|
-
get: () =>
|
|
998
|
-
init: () =>
|
|
1317
|
+
get: () => get2,
|
|
1318
|
+
init: () => init3
|
|
999
1319
|
});
|
|
1000
|
-
var
|
|
1001
|
-
var
|
|
1002
|
-
var
|
|
1003
|
-
var
|
|
1004
|
-
var
|
|
1005
|
-
var
|
|
1320
|
+
var import_crypto2 = require("crypto");
|
|
1321
|
+
var apiKey3 = null;
|
|
1322
|
+
var baseUrl3 = "https://spans.fallom.com";
|
|
1323
|
+
var initialized3 = false;
|
|
1324
|
+
var syncInterval2 = null;
|
|
1325
|
+
var debugMode3 = false;
|
|
1006
1326
|
var configCache = /* @__PURE__ */ new Map();
|
|
1007
|
-
var
|
|
1327
|
+
var SYNC_TIMEOUT2 = 2e3;
|
|
1008
1328
|
var RECORD_TIMEOUT = 1e3;
|
|
1009
|
-
function
|
|
1010
|
-
if (
|
|
1329
|
+
function log3(msg) {
|
|
1330
|
+
if (debugMode3) {
|
|
1011
1331
|
console.log(`[Fallom] ${msg}`);
|
|
1012
1332
|
}
|
|
1013
1333
|
}
|
|
1014
|
-
function
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
if (!
|
|
1334
|
+
function init3(options = {}) {
|
|
1335
|
+
apiKey3 = options.apiKey || process.env.FALLOM_API_KEY || null;
|
|
1336
|
+
baseUrl3 = options.baseUrl || process.env.FALLOM_BASE_URL || "https://spans.fallom.com";
|
|
1337
|
+
initialized3 = true;
|
|
1338
|
+
if (!apiKey3) {
|
|
1019
1339
|
return;
|
|
1020
1340
|
}
|
|
1021
1341
|
fetchConfigs().catch(() => {
|
|
1022
1342
|
});
|
|
1023
|
-
if (!
|
|
1024
|
-
|
|
1343
|
+
if (!syncInterval2) {
|
|
1344
|
+
syncInterval2 = setInterval(() => {
|
|
1025
1345
|
fetchConfigs().catch(() => {
|
|
1026
1346
|
});
|
|
1027
1347
|
}, 3e4);
|
|
1028
|
-
|
|
1348
|
+
syncInterval2.unref();
|
|
1029
1349
|
}
|
|
1030
1350
|
}
|
|
1031
|
-
function
|
|
1032
|
-
if (!
|
|
1351
|
+
function ensureInit2() {
|
|
1352
|
+
if (!initialized3) {
|
|
1033
1353
|
try {
|
|
1034
|
-
|
|
1354
|
+
init3();
|
|
1035
1355
|
} catch {
|
|
1036
1356
|
}
|
|
1037
1357
|
}
|
|
1038
1358
|
}
|
|
1039
|
-
async function fetchConfigs(timeout =
|
|
1040
|
-
if (!
|
|
1041
|
-
|
|
1359
|
+
async function fetchConfigs(timeout = SYNC_TIMEOUT2) {
|
|
1360
|
+
if (!apiKey3) {
|
|
1361
|
+
log3("_fetchConfigs: No API key, skipping");
|
|
1042
1362
|
return;
|
|
1043
1363
|
}
|
|
1044
1364
|
try {
|
|
1045
|
-
|
|
1365
|
+
log3(`Fetching configs from ${baseUrl3}/configs`);
|
|
1046
1366
|
const controller = new AbortController();
|
|
1047
1367
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1048
|
-
const resp = await fetch(`${
|
|
1049
|
-
headers: { Authorization: `Bearer ${
|
|
1368
|
+
const resp = await fetch(`${baseUrl3}/configs`, {
|
|
1369
|
+
headers: { Authorization: `Bearer ${apiKey3}` },
|
|
1050
1370
|
signal: controller.signal
|
|
1051
1371
|
});
|
|
1052
1372
|
clearTimeout(timeoutId);
|
|
1053
|
-
|
|
1373
|
+
log3(`Response status: ${resp.status}`);
|
|
1054
1374
|
if (resp.ok) {
|
|
1055
1375
|
const data = await resp.json();
|
|
1056
1376
|
const configs = data.configs || [];
|
|
1057
|
-
|
|
1377
|
+
log3(`Got ${configs.length} configs: ${configs.map((c) => c.key)}`);
|
|
1058
1378
|
for (const c of configs) {
|
|
1059
1379
|
const key = c.key;
|
|
1060
1380
|
const version = c.version || 1;
|
|
1061
|
-
|
|
1381
|
+
log3(`Config '${key}' v${version}: ${JSON.stringify(c.variants)}`);
|
|
1062
1382
|
if (!configCache.has(key)) {
|
|
1063
1383
|
configCache.set(key, { versions: /* @__PURE__ */ new Map(), latest: null });
|
|
1064
1384
|
}
|
|
@@ -1067,21 +1387,21 @@ async function fetchConfigs(timeout = SYNC_TIMEOUT) {
|
|
|
1067
1387
|
cached.latest = version;
|
|
1068
1388
|
}
|
|
1069
1389
|
} else {
|
|
1070
|
-
|
|
1390
|
+
log3(`Fetch failed: ${resp.statusText}`);
|
|
1071
1391
|
}
|
|
1072
1392
|
} catch (e) {
|
|
1073
|
-
|
|
1393
|
+
log3(`Fetch exception: ${e}`);
|
|
1074
1394
|
}
|
|
1075
1395
|
}
|
|
1076
|
-
async function fetchSpecificVersion(configKey, version, timeout =
|
|
1077
|
-
if (!
|
|
1396
|
+
async function fetchSpecificVersion(configKey, version, timeout = SYNC_TIMEOUT2) {
|
|
1397
|
+
if (!apiKey3) return null;
|
|
1078
1398
|
try {
|
|
1079
1399
|
const controller = new AbortController();
|
|
1080
1400
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1081
1401
|
const resp = await fetch(
|
|
1082
|
-
`${
|
|
1402
|
+
`${baseUrl3}/configs/${configKey}/version/${version}`,
|
|
1083
1403
|
{
|
|
1084
|
-
headers: { Authorization: `Bearer ${
|
|
1404
|
+
headers: { Authorization: `Bearer ${apiKey3}` },
|
|
1085
1405
|
signal: controller.signal
|
|
1086
1406
|
}
|
|
1087
1407
|
);
|
|
@@ -1098,22 +1418,22 @@ async function fetchSpecificVersion(configKey, version, timeout = SYNC_TIMEOUT)
|
|
|
1098
1418
|
}
|
|
1099
1419
|
return null;
|
|
1100
1420
|
}
|
|
1101
|
-
async function
|
|
1421
|
+
async function get2(configKey, sessionId, options = {}) {
|
|
1102
1422
|
const { version, fallback, debug = false } = options;
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1423
|
+
debugMode3 = debug;
|
|
1424
|
+
ensureInit2();
|
|
1425
|
+
log3(`get() called: configKey=${configKey}, sessionId=${sessionId}, fallback=${fallback}`);
|
|
1106
1426
|
try {
|
|
1107
1427
|
let configData = configCache.get(configKey);
|
|
1108
|
-
|
|
1428
|
+
log3(`Cache lookup for '${configKey}': ${configData ? "found" : "not found"}`);
|
|
1109
1429
|
if (!configData) {
|
|
1110
|
-
|
|
1111
|
-
await fetchConfigs(
|
|
1430
|
+
log3("Not in cache, fetching...");
|
|
1431
|
+
await fetchConfigs(SYNC_TIMEOUT2);
|
|
1112
1432
|
configData = configCache.get(configKey);
|
|
1113
|
-
|
|
1433
|
+
log3(`After fetch, cache lookup: ${configData ? "found" : "still not found"}`);
|
|
1114
1434
|
}
|
|
1115
1435
|
if (!configData) {
|
|
1116
|
-
|
|
1436
|
+
log3(`Config not found, using fallback: ${fallback}`);
|
|
1117
1437
|
if (fallback) {
|
|
1118
1438
|
console.warn(`[Fallom WARNING] Config '${configKey}' not found, using fallback model: ${fallback}`);
|
|
1119
1439
|
return returnWithTrace(configKey, sessionId, fallback, 0);
|
|
@@ -1127,7 +1447,7 @@ async function get(configKey, sessionId, options = {}) {
|
|
|
1127
1447
|
if (version !== void 0) {
|
|
1128
1448
|
config = configData.versions.get(version);
|
|
1129
1449
|
if (!config) {
|
|
1130
|
-
config = await fetchSpecificVersion(configKey, version,
|
|
1450
|
+
config = await fetchSpecificVersion(configKey, version, SYNC_TIMEOUT2) || void 0;
|
|
1131
1451
|
}
|
|
1132
1452
|
if (!config) {
|
|
1133
1453
|
if (fallback) {
|
|
@@ -1151,22 +1471,22 @@ async function get(configKey, sessionId, options = {}) {
|
|
|
1151
1471
|
const variantsRaw = config.variants;
|
|
1152
1472
|
const configVersion = config.version || targetVersion;
|
|
1153
1473
|
const variants = Array.isArray(variantsRaw) ? variantsRaw : Object.values(variantsRaw);
|
|
1154
|
-
|
|
1155
|
-
const hashBytes = (0,
|
|
1474
|
+
log3(`Config found! Version: ${configVersion}, Variants: ${JSON.stringify(variants)}`);
|
|
1475
|
+
const hashBytes = (0, import_crypto2.createHash)("md5").update(sessionId).digest();
|
|
1156
1476
|
const hashVal = hashBytes.readUInt32BE(0) % 1e6;
|
|
1157
|
-
|
|
1477
|
+
log3(`Session hash: ${hashVal} (out of 1,000,000)`);
|
|
1158
1478
|
let cumulative = 0;
|
|
1159
1479
|
let assignedModel = variants[variants.length - 1].model;
|
|
1160
1480
|
for (const v of variants) {
|
|
1161
1481
|
const oldCumulative = cumulative;
|
|
1162
1482
|
cumulative += v.weight * 1e4;
|
|
1163
|
-
|
|
1483
|
+
log3(`Variant ${v.model}: weight=${v.weight}%, range=${oldCumulative}-${cumulative}, hash=${hashVal}, match=${hashVal < cumulative}`);
|
|
1164
1484
|
if (hashVal < cumulative) {
|
|
1165
1485
|
assignedModel = v.model;
|
|
1166
1486
|
break;
|
|
1167
1487
|
}
|
|
1168
1488
|
}
|
|
1169
|
-
|
|
1489
|
+
log3(`\u2705 Assigned model: ${assignedModel}`);
|
|
1170
1490
|
return returnWithTrace(configKey, sessionId, assignedModel, configVersion);
|
|
1171
1491
|
} catch (e) {
|
|
1172
1492
|
if (e instanceof Error && e.message.includes("not found")) {
|
|
@@ -1191,14 +1511,14 @@ function returnWithTrace(configKey, sessionId, model, version) {
|
|
|
1191
1511
|
return model;
|
|
1192
1512
|
}
|
|
1193
1513
|
async function recordSession(configKey, version, sessionId, model) {
|
|
1194
|
-
if (!
|
|
1514
|
+
if (!apiKey3) return;
|
|
1195
1515
|
try {
|
|
1196
1516
|
const controller = new AbortController();
|
|
1197
1517
|
const timeoutId = setTimeout(() => controller.abort(), RECORD_TIMEOUT);
|
|
1198
|
-
await fetch(`${
|
|
1518
|
+
await fetch(`${baseUrl3}/sessions`, {
|
|
1199
1519
|
method: "POST",
|
|
1200
1520
|
headers: {
|
|
1201
|
-
Authorization: `Bearer ${
|
|
1521
|
+
Authorization: `Bearer ${apiKey3}`,
|
|
1202
1522
|
"Content-Type": "application/json"
|
|
1203
1523
|
},
|
|
1204
1524
|
body: JSON.stringify({
|
|
@@ -1214,30 +1534,41 @@ async function recordSession(configKey, version, sessionId, model) {
|
|
|
1214
1534
|
}
|
|
1215
1535
|
}
|
|
1216
1536
|
|
|
1537
|
+
// src/index.ts
|
|
1538
|
+
init_prompts();
|
|
1539
|
+
|
|
1217
1540
|
// src/init.ts
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1541
|
+
init_prompts();
|
|
1542
|
+
async function init4(options = {}) {
|
|
1543
|
+
const baseUrl4 = options.baseUrl || process.env.FALLOM_BASE_URL || "https://spans.fallom.com";
|
|
1544
|
+
await init2({
|
|
1221
1545
|
apiKey: options.apiKey,
|
|
1222
|
-
baseUrl:
|
|
1546
|
+
baseUrl: baseUrl4,
|
|
1223
1547
|
captureContent: options.captureContent,
|
|
1224
1548
|
debug: options.debug
|
|
1225
1549
|
});
|
|
1226
|
-
|
|
1550
|
+
init3({
|
|
1551
|
+
apiKey: options.apiKey,
|
|
1552
|
+
baseUrl: baseUrl4
|
|
1553
|
+
});
|
|
1554
|
+
init({
|
|
1227
1555
|
apiKey: options.apiKey,
|
|
1228
|
-
baseUrl:
|
|
1556
|
+
baseUrl: baseUrl4
|
|
1229
1557
|
});
|
|
1230
1558
|
}
|
|
1231
1559
|
|
|
1232
1560
|
// src/index.ts
|
|
1561
|
+
init_prompts();
|
|
1233
1562
|
var index_default = {
|
|
1234
|
-
init:
|
|
1563
|
+
init: init4,
|
|
1235
1564
|
trace: trace_exports,
|
|
1236
|
-
models: models_exports
|
|
1565
|
+
models: models_exports,
|
|
1566
|
+
prompts: prompts_exports
|
|
1237
1567
|
};
|
|
1238
1568
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1239
1569
|
0 && (module.exports = {
|
|
1240
1570
|
init,
|
|
1241
1571
|
models,
|
|
1572
|
+
prompts,
|
|
1242
1573
|
trace
|
|
1243
1574
|
});
|