@intuned/browser-dev 0.1.4-dev.0
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/.babelrc +21 -0
- package/.eslintignore +10 -0
- package/.eslintrc.js +39 -0
- package/BROWSER_SCRIPTS_SETUP.md +84 -0
- package/LICENSE +43 -0
- package/README.md +160 -0
- package/RELEASE.md +60 -0
- package/dist/ai/export.d.js +5 -0
- package/dist/ai/export.d.ts +641 -0
- package/dist/ai/extractStructuredData.js +320 -0
- package/dist/ai/extractStructuredDataUsingAi.js +142 -0
- package/dist/ai/extractionHelpers/screenshotHelpers.js +56 -0
- package/dist/ai/extractionHelpers/validateSchema.js +148 -0
- package/dist/ai/index.d.ts +641 -0
- package/dist/ai/index.js +19 -0
- package/dist/ai/isPageLoaded.js +80 -0
- package/dist/ai/prompt.js +39 -0
- package/dist/ai/tests/testCheckAllTypesAreStrings.spec.js +137 -0
- package/dist/ai/tests/testExtractFromContent.spec.js +372 -0
- package/dist/ai/tests/testExtractStructuredData.spec.js +646 -0
- package/dist/ai/tests/testIsPageLoaded.spec.js +277 -0
- package/dist/ai/tools/index.js +48 -0
- package/dist/ai/types/errors.js +67 -0
- package/dist/ai/types/models.js +45 -0
- package/dist/ai/types/types.js +48 -0
- package/dist/ai/validators.js +167 -0
- package/dist/common/Logger/index.js +60 -0
- package/dist/common/Logger/types.js +5 -0
- package/dist/common/SdkError.js +50 -0
- package/dist/common/aiModelsValidations.js +32 -0
- package/dist/common/ensureBrowserScripts.js +14 -0
- package/dist/common/extendedTest.js +157 -0
- package/dist/common/extractionHelpers.js +19 -0
- package/dist/common/formatZodError.js +18 -0
- package/dist/common/fuzzySearch/fuzzySearch.test.js +250 -0
- package/dist/common/fuzzySearch/levenshtein-search.js +298 -0
- package/dist/common/fuzzySearch/utils.js +23 -0
- package/dist/common/getModelProvider.js +18 -0
- package/dist/common/getSimplifiedHtml.js +122 -0
- package/dist/common/hashObject.js +32 -0
- package/dist/common/html2markdown/convertElementToMarkdown.js +469 -0
- package/dist/common/html2markdown/index.js +19 -0
- package/dist/common/jwtTokenManager.js +57 -0
- package/dist/common/loadRuntime.js +16 -0
- package/dist/common/locatorHelpers.js +41 -0
- package/dist/common/matching/collectStrings.js +32 -0
- package/dist/common/matching/levenshtein.js +40 -0
- package/dist/common/matching/matching.js +317 -0
- package/dist/common/matching/types.js +1 -0
- package/dist/common/noEmpty.js +9 -0
- package/dist/common/saveSnapshotWithExamples.js +60 -0
- package/dist/common/script.js +2602 -0
- package/dist/common/tests/testEnsureBrowserScript.spec.js +31 -0
- package/dist/common/xpathMapping.js +107 -0
- package/dist/helpers/clickUntilExhausted.js +85 -0
- package/dist/helpers/downloadFile.js +125 -0
- package/dist/helpers/export.d.js +5 -0
- package/dist/helpers/export.d.ts +1220 -0
- package/dist/helpers/extractMarkdown.js +35 -0
- package/dist/helpers/filterEmptyValues.js +54 -0
- package/dist/helpers/gotoUrl.js +98 -0
- package/dist/helpers/index.d.ts +1220 -0
- package/dist/helpers/index.js +122 -0
- package/dist/helpers/processDate.js +25 -0
- package/dist/helpers/resolveUrl.js +64 -0
- package/dist/helpers/sanitizeHtml.js +74 -0
- package/dist/helpers/saveFileToS3.js +50 -0
- package/dist/helpers/scrollToLoadContent.js +57 -0
- package/dist/helpers/tests/testClickUntilExhausted.spec.js +372 -0
- package/dist/helpers/tests/testDownloadFile.spec.js +206 -0
- package/dist/helpers/tests/testExtractMarkdown.spec.js +290 -0
- package/dist/helpers/tests/testFilterEmptyValues.spec.js +151 -0
- package/dist/helpers/tests/testGoToUrl.spec.js +37 -0
- package/dist/helpers/tests/testProcessDate.spec.js +13 -0
- package/dist/helpers/tests/testResolveUrl.spec.js +341 -0
- package/dist/helpers/tests/testSanitizeHtml.spec.js +330 -0
- package/dist/helpers/tests/testScrollToLoadContent.spec.js +163 -0
- package/dist/helpers/tests/testValidateDataUsingSchema.spec.js +342 -0
- package/dist/helpers/tests/testWithDomSettledWait.spec.js +164 -0
- package/dist/helpers/tests/testWithNetworkIdleWait.spec.js +114 -0
- package/dist/helpers/types/Attachment.js +115 -0
- package/dist/helpers/types/CustomTypeRegistry.js +48 -0
- package/dist/helpers/types/RunEnvironment.js +18 -0
- package/dist/helpers/types/ValidationError.js +17 -0
- package/dist/helpers/types/index.js +51 -0
- package/dist/helpers/uploadFileToS3.js +154 -0
- package/dist/helpers/utils/getS3Client.js +22 -0
- package/dist/helpers/utils/index.js +73 -0
- package/dist/helpers/utils/isDownload.js +10 -0
- package/dist/helpers/utils/isGenerateCodeMode.js +9 -0
- package/dist/helpers/utils/isLocator.js +9 -0
- package/dist/helpers/utils/jwtTokenManager.js +18 -0
- package/dist/helpers/validateDataUsingSchema.js +103 -0
- package/dist/helpers/waitForDomSettled.js +90 -0
- package/dist/helpers/withNetworkSettledWait.js +91 -0
- package/dist/index.d.js +16 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +16 -0
- package/dist/intunedServices/ApiGateway/aiApiGateway.js +143 -0
- package/dist/intunedServices/ApiGateway/factory.js +16 -0
- package/dist/intunedServices/ApiGateway/providers/Anthropic.js +26 -0
- package/dist/intunedServices/ApiGateway/providers/Gemini.js +29 -0
- package/dist/intunedServices/ApiGateway/providers/OpenAI.js +29 -0
- package/dist/intunedServices/ApiGateway/tests/testApiGateway.spec.js +355 -0
- package/dist/intunedServices/ApiGateway/types.js +11 -0
- package/dist/intunedServices/cache/cache.js +61 -0
- package/dist/intunedServices/cache/index.js +12 -0
- package/dist/intunedServices/cache/tests/testCache.spec.js +117 -0
- package/dist/optimized-extractors/common/buildExamplesPrompt.js +12 -0
- package/dist/optimized-extractors/common/buildImagesFromPage.js +55 -0
- package/dist/optimized-extractors/common/extractStructuredDataUsingClaude.js +135 -0
- package/dist/optimized-extractors/common/extractStructuredDataUsingGoogle.js +37 -0
- package/dist/optimized-extractors/common/extractStructuredDataUsingOpenAi.js +132 -0
- package/dist/optimized-extractors/common/extractStrucutredDataUsingAiInstance.js +122 -0
- package/dist/optimized-extractors/common/findTableHeaders.js +162 -0
- package/dist/optimized-extractors/common/index.js +55 -0
- package/dist/optimized-extractors/common/isTableHeaderOrFooter.js +84 -0
- package/dist/optimized-extractors/common/matching/matching.js +212 -0
- package/dist/optimized-extractors/common/matching/matching.test.js +655 -0
- package/dist/optimized-extractors/common/matching/types.js +18 -0
- package/dist/optimized-extractors/common/matching/utils.js +184 -0
- package/dist/optimized-extractors/common/utils.js +58 -0
- package/dist/optimized-extractors/export.d.js +5 -0
- package/dist/optimized-extractors/export.d.ts +397 -0
- package/dist/optimized-extractors/extractArray.js +120 -0
- package/dist/optimized-extractors/extractObject.js +104 -0
- package/dist/optimized-extractors/index.d.ts +397 -0
- package/dist/optimized-extractors/index.js +31 -0
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/dynamicListExtractor.spec.js +269 -0
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/findSetOfXpathsToCreateAnArrayExtractor.test.js +22 -0
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/getContainerElement.test.js +21 -0
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/partOfSameArrayXpath.test.js +42 -0
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/testArrayExtractorFromLocator.spec.js +146 -0
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/testArrayExtractorFromPage.spec.js +130 -0
- package/dist/optimized-extractors/listExtractionHelpers/__tests__/verifyThatAllXpathsArePartOfSameArray.test.js +9 -0
- package/dist/optimized-extractors/listExtractionHelpers/dynamicListExtractor.js +160 -0
- package/dist/optimized-extractors/listExtractionHelpers/errors.js +46 -0
- package/dist/optimized-extractors/listExtractionHelpers/getListMatches.js +14 -0
- package/dist/optimized-extractors/listExtractionHelpers/runAiExtraction.js +243 -0
- package/dist/optimized-extractors/listExtractionHelpers/typesAndSchema.js +5 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/extractPropertiesUsingGPTFromArray.js +277 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/extractStructuredListUsingAi.js +44 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/getListContainerXpath.js +94 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/getRelativeContainerXpathSelector.js +20 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/getSimplifiedHtmlPerListItem.js +21 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/tablesUtils.js +48 -0
- package/dist/optimized-extractors/listExtractionHelpers/utils/validateOptions.js +52 -0
- package/dist/optimized-extractors/models/anthropicModel.js +23 -0
- package/dist/optimized-extractors/models/openaiModel.js +23 -0
- package/dist/optimized-extractors/objectExtractionHelpers/AIExtractors.js +73 -0
- package/dist/optimized-extractors/objectExtractionHelpers/__tests__/checksumUtils.test.js +103 -0
- package/dist/optimized-extractors/objectExtractionHelpers/__tests__/testObjectExtractorFromLocator.spec.js +107 -0
- package/dist/optimized-extractors/objectExtractionHelpers/__tests__/testObjectExtractorFromPage.spec.js +107 -0
- package/dist/optimized-extractors/objectExtractionHelpers/calculateObjectExampleHash.js +28 -0
- package/dist/optimized-extractors/objectExtractionHelpers/captureSnapshot.js +26 -0
- package/dist/optimized-extractors/objectExtractionHelpers/checksumUtils.js +32 -0
- package/dist/optimized-extractors/objectExtractionHelpers/constants.js +7 -0
- package/dist/optimized-extractors/objectExtractionHelpers/dynamicObjectExtractor.js +106 -0
- package/dist/optimized-extractors/objectExtractionHelpers/errors.js +42 -0
- package/dist/optimized-extractors/objectExtractionHelpers/findDomMatches.js +54 -0
- package/dist/optimized-extractors/objectExtractionHelpers/getSimplifiedHtml.js +122 -0
- package/dist/optimized-extractors/objectExtractionHelpers/typesAndSchemas.js +5 -0
- package/dist/optimized-extractors/objectExtractionHelpers/validateDynamicObjectExtractorOptions.js +52 -0
- package/dist/optimized-extractors/types/aiModelsValidation.js +45 -0
- package/dist/optimized-extractors/types/errors.js +42 -0
- package/dist/optimized-extractors/types/jsonSchema.d.js +5 -0
- package/dist/optimized-extractors/types/jsonSchema.d.ts +50 -0
- package/dist/optimized-extractors/types/types.js +5 -0
- package/dist/optimized-extractors/validators.js +152 -0
- package/dist/types/intuned-runtime.d.js +1 -0
- package/dist/types/intuned-runtime.d.ts +64 -0
- package/dist/vite-env.d.js +1 -0
- package/dist/vite-env.d.ts +9 -0
- package/generated-docs/ai/functions/extractStructuredData.mdx +255 -0
- package/generated-docs/ai/functions/isPageLoaded.mdx +88 -0
- package/generated-docs/ai/interfaces/ArraySchema.mdx +36 -0
- package/generated-docs/ai/interfaces/BasicSchema.mdx +14 -0
- package/generated-docs/ai/interfaces/BooleanSchema.mdx +28 -0
- package/generated-docs/ai/interfaces/ImageBufferContentItem.mdx +16 -0
- package/generated-docs/ai/interfaces/ImageUrlContentItem.mdx +16 -0
- package/generated-docs/ai/interfaces/NumberSchema.mdx +35 -0
- package/generated-docs/ai/interfaces/ObjectSchema.mdx +39 -0
- package/generated-docs/ai/interfaces/StringSchema.mdx +35 -0
- package/generated-docs/ai/interfaces/TextContentItem.mdx +14 -0
- package/generated-docs/ai/type-aliases/ContentItem.mdx +12 -0
- package/generated-docs/ai/type-aliases/JsonSchema.mdx +47 -0
- package/generated-docs/ai/type-aliases/SUPPORTED_MODELS.mdx +85 -0
- package/generated-docs/helpers/functions/downloadFile.mdx +99 -0
- package/generated-docs/helpers/functions/extractMarkdown.mdx +56 -0
- package/generated-docs/helpers/functions/filterEmptyValues.mdx +51 -0
- package/generated-docs/helpers/functions/goToUrl.mdx +124 -0
- package/generated-docs/helpers/functions/processDate.mdx +55 -0
- package/generated-docs/helpers/functions/resolveUrl.mdx +165 -0
- package/generated-docs/helpers/functions/sanitizeHtml.mdx +113 -0
- package/generated-docs/helpers/functions/saveFileToS3.mdx +127 -0
- package/generated-docs/helpers/functions/scrollToLoadContent.mdx +89 -0
- package/generated-docs/helpers/functions/uploadFileToS3.mdx +121 -0
- package/generated-docs/helpers/functions/validateDataUsingSchema.mdx +90 -0
- package/generated-docs/helpers/functions/waitForDomSettled.mdx +91 -0
- package/generated-docs/helpers/functions/withNetworkSettledWait.mdx +76 -0
- package/generated-docs/helpers/interfaces/Attachment.mdx +56 -0
- package/generated-docs/helpers/interfaces/S3Configs.mdx +52 -0
- package/generated-docs/helpers/interfaces/SanitizeHtmlOptions.mdx +22 -0
- package/generated-docs/helpers/type-aliases/AttachmentType.mdx +10 -0
- package/generated-docs/helpers/type-aliases/FileType.mdx +61 -0
- package/generated-docs/helpers/type-aliases/Trigger.mdx +62 -0
- package/how-to-generate-docs.md +61 -0
- package/how-to-run-tests.md +42 -0
- package/intuned-runtime-setup.md +13 -0
- package/package.json +124 -0
- package/tsconfig.eslint.json +5 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _extendedTest = require("../../../common/extendedTest");
|
|
4
|
+
var _vitest = require("vitest");
|
|
5
|
+
var _aiApiGateway = require("../aiApiGateway");
|
|
6
|
+
var _getModelProvider = require("../../../common/getModelProvider");
|
|
7
|
+
var _Anthropic = require("../providers/Anthropic");
|
|
8
|
+
var _OpenAI = require("../providers/OpenAI");
|
|
9
|
+
var _Gemini = require("../providers/Gemini");
|
|
10
|
+
var _loadRuntime = require("../../../common/loadRuntime");
|
|
11
|
+
_vitest.vi.mock("../../../common/jwtTokenManager", () => ({
|
|
12
|
+
backendFunctionsTokenManager: {
|
|
13
|
+
fetchWithToken: _vitest.vi.fn()
|
|
14
|
+
}
|
|
15
|
+
}));
|
|
16
|
+
_vitest.vi.mock("../../../common/getModelProvider", () => ({
|
|
17
|
+
getModelProvider: _vitest.vi.fn()
|
|
18
|
+
}));
|
|
19
|
+
_vitest.vi.mock("../providers/Anthropic", () => ({
|
|
20
|
+
createAnthropicInstance: _vitest.vi.fn()
|
|
21
|
+
}));
|
|
22
|
+
_vitest.vi.mock("../providers/OpenAI", () => ({
|
|
23
|
+
createOpenAIInstance: _vitest.vi.fn()
|
|
24
|
+
}));
|
|
25
|
+
_vitest.vi.mock("../providers/Gemini", () => ({
|
|
26
|
+
createGoogleInstance: _vitest.vi.fn()
|
|
27
|
+
}));
|
|
28
|
+
_vitest.vi.mock("../../../common/loadRuntime", () => ({
|
|
29
|
+
loadRuntime: _vitest.vi.fn()
|
|
30
|
+
}));
|
|
31
|
+
const mockGetModelProvider = _vitest.vi.mocked(_getModelProvider.getModelProvider);
|
|
32
|
+
const mockCreateAnthropicInstance = _vitest.vi.mocked(_Anthropic.createAnthropicInstance);
|
|
33
|
+
const mockCreateOpenAIInstance = _vitest.vi.mocked(_OpenAI.createOpenAIInstance);
|
|
34
|
+
const mockCreateGoogleInstance = _vitest.vi.mocked(_Gemini.createGoogleInstance);
|
|
35
|
+
const mockLoadRuntime = _vitest.vi.mocked(_loadRuntime.loadRuntime);
|
|
36
|
+
(0, _extendedTest.describe)("APIGateway", () => {
|
|
37
|
+
let originalEnv;
|
|
38
|
+
(0, _extendedTest.beforeEach)(() => {
|
|
39
|
+
originalEnv = process.env;
|
|
40
|
+
process.env = {
|
|
41
|
+
...originalEnv,
|
|
42
|
+
FUNCTIONS_DOMAIN: "https://functions.example.com",
|
|
43
|
+
INTUNED_WORKSPACE_ID: "workspace123",
|
|
44
|
+
INTUNED_INTEGRATION_ID: "integration456",
|
|
45
|
+
ANTHROPIC_API_KEY: undefined,
|
|
46
|
+
OPENAI_API_KEY: undefined,
|
|
47
|
+
GOOGLE_API_KEY: undefined
|
|
48
|
+
};
|
|
49
|
+
_vitest.vi.clearAllMocks();
|
|
50
|
+
});
|
|
51
|
+
(0, _extendedTest.afterEach)(() => {
|
|
52
|
+
process.env = originalEnv;
|
|
53
|
+
});
|
|
54
|
+
(0, _extendedTest.describe)("constructor", () => {
|
|
55
|
+
(0, _extendedTest.it)("should initialize with provided model and apiKey", () => {
|
|
56
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
57
|
+
apiKey: "sk-test123",
|
|
58
|
+
model: "gpt-4"
|
|
59
|
+
});
|
|
60
|
+
(0, _extendedTest.expect)(gateway["model"]).toBe("gpt-4");
|
|
61
|
+
(0, _extendedTest.expect)(gateway["apiKey"]).toBe("sk-test123");
|
|
62
|
+
});
|
|
63
|
+
(0, _extendedTest.it)("should use default model when not provided", () => {
|
|
64
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
65
|
+
apiKey: "sk-test123",
|
|
66
|
+
model: "gpt-4o-2024-08-06"
|
|
67
|
+
});
|
|
68
|
+
(0, _extendedTest.expect)(gateway["model"]).toBe("gpt-4o-2024-08-06");
|
|
69
|
+
});
|
|
70
|
+
(0, _extendedTest.it)("should allow no parameters", () => {
|
|
71
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
72
|
+
model: "gpt-4o-2024-08-06"
|
|
73
|
+
});
|
|
74
|
+
(0, _extendedTest.expect)(gateway["model"]).toBe("gpt-4o-2024-08-06");
|
|
75
|
+
(0, _extendedTest.expect)(gateway["apiKey"]).toBeUndefined();
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
(0, _extendedTest.describe)("detectProvider", () => {
|
|
79
|
+
(0, _extendedTest.it)("should detect openai models", () => {
|
|
80
|
+
mockGetModelProvider.mockReturnValue("openai");
|
|
81
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
82
|
+
model: "gpt-4"
|
|
83
|
+
});
|
|
84
|
+
(0, _extendedTest.expect)(gateway["detectProvider"]("gpt-4")).toBe("openai");
|
|
85
|
+
(0, _extendedTest.expect)(mockGetModelProvider).toHaveBeenCalledWith("gpt-4");
|
|
86
|
+
});
|
|
87
|
+
(0, _extendedTest.it)("should detect anthropic models", () => {
|
|
88
|
+
mockGetModelProvider.mockReturnValue("anthropic");
|
|
89
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
90
|
+
model: "claude-3-sonnet"
|
|
91
|
+
});
|
|
92
|
+
(0, _extendedTest.expect)(gateway["detectProvider"]("claude-3-sonnet")).toBe("anthropic");
|
|
93
|
+
(0, _extendedTest.expect)(mockGetModelProvider).toHaveBeenCalledWith("claude-3-sonnet");
|
|
94
|
+
});
|
|
95
|
+
(0, _extendedTest.it)("should handle case insensitive models", () => {
|
|
96
|
+
mockGetModelProvider.mockReturnValue("anthropic");
|
|
97
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
98
|
+
model: "CLAUDE-3-OPUS"
|
|
99
|
+
});
|
|
100
|
+
(0, _extendedTest.expect)(gateway["detectProvider"]("CLAUDE-3-OPUS")).toBe("anthropic");
|
|
101
|
+
(0, _extendedTest.expect)(mockGetModelProvider).toHaveBeenCalledWith("claude-3-opus");
|
|
102
|
+
});
|
|
103
|
+
(0, _extendedTest.it)("should return unknown for unsupported models", () => {
|
|
104
|
+
mockGetModelProvider.mockReturnValue("unknown");
|
|
105
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
106
|
+
model: "unknown-model"
|
|
107
|
+
});
|
|
108
|
+
(0, _extendedTest.expect)(gateway["detectProvider"]("unknown-model")).toBe("unknown");
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
(0, _extendedTest.describe)("buildGatewayUrl", () => {
|
|
112
|
+
(0, _extendedTest.it)("should build correct URL for anthropic", async () => {
|
|
113
|
+
mockGetModelProvider.mockReturnValue("anthropic");
|
|
114
|
+
mockLoadRuntime.mockResolvedValue(() => ({
|
|
115
|
+
runId: "test"
|
|
116
|
+
}));
|
|
117
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
118
|
+
model: "claude-3-sonnet"
|
|
119
|
+
});
|
|
120
|
+
await gateway["ensureInitialized"]();
|
|
121
|
+
const result = gateway["buildGatewayUrl"]("anthropic");
|
|
122
|
+
(0, _extendedTest.expect)(result).toBe("https://functions.example.com/api/workspace123/functions/integration456/anthropic/v1");
|
|
123
|
+
});
|
|
124
|
+
(0, _extendedTest.it)("should build correct URL for google_vertexai", async () => {
|
|
125
|
+
mockGetModelProvider.mockReturnValue("google_vertexai");
|
|
126
|
+
mockLoadRuntime.mockResolvedValue(() => ({
|
|
127
|
+
runId: "test"
|
|
128
|
+
}));
|
|
129
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
130
|
+
model: "gemini-pro"
|
|
131
|
+
});
|
|
132
|
+
await gateway["ensureInitialized"]();
|
|
133
|
+
const result = gateway["buildGatewayUrl"]("google_vertexai");
|
|
134
|
+
(0, _extendedTest.expect)(result).toBe("https://functions.example.com/api/workspace123/functions/integration456/google_vertexai/v1beta");
|
|
135
|
+
});
|
|
136
|
+
(0, _extendedTest.it)("should build correct URL for other providers", async () => {
|
|
137
|
+
mockGetModelProvider.mockReturnValue("openai");
|
|
138
|
+
mockLoadRuntime.mockResolvedValue(() => ({
|
|
139
|
+
runId: "test"
|
|
140
|
+
}));
|
|
141
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
142
|
+
model: "gpt-4"
|
|
143
|
+
});
|
|
144
|
+
await gateway["ensureInitialized"]();
|
|
145
|
+
const result = gateway["buildGatewayUrl"]("openai");
|
|
146
|
+
(0, _extendedTest.expect)(result).toBe("https://functions.example.com/api/workspace123/functions/integration456/openai");
|
|
147
|
+
});
|
|
148
|
+
(0, _extendedTest.it)("should strip trailing slash from domain", async () => {
|
|
149
|
+
process.env.FUNCTIONS_DOMAIN = "https://functions.example.com/";
|
|
150
|
+
mockGetModelProvider.mockReturnValue("openai");
|
|
151
|
+
mockLoadRuntime.mockResolvedValue(() => ({
|
|
152
|
+
runId: "test"
|
|
153
|
+
}));
|
|
154
|
+
const newGateway = new _aiApiGateway.APIGateway({
|
|
155
|
+
model: "gpt-4"
|
|
156
|
+
});
|
|
157
|
+
await newGateway["ensureInitialized"]();
|
|
158
|
+
const result = newGateway["buildGatewayUrl"]("openai");
|
|
159
|
+
(0, _extendedTest.expect)(result).toBe("https://functions.example.com/api/workspace123/functions/integration456/openai");
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
(0, _extendedTest.describe)("ensureInitialized", () => {
|
|
163
|
+
(0, _extendedTest.it)("should use direct mode when API key provided", async () => {
|
|
164
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
165
|
+
apiKey: "sk-test123",
|
|
166
|
+
model: "gpt-4"
|
|
167
|
+
});
|
|
168
|
+
await gateway["ensureInitialized"]();
|
|
169
|
+
(0, _extendedTest.expect)(gateway["useGateway"]).toBe(false);
|
|
170
|
+
(0, _extendedTest.expect)(gateway["apiKey"]).toBe("sk-test123");
|
|
171
|
+
(0, _extendedTest.expect)(gateway["isInitialized"]).toBe(true);
|
|
172
|
+
});
|
|
173
|
+
(0, _extendedTest.it)("should find API key in environment and use direct mode", async () => {
|
|
174
|
+
process.env.OPENAI_API_KEY = "sk-env-key";
|
|
175
|
+
mockGetModelProvider.mockReturnValue("openai");
|
|
176
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
177
|
+
model: "gpt-4"
|
|
178
|
+
});
|
|
179
|
+
await gateway["ensureInitialized"]();
|
|
180
|
+
(0, _extendedTest.expect)(gateway["useGateway"]).toBe(false);
|
|
181
|
+
(0, _extendedTest.expect)(gateway["apiKey"]).toBe("sk-env-key");
|
|
182
|
+
(0, _extendedTest.expect)(gateway["isInitialized"]).toBe(true);
|
|
183
|
+
});
|
|
184
|
+
(0, _extendedTest.it)("should use gateway mode when no API key and in intuned context", async () => {
|
|
185
|
+
mockGetModelProvider.mockReturnValue("anthropic");
|
|
186
|
+
mockLoadRuntime.mockResolvedValue(() => ({
|
|
187
|
+
runId: "test"
|
|
188
|
+
}));
|
|
189
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
190
|
+
model: "claude-3-sonnet"
|
|
191
|
+
});
|
|
192
|
+
await gateway["ensureInitialized"]();
|
|
193
|
+
(0, _extendedTest.expect)(gateway["useGateway"]).toBe(true);
|
|
194
|
+
(0, _extendedTest.expect)(gateway["isInitialized"]).toBe(true);
|
|
195
|
+
(0, _extendedTest.expect)(gateway["config"]).toEqual({
|
|
196
|
+
functionsDomain: "https://functions.example.com",
|
|
197
|
+
workspaceId: "workspace123",
|
|
198
|
+
integrationId: "integration456"
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
(0, _extendedTest.it)("should throw error when no API key and not in intuned context", async () => {
|
|
202
|
+
mockGetModelProvider.mockReturnValue("openai");
|
|
203
|
+
mockLoadRuntime.mockResolvedValue(() => null);
|
|
204
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
205
|
+
model: "gpt-4"
|
|
206
|
+
});
|
|
207
|
+
await (0, _extendedTest.expect)(gateway["ensureInitialized"]()).rejects.toThrow("No API key provided and not running in Intuned context");
|
|
208
|
+
});
|
|
209
|
+
(0, _extendedTest.it)("should throw error when in intuned context but missing env vars", async () => {
|
|
210
|
+
delete process.env.FUNCTIONS_DOMAIN;
|
|
211
|
+
mockGetModelProvider.mockReturnValue("openai");
|
|
212
|
+
mockLoadRuntime.mockResolvedValue(() => ({
|
|
213
|
+
runId: "test"
|
|
214
|
+
}));
|
|
215
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
216
|
+
model: "gpt-4"
|
|
217
|
+
});
|
|
218
|
+
await (0, _extendedTest.expect)(gateway["ensureInitialized"]()).rejects.toThrow("Gateway configuration is incomplete. Missing environment variables: FUNCTIONS_DOMAIN");
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
(0, _extendedTest.describe)("createProviderInstance", () => {
|
|
222
|
+
(0, _extendedTest.it)("should create anthropic instance with gateway mode", async () => {
|
|
223
|
+
mockGetModelProvider.mockReturnValue("anthropic");
|
|
224
|
+
mockLoadRuntime.mockResolvedValue(() => ({
|
|
225
|
+
runId: "test"
|
|
226
|
+
}));
|
|
227
|
+
const mockInstance = {
|
|
228
|
+
chat: _vitest.vi.fn()
|
|
229
|
+
};
|
|
230
|
+
mockCreateAnthropicInstance.mockReturnValue(mockInstance);
|
|
231
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
232
|
+
model: "claude-3-sonnet"
|
|
233
|
+
});
|
|
234
|
+
const result = await gateway.createProviderInstance();
|
|
235
|
+
(0, _extendedTest.expect)(mockCreateAnthropicInstance).toHaveBeenCalledWith({
|
|
236
|
+
apiKey: "--THIS_VALUE_WILL_BE_REPLACED_BY_INTUNED_BE--",
|
|
237
|
+
headers: undefined,
|
|
238
|
+
model: "claude-3-sonnet",
|
|
239
|
+
baseUrl: "https://functions.example.com/api/workspace123/functions/integration456/anthropic/v1"
|
|
240
|
+
});
|
|
241
|
+
(0, _extendedTest.expect)(result).toBe(mockInstance);
|
|
242
|
+
});
|
|
243
|
+
(0, _extendedTest.it)("should create openai instance with direct API key", async () => {
|
|
244
|
+
mockGetModelProvider.mockReturnValue("openai");
|
|
245
|
+
const mockInstance = {
|
|
246
|
+
chat: _vitest.vi.fn()
|
|
247
|
+
};
|
|
248
|
+
mockCreateOpenAIInstance.mockReturnValue(mockInstance);
|
|
249
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
250
|
+
model: "gpt-4",
|
|
251
|
+
apiKey: "sk-test123"
|
|
252
|
+
});
|
|
253
|
+
const result = await gateway.createProviderInstance();
|
|
254
|
+
(0, _extendedTest.expect)(mockCreateOpenAIInstance).toHaveBeenCalledWith({
|
|
255
|
+
apiKey: "sk-test123",
|
|
256
|
+
headers: undefined,
|
|
257
|
+
model: "gpt-4",
|
|
258
|
+
baseUrl: undefined
|
|
259
|
+
});
|
|
260
|
+
(0, _extendedTest.expect)(result).toBe(mockInstance);
|
|
261
|
+
});
|
|
262
|
+
(0, _extendedTest.it)("should create google instance", async () => {
|
|
263
|
+
mockGetModelProvider.mockReturnValue("google_vertexai");
|
|
264
|
+
mockLoadRuntime.mockResolvedValue(() => ({
|
|
265
|
+
runId: "test"
|
|
266
|
+
}));
|
|
267
|
+
const mockInstance = {
|
|
268
|
+
chat: _vitest.vi.fn()
|
|
269
|
+
};
|
|
270
|
+
mockCreateGoogleInstance.mockReturnValue(mockInstance);
|
|
271
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
272
|
+
model: "gemini-pro"
|
|
273
|
+
});
|
|
274
|
+
const result = await gateway.createProviderInstance();
|
|
275
|
+
(0, _extendedTest.expect)(mockCreateGoogleInstance).toHaveBeenCalled();
|
|
276
|
+
(0, _extendedTest.expect)(result).toBe(mockInstance);
|
|
277
|
+
});
|
|
278
|
+
(0, _extendedTest.it)("should throw error for unsupported provider", async () => {
|
|
279
|
+
mockGetModelProvider.mockReturnValue("unknown");
|
|
280
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
281
|
+
model: "unknown-model",
|
|
282
|
+
apiKey: "sk-test"
|
|
283
|
+
});
|
|
284
|
+
await (0, _extendedTest.expect)(gateway.createProviderInstance()).rejects.toThrow("Unsupported provider: unknown");
|
|
285
|
+
});
|
|
286
|
+
(0, _extendedTest.it)("should pass extra headers", async () => {
|
|
287
|
+
mockGetModelProvider.mockReturnValue("openai");
|
|
288
|
+
const mockInstance = {
|
|
289
|
+
chat: _vitest.vi.fn()
|
|
290
|
+
};
|
|
291
|
+
mockCreateOpenAIInstance.mockReturnValue(mockInstance);
|
|
292
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
293
|
+
model: "gpt-4",
|
|
294
|
+
apiKey: "sk-test123"
|
|
295
|
+
});
|
|
296
|
+
await gateway.createProviderInstance({
|
|
297
|
+
"Custom-Header": "value"
|
|
298
|
+
});
|
|
299
|
+
(0, _extendedTest.expect)(mockCreateOpenAIInstance).toHaveBeenCalledWith({
|
|
300
|
+
apiKey: "sk-test123",
|
|
301
|
+
headers: {
|
|
302
|
+
"Custom-Header": "value"
|
|
303
|
+
},
|
|
304
|
+
model: "gpt-4",
|
|
305
|
+
baseUrl: undefined
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
(0, _extendedTest.describe)("getModel", () => {
|
|
310
|
+
(0, _extendedTest.it)("should return language model from provider instance", async () => {
|
|
311
|
+
mockGetModelProvider.mockReturnValue("anthropic");
|
|
312
|
+
const mockModelInstance = {
|
|
313
|
+
generate: _vitest.vi.fn()
|
|
314
|
+
};
|
|
315
|
+
const mockProviderInstance = {
|
|
316
|
+
chat: _vitest.vi.fn().mockReturnValue(mockModelInstance)
|
|
317
|
+
};
|
|
318
|
+
mockCreateAnthropicInstance.mockReturnValue(mockProviderInstance);
|
|
319
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
320
|
+
model: "claude-3-sonnet",
|
|
321
|
+
apiKey: "sk-test"
|
|
322
|
+
});
|
|
323
|
+
const result = await gateway.getModel();
|
|
324
|
+
(0, _extendedTest.expect)(mockProviderInstance.chat).toHaveBeenCalledWith("claude-3-sonnet");
|
|
325
|
+
(0, _extendedTest.expect)(result).toBe(mockModelInstance);
|
|
326
|
+
});
|
|
327
|
+
(0, _extendedTest.it)("should pass through headers", async () => {
|
|
328
|
+
mockGetModelProvider.mockReturnValue("openai");
|
|
329
|
+
const mockModelInstance = {
|
|
330
|
+
generate: _vitest.vi.fn()
|
|
331
|
+
};
|
|
332
|
+
const mockProviderInstance = {
|
|
333
|
+
chat: _vitest.vi.fn().mockReturnValue(mockModelInstance)
|
|
334
|
+
};
|
|
335
|
+
mockCreateOpenAIInstance.mockReturnValue(mockProviderInstance);
|
|
336
|
+
const gateway = new _aiApiGateway.APIGateway({
|
|
337
|
+
model: "gpt-4",
|
|
338
|
+
apiKey: "sk-test123"
|
|
339
|
+
});
|
|
340
|
+
const result = await gateway.getModel({
|
|
341
|
+
"Custom-Header": "value"
|
|
342
|
+
});
|
|
343
|
+
(0, _extendedTest.expect)(mockCreateOpenAIInstance).toHaveBeenCalledWith({
|
|
344
|
+
apiKey: "sk-test123",
|
|
345
|
+
headers: {
|
|
346
|
+
"Custom-Header": "value"
|
|
347
|
+
},
|
|
348
|
+
model: "gpt-4",
|
|
349
|
+
baseUrl: undefined
|
|
350
|
+
});
|
|
351
|
+
(0, _extendedTest.expect)(mockProviderInstance.chat).toHaveBeenCalledWith("gpt-4");
|
|
352
|
+
(0, _extendedTest.expect)(result).toBe(mockModelInstance);
|
|
353
|
+
});
|
|
354
|
+
});
|
|
355
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.GatewayMode = void 0;
|
|
7
|
+
let GatewayMode = exports.GatewayMode = function (GatewayMode) {
|
|
8
|
+
GatewayMode["DIRECT"] = "direct";
|
|
9
|
+
GatewayMode["GATEWAY"] = "gateway";
|
|
10
|
+
return GatewayMode;
|
|
11
|
+
}({});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.cache = void 0;
|
|
7
|
+
var _zod = require("zod");
|
|
8
|
+
var _jwtTokenManager = require("../../common/jwtTokenManager");
|
|
9
|
+
var _Logger = require("../../common/Logger");
|
|
10
|
+
const forbiddenCharacters = /[:#]/g;
|
|
11
|
+
const keySchema = _zod.z.string().min(1, "Key must be at least 1 character long").refine(key => {
|
|
12
|
+
var _key$match;
|
|
13
|
+
return (((_key$match = key.match(forbiddenCharacters)) === null || _key$match === void 0 ? void 0 : _key$match.length) ?? 0) === 0;
|
|
14
|
+
}, 'Key cannot contain the following characters: ":" or "#"');
|
|
15
|
+
class Cache {
|
|
16
|
+
async get(key) {
|
|
17
|
+
try {
|
|
18
|
+
const parsedKey = keySchema.parse(key);
|
|
19
|
+
const response = await (0, _jwtTokenManager.callBackendFunctionWithToken)(`cache/${parsedKey}`, {
|
|
20
|
+
method: "GET"
|
|
21
|
+
});
|
|
22
|
+
const contentType = response.headers.get("content-type");
|
|
23
|
+
if (!(contentType !== null && contentType !== void 0 && contentType.includes("application/json"))) {
|
|
24
|
+
const responseText = await response.text();
|
|
25
|
+
throw new Error(`Server returned ${contentType} instead of JSON. This usually indicates an authentication issue or wrong endpoint. Response: ${responseText.substring(0, 200)}...`);
|
|
26
|
+
}
|
|
27
|
+
const json = await response.json();
|
|
28
|
+
if (!response.ok) {
|
|
29
|
+
throw new Error(`Failed to get cache value for key ${parsedKey}: ${json.message}`);
|
|
30
|
+
}
|
|
31
|
+
return json.value;
|
|
32
|
+
} catch (error) {
|
|
33
|
+
throw new Error(`Failed to get cache value for key ${key}: ${error}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async set(key, value) {
|
|
37
|
+
try {
|
|
38
|
+
const keyResult = keySchema.parse(key);
|
|
39
|
+
const response = await (0, _jwtTokenManager.callBackendFunctionWithToken)(`cache/${keyResult}`, {
|
|
40
|
+
method: "PUT",
|
|
41
|
+
body: JSON.stringify(value),
|
|
42
|
+
headers: {
|
|
43
|
+
"Content-Type": "application/json"
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const contentType = response.headers.get("content-type");
|
|
47
|
+
if (!(contentType !== null && contentType !== void 0 && contentType.includes("application/json"))) {
|
|
48
|
+
const responseText = await response.text();
|
|
49
|
+
_Logger.logger.error(`Expected JSON but got content-type: ${contentType}`);
|
|
50
|
+
throw new Error(`Server returned ${contentType} instead of JSON. This usually indicates an authentication issue or wrong endpoint. Response: ${responseText.substring(0, 200)}...`);
|
|
51
|
+
}
|
|
52
|
+
const json = await response.json();
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
throw new Error(`Failed to set cache value for key ${keyResult}: ${json.message}`);
|
|
55
|
+
}
|
|
56
|
+
} catch (error) {
|
|
57
|
+
throw new Error(`Failed to set cache value for key ${key}: ${error}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const cache = exports.cache = new Cache();
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _extendedTest = require("../../../common/extendedTest");
|
|
4
|
+
var _cache = require("../cache");
|
|
5
|
+
var _vitest = require("vitest");
|
|
6
|
+
var _jwtTokenManager = require("../../../common/jwtTokenManager");
|
|
7
|
+
_vitest.vi.mock("../../../common/jwtTokenManager", () => ({
|
|
8
|
+
callBackendFunctionWithToken: _vitest.vi.fn()
|
|
9
|
+
}));
|
|
10
|
+
const mockCallBackendFunction = _vitest.vi.mocked(_jwtTokenManager.callBackendFunctionWithToken);
|
|
11
|
+
(0, _extendedTest.describe)("Cache", () => {
|
|
12
|
+
(0, _extendedTest.beforeEach)(() => {
|
|
13
|
+
_vitest.vi.clearAllMocks();
|
|
14
|
+
});
|
|
15
|
+
(0, _extendedTest.describe)("get", () => {
|
|
16
|
+
(0, _extendedTest.it)("should return value when successful", async () => {
|
|
17
|
+
const mockResponse = {
|
|
18
|
+
ok: true,
|
|
19
|
+
headers: {
|
|
20
|
+
get: _vitest.vi.fn().mockReturnValue("application/json")
|
|
21
|
+
},
|
|
22
|
+
json: _vitest.vi.fn().mockResolvedValue({
|
|
23
|
+
value: "cached_data"
|
|
24
|
+
})
|
|
25
|
+
};
|
|
26
|
+
mockCallBackendFunction.mockResolvedValue(mockResponse);
|
|
27
|
+
const result = await _cache.cache.get("test_key");
|
|
28
|
+
(0, _extendedTest.expect)(result).toBe("cached_data");
|
|
29
|
+
(0, _extendedTest.expect)(mockCallBackendFunction).toHaveBeenCalledWith("cache/test_key", {
|
|
30
|
+
method: "GET"
|
|
31
|
+
});
|
|
32
|
+
(0, _extendedTest.expect)(mockResponse.json).toHaveBeenCalled();
|
|
33
|
+
});
|
|
34
|
+
(0, _extendedTest.it)("should throw error when response is not ok", async () => {
|
|
35
|
+
const mockResponse = {
|
|
36
|
+
ok: false,
|
|
37
|
+
headers: {
|
|
38
|
+
get: _vitest.vi.fn().mockReturnValue("application/json")
|
|
39
|
+
},
|
|
40
|
+
json: _vitest.vi.fn().mockResolvedValue({
|
|
41
|
+
message: "Cache miss"
|
|
42
|
+
})
|
|
43
|
+
};
|
|
44
|
+
mockCallBackendFunction.mockResolvedValue(mockResponse);
|
|
45
|
+
await (0, _extendedTest.expect)(_cache.cache.get("test_key")).rejects.toThrow("Failed to get cache value for key test_key: Cache miss");
|
|
46
|
+
});
|
|
47
|
+
(0, _extendedTest.it)("should throw error for empty key", async () => {
|
|
48
|
+
await (0, _extendedTest.expect)(_cache.cache.get("")).rejects.toThrow("Failed to get cache value for key : [");
|
|
49
|
+
});
|
|
50
|
+
(0, _extendedTest.it)("should throw error for key with colon", async () => {
|
|
51
|
+
await (0, _extendedTest.expect)(_cache.cache.get("invalid:key")).rejects.toThrow("Failed to get cache value for key invalid:key: [");
|
|
52
|
+
});
|
|
53
|
+
(0, _extendedTest.it)("should throw error for key with hash", async () => {
|
|
54
|
+
await (0, _extendedTest.expect)(_cache.cache.get("invalid#key")).rejects.toThrow("Failed to get cache value for key invalid#key: [");
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
(0, _extendedTest.describe)("set", () => {
|
|
58
|
+
(0, _extendedTest.it)("should call backend correctly when successful", async () => {
|
|
59
|
+
const mockResponse = {
|
|
60
|
+
ok: true,
|
|
61
|
+
headers: {
|
|
62
|
+
get: _vitest.vi.fn().mockReturnValue("application/json")
|
|
63
|
+
},
|
|
64
|
+
json: _vitest.vi.fn().mockResolvedValue({})
|
|
65
|
+
};
|
|
66
|
+
mockCallBackendFunction.mockResolvedValue(mockResponse);
|
|
67
|
+
const testValue = {
|
|
68
|
+
data: "test"
|
|
69
|
+
};
|
|
70
|
+
await _cache.cache.set("test_key", testValue);
|
|
71
|
+
(0, _extendedTest.expect)(mockCallBackendFunction).toHaveBeenCalledWith("cache/test_key", {
|
|
72
|
+
method: "PUT",
|
|
73
|
+
body: JSON.stringify(testValue),
|
|
74
|
+
headers: {
|
|
75
|
+
"Content-Type": "application/json"
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
(0, _extendedTest.expect)(mockResponse.json).toHaveBeenCalled();
|
|
79
|
+
});
|
|
80
|
+
(0, _extendedTest.it)("should throw error when response is not ok", async () => {
|
|
81
|
+
const mockResponse = {
|
|
82
|
+
ok: false,
|
|
83
|
+
headers: {
|
|
84
|
+
get: _vitest.vi.fn().mockReturnValue("application/json")
|
|
85
|
+
},
|
|
86
|
+
json: _vitest.vi.fn().mockResolvedValue({
|
|
87
|
+
message: "Set failed"
|
|
88
|
+
})
|
|
89
|
+
};
|
|
90
|
+
mockCallBackendFunction.mockResolvedValue(mockResponse);
|
|
91
|
+
await (0, _extendedTest.expect)(_cache.cache.set("test_key", "value")).rejects.toThrow("Failed to set cache value for key test_key: Set failed");
|
|
92
|
+
});
|
|
93
|
+
(0, _extendedTest.it)("should throw error for empty key", async () => {
|
|
94
|
+
await (0, _extendedTest.expect)(_cache.cache.set("", "value")).rejects.toThrow("Failed to set cache value for key : [");
|
|
95
|
+
});
|
|
96
|
+
(0, _extendedTest.it)("should throw error for key with forbidden characters", async () => {
|
|
97
|
+
await (0, _extendedTest.expect)(_cache.cache.set("invalid:key", "value")).rejects.toThrow("Failed to set cache value for key invalid:key: [");
|
|
98
|
+
await (0, _extendedTest.expect)(_cache.cache.set("invalid#key", "value")).rejects.toThrow("Failed to set cache value for key invalid#key: [");
|
|
99
|
+
});
|
|
100
|
+
(0, _extendedTest.it)("should handle different value types", async () => {
|
|
101
|
+
const mockResponse = {
|
|
102
|
+
ok: true,
|
|
103
|
+
headers: {
|
|
104
|
+
get: _vitest.vi.fn().mockReturnValue("application/json")
|
|
105
|
+
},
|
|
106
|
+
json: _vitest.vi.fn().mockResolvedValue({})
|
|
107
|
+
};
|
|
108
|
+
mockCallBackendFunction.mockResolvedValue(mockResponse);
|
|
109
|
+
await _cache.cache.set("key1", "string_value");
|
|
110
|
+
await _cache.cache.set("key2", {
|
|
111
|
+
object: "value"
|
|
112
|
+
});
|
|
113
|
+
await _cache.cache.set("key3", 123);
|
|
114
|
+
(0, _extendedTest.expect)(mockCallBackendFunction).toHaveBeenCalledTimes(3);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.buildExamplesPrompt = buildExamplesPrompt;
|
|
7
|
+
function buildExamplesPrompt({
|
|
8
|
+
entityName,
|
|
9
|
+
examples
|
|
10
|
+
}) {
|
|
11
|
+
return `Ensure your extraction of ` + entityName + ` matches these examples in format and content. Follow these guidelines:` + "\n" + `1. **String Data**: Match the formatting and any transformations applied in the examples. If strings were reformed or parts were removed in the examples, apply the same changes to your extraction,.` + "\n" + `2. **Numerical Data**: Keep numbers in the same format as the examples. Ensure consistency in units, rounding, and notation.` + "\n" + `3. **Date Data**: Align the date format with the examples provided. Maintain the same order, separators, and any additional formatting rules.` + "\n" + `Consistency with these examples is crucial for accurate data extraction:` + "\n" + examples.map((e, index) => `${index}. ` + JSON.stringify(e)).join("\n");
|
|
12
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.buildImagesFromPageOrHandle = buildImagesFromPageOrHandle;
|
|
7
|
+
exports.captureFullPageImagesWithOverlap = captureFullPageImagesWithOverlap;
|
|
8
|
+
var _neverthrow = require("neverthrow");
|
|
9
|
+
var errors = _interopRequireWildcard(require("../types/errors"));
|
|
10
|
+
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); }
|
|
11
|
+
async function captureFullPageImagesWithOverlap(page, options = {
|
|
12
|
+
overlap: 200,
|
|
13
|
+
sliceHeight: 1000
|
|
14
|
+
}) {
|
|
15
|
+
const totalHeight = await page.evaluate(() => document.body.scrollHeight);
|
|
16
|
+
let currentHeight = 0;
|
|
17
|
+
const buffers = [];
|
|
18
|
+
while (currentHeight < totalHeight) {
|
|
19
|
+
if (buffers.length > 10) {
|
|
20
|
+
console.info(`the page is too long, only first ${totalHeight} px of the page will be captured.`);
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
await page.setViewportSize({
|
|
24
|
+
width: 1200,
|
|
25
|
+
height: options.sliceHeight
|
|
26
|
+
});
|
|
27
|
+
await page.evaluate(y => window.scrollTo(0, y), currentHeight - (currentHeight > 0 ? options.overlap : 0));
|
|
28
|
+
await page.waitForTimeout(500);
|
|
29
|
+
const buffer = await page.screenshot();
|
|
30
|
+
buffers.push(buffer);
|
|
31
|
+
currentHeight += options.sliceHeight - options.overlap;
|
|
32
|
+
}
|
|
33
|
+
return buffers;
|
|
34
|
+
}
|
|
35
|
+
async function buildImagesFromPageOrHandle(page, searchRegionHandler) {
|
|
36
|
+
const originalViewPortSize = page.viewportSize();
|
|
37
|
+
await page.setViewportSize({
|
|
38
|
+
width: 1200,
|
|
39
|
+
height: 800
|
|
40
|
+
});
|
|
41
|
+
if (searchRegionHandler) {
|
|
42
|
+
const size = await searchRegionHandler.boundingBox();
|
|
43
|
+
if (!size) {
|
|
44
|
+
return (0, _neverthrow.err)(errors.other("the provided search region is very large, image extraction support up to 5000px height."));
|
|
45
|
+
}
|
|
46
|
+
return (0, _neverthrow.ok)([await searchRegionHandler.screenshot({
|
|
47
|
+
type: "png"
|
|
48
|
+
})]);
|
|
49
|
+
}
|
|
50
|
+
const fullPageImages = await captureFullPageImagesWithOverlap(page);
|
|
51
|
+
if (originalViewPortSize) {
|
|
52
|
+
await page.setViewportSize(originalViewPortSize);
|
|
53
|
+
}
|
|
54
|
+
return (0, _neverthrow.ok)(fullPageImages);
|
|
55
|
+
}
|