@intuned/browser-dev 0.1.17-dev.1 → 0.1.17-dev10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/loadRuntime.js +11 -1
- package/dist/intunedServices/ApiGateway/aiApiGateway.js +7 -1
- package/dist/intunedServices/ApiGateway/providers/Anthropic.js +4 -1
- package/dist/intunedServices/ApiGateway/runInfoHeaders.js +25 -0
- package/dist/intunedServices/ApiGateway/tests/testApiGateway.spec.js +129 -1
- package/dist/optimized-extractors/common/extractStructuredDataUsingClaude.js +13 -7
- package/dist/optimized-extractors/common/extractStructuredDataUsingOpenAi.js +18 -14
- package/dist/optimized-extractors/common/extractStrucutredDataUsingAiInstance.js +17 -8
- package/dist/optimized-extractors/common/index.js +2 -6
- package/dist/optimized-extractors/common/utils.js +0 -15
- package/dist/types/intuned-runtime.d.ts +11 -0
- package/package.json +1 -1
- package/.claude/settings.local.json +0 -8
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.loadRuntime = exports.loadGetAiGatewayConfig = void 0;
|
|
6
|
+
exports.loadRuntime = exports.loadRunInfo = exports.loadGetAiGatewayConfig = void 0;
|
|
7
7
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
8
8
|
const loadRuntime = async () => {
|
|
9
9
|
try {
|
|
@@ -14,6 +14,16 @@ const loadRuntime = async () => {
|
|
|
14
14
|
}
|
|
15
15
|
};
|
|
16
16
|
exports.loadRuntime = loadRuntime;
|
|
17
|
+
const loadRunInfo = async () => {
|
|
18
|
+
try {
|
|
19
|
+
const runtime = await Promise.resolve().then(() => _interopRequireWildcard(require("@intuned/runtime")));
|
|
20
|
+
const fn = runtime.runInfo;
|
|
21
|
+
return typeof fn === "function" ? fn() : undefined;
|
|
22
|
+
} catch {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
exports.loadRunInfo = loadRunInfo;
|
|
17
27
|
const loadGetAiGatewayConfig = async () => {
|
|
18
28
|
const runtime = await Promise.resolve().then(() => _interopRequireWildcard(require("@intuned/runtime")));
|
|
19
29
|
const fn = runtime.getAiGatewayConfig;
|
|
@@ -10,6 +10,7 @@ var _OpenAI = require("./providers/OpenAI");
|
|
|
10
10
|
var _Gemini = require("./providers/Gemini");
|
|
11
11
|
var _dotenv = require("dotenv");
|
|
12
12
|
var _loadRuntime = require("../../common/loadRuntime");
|
|
13
|
+
var _runInfoHeaders = require("./runInfoHeaders");
|
|
13
14
|
(0, _dotenv.config)();
|
|
14
15
|
class APIGateway {
|
|
15
16
|
useGateway = false;
|
|
@@ -79,10 +80,15 @@ class APIGateway {
|
|
|
79
80
|
baseUrl,
|
|
80
81
|
apiKey
|
|
81
82
|
} = getAiGatewayConfig();
|
|
83
|
+
const runInfoHeaders = (0, _runInfoHeaders.buildRunInfoHeaders)(await (0, _loadRuntime.loadRunInfo)());
|
|
84
|
+
const mergedHeaders = {
|
|
85
|
+
...runInfoHeaders,
|
|
86
|
+
...(extraHeaders ?? {})
|
|
87
|
+
};
|
|
82
88
|
return {
|
|
83
89
|
model: this.model,
|
|
84
90
|
apiKey,
|
|
85
|
-
extraHeaders,
|
|
91
|
+
extraHeaders: Object.keys(mergedHeaders).length > 0 ? mergedHeaders : undefined,
|
|
86
92
|
baseUrl
|
|
87
93
|
};
|
|
88
94
|
} catch (error) {
|
|
@@ -9,16 +9,19 @@ var _jwtTokenManager = require("../../../common/jwtTokenManager");
|
|
|
9
9
|
const createAnthropicInstance = input => {
|
|
10
10
|
const {
|
|
11
11
|
apiKey,
|
|
12
|
+
headers,
|
|
12
13
|
baseUrl
|
|
13
14
|
} = input;
|
|
14
15
|
if (apiKey && baseUrl === undefined) {
|
|
15
16
|
return (0, _anthropic.createAnthropic)({
|
|
16
|
-
apiKey
|
|
17
|
+
apiKey,
|
|
18
|
+
headers
|
|
17
19
|
});
|
|
18
20
|
} else {
|
|
19
21
|
const baseURLWithV1 = baseUrl ? `${baseUrl}/v1` : undefined;
|
|
20
22
|
return (0, _anthropic.createAnthropic)({
|
|
21
23
|
apiKey,
|
|
24
|
+
headers,
|
|
22
25
|
baseURL: baseURLWithV1,
|
|
23
26
|
fetch: _jwtTokenManager.backendFunctionsTokenManager.fetchWithToken.bind(_jwtTokenManager.backendFunctionsTokenManager)
|
|
24
27
|
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.buildRunInfoHeaders = buildRunInfoHeaders;
|
|
7
|
+
function buildRunInfoHeaders(runInfo) {
|
|
8
|
+
const headers = {};
|
|
9
|
+
if (!runInfo) {
|
|
10
|
+
return headers;
|
|
11
|
+
}
|
|
12
|
+
if (runInfo.jobId) {
|
|
13
|
+
headers["x-intuned-job-id"] = runInfo.jobId;
|
|
14
|
+
}
|
|
15
|
+
if (runInfo.jobRunId) {
|
|
16
|
+
headers["x-intuned-job-run-id"] = runInfo.jobRunId;
|
|
17
|
+
}
|
|
18
|
+
if (runInfo.runId) {
|
|
19
|
+
headers["x-intuned-run-id"] = runInfo.runId;
|
|
20
|
+
}
|
|
21
|
+
if (runInfo.authSessionId) {
|
|
22
|
+
headers["x-intuned-auth-session-id"] = runInfo.authSessionId;
|
|
23
|
+
}
|
|
24
|
+
return headers;
|
|
25
|
+
}
|
|
@@ -27,7 +27,8 @@ _vitest.vi.mock("../providers/Gemini", () => ({
|
|
|
27
27
|
}));
|
|
28
28
|
_vitest.vi.mock("../../../common/loadRuntime", () => ({
|
|
29
29
|
loadRuntime: _vitest.vi.fn(),
|
|
30
|
-
loadGetAiGatewayConfig: _vitest.vi.fn()
|
|
30
|
+
loadGetAiGatewayConfig: _vitest.vi.fn(),
|
|
31
|
+
loadRunInfo: _vitest.vi.fn()
|
|
31
32
|
}));
|
|
32
33
|
const mockGetModelProvider = _vitest.vi.mocked(_getModelProvider.getModelProvider);
|
|
33
34
|
const mockCreateAnthropicInstance = _vitest.vi.mocked(_Anthropic.createAnthropicInstance);
|
|
@@ -35,6 +36,7 @@ const mockCreateOpenAIInstance = _vitest.vi.mocked(_OpenAI.createOpenAIInstance)
|
|
|
35
36
|
const mockCreateGoogleInstance = _vitest.vi.mocked(_Gemini.createGoogleInstance);
|
|
36
37
|
const mockLoadRuntime = _vitest.vi.mocked(_loadRuntime.loadRuntime);
|
|
37
38
|
const mockLoadGetAiGatewayConfig = _vitest.vi.mocked(_loadRuntime.loadGetAiGatewayConfig);
|
|
39
|
+
const mockLoadRunInfo = _vitest.vi.mocked(_loadRuntime.loadRunInfo);
|
|
38
40
|
(0, _extendedTest.describe)("APIGateway", () => {
|
|
39
41
|
let originalEnv;
|
|
40
42
|
(0, _extendedTest.beforeEach)(() => {
|
|
@@ -49,6 +51,7 @@ const mockLoadGetAiGatewayConfig = _vitest.vi.mocked(_loadRuntime.loadGetAiGatew
|
|
|
49
51
|
GOOGLE_API_KEY: undefined
|
|
50
52
|
};
|
|
51
53
|
_vitest.vi.clearAllMocks();
|
|
54
|
+
mockLoadRunInfo.mockResolvedValue(undefined);
|
|
52
55
|
});
|
|
53
56
|
(0, _extendedTest.afterEach)(() => {
|
|
54
57
|
process.env = originalEnv;
|
|
@@ -201,6 +204,99 @@ const mockLoadGetAiGatewayConfig = _vitest.vi.mocked(_loadRuntime.loadGetAiGatew
|
|
|
201
204
|
await gateway["ensureInitialized"]();
|
|
202
205
|
await (0, _extendedTest.expect)(gateway["getModelConfig"]()).rejects.toThrow("Failed to load gateway configuration from @intuned/runtime");
|
|
203
206
|
});
|
|
207
|
+
(0, _extendedTest.it)("should attach x-intuned-* headers from runInfo in gateway mode", async () => {
|
|
208
|
+
mockGetModelProvider.mockReturnValue("anthropic");
|
|
209
|
+
mockLoadRuntime.mockResolvedValue(() => ({
|
|
210
|
+
runId: "test"
|
|
211
|
+
}));
|
|
212
|
+
mockLoadGetAiGatewayConfig.mockResolvedValue(() => ({
|
|
213
|
+
baseUrl: "https://gw.example.com/intuned-ai-gateway",
|
|
214
|
+
apiKey: "resolved-token"
|
|
215
|
+
}));
|
|
216
|
+
mockLoadRunInfo.mockResolvedValue({
|
|
217
|
+
runEnvironment: "DEPLOYED",
|
|
218
|
+
jobId: "job-1",
|
|
219
|
+
jobRunId: "run-1",
|
|
220
|
+
runId: "r-1",
|
|
221
|
+
authSessionId: "auth-1"
|
|
222
|
+
});
|
|
223
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
224
|
+
model: "claude-3-sonnet"
|
|
225
|
+
});
|
|
226
|
+
await gateway["ensureInitialized"]();
|
|
227
|
+
const result = await gateway["getModelConfig"]();
|
|
228
|
+
(0, _extendedTest.expect)(result.extraHeaders).toEqual({
|
|
229
|
+
"x-intuned-job-id": "job-1",
|
|
230
|
+
"x-intuned-job-run-id": "run-1",
|
|
231
|
+
"x-intuned-run-id": "r-1",
|
|
232
|
+
"x-intuned-auth-session-id": "auth-1"
|
|
233
|
+
});
|
|
234
|
+
});
|
|
235
|
+
(0, _extendedTest.it)("should only attach headers for present runInfo fields", async () => {
|
|
236
|
+
mockGetModelProvider.mockReturnValue("anthropic");
|
|
237
|
+
mockLoadRuntime.mockResolvedValue(() => ({
|
|
238
|
+
runId: "test"
|
|
239
|
+
}));
|
|
240
|
+
mockLoadGetAiGatewayConfig.mockResolvedValue(() => ({
|
|
241
|
+
baseUrl: "https://gw.example.com/intuned-ai-gateway",
|
|
242
|
+
apiKey: "resolved-token"
|
|
243
|
+
}));
|
|
244
|
+
mockLoadRunInfo.mockResolvedValue({
|
|
245
|
+
runEnvironment: "DEPLOYED",
|
|
246
|
+
jobId: "job-1"
|
|
247
|
+
});
|
|
248
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
249
|
+
model: "claude-3-sonnet"
|
|
250
|
+
});
|
|
251
|
+
await gateway["ensureInitialized"]();
|
|
252
|
+
const result = await gateway["getModelConfig"]();
|
|
253
|
+
(0, _extendedTest.expect)(result.extraHeaders).toEqual({
|
|
254
|
+
"x-intuned-job-id": "job-1"
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
(0, _extendedTest.it)("should let caller-provided headers override runInfo-derived ones", async () => {
|
|
258
|
+
mockGetModelProvider.mockReturnValue("anthropic");
|
|
259
|
+
mockLoadRuntime.mockResolvedValue(() => ({
|
|
260
|
+
runId: "test"
|
|
261
|
+
}));
|
|
262
|
+
mockLoadGetAiGatewayConfig.mockResolvedValue(() => ({
|
|
263
|
+
baseUrl: "https://gw.example.com/intuned-ai-gateway",
|
|
264
|
+
apiKey: "resolved-token"
|
|
265
|
+
}));
|
|
266
|
+
mockLoadRunInfo.mockResolvedValue({
|
|
267
|
+
runEnvironment: "DEPLOYED",
|
|
268
|
+
jobId: "from-runinfo"
|
|
269
|
+
});
|
|
270
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
271
|
+
model: "claude-3-sonnet"
|
|
272
|
+
});
|
|
273
|
+
await gateway["ensureInitialized"]();
|
|
274
|
+
const result = await gateway["getModelConfig"]({
|
|
275
|
+
"x-intuned-job-id": "from-caller",
|
|
276
|
+
"Custom-Header": "value"
|
|
277
|
+
});
|
|
278
|
+
(0, _extendedTest.expect)(result.extraHeaders).toEqual({
|
|
279
|
+
"x-intuned-job-id": "from-caller",
|
|
280
|
+
"Custom-Header": "value"
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
(0, _extendedTest.it)("should leave extraHeaders undefined when no runInfo and no caller headers", async () => {
|
|
284
|
+
mockGetModelProvider.mockReturnValue("anthropic");
|
|
285
|
+
mockLoadRuntime.mockResolvedValue(() => ({
|
|
286
|
+
runId: "test"
|
|
287
|
+
}));
|
|
288
|
+
mockLoadGetAiGatewayConfig.mockResolvedValue(() => ({
|
|
289
|
+
baseUrl: "https://gw.example.com/intuned-ai-gateway",
|
|
290
|
+
apiKey: "resolved-token"
|
|
291
|
+
}));
|
|
292
|
+
mockLoadRunInfo.mockResolvedValue(undefined);
|
|
293
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
294
|
+
model: "claude-3-sonnet"
|
|
295
|
+
});
|
|
296
|
+
await gateway["ensureInitialized"]();
|
|
297
|
+
const result = await gateway["getModelConfig"]();
|
|
298
|
+
(0, _extendedTest.expect)(result.extraHeaders).toBeUndefined();
|
|
299
|
+
});
|
|
204
300
|
});
|
|
205
301
|
(0, _extendedTest.describe)("createProviderInstance", () => {
|
|
206
302
|
(0, _extendedTest.it)("should create anthropic instance with gateway mode", async () => {
|
|
@@ -228,6 +324,38 @@ const mockLoadGetAiGatewayConfig = _vitest.vi.mocked(_loadRuntime.loadGetAiGatew
|
|
|
228
324
|
});
|
|
229
325
|
(0, _extendedTest.expect)(result).toBe(mockInstance);
|
|
230
326
|
});
|
|
327
|
+
(0, _extendedTest.it)("should pass runInfo-derived headers to the anthropic gateway provider", async () => {
|
|
328
|
+
mockGetModelProvider.mockReturnValue("anthropic");
|
|
329
|
+
mockLoadRuntime.mockResolvedValue(() => ({
|
|
330
|
+
runId: "test"
|
|
331
|
+
}));
|
|
332
|
+
mockLoadGetAiGatewayConfig.mockResolvedValue(() => ({
|
|
333
|
+
baseUrl: "https://functions.example.com/api/workspace123/functions/integration456/intuned-ai-gateway",
|
|
334
|
+
apiKey: "resolved-token"
|
|
335
|
+
}));
|
|
336
|
+
mockLoadRunInfo.mockResolvedValue({
|
|
337
|
+
runEnvironment: "DEPLOYED",
|
|
338
|
+
jobId: "job-1",
|
|
339
|
+
jobRunId: "run-1"
|
|
340
|
+
});
|
|
341
|
+
const mockInstance = {
|
|
342
|
+
chat: _vitest.vi.fn()
|
|
343
|
+
};
|
|
344
|
+
mockCreateAnthropicInstance.mockReturnValue(mockInstance);
|
|
345
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
346
|
+
model: "claude-3-sonnet"
|
|
347
|
+
});
|
|
348
|
+
await gateway.createProviderInstance();
|
|
349
|
+
(0, _extendedTest.expect)(mockCreateAnthropicInstance).toHaveBeenCalledWith({
|
|
350
|
+
apiKey: "resolved-token",
|
|
351
|
+
headers: {
|
|
352
|
+
"x-intuned-job-id": "job-1",
|
|
353
|
+
"x-intuned-job-run-id": "run-1"
|
|
354
|
+
},
|
|
355
|
+
model: "claude-3-sonnet",
|
|
356
|
+
baseUrl: "https://functions.example.com/api/workspace123/functions/integration456/intuned-ai-gateway"
|
|
357
|
+
});
|
|
358
|
+
});
|
|
231
359
|
(0, _extendedTest.it)("should create openai instance with direct API key", async () => {
|
|
232
360
|
mockGetModelProvider.mockReturnValue("openai");
|
|
233
361
|
const mockInstance = {
|
|
@@ -8,10 +8,10 @@ var _anthropicModel = require("../models/anthropicModel");
|
|
|
8
8
|
var _neverthrow = require("neverthrow");
|
|
9
9
|
var Errors = _interopRequireWildcard(require("../types/errors"));
|
|
10
10
|
var _utils = require("./utils");
|
|
11
|
+
var _Logger = require("../../common/Logger");
|
|
11
12
|
var _aiModelsValidations = require("../common/aiModelsValidations");
|
|
12
13
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
13
14
|
async function extractStructuredDataUsingClaude(input) {
|
|
14
|
-
var _unwrappedResponse$us, _unwrappedResponse$us2;
|
|
15
15
|
const {
|
|
16
16
|
entityName,
|
|
17
17
|
model,
|
|
@@ -96,9 +96,6 @@ async function extractStructuredDataUsingClaude(input) {
|
|
|
96
96
|
return (0, _neverthrow.err)(response.error);
|
|
97
97
|
}
|
|
98
98
|
const unwrappedResponse = response.value.data;
|
|
99
|
-
const costInCents = (0, _utils.parseCostInCents)(response.value.response.headers.get("x-ai-cost-in-cents"));
|
|
100
|
-
const totalTokens = (((_unwrappedResponse$us = unwrappedResponse.usage) === null || _unwrappedResponse$us === void 0 ? void 0 : _unwrappedResponse$us.input_tokens) ?? 0) + (((_unwrappedResponse$us2 = unwrappedResponse.usage) === null || _unwrappedResponse$us2 === void 0 ? void 0 : _unwrappedResponse$us2.output_tokens) ?? 0);
|
|
101
|
-
(0, _utils.logAiCallUsage)(costInCents, totalTokens);
|
|
102
99
|
if (unwrappedResponse.stop_reason === "max_tokens") {
|
|
103
100
|
return (0, _neverthrow.err)(Errors.AiCallFailed("response from ai exceeds model maximum output tokens, try to be more specific with what data you need to extract"));
|
|
104
101
|
}
|
|
@@ -120,9 +117,18 @@ async function extractStructuredDataUsingClaude(input) {
|
|
|
120
117
|
return (0, _neverthrow.err)(Errors.invalidExtractionResult("the model was not able to extract data correctly"));
|
|
121
118
|
}
|
|
122
119
|
const result = (0, _utils.getResultFromOutputSchema)(originalJsonSchema, entityName, tool.input);
|
|
120
|
+
const callCost = response.value.response.headers.get("x-ai-cost-in-cents");
|
|
121
|
+
if (input.logAiCallCost) {
|
|
122
|
+
if (apiKey) {
|
|
123
|
+
_Logger.logger.info(`extractor ${input.identifier}: AI cost is not calculated (using custom API key)`);
|
|
124
|
+
} else if (callCost) {
|
|
125
|
+
const cost = parseFloat(callCost);
|
|
126
|
+
if (!isNaN(cost)) {
|
|
127
|
+
_Logger.logger.info(`extractor ${input.identifier}: AI cost is $${cost / 100}`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
123
131
|
return (0, _neverthrow.ok)({
|
|
124
|
-
result
|
|
125
|
-
costInCents,
|
|
126
|
-
totalTokens
|
|
132
|
+
result
|
|
127
133
|
});
|
|
128
134
|
}
|
|
@@ -7,10 +7,11 @@ exports.extractStructuredDataUsingOpenAi = extractStructuredDataUsingOpenAi;
|
|
|
7
7
|
var _neverthrow = require("neverthrow");
|
|
8
8
|
var Errors = _interopRequireWildcard(require("../types/errors"));
|
|
9
9
|
var _utils = require("./utils");
|
|
10
|
+
var _Logger = require("../../common/Logger");
|
|
10
11
|
var _openaiModel = require("../models/openaiModel");
|
|
11
12
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
12
13
|
async function extractStructuredDataUsingOpenAi(input) {
|
|
13
|
-
var _completion$value$dat, _completion$value$dat2
|
|
14
|
+
var _completion$value$dat, _completion$value$dat2;
|
|
14
15
|
const {
|
|
15
16
|
entityName,
|
|
16
17
|
model,
|
|
@@ -49,16 +50,13 @@ async function extractStructuredDataUsingOpenAi(input) {
|
|
|
49
50
|
content.push(...imageContent);
|
|
50
51
|
}
|
|
51
52
|
const modelName = input.model;
|
|
52
|
-
const supportsCustomTemperature = !/^(o\d|gpt-5)/i.test(modelName);
|
|
53
53
|
const toolName = `extract_${entityName}`;
|
|
54
54
|
const openAiInstance = (0, _openaiModel.createOpenAIInstance)({
|
|
55
55
|
apiKey
|
|
56
56
|
});
|
|
57
57
|
const completion = await (0, _neverthrow.fromPromise)(openAiInstance.chat.completions.create({
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
temperature: 0
|
|
61
|
-
} : {}),
|
|
58
|
+
max_tokens: 4000,
|
|
59
|
+
temperature: 0,
|
|
62
60
|
model: modelName,
|
|
63
61
|
messages: [{
|
|
64
62
|
role: "system",
|
|
@@ -92,17 +90,14 @@ async function extractStructuredDataUsingOpenAi(input) {
|
|
|
92
90
|
if (completion.isErr()) {
|
|
93
91
|
return (0, _neverthrow.err)(completion.error);
|
|
94
92
|
}
|
|
95
|
-
const costInCents = (0, _utils.parseCostInCents)(completion.value.response.headers.get("x-ai-cost-in-cents"));
|
|
96
|
-
const totalTokens = (_completion$value$dat = completion.value.data.usage) === null || _completion$value$dat === void 0 ? void 0 : _completion$value$dat.total_tokens;
|
|
97
|
-
(0, _utils.logAiCallUsage)(costInCents, totalTokens);
|
|
98
93
|
if (completion.value.data.choices[0].finish_reason === "length") {
|
|
99
94
|
return (0, _neverthrow.err)(Errors.AiCallFailed("response from ai exceeds model maximum output tokens, try to be more specific with what data you need to extract"));
|
|
100
95
|
}
|
|
101
|
-
const noDataFound = (_completion$value$
|
|
96
|
+
const noDataFound = (_completion$value$dat = completion.value.data.choices[0].message.tool_calls) === null || _completion$value$dat === void 0 ? void 0 : _completion$value$dat.some(content => content.type === "function" && content.function.name == "no_data_found");
|
|
102
97
|
if (noDataFound) {
|
|
103
98
|
return (0, _neverthrow.err)(Errors.NoDataFound("data isn't found in the text or images."));
|
|
104
99
|
}
|
|
105
|
-
let functionCall = (_completion$value$
|
|
100
|
+
let functionCall = (_completion$value$dat2 = completion.value.data.choices[0].message.tool_calls) === null || _completion$value$dat2 === void 0 || (_completion$value$dat2 = _completion$value$dat2.find(t => t.type === "function" && t.function.name === toolName)) === null || _completion$value$dat2 === void 0 ? void 0 : _completion$value$dat2.function;
|
|
106
101
|
if (!functionCall) {
|
|
107
102
|
functionCall = completion.value.data.choices[0].message.function_call;
|
|
108
103
|
if (!functionCall) {
|
|
@@ -119,9 +114,18 @@ async function extractStructuredDataUsingOpenAi(input) {
|
|
|
119
114
|
}
|
|
120
115
|
const result = (0, _utils.getResultFromOutputSchema)(originalJsonSchema, entityName, parsedData.value);
|
|
121
116
|
const formatted = (0, _utils.cleanupAiResult)(result);
|
|
117
|
+
const callCost = completion.value.response.headers.get("x-ai-cost-in-cents");
|
|
118
|
+
if (input.logAiCallCost) {
|
|
119
|
+
if (apiKey) {
|
|
120
|
+
_Logger.logger.info(`extractor ${input.identifier}: AI cost is not calculated (using custom API key)`);
|
|
121
|
+
} else if (callCost) {
|
|
122
|
+
const cost = parseFloat(callCost);
|
|
123
|
+
if (!isNaN(cost)) {
|
|
124
|
+
_Logger.logger.info(`extractor ${input.identifier}: AI cost is $${cost / 100}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
122
128
|
return (0, _neverthrow.ok)({
|
|
123
|
-
result: formatted
|
|
124
|
-
costInCents,
|
|
125
|
-
totalTokens
|
|
129
|
+
result: formatted
|
|
126
130
|
});
|
|
127
131
|
}
|
|
@@ -7,10 +7,11 @@ exports.extractStructuredDataUsingAiInstance = extractStructuredDataUsingAiInsta
|
|
|
7
7
|
var _neverthrow = require("neverthrow");
|
|
8
8
|
var Errors = _interopRequireWildcard(require("../types/errors"));
|
|
9
9
|
var _utils = require("./utils");
|
|
10
|
+
var _Logger = require("../../common/Logger");
|
|
10
11
|
var _ai = require("ai");
|
|
11
12
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
12
13
|
async function extractStructuredDataUsingAiInstance(input) {
|
|
13
|
-
var _apiResult$value$
|
|
14
|
+
var _apiResult$value$tool, _apiResult$value$tool2, _apiResult$value$resp;
|
|
14
15
|
const {
|
|
15
16
|
entityName,
|
|
16
17
|
model,
|
|
@@ -19,7 +20,9 @@ async function extractStructuredDataUsingAiInstance(input) {
|
|
|
19
20
|
text,
|
|
20
21
|
extraUserMessages,
|
|
21
22
|
images,
|
|
22
|
-
|
|
23
|
+
apiKey,
|
|
24
|
+
apiName,
|
|
25
|
+
maxTokens
|
|
23
26
|
} = input;
|
|
24
27
|
const processedJsonSchema = (0, _utils.processInputSchema)(originalJsonSchema, entityName);
|
|
25
28
|
const content = [];
|
|
@@ -85,9 +88,6 @@ async function extractStructuredDataUsingAiInstance(input) {
|
|
|
85
88
|
if (apiResult.isErr()) {
|
|
86
89
|
return (0, _neverthrow.err)(apiResult.error);
|
|
87
90
|
}
|
|
88
|
-
const costInCents = (0, _utils.parseCostInCents)((_apiResult$value$resp = apiResult.value.response.headers) === null || _apiResult$value$resp === void 0 ? void 0 : _apiResult$value$resp["x-ai-cost-in-cents"]);
|
|
89
|
-
const totalTokens = (_apiResult$value$usag = apiResult.value.usage) === null || _apiResult$value$usag === void 0 ? void 0 : _apiResult$value$usag.totalTokens;
|
|
90
|
-
(0, _utils.logAiCallUsage)(costInCents, totalTokens);
|
|
91
91
|
if (apiResult.value.finishReason === "length") {
|
|
92
92
|
return (0, _neverthrow.err)(Errors.AiCallFailed("response from ai exceeds model maximum output tokens, try to be more specific with what data you need to extract"));
|
|
93
93
|
}
|
|
@@ -105,9 +105,18 @@ async function extractStructuredDataUsingAiInstance(input) {
|
|
|
105
105
|
}
|
|
106
106
|
const result = (0, _utils.getResultFromOutputSchema)(originalJsonSchema, entityName, extractedData);
|
|
107
107
|
const formatted = (0, _utils.cleanupAiResult)(result);
|
|
108
|
+
const callCost = (_apiResult$value$resp = apiResult.value.response.headers) === null || _apiResult$value$resp === void 0 ? void 0 : _apiResult$value$resp["x-ai-cost-in-cents"];
|
|
109
|
+
if (input.logAiCallCost) {
|
|
110
|
+
if (apiKey) {
|
|
111
|
+
_Logger.logger.info(`extractor ${input.identifier}: AI cost is not calculated (using custom API key)`);
|
|
112
|
+
} else if (callCost) {
|
|
113
|
+
const cost = parseFloat(callCost);
|
|
114
|
+
if (!isNaN(cost)) {
|
|
115
|
+
_Logger.logger.info(`extractor ${input.identifier}: AI cost is $${cost / 100}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
108
119
|
return (0, _neverthrow.ok)({
|
|
109
|
-
result: formatted
|
|
110
|
-
costInCents,
|
|
111
|
-
totalTokens
|
|
120
|
+
result: formatted
|
|
112
121
|
});
|
|
113
122
|
}
|
|
@@ -47,13 +47,9 @@ async function extractStructuredDataUsingAi(input) {
|
|
|
47
47
|
return (0, _neverthrow.err)(extractionResult.error);
|
|
48
48
|
}
|
|
49
49
|
const {
|
|
50
|
-
result
|
|
51
|
-
costInCents,
|
|
52
|
-
totalTokens
|
|
50
|
+
result
|
|
53
51
|
} = extractionResult.value;
|
|
54
52
|
return (0, _neverthrow.ok)({
|
|
55
|
-
result: (0, _utils.cleanupAiResult)(result)
|
|
56
|
-
costInCents,
|
|
57
|
-
totalTokens
|
|
53
|
+
result: (0, _utils.cleanupAiResult)(result)
|
|
58
54
|
});
|
|
59
55
|
}
|
|
@@ -6,26 +6,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.cleanupAiResult = cleanupAiResult;
|
|
7
7
|
exports.getRandomItems = getRandomItems;
|
|
8
8
|
exports.getResultFromOutputSchema = getResultFromOutputSchema;
|
|
9
|
-
exports.logAiCallUsage = logAiCallUsage;
|
|
10
|
-
exports.parseCostInCents = parseCostInCents;
|
|
11
9
|
exports.processInputSchema = processInputSchema;
|
|
12
|
-
var _Logger = require("../../common/Logger");
|
|
13
10
|
function getRandomItems(arr, numItems) {
|
|
14
11
|
const shuffled = arr.sort(() => 0.5 - Math.random());
|
|
15
12
|
return shuffled.slice(0, numItems);
|
|
16
13
|
}
|
|
17
|
-
function parseCostInCents(headerValue) {
|
|
18
|
-
if (!headerValue) return undefined;
|
|
19
|
-
const cost = parseFloat(headerValue);
|
|
20
|
-
return isNaN(cost) ? undefined : cost;
|
|
21
|
-
}
|
|
22
|
-
function logAiCallUsage(costInCents, totalTokens) {
|
|
23
|
-
if (costInCents !== undefined) {
|
|
24
|
-
_Logger.logger.info(`Total LLM Cost In Cents: ${costInCents}`);
|
|
25
|
-
} else if (totalTokens !== undefined) {
|
|
26
|
-
_Logger.logger.info(`Total LLM Tokens: ${totalTokens}`);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
14
|
function processInputSchema(originalJsonSchema, entityName) {
|
|
30
15
|
const internalSchema = structuredClone(originalJsonSchema);
|
|
31
16
|
delete internalSchema.description;
|
|
@@ -9,7 +9,18 @@ declare module "@intuned/runtime" {
|
|
|
9
9
|
password: string;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
export interface RunInfo {
|
|
13
|
+
runEnvironment: string;
|
|
14
|
+
runId?: string;
|
|
15
|
+
jobId?: string;
|
|
16
|
+
jobRunId?: string;
|
|
17
|
+
queueId?: string;
|
|
18
|
+
proxy?: string;
|
|
19
|
+
authSessionId?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
12
22
|
export function getExecutionContext(): any;
|
|
23
|
+
export function runInfo(): RunInfo;
|
|
13
24
|
export function extendTimeout(): void;
|
|
14
25
|
export function runWithContext<R, TArgs extends any[]>(
|
|
15
26
|
contextData: any,
|
package/package.json
CHANGED