diff --git a/.fernignore b/.fernignore index 19625584..7f3bf4cb 100644 --- a/.fernignore +++ b/.fernignore @@ -10,11 +10,15 @@ src/humanloop.client.ts src/overload.ts src/error.ts src/context.ts +src/cli.ts +src/cache +src/sync # Tests # Modified due to issues with OTEL tests/unit/fetcher/stream-wrappers/webpack.test.ts +tests/custom/ # CI Action diff --git a/jest.config.mjs b/jest.config.mjs index 9eb4a4af..b4a8227b 100644 --- a/jest.config.mjs +++ b/jest.config.mjs @@ -3,6 +3,11 @@ export default { preset: "ts-jest", testEnvironment: "node", moduleNameMapper: { - "^(?!.*node_modules)(.+)\\.js$": "$1", + // Only map .js files in our src directory, not node_modules + "^src/(.+)\\.js$": "/src/$1", }, + // Add transformIgnorePatterns to handle ESM modules in node_modules + transformIgnorePatterns: [ + "node_modules/(?!(@traceloop|js-tiktoken|base64-js)/)", + ], }; diff --git a/package.json b/package.json index ceeadcf3..c172c50d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "humanloop", - "version": "0.8.21-beta1", + "version": "0.8.21", "private": false, "repository": "https://github.com/humanloop/humanloop-node", "main": "./index.js", @@ -26,6 +26,8 @@ "@traceloop/instrumentation-cohere": ">=0.11.1", "@traceloop/instrumentation-openai": ">=0.11.3", "@traceloop/ai-semantic-conventions": ">=0.11.6", + "dotenv": "^16.5.0", + "commander": "^14.0.0", "cli-progress": "^3.12.0", "lodash": "^4.17.21" }, @@ -46,7 +48,6 @@ "openai": "^4.74.0", "@anthropic-ai/sdk": "^0.32.1", "cohere-ai": "^7.15.0", - "dotenv": "^16.4.6", "jsonschema": "^1.4.1", "@types/cli-progress": "^3.11.6", "@types/lodash": "4.14.74", @@ -56,5 +57,8 @@ "fs": false, "os": false, "path": false + }, + "bin": { + "humanloop": "./cli.js" } } diff --git a/reference.md b/reference.md index afc2e70e..b23e28a2 100644 --- a/reference.md +++ b/reference.md @@ -1342,7 +1342,7 @@ await client.prompts.updateMonitoring("pr_30gco7dx6JDq4200GVOHa", { -
client.prompts.serialize(id, { ...params }) -> void +
client.prompts.serialize(id, { ...params }) -> string
@@ -7313,7 +7313,7 @@ await client.agents.updateMonitoring("ag_1234567890", {
-
client.agents.serialize(id, { ...params }) -> void +
client.agents.serialize(id, { ...params }) -> string
diff --git a/src/api/resources/agents/client/Client.ts b/src/api/resources/agents/client/Client.ts index 842af06d..fe32296d 100644 --- a/src/api/resources/agents/client/Client.ts +++ b/src/api/resources/agents/client/Client.ts @@ -49,7 +49,49 @@ export class Agents { * @throws {@link Humanloop.UnprocessableEntityError} * * @example - * await client.agents.log() + * await client.agents.log({ + * path: "Banking/Teller Agent", + * agent: { + * provider: "anthropic", + * endpoint: "chat", + * model: "claude-3-7-sonnet-latest", + * reasoningEffort: 1024, + * template: [{ + * role: "system", + * content: "You are a helpful digital assistant, helping users navigate our digital banking platform." + * }], + * maxIterations: 3, + * tools: [{ + * type: "file", + * link: { + * fileId: "pr_1234567890", + * versionId: "prv_1234567890" + * }, + * onAgentCall: "continue" + * }, { + * type: "inline", + * jsonSchema: { + * name: "stop", + * description: "Call this tool when you have finished your task.", + * parameters: { + * "type": "object", + * "properties": { + * "output": { + * "type": "string", + * "description": "The final output to return to the user." + * } + * }, + * "additionalProperties": false, + * "required": [ + * "output" + * ] + * }, + * strict: true + * }, + * onAgentCall: "stop" + * }] + * } + * }) */ public async log( request: Humanloop.AgentLogRequest = {}, @@ -76,8 +118,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -149,14 +191,27 @@ export class Agents { * @throws {@link Humanloop.UnprocessableEntityError} * * @example - * await client.agents.updateLog("id", "log_id") + * await client.agents.updateLog("ag_1234567890", "log_1234567890", { + * messages: [{ + * role: "user", + * content: "I need to withdraw $1000" + * }, { + * role: "assistant", + * content: "Of course! Would you like to use your savings or checking account?" + * }], + * outputMessage: { + * role: "assistant", + * content: "I'm sorry, I can't help with that." + * }, + * logStatus: "complete" + * }) */ public async updateLog( id: string, logId: string, request: Humanloop.UpdateAgentLogRequest = {}, requestOptions?: Agents.RequestOptions, - ): Promise { + ): Promise { const _response = await (this._options.fetcher ?? core.fetcher)({ url: urlJoin( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -168,8 +223,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -183,7 +238,7 @@ export class Agents { abortSignal: requestOptions?.abortSignal, }); if (_response.ok) { - return serializers.LogResponse.parseOrThrow(_response.body, { + return serializers.AgentLogResponse.parseOrThrow(_response.body, { unrecognizedObjectKeys: "passthrough", allowUnrecognizedUnionMembers: true, allowUnrecognizedEnumValues: true, @@ -230,23 +285,26 @@ export class Agents { } /** - * Call an Agent. + * Call an Agent. The Agent will run on the Humanloop runtime and return a completed Agent Log. + * + * If the Agent requires a tool call that cannot be ran by Humanloop, execution will halt. To continue, + * pass the ID of the incomplete Log and the required tool call to the /agents/continue endpoint. * - * Calling an Agent calls the model provider before logging - * the request, responses and metadata to Humanloop. + * The agent will run for the maximum number of iterations, or until it encounters a stop condition, + * according to its configuration. * * You can use query parameters `version_id`, or `environment`, to target * an existing version of the Agent. Otherwise the default deployed version will be chosen. * * Instead of targeting an existing version explicitly, you can instead pass in - * Agent details in the request body. In this case, we will check if the details correspond - * to an existing version of the Agent. If they do not, we will create a new version. This is helpful - * in the case where you are storing or deriving your Agent details in code. + * Agent details in the request body. A new version is created if it does not match + * any existing ones. This is helpful in the case where you are storing or deriving + * your Agent details in code. */ public async callStream( request: Humanloop.AgentsCallStreamRequest, requestOptions?: Agents.RequestOptions, - ): Promise> { + ): Promise> { const { versionId, environment, ..._body } = request; const _queryParams: Record = {}; if (versionId != null) { @@ -268,8 +326,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -291,7 +349,7 @@ export class Agents { return new core.Stream({ stream: _response.body, parse: async (data) => { - return serializers.AgentContinueCallStreamResponse.parseOrThrow(data, { + return serializers.AgentCallStreamResponse.parseOrThrow(data, { unrecognizedObjectKeys: "passthrough", allowUnrecognizedUnionMembers: true, allowUnrecognizedEnumValues: true, @@ -343,18 +401,21 @@ export class Agents { } /** - * Call an Agent. + * Call an Agent. The Agent will run on the Humanloop runtime and return a completed Agent Log. + * + * If the Agent requires a tool call that cannot be ran by Humanloop, execution will halt. To continue, + * pass the ID of the incomplete Log and the required tool call to the /agents/continue endpoint. * - * Calling an Agent calls the model provider before logging - * the request, responses and metadata to Humanloop. + * The agent will run for the maximum number of iterations, or until it encounters a stop condition, + * according to its configuration. * * You can use query parameters `version_id`, or `environment`, to target * an existing version of the Agent. Otherwise the default deployed version will be chosen. * * Instead of targeting an existing version explicitly, you can instead pass in - * Agent details in the request body. In this case, we will check if the details correspond - * to an existing version of the Agent. If they do not, we will create a new version. This is helpful - * in the case where you are storing or deriving your Agent details in code. + * Agent details in the request body. A new version is created if it does not match + * any existing ones. This is helpful in the case where you are storing or deriving + * your Agent details in code. * * @param {Humanloop.AgentsCallRequest} request * @param {Agents.RequestOptions} requestOptions - Request-specific configuration. @@ -362,12 +423,18 @@ export class Agents { * @throws {@link Humanloop.UnprocessableEntityError} * * @example - * await client.agents.call({}) + * await client.agents.call({ + * path: "Banking/Teller Agent", + * messages: [{ + * role: "user", + * content: "I'd like to deposit $1000 to my savings account from my checking account." + * }] + * }) */ public async call( request: Humanloop.AgentsCallRequest, requestOptions?: Agents.RequestOptions, - ): Promise { + ): Promise { const { versionId, environment, ..._body } = request; const _queryParams: Record = {}; if (versionId != null) { @@ -389,8 +456,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -408,7 +475,7 @@ export class Agents { abortSignal: requestOptions?.abortSignal, }); if (_response.ok) { - return serializers.AgentContinueCallResponse.parseOrThrow(_response.body, { + return serializers.AgentCallResponse.parseOrThrow(_response.body, { unrecognizedObjectKeys: "passthrough", allowUnrecognizedUnionMembers: true, allowUnrecognizedEnumValues: true, @@ -455,15 +522,15 @@ export class Agents { /** * Continue an incomplete Agent call. * - * This endpoint allows continuing an existing incomplete Agent call, using the context - * from the previous interaction. The Agent will resume processing from where it left off. + * This endpoint allows continuing an existing incomplete Agent call, by passing the tool call + * requested by the Agent. The Agent will resume processing from where it left off. * - * The original log must be in an incomplete state to be continued. + * The messages in the request will be appended to the original messages in the Log. You do not + * have to provide the previous conversation history. * - * The messages in the request will be appended - * to the original messages in the log. + * The original log must be in an incomplete state to be continued. */ - public async continueStream( + public async continueCallStream( request: Humanloop.AgentsContinueCallStreamRequest, requestOptions?: Agents.RequestOptions, ): Promise> { @@ -478,8 +545,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -488,7 +555,9 @@ export class Agents { contentType: "application/json", requestType: "json", body: { - ...serializers.AgentsContinueCallStreamRequest.jsonOrThrow(request, { unrecognizedObjectKeys: "strip" }), + ...serializers.AgentsContinueCallStreamRequest.jsonOrThrow(request, { + unrecognizedObjectKeys: "strip", + }), stream: true, }, responseType: "sse", @@ -554,28 +623,30 @@ export class Agents { /** * Continue an incomplete Agent call. * - * This endpoint allows continuing an existing incomplete Agent call, using the context - * from the previous interaction. The Agent will resume processing from where it left off. + * This endpoint allows continuing an existing incomplete Agent call, by passing the tool call + * requested by the Agent. The Agent will resume processing from where it left off. * - * The original log must be in an incomplete state to be continued. + * The messages in the request will be appended to the original messages in the Log. You do not + * have to provide the previous conversation history. * - * The messages in the request will be appended - * to the original messages in the log. + * The original log must be in an incomplete state to be continued. * - * @param {Humanloop.AgentsContinueRequest} request + * @param {Humanloop.AgentsContinueCallRequest} request * @param {Agents.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Humanloop.UnprocessableEntityError} * * @example - * await client.agents.continue({ - * logId: "log_id", + * await client.agents.continueCall({ + * logId: "log_1234567890", * messages: [{ - * role: "user" + * role: "tool", + * content: "{\"type\": \"checking\", \"balance\": 5200}", + * toolCallId: "tc_1234567890" * }] * }) */ - public async continue( + public async continueCall( request: Humanloop.AgentsContinueCallRequest, requestOptions?: Agents.RequestOptions, ): Promise { @@ -590,8 +661,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -661,108 +732,114 @@ export class Agents { * @throws {@link Humanloop.UnprocessableEntityError} * * @example - * await client.agents.list() + * await client.agents.list({ + * size: 1 + * }) */ public async list( request: Humanloop.ListAgentsGetRequest = {}, requestOptions?: Agents.RequestOptions, - ): Promise { - const { page, size, name, userFilter, sortBy, order } = request; - const _queryParams: Record = {}; - if (page != null) { - _queryParams["page"] = page.toString(); - } - - if (size != null) { - _queryParams["size"] = size.toString(); - } - - if (name != null) { - _queryParams["name"] = name; - } - - if (userFilter != null) { - _queryParams["user_filter"] = userFilter; - } - - if (sortBy != null) { - _queryParams["sort_by"] = serializers.ProjectSortBy.jsonOrThrow(sortBy, { - unrecognizedObjectKeys: "strip", - }); - } - - if (order != null) { - _queryParams["order"] = serializers.SortOrder.jsonOrThrow(order, { unrecognizedObjectKeys: "strip" }); - } - - const _response = await (this._options.fetcher ?? core.fetcher)({ - url: urlJoin( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)) ?? - environments.HumanloopEnvironment.Default, - "agents", - ), - method: "GET", - headers: { - "X-Fern-Language": "JavaScript", - "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - ...(await this._getCustomAuthorizationHeaders()), - ...requestOptions?.headers, - }, - contentType: "application/json", - queryParameters: _queryParams, - requestType: "json", - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return serializers.PaginatedDataAgentResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], + ): Promise> { + const list = async (request: Humanloop.ListAgentsGetRequest): Promise => { + const { page, size, name, userFilter, sortBy, order } = request; + const _queryParams: Record = {}; + if (page != null) { + _queryParams["page"] = page.toString(); + } + if (size != null) { + _queryParams["size"] = size.toString(); + } + if (name != null) { + _queryParams["name"] = name; + } + if (userFilter != null) { + _queryParams["user_filter"] = userFilter; + } + if (sortBy != null) { + _queryParams["sort_by"] = serializers.FileSortBy.jsonOrThrow(sortBy, { + unrecognizedObjectKeys: "strip", + }); + } + if (order != null) { + _queryParams["order"] = serializers.SortOrder.jsonOrThrow(order, { unrecognizedObjectKeys: "strip" }); + } + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: urlJoin( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)) ?? + environments.HumanloopEnvironment.Default, + "agents", + ), + method: "GET", + headers: { + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "humanloop", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + ...(await this._getCustomAuthorizationHeaders()), + ...requestOptions?.headers, + }, + contentType: "application/json", + queryParameters: _queryParams, + requestType: "json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, }); - } - - if (_response.error.reason === "status-code") { - switch (_response.error.statusCode) { - case 422: - throw new Humanloop.UnprocessableEntityError( - serializers.HttpValidationError.parseOrThrow(_response.error.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }), - ); - default: + if (_response.ok) { + return serializers.PaginatedDataAgentResponse.parseOrThrow(_response.body, { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }); + } + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Humanloop.UnprocessableEntityError( + serializers.HttpValidationError.parseOrThrow(_response.error.body, { + unrecognizedObjectKeys: "passthrough", + allowUnrecognizedUnionMembers: true, + allowUnrecognizedEnumValues: true, + skipValidation: true, + breadcrumbsPrefix: ["response"], + }), + ); + default: + throw new errors.HumanloopError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + }); + } + } + switch (_response.error.reason) { + case "non-json": throw new errors.HumanloopError({ statusCode: _response.error.statusCode, - body: _response.error.body, + body: _response.error.rawBody, + }); + case "timeout": + throw new errors.HumanloopTimeoutError("Timeout exceeded when calling GET /agents."); + case "unknown": + throw new errors.HumanloopError({ + message: _response.error.errorMessage, }); } - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.HumanloopError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - }); - case "timeout": - throw new errors.HumanloopTimeoutError("Timeout exceeded when calling GET /agents."); - case "unknown": - throw new errors.HumanloopError({ - message: _response.error.errorMessage, - }); - } + }; + let _offset = request?.page != null ? request?.page : 1; + return new core.Pageable({ + response: await list(request), + hasNextPage: (response) => (response?.records ?? []).length > 0, + getItems: (response) => response?.records ?? [], + loadPage: (_response) => { + _offset += 1; + return list(core.setObjectProperty(request, "page", _offset)); + }, + }); } /** @@ -782,7 +859,40 @@ export class Agents { * * @example * await client.agents.upsert({ - * model: "model" + * path: "Banking/Teller Agent", + * provider: "anthropic", + * endpoint: "chat", + * model: "claude-3-7-sonnet-latest", + * reasoningEffort: 1024, + * template: [{ + * role: "system", + * content: "You are a helpful digital assistant, helping users navigate our digital banking platform." + * }], + * maxIterations: 3, + * tools: [{ + * type: "inline", + * jsonSchema: { + * name: "stop", + * description: "Call this tool when you have finished your task.", + * parameters: { + * "type": "object", + * "properties": { + * "output": { + * "type": "string", + * "description": "The final output to return to the user." + * } + * }, + * "additionalProperties": false, + * "required": [ + * "output" + * ] + * }, + * strict: true + * }, + * onAgentCall: "stop" + * }], + * versionName: "teller-agent-v1", + * versionDescription: "Initial version" * }) */ public async upsert( @@ -800,8 +910,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -869,7 +979,7 @@ export class Agents { * @throws {@link Humanloop.UnprocessableEntityError} * * @example - * await client.agents.deleteAgentVersion("id", "version_id") + * await client.agents.deleteAgentVersion("ag_1234567890", "agv_1234567890") */ public async deleteAgentVersion( id: string, @@ -887,8 +997,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -952,7 +1062,10 @@ export class Agents { * @throws {@link Humanloop.UnprocessableEntityError} * * @example - * await client.agents.patchAgentVersion("id", "version_id", {}) + * await client.agents.patchAgentVersion("ag_1234567890", "agv_1234567890", { + * name: "teller-agent-v2", + * description: "Updated version" + * }) */ public async patchAgentVersion( id: string, @@ -971,8 +1084,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1045,7 +1158,7 @@ export class Agents { * @throws {@link Humanloop.UnprocessableEntityError} * * @example - * await client.agents.get("id") + * await client.agents.get("ag_1234567890") */ public async get( id: string, @@ -1073,8 +1186,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1141,7 +1254,7 @@ export class Agents { * @throws {@link Humanloop.UnprocessableEntityError} * * @example - * await client.agents.delete("id") + * await client.agents.delete("ag_1234567890") */ public async delete(id: string, requestOptions?: Agents.RequestOptions): Promise { const _response = await (this._options.fetcher ?? core.fetcher)({ @@ -1155,8 +1268,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1217,7 +1330,9 @@ export class Agents { * @throws {@link Humanloop.UnprocessableEntityError} * * @example - * await client.agents.move("id") + * await client.agents.move("ag_1234567890", { + * path: "new directory/new name" + * }) */ public async move( id: string, @@ -1235,8 +1350,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1304,7 +1419,7 @@ export class Agents { * @throws {@link Humanloop.UnprocessableEntityError} * * @example - * await client.agents.listVersions("id") + * await client.agents.listVersions("ag_1234567890") */ public async listVersions( id: string, @@ -1328,8 +1443,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1425,8 +1540,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1517,8 +1632,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1580,7 +1695,7 @@ export class Agents { * @throws {@link Humanloop.UnprocessableEntityError} * * @example - * await client.agents.listEnvironments("id") + * await client.agents.listEnvironments("ag_1234567890") */ public async listEnvironments( id: string, @@ -1597,8 +1712,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1668,7 +1783,17 @@ export class Agents { * @throws {@link Humanloop.UnprocessableEntityError} * * @example - * await client.agents.updateMonitoring("id", {}) + * await client.agents.updateMonitoring("ag_1234567890", { + * activate: [{ + * evaluatorVersionId: "ev_1234567890" + * }, { + * evaluatorId: "ev_2345678901", + * environmentId: "env_1234567890" + * }], + * deactivate: [{ + * evaluatorVersionId: "ev_0987654321" + * }] + * }) */ public async updateMonitoring( id: string, @@ -1686,8 +1811,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1769,7 +1894,7 @@ export class Agents { id: string, request: Humanloop.SerializeAgentsIdSerializeGetRequest = {}, requestOptions?: Agents.RequestOptions, - ): Promise { + ): Promise { const { versionId, environment } = request; const _queryParams: Record = {}; if (versionId != null) { @@ -1791,8 +1916,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1801,12 +1926,13 @@ export class Agents { contentType: "application/json", queryParameters: _queryParams, requestType: "json", + responseType: "text", timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, maxRetries: requestOptions?.maxRetries, abortSignal: requestOptions?.abortSignal, }); if (_response.ok) { - return _response.body; + return _response.body as string; } if (_response.error.reason === "status-code") { @@ -1875,8 +2001,8 @@ export class Agents { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), diff --git a/src/api/resources/agents/client/requests/AgentLogRequest.ts b/src/api/resources/agents/client/requests/AgentLogRequest.ts index 5852bf02..e8c8cfcf 100644 --- a/src/api/resources/agents/client/requests/AgentLogRequest.ts +++ b/src/api/resources/agents/client/requests/AgentLogRequest.ts @@ -89,8 +89,14 @@ export interface AgentLogRequest { * - `{'type': 'function', 'function': {name': }}` forces the model to use the named function. */ toolChoice?: Humanloop.AgentLogRequestToolChoice; - /** Details of your Agent. A new Agent version will be created if the provided details are new. */ - agent?: Humanloop.AgentKernelRequest; + /** + * The Agent configuration to use. Two formats are supported: + * - An object representing the details of the Agent configuration + * - A string representing the raw contents of a .agent file + * + * A new Agent version will be created if the provided details do not match any existing version. + */ + agent?: Humanloop.AgentLogRequestAgent; /** When the logged event started. */ startTime?: Date; /** When the logged event ended. */ diff --git a/src/api/resources/agents/client/requests/AgentsCallRequest.ts b/src/api/resources/agents/client/requests/AgentsCallRequest.ts index 1f554921..a7bfda40 100644 --- a/src/api/resources/agents/client/requests/AgentsCallRequest.ts +++ b/src/api/resources/agents/client/requests/AgentsCallRequest.ts @@ -37,8 +37,14 @@ export interface AgentsCallRequest { * - `{'type': 'function', 'function': {name': }}` forces the model to use the named function. */ toolChoice?: Humanloop.AgentsCallRequestToolChoice; - /** Details of your Agent. A new Agent version will be created if the provided details are new. */ - agent?: Humanloop.AgentKernelRequest; + /** + * The Agent configuration to use. Two formats are supported: + * - An object representing the details of the Agent configuration + * - A string representing the raw contents of a .agent file + * + * A new Agent version will be created if the provided details do not match any existing version. + */ + agent?: Humanloop.AgentsCallRequestAgent; /** The inputs passed to the prompt template. */ inputs?: Record; /** Identifies where the model was called from. */ diff --git a/src/api/resources/agents/client/requests/AgentsCallStreamRequest.ts b/src/api/resources/agents/client/requests/AgentsCallStreamRequest.ts index 46ef71f9..71e96329 100644 --- a/src/api/resources/agents/client/requests/AgentsCallStreamRequest.ts +++ b/src/api/resources/agents/client/requests/AgentsCallStreamRequest.ts @@ -31,8 +31,14 @@ export interface AgentsCallStreamRequest { * - `{'type': 'function', 'function': {name': }}` forces the model to use the named function. */ toolChoice?: Humanloop.AgentsCallStreamRequestToolChoice; - /** Details of your Agent. A new Agent version will be created if the provided details are new. */ - agent?: Humanloop.AgentKernelRequest; + /** + * The Agent configuration to use. Two formats are supported: + * - An object representing the details of the Agent configuration + * - A string representing the raw contents of a .agent file + * + * A new Agent version will be created if the provided details do not match any existing version. + */ + agent?: Humanloop.AgentsCallStreamRequestAgent; /** The inputs passed to the prompt template. */ inputs?: Record; /** Identifies where the model was called from. */ diff --git a/src/api/resources/agents/client/requests/AgentsContinueRequest.ts b/src/api/resources/agents/client/requests/AgentsContinueRequest.ts deleted file mode 100644 index eb9aee76..00000000 --- a/src/api/resources/agents/client/requests/AgentsContinueRequest.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ - -import * as Humanloop from "../../../../index"; - -/** - * @example - * { - * logId: "log_id", - * messages: [{ - * role: "user" - * }] - * } - */ -export interface AgentsContinueCallRequest { - /** This identifies the Agent Log to continue. */ - logId: string; - /** The additional messages with which to continue the Agent Log. Often, these should start with the Tool messages with results for the previous Assistant message's tool calls. */ - messages: Humanloop.ChatMessage[]; - /** API keys required by each provider to make API calls. The API keys provided here are not stored by Humanloop. If not specified here, Humanloop will fall back to the key saved to your organization. */ - providerApiKeys?: Humanloop.ProviderApiKeys; - /** If true, populate `trace_children` for the returned Agent Log. Defaults to false. */ - includeTraceChildren?: boolean; -} diff --git a/src/api/resources/agents/client/requests/AgentsContinueStreamRequest.ts b/src/api/resources/agents/client/requests/AgentsContinueStreamRequest.ts deleted file mode 100644 index f5648052..00000000 --- a/src/api/resources/agents/client/requests/AgentsContinueStreamRequest.ts +++ /dev/null @@ -1,25 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ - -import * as Humanloop from "../../../../index"; - -/** - * @example - * { - * logId: "log_id", - * messages: [{ - * role: "user" - * }] - * } - */ -export interface AgentsContinueStreamRequest { - /** This identifies the Agent Log to continue. */ - logId: string; - /** The additional messages with which to continue the Agent Log. Often, these should start with the Tool messages with results for the previous Assistant message's tool calls. */ - messages: Humanloop.ChatMessage[]; - /** API keys required by each provider to make API calls. The API keys provided here are not stored by Humanloop. If not specified here, Humanloop will fall back to the key saved to your organization. */ - providerApiKeys?: Humanloop.ProviderApiKeys; - /** If true, populate `trace_children` for the returned Agent Log. Defaults to false. */ - includeTraceChildren?: boolean; -} diff --git a/src/api/resources/agents/client/requests/ListAgentsGetRequest.ts b/src/api/resources/agents/client/requests/ListAgentsGetRequest.ts index 2a81c3f7..fb166857 100644 --- a/src/api/resources/agents/client/requests/ListAgentsGetRequest.ts +++ b/src/api/resources/agents/client/requests/ListAgentsGetRequest.ts @@ -30,7 +30,7 @@ export interface ListAgentsGetRequest { /** * Field to sort Agents by */ - sortBy?: Humanloop.ProjectSortBy; + sortBy?: Humanloop.FileSortBy; /** * Direction to sort by. */ diff --git a/src/api/resources/agents/types/AgentLogRequestAgent.ts b/src/api/resources/agents/types/AgentLogRequestAgent.ts new file mode 100644 index 00000000..db749773 --- /dev/null +++ b/src/api/resources/agents/types/AgentLogRequestAgent.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Humanloop from "../../../index"; + +/** + * The Agent configuration to use. Two formats are supported: + * - An object representing the details of the Agent configuration + * - A string representing the raw contents of a .agent file + * + * A new Agent version will be created if the provided details do not match any existing version. + */ +export type AgentLogRequestAgent = Humanloop.AgentKernelRequest | string; diff --git a/src/api/resources/agents/types/AgentsCallRequestAgent.ts b/src/api/resources/agents/types/AgentsCallRequestAgent.ts new file mode 100644 index 00000000..a8f0dbdb --- /dev/null +++ b/src/api/resources/agents/types/AgentsCallRequestAgent.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Humanloop from "../../../index"; + +/** + * The Agent configuration to use. Two formats are supported: + * - An object representing the details of the Agent configuration + * - A string representing the raw contents of a .agent file + * + * A new Agent version will be created if the provided details do not match any existing version. + */ +export type AgentsCallRequestAgent = Humanloop.AgentKernelRequest | string; diff --git a/src/api/resources/agents/types/AgentsCallStreamRequestAgent.ts b/src/api/resources/agents/types/AgentsCallStreamRequestAgent.ts new file mode 100644 index 00000000..3452db81 --- /dev/null +++ b/src/api/resources/agents/types/AgentsCallStreamRequestAgent.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Humanloop from "../../../index"; + +/** + * The Agent configuration to use. Two formats are supported: + * - An object representing the details of the Agent configuration + * - A string representing the raw contents of a .agent file + * + * A new Agent version will be created if the provided details do not match any existing version. + */ +export type AgentsCallStreamRequestAgent = Humanloop.AgentKernelRequest | string; diff --git a/src/api/resources/agents/types/index.ts b/src/api/resources/agents/types/index.ts index 8a8a004f..1a1043c1 100644 --- a/src/api/resources/agents/types/index.ts +++ b/src/api/resources/agents/types/index.ts @@ -1,6 +1,9 @@ export * from "./AgentLogRequestToolChoice"; +export * from "./AgentLogRequestAgent"; export * from "./AgentsCallStreamRequestToolChoice"; +export * from "./AgentsCallStreamRequestAgent"; export * from "./AgentsCallRequestToolChoice"; +export * from "./AgentsCallRequestAgent"; export * from "./AgentRequestTemplate"; export * from "./AgentRequestStop"; export * from "./AgentRequestReasoningEffort"; diff --git a/src/api/resources/datasets/client/Client.ts b/src/api/resources/datasets/client/Client.ts index cd17b306..140deb82 100644 --- a/src/api/resources/datasets/client/Client.ts +++ b/src/api/resources/datasets/client/Client.ts @@ -89,7 +89,7 @@ export class Datasets { _queryParams["user_filter"] = userFilter; } if (sortBy != null) { - _queryParams["sort_by"] = serializers.ProjectSortBy.jsonOrThrow(sortBy, { + _queryParams["sort_by"] = serializers.FileSortBy.jsonOrThrow(sortBy, { unrecognizedObjectKeys: "strip", }); } @@ -107,8 +107,8 @@ export class Datasets { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -275,8 +275,8 @@ export class Datasets { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -388,8 +388,8 @@ export class Datasets { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -470,8 +470,8 @@ export class Datasets { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -550,8 +550,8 @@ export class Datasets { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -656,8 +656,8 @@ export class Datasets { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -763,8 +763,8 @@ export class Datasets { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -850,8 +850,8 @@ export class Datasets { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -934,8 +934,8 @@ export class Datasets { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1055,8 +1055,8 @@ export class Datasets { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1155,8 +1155,8 @@ export class Datasets { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1246,8 +1246,8 @@ export class Datasets { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1326,8 +1326,8 @@ export class Datasets { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), diff --git a/src/api/resources/datasets/client/requests/ListDatasetsGetRequest.ts b/src/api/resources/datasets/client/requests/ListDatasetsGetRequest.ts index c51ad97c..b171bf20 100644 --- a/src/api/resources/datasets/client/requests/ListDatasetsGetRequest.ts +++ b/src/api/resources/datasets/client/requests/ListDatasetsGetRequest.ts @@ -30,7 +30,7 @@ export interface ListDatasetsGetRequest { /** * Field to sort Datasets by */ - sortBy?: Humanloop.ProjectSortBy; + sortBy?: Humanloop.FileSortBy; /** * Direction to sort by. */ diff --git a/src/api/resources/directories/client/Client.ts b/src/api/resources/directories/client/Client.ts index a9e2a6e9..4b587207 100644 --- a/src/api/resources/directories/client/Client.ts +++ b/src/api/resources/directories/client/Client.ts @@ -55,8 +55,8 @@ export class Directories { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -139,8 +139,8 @@ export class Directories { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -224,8 +224,8 @@ export class Directories { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -307,8 +307,8 @@ export class Directories { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -387,8 +387,8 @@ export class Directories { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), diff --git a/src/api/resources/evaluations/client/Client.ts b/src/api/resources/evaluations/client/Client.ts index 93e1d4e1..158e39e2 100644 --- a/src/api/resources/evaluations/client/Client.ts +++ b/src/api/resources/evaluations/client/Client.ts @@ -88,8 +88,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -190,8 +190,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -283,8 +283,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -374,8 +374,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -463,8 +463,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -546,8 +546,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -624,8 +624,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -723,8 +723,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -813,8 +813,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -894,8 +894,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -981,8 +981,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1074,8 +1074,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1161,8 +1161,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1267,8 +1267,8 @@ export class Evaluations { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), diff --git a/src/api/resources/evaluators/client/Client.ts b/src/api/resources/evaluators/client/Client.ts index c39703a9..4913a258 100644 --- a/src/api/resources/evaluators/client/Client.ts +++ b/src/api/resources/evaluators/client/Client.ts @@ -73,8 +73,8 @@ export class Evaluators { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -168,7 +168,7 @@ export class Evaluators { _queryParams["user_filter"] = userFilter; } if (sortBy != null) { - _queryParams["sort_by"] = serializers.ProjectSortBy.jsonOrThrow(sortBy, { + _queryParams["sort_by"] = serializers.FileSortBy.jsonOrThrow(sortBy, { unrecognizedObjectKeys: "strip", }); } @@ -186,8 +186,8 @@ export class Evaluators { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -296,8 +296,8 @@ export class Evaluators { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -396,8 +396,8 @@ export class Evaluators { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -478,8 +478,8 @@ export class Evaluators { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -560,8 +560,8 @@ export class Evaluators { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -653,8 +653,8 @@ export class Evaluators { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -740,8 +740,8 @@ export class Evaluators { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -824,8 +824,8 @@ export class Evaluators { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -923,8 +923,8 @@ export class Evaluators { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1015,8 +1015,8 @@ export class Evaluators { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1095,8 +1095,8 @@ export class Evaluators { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1186,8 +1186,8 @@ export class Evaluators { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), diff --git a/src/api/resources/evaluators/client/requests/ListEvaluatorsGetRequest.ts b/src/api/resources/evaluators/client/requests/ListEvaluatorsGetRequest.ts index 676ff433..67c8497e 100644 --- a/src/api/resources/evaluators/client/requests/ListEvaluatorsGetRequest.ts +++ b/src/api/resources/evaluators/client/requests/ListEvaluatorsGetRequest.ts @@ -30,7 +30,7 @@ export interface ListEvaluatorsGetRequest { /** * Field to sort Evaluators by */ - sortBy?: Humanloop.ProjectSortBy; + sortBy?: Humanloop.FileSortBy; /** * Direction to sort by. */ diff --git a/src/api/resources/files/client/Client.ts b/src/api/resources/files/client/Client.ts index 83aa8ff1..d32c1153 100644 --- a/src/api/resources/files/client/Client.ts +++ b/src/api/resources/files/client/Client.ts @@ -48,7 +48,18 @@ export class Files { request: Humanloop.ListFilesFilesGetRequest = {}, requestOptions?: Files.RequestOptions, ): Promise { - const { page, size, name, template, type: type_, environment, sortBy, order } = request; + const { + page, + size, + name, + path, + template, + type: type_, + environment, + sortBy, + order, + includeRawFileContent, + } = request; const _queryParams: Record = {}; if (page != null) { _queryParams["page"] = page.toString(); @@ -62,6 +73,10 @@ export class Files { _queryParams["name"] = name; } + if (path != null) { + _queryParams["path"] = path; + } + if (template != null) { _queryParams["template"] = template.toString(); } @@ -81,15 +96,17 @@ export class Files { } if (sortBy != null) { - _queryParams["sort_by"] = serializers.ProjectSortBy.jsonOrThrow(sortBy, { - unrecognizedObjectKeys: "strip", - }); + _queryParams["sort_by"] = serializers.FileSortBy.jsonOrThrow(sortBy, { unrecognizedObjectKeys: "strip" }); } if (order != null) { _queryParams["order"] = serializers.SortOrder.jsonOrThrow(order, { unrecognizedObjectKeys: "strip" }); } + if (includeRawFileContent != null) { + _queryParams["include_raw_file_content"] = includeRawFileContent.toString(); + } + const _response = await (this._options.fetcher ?? core.fetcher)({ url: urlJoin( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -101,8 +118,8 @@ export class Files { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -180,12 +197,16 @@ export class Files { request: Humanloop.BodyRetrieveByPathFilesRetrieveByPathPost, requestOptions?: Files.RequestOptions, ): Promise { - const { environment, ..._body } = request; + const { environment, includeRawFileContent, ..._body } = request; const _queryParams: Record = {}; if (environment != null) { _queryParams["environment"] = environment; } + if (includeRawFileContent != null) { + _queryParams["include_raw_file_content"] = includeRawFileContent.toString(); + } + const _response = await (this._options.fetcher ?? core.fetcher)({ url: urlJoin( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -197,8 +218,8 @@ export class Files { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), diff --git a/src/api/resources/files/client/requests/BodyRetrieveByPathFilesRetrieveByPathPost.ts b/src/api/resources/files/client/requests/BodyRetrieveByPathFilesRetrieveByPathPost.ts index 7c5c0012..756e769c 100644 --- a/src/api/resources/files/client/requests/BodyRetrieveByPathFilesRetrieveByPathPost.ts +++ b/src/api/resources/files/client/requests/BodyRetrieveByPathFilesRetrieveByPathPost.ts @@ -13,6 +13,10 @@ export interface BodyRetrieveByPathFilesRetrieveByPathPost { * Name of the Environment to retrieve a deployed Version from. */ environment?: string; + /** + * Whether to include the raw file content in the response. Currently only supported for Agents and Prompts. + */ + includeRawFileContent?: boolean; /** Path of the File to retrieve. */ path: string; } diff --git a/src/api/resources/files/client/requests/ListFilesFilesGetRequest.ts b/src/api/resources/files/client/requests/ListFilesFilesGetRequest.ts index 592e4e8b..4fc50bd5 100644 --- a/src/api/resources/files/client/requests/ListFilesFilesGetRequest.ts +++ b/src/api/resources/files/client/requests/ListFilesFilesGetRequest.ts @@ -21,6 +21,10 @@ export interface ListFilesFilesGetRequest { * Case-insensitive filter for file name. */ name?: string; + /** + * Path of the directory to filter for. Returns files in this directory and all its subdirectories. + */ + path?: string; /** * Filter to include only template files. */ @@ -36,9 +40,13 @@ export interface ListFilesFilesGetRequest { /** * Field to sort files by */ - sortBy?: Humanloop.ProjectSortBy; + sortBy?: Humanloop.FileSortBy; /** * Direction to sort by. */ order?: Humanloop.SortOrder; + /** + * Whether to include the raw file content in the response. Currently only supported for Agents and Prompts. + */ + includeRawFileContent?: boolean; } diff --git a/src/api/resources/flows/client/Client.ts b/src/api/resources/flows/client/Client.ts index e548186e..9dbbe18d 100644 --- a/src/api/resources/flows/client/Client.ts +++ b/src/api/resources/flows/client/Client.ts @@ -98,8 +98,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -198,8 +198,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -298,8 +298,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -380,8 +380,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -462,8 +462,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -554,7 +554,7 @@ export class Flows { _queryParams["user_filter"] = userFilter; } if (sortBy != null) { - _queryParams["sort_by"] = serializers.ProjectSortBy.jsonOrThrow(sortBy, { + _queryParams["sort_by"] = serializers.FileSortBy.jsonOrThrow(sortBy, { unrecognizedObjectKeys: "strip", }); } @@ -572,8 +572,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -688,8 +688,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -781,8 +781,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -868,8 +868,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -952,8 +952,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1051,8 +1051,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1143,8 +1143,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1223,8 +1223,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1316,8 +1316,8 @@ export class Flows { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), diff --git a/src/api/resources/flows/client/requests/ListFlowsGetRequest.ts b/src/api/resources/flows/client/requests/ListFlowsGetRequest.ts index e7a219a6..3f93e86e 100644 --- a/src/api/resources/flows/client/requests/ListFlowsGetRequest.ts +++ b/src/api/resources/flows/client/requests/ListFlowsGetRequest.ts @@ -30,7 +30,7 @@ export interface ListFlowsGetRequest { /** * Field to sort Flows by */ - sortBy?: Humanloop.ProjectSortBy; + sortBy?: Humanloop.FileSortBy; /** * Direction to sort by. */ diff --git a/src/api/resources/logs/client/Client.ts b/src/api/resources/logs/client/Client.ts index e8e0dcb3..e0aa3aa5 100644 --- a/src/api/resources/logs/client/Client.ts +++ b/src/api/resources/logs/client/Client.ts @@ -136,8 +136,8 @@ export class Logs { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -242,8 +242,8 @@ export class Logs { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -318,8 +318,8 @@ export class Logs { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), diff --git a/src/api/resources/prompts/client/Client.ts b/src/api/resources/prompts/client/Client.ts index 9541f43a..1bb67cbe 100644 --- a/src/api/resources/prompts/client/Client.ts +++ b/src/api/resources/prompts/client/Client.ts @@ -129,8 +129,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -221,8 +221,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -321,8 +321,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -502,8 +502,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -600,7 +600,7 @@ export class Prompts { _queryParams["user_filter"] = userFilter; } if (sortBy != null) { - _queryParams["sort_by"] = serializers.ProjectSortBy.jsonOrThrow(sortBy, { + _queryParams["sort_by"] = serializers.FileSortBy.jsonOrThrow(sortBy, { unrecognizedObjectKeys: "strip", }); } @@ -618,8 +618,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -731,8 +731,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -831,8 +831,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -913,8 +913,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -995,8 +995,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1099,8 +1099,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1193,8 +1193,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1280,8 +1280,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1364,8 +1364,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1463,8 +1463,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1555,8 +1555,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1635,8 +1635,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1728,8 +1728,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1811,7 +1811,7 @@ export class Prompts { id: string, request: Humanloop.SerializePromptsIdSerializeGetRequest = {}, requestOptions?: Prompts.RequestOptions, - ): Promise { + ): Promise { const { versionId, environment } = request; const _queryParams: Record = {}; if (versionId != null) { @@ -1833,8 +1833,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1843,12 +1843,13 @@ export class Prompts { contentType: "application/json", queryParameters: _queryParams, requestType: "json", + responseType: "text", timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, maxRetries: requestOptions?.maxRetries, abortSignal: requestOptions?.abortSignal, }); if (_response.ok) { - return _response.body; + return _response.body as string; } if (_response.error.reason === "status-code") { @@ -1917,8 +1918,8 @@ export class Prompts { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), diff --git a/src/api/resources/prompts/client/requests/ListPromptsGetRequest.ts b/src/api/resources/prompts/client/requests/ListPromptsGetRequest.ts index 0344a789..f681b09d 100644 --- a/src/api/resources/prompts/client/requests/ListPromptsGetRequest.ts +++ b/src/api/resources/prompts/client/requests/ListPromptsGetRequest.ts @@ -30,7 +30,7 @@ export interface ListPromptsGetRequest { /** * Field to sort Prompts by */ - sortBy?: Humanloop.ProjectSortBy; + sortBy?: Humanloop.FileSortBy; /** * Direction to sort by. */ diff --git a/src/api/resources/prompts/client/requests/PromptLogRequest.ts b/src/api/resources/prompts/client/requests/PromptLogRequest.ts index 45a47afd..ca87b895 100644 --- a/src/api/resources/prompts/client/requests/PromptLogRequest.ts +++ b/src/api/resources/prompts/client/requests/PromptLogRequest.ts @@ -75,8 +75,14 @@ export interface PromptLogRequest { * - `{'type': 'function', 'function': {name': }}` forces the model to use the named function. */ toolChoice?: Humanloop.PromptLogRequestToolChoice; - /** Details of your Prompt. A new Prompt version will be created if the provided details are new. */ - prompt?: Humanloop.PromptKernelRequest; + /** + * The Prompt configuration to use. Two formats are supported: + * - An object representing the details of the Prompt configuration + * - A string representing the raw contents of a .prompt file + * + * A new Prompt version will be created if the provided details do not match any existing version. + */ + prompt?: Humanloop.PromptLogRequestPrompt; /** When the logged event started. */ startTime?: Date; /** When the logged event ended. */ diff --git a/src/api/resources/prompts/client/requests/PromptsCallRequest.ts b/src/api/resources/prompts/client/requests/PromptsCallRequest.ts index 4e1595fc..f699ecfb 100644 --- a/src/api/resources/prompts/client/requests/PromptsCallRequest.ts +++ b/src/api/resources/prompts/client/requests/PromptsCallRequest.ts @@ -91,8 +91,14 @@ export interface PromptsCallRequest { * - `{'type': 'function', 'function': {name': }}` forces the model to use the named function. */ toolChoice?: Humanloop.PromptsCallRequestToolChoice; - /** Details of your Prompt. A new Prompt version will be created if the provided details are new. */ - prompt?: Humanloop.PromptKernelRequest; + /** + * The Prompt configuration to use. Two formats are supported: + * - An object representing the details of the Prompt configuration + * - A string representing the raw contents of a .prompt file + * + * A new Prompt version will be created if the provided details do not match any existing version. + */ + prompt?: Humanloop.PromptsCallRequestPrompt; /** The inputs passed to the prompt template. */ inputs?: Record; /** Identifies where the model was called from. */ diff --git a/src/api/resources/prompts/client/requests/PromptsCallStreamRequest.ts b/src/api/resources/prompts/client/requests/PromptsCallStreamRequest.ts index b444e68c..380b2ab5 100644 --- a/src/api/resources/prompts/client/requests/PromptsCallStreamRequest.ts +++ b/src/api/resources/prompts/client/requests/PromptsCallStreamRequest.ts @@ -31,8 +31,14 @@ export interface PromptsCallStreamRequest { * - `{'type': 'function', 'function': {name': }}` forces the model to use the named function. */ toolChoice?: Humanloop.PromptsCallStreamRequestToolChoice; - /** Details of your Prompt. A new Prompt version will be created if the provided details are new. */ - prompt?: Humanloop.PromptKernelRequest; + /** + * The Prompt configuration to use. Two formats are supported: + * - An object representing the details of the Prompt configuration + * - A string representing the raw contents of a .prompt file + * + * A new Prompt version will be created if the provided details do not match any existing version. + */ + prompt?: Humanloop.PromptsCallStreamRequestPrompt; /** The inputs passed to the prompt template. */ inputs?: Record; /** Identifies where the model was called from. */ diff --git a/src/api/resources/prompts/types/PromptLogRequestPrompt.ts b/src/api/resources/prompts/types/PromptLogRequestPrompt.ts new file mode 100644 index 00000000..d5acbbb9 --- /dev/null +++ b/src/api/resources/prompts/types/PromptLogRequestPrompt.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Humanloop from "../../../index"; + +/** + * The Prompt configuration to use. Two formats are supported: + * - An object representing the details of the Prompt configuration + * - A string representing the raw contents of a .prompt file + * + * A new Prompt version will be created if the provided details do not match any existing version. + */ +export type PromptLogRequestPrompt = Humanloop.PromptKernelRequest | string; diff --git a/src/api/resources/prompts/types/PromptsCallRequestPrompt.ts b/src/api/resources/prompts/types/PromptsCallRequestPrompt.ts new file mode 100644 index 00000000..3cdee1e7 --- /dev/null +++ b/src/api/resources/prompts/types/PromptsCallRequestPrompt.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Humanloop from "../../../index"; + +/** + * The Prompt configuration to use. Two formats are supported: + * - An object representing the details of the Prompt configuration + * - A string representing the raw contents of a .prompt file + * + * A new Prompt version will be created if the provided details do not match any existing version. + */ +export type PromptsCallRequestPrompt = Humanloop.PromptKernelRequest | string; diff --git a/src/api/resources/prompts/types/PromptsCallStreamRequestPrompt.ts b/src/api/resources/prompts/types/PromptsCallStreamRequestPrompt.ts new file mode 100644 index 00000000..5e841cee --- /dev/null +++ b/src/api/resources/prompts/types/PromptsCallStreamRequestPrompt.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Humanloop from "../../../index"; + +/** + * The Prompt configuration to use. Two formats are supported: + * - An object representing the details of the Prompt configuration + * - A string representing the raw contents of a .prompt file + * + * A new Prompt version will be created if the provided details do not match any existing version. + */ +export type PromptsCallStreamRequestPrompt = Humanloop.PromptKernelRequest | string; diff --git a/src/api/resources/prompts/types/index.ts b/src/api/resources/prompts/types/index.ts index 8265b2f3..f8045c03 100644 --- a/src/api/resources/prompts/types/index.ts +++ b/src/api/resources/prompts/types/index.ts @@ -1,7 +1,10 @@ export * from "./PromptLogRequestToolChoice"; +export * from "./PromptLogRequestPrompt"; export * from "./PromptLogUpdateRequestToolChoice"; export * from "./PromptsCallStreamRequestToolChoice"; +export * from "./PromptsCallStreamRequestPrompt"; export * from "./PromptsCallRequestToolChoice"; +export * from "./PromptsCallRequestPrompt"; export * from "./PromptRequestTemplate"; export * from "./PromptRequestStop"; export * from "./PromptRequestReasoningEffort"; diff --git a/src/api/resources/tools/client/Client.ts b/src/api/resources/tools/client/Client.ts index c5a81fb5..53f63ace 100644 --- a/src/api/resources/tools/client/Client.ts +++ b/src/api/resources/tools/client/Client.ts @@ -79,8 +79,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -211,8 +211,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -303,8 +303,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -395,7 +395,7 @@ export class Tools { _queryParams["user_filter"] = userFilter; } if (sortBy != null) { - _queryParams["sort_by"] = serializers.ProjectSortBy.jsonOrThrow(sortBy, { + _queryParams["sort_by"] = serializers.FileSortBy.jsonOrThrow(sortBy, { unrecognizedObjectKeys: "strip", }); } @@ -413,8 +413,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -536,8 +536,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -636,8 +636,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -718,8 +718,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -800,8 +800,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -893,8 +893,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -980,8 +980,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1064,8 +1064,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1163,8 +1163,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1255,8 +1255,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1335,8 +1335,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1428,8 +1428,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1513,8 +1513,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1604,8 +1604,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), @@ -1693,8 +1693,8 @@ export class Tools { headers: { "X-Fern-Language": "JavaScript", "X-Fern-SDK-Name": "humanloop", - "X-Fern-SDK-Version": "0.8.21-beta1", - "User-Agent": "humanloop/0.8.21-beta1", + "X-Fern-SDK-Version": "0.8.21", + "User-Agent": "humanloop/0.8.21", "X-Fern-Runtime": core.RUNTIME.type, "X-Fern-Runtime-Version": core.RUNTIME.version, ...(await this._getCustomAuthorizationHeaders()), diff --git a/src/api/resources/tools/client/requests/ListToolsGetRequest.ts b/src/api/resources/tools/client/requests/ListToolsGetRequest.ts index 2e5884d5..95c01c87 100644 --- a/src/api/resources/tools/client/requests/ListToolsGetRequest.ts +++ b/src/api/resources/tools/client/requests/ListToolsGetRequest.ts @@ -30,7 +30,7 @@ export interface ListToolsGetRequest { /** * Field to sort Tools by */ - sortBy?: Humanloop.ProjectSortBy; + sortBy?: Humanloop.FileSortBy; /** * Direction to sort by. */ diff --git a/src/api/types/AgentResponse.ts b/src/api/types/AgentResponse.ts index b9251aac..beebd2ed 100644 --- a/src/api/types/AgentResponse.ts +++ b/src/api/types/AgentResponse.ts @@ -100,4 +100,6 @@ export interface AgentResponse { evaluators?: Humanloop.MonitoringEvaluatorResponse[]; /** Aggregation of Evaluator results for the Agent Version. */ evaluatorAggregates?: Humanloop.EvaluatorAggregate[]; + /** The raw content of the Agent. Corresponds to the .agent file. */ + rawFileContent?: string; } diff --git a/src/api/types/EventType.ts b/src/api/types/EventType.ts index cba1c9f1..5d287d29 100644 --- a/src/api/types/EventType.ts +++ b/src/api/types/EventType.ts @@ -10,19 +10,20 @@ export type EventType = | "agent_turn_suspend" | "agent_turn_continue" | "agent_turn_end" + | "agent_turn_error" | "agent_start" | "agent_update" | "agent_end" | "tool_start" | "tool_update" | "tool_end" - | "error" - | "agent_generation_error"; + | "error"; export const EventType = { AgentTurnStart: "agent_turn_start", AgentTurnSuspend: "agent_turn_suspend", AgentTurnContinue: "agent_turn_continue", AgentTurnEnd: "agent_turn_end", + AgentTurnError: "agent_turn_error", AgentStart: "agent_start", AgentUpdate: "agent_update", AgentEnd: "agent_end", @@ -30,5 +31,4 @@ export const EventType = { ToolUpdate: "tool_update", ToolEnd: "tool_end", Error: "error", - AgentGenerationError: "agent_generation_error", } as const; diff --git a/src/api/types/ProjectSortBy.ts b/src/api/types/FileSortBy.ts similarity index 66% rename from src/api/types/ProjectSortBy.ts rename to src/api/types/FileSortBy.ts index 9b3ed0cb..df2b6d4e 100644 --- a/src/api/types/ProjectSortBy.ts +++ b/src/api/types/FileSortBy.ts @@ -5,8 +5,8 @@ /** * An enumeration. */ -export type ProjectSortBy = "created_at" | "updated_at" | "name"; -export const ProjectSortBy = { +export type FileSortBy = "created_at" | "updated_at" | "name"; +export const FileSortBy = { CreatedAt: "created_at", UpdatedAt: "updated_at", Name: "name", diff --git a/src/api/types/PopulateTemplateResponse.ts b/src/api/types/PopulateTemplateResponse.ts index c92b9621..f268d97f 100644 --- a/src/api/types/PopulateTemplateResponse.ts +++ b/src/api/types/PopulateTemplateResponse.ts @@ -94,6 +94,8 @@ export interface PopulateTemplateResponse { evaluators?: Humanloop.MonitoringEvaluatorResponse[]; /** Aggregation of Evaluator results for the Prompt Version. */ evaluatorAggregates?: Humanloop.EvaluatorAggregate[]; + /** The raw content of the Prompt. Corresponds to the .prompt file. */ + rawFileContent?: string; /** The template populated with the input values you provided in the request. Returns None if no template exists. */ populatedTemplate?: Humanloop.PopulateTemplateResponsePopulatedTemplate; } diff --git a/src/api/types/PromptResponse.ts b/src/api/types/PromptResponse.ts index beb732f6..bd177e9d 100644 --- a/src/api/types/PromptResponse.ts +++ b/src/api/types/PromptResponse.ts @@ -94,4 +94,6 @@ export interface PromptResponse { evaluators?: Humanloop.MonitoringEvaluatorResponse[]; /** Aggregation of Evaluator results for the Prompt Version. */ evaluatorAggregates?: Humanloop.EvaluatorAggregate[]; + /** The raw content of the Prompt. Corresponds to the .prompt file. */ + rawFileContent?: string; } diff --git a/src/api/types/index.ts b/src/api/types/index.ts index 50b0fe8b..11a2bba7 100644 --- a/src/api/types/index.ts +++ b/src/api/types/index.ts @@ -80,6 +80,7 @@ export * from "./FileEnvironmentVariableRequest"; export * from "./FileId"; export * from "./FilePath"; export * from "./FileRequest"; +export * from "./FileSortBy"; export * from "./FileType"; export * from "./FlowKernelRequest"; export * from "./FlowLogResponse"; @@ -134,7 +135,6 @@ export * from "./PopulateTemplateResponseStop"; export * from "./PopulateTemplateResponseReasoningEffort"; export * from "./PopulateTemplateResponsePopulatedTemplate"; export * from "./PopulateTemplateResponse"; -export * from "./ProjectSortBy"; export * from "./PromptCallLogResponse"; export * from "./PromptCallResponseToolChoice"; export * from "./PromptCallResponse"; diff --git a/src/cache/LRUCache.ts b/src/cache/LRUCache.ts new file mode 100644 index 00000000..30d0877b --- /dev/null +++ b/src/cache/LRUCache.ts @@ -0,0 +1,48 @@ +/** + * LRU Cache implementation + */ +export default class LRUCache { + private cache: Map; + private readonly maxSize: number; + + constructor(maxSize: number) { + this.cache = new Map(); + this.maxSize = maxSize; + } + + get(key: K): V | undefined { + if (!this.cache.has(key)) { + return undefined; + } + + // Get the value + const value = this.cache.get(key); + + // Remove key and re-insert to mark as most recently used + this.cache.delete(key); + this.cache.set(key, value!); + + return value; + } + + set(key: K, value: V): void { + // If key already exists, refresh its position + if (this.cache.has(key)) { + this.cache.delete(key); + } + // If cache is full, remove the least recently used item (first item in the map) + else if (this.cache.size >= this.maxSize) { + const lruKey = this.cache.keys().next().value; + if (lruKey) { + this.cache.delete(lruKey); + } + } + + // Add new key-value pair + this.cache.set(key, value); + } + + clear(): void { + this.cache.clear(); + } +} diff --git a/src/cache/index.ts b/src/cache/index.ts new file mode 100644 index 00000000..d440ec99 --- /dev/null +++ b/src/cache/index.ts @@ -0,0 +1 @@ +export { default as LRUCache } from './LRUCache'; \ No newline at end of file diff --git a/src/cli.ts b/src/cli.ts new file mode 100644 index 00000000..6df8d05a --- /dev/null +++ b/src/cli.ts @@ -0,0 +1,183 @@ +#!/usr/bin/env node +import * as dotenv from "dotenv"; +import { Command } from "commander"; +import path from "path"; + +import { HumanloopClient } from "./humanloop.client"; +import FileSyncer from "./sync/FileSyncer"; +import { SDK_VERSION } from "./version"; + +dotenv.config(); + +const LogType = { + SUCCESS: "\x1b[92m", // green + ERROR: "\x1b[91m", // red + INFO: "\x1b[96m", // cyan + WARN: "\x1b[93m", // yellow + RESET: "\x1b[0m", +} as const; + +function log(message: string, type: keyof typeof LogType): void { + console.log(`${LogType[type]}${message}${LogType.RESET}`); +} + +const program = new Command(); +program + .name("humanloop") + .description("Humanloop CLI for managing sync operations") + .version(SDK_VERSION); + +interface CommonOptions { + apiKey?: string; + envFile?: string; + baseUrl?: string; + localFilesDirectory?: string; +} + +interface PullOptions extends CommonOptions { + path?: string; + environment?: string; + verbose?: boolean; + quiet?: boolean; +} + +const addCommonOptions = (command: Command) => + command + .option("--api-key ", "Humanloop API key") + .option("--env-file ", "Path to .env file") + .option("--base-url ", "Base URL for Humanloop API") + .option( + "--local-dir, --local-files-directory ", + "Directory where Humanloop files are stored locally (default: humanloop/)", + "humanloop", + ); + +// Instantiate a HumanloopClient for the CLI +function getClient(options: CommonOptions): HumanloopClient { + if (options.envFile) { + const result = dotenv.config({ path: options.envFile }); + if (result.error) { + log( + `Failed to load environment file: ${options.envFile} (file not found or invalid format)`, + "ERROR", + ); + process.exit(1); + } + } + + const apiKey = options.apiKey || process.env.HUMANLOOP_API_KEY; + if (!apiKey) { + log( + "No API key found. Set HUMANLOOP_API_KEY in .env file or environment, or use --api-key", + "ERROR", + ); + process.exit(1); + } + + return new HumanloopClient({ + apiKey, + baseUrl: options.baseUrl, + localFilesDirectory: options.localFilesDirectory, + }); +} + +// Helper to handle sync errors +function handleSyncErrors(fn: (options: T) => Promise) { + return async (options: T) => { + try { + await fn(options); + } catch (error) { + log(`Error: ${error}`, "ERROR"); + process.exit(1); + } + }; +} + +// Pull command +addCommonOptions( + program + .command("pull") + .description( + "Pull Prompt and Agent files from Humanloop to your local filesystem.\n\n" + + "This command will:\n" + + "1. Fetch Prompt and Agent files from your Humanloop workspace\n" + + "2. Save them to your local filesystem (directory specified by --local-files-directory, default: humanloop/)\n" + + "3. Maintain the same directory structure as in Humanloop\n" + + "4. Add appropriate file extensions (.prompt or .agent)\n\n" + + "For example, with the default --local-files-directory=humanloop, files will be saved as:\n" + + "./humanloop/\n" + + "├── my_project/\n" + + "│ ├── prompts/\n" + + "│ │ ├── my_prompt.prompt\n" + + "│ │ └── nested/\n" + + "│ │ └── another_prompt.prompt\n" + + "│ └── agents/\n" + + "│ └── my_agent.agent\n" + + "└── another_project/\n" + + " └── prompts/\n" + + " └── other_prompt.prompt\n\n" + + "If you specify --local-files-directory=data/humanloop, files will be saved in ./data/humanloop/ instead.\n\n" + + "If a file exists both locally and in the Humanloop workspace, the local file will be overwritten\n" + + "with the version from Humanloop. Files that only exist locally will not be affected.\n\n" + + "Currently only supports syncing Prompt and Agent files. Other file types will be skipped.", + ) + .option( + "-p, --path ", + "Path in the Humanloop workspace to pull from (file or directory). " + + "You can pull an entire directory (e.g. 'my/directory') or a specific file (e.g. 'my/directory/my_prompt.prompt'). " + + "When pulling a directory, all files within that directory and its subdirectories will be included. " + + "Paths should not contain leading or trailing slashes. " + + "If not specified, pulls from the root of the remote workspace.", + ) + .option( + "-e, --environment ", + "Environment to pull from (e.g. 'production', 'staging')", + ) + .option("-v, --verbose", "Show detailed information about the operation") + .option("-q, --quiet", "Suppress output of successful files"), +).action( + handleSyncErrors(async (options: PullOptions) => { + const client = getClient(options); + + // Create a separate FileSyncer instance with log level based on verbose flag only + const fileSyncer = new FileSyncer(client, { + baseDir: options.localFilesDirectory, + verbose: options.verbose, + }); + + log("Pulling files from Humanloop...", "INFO"); + log(`Path: ${options.path || "(root)"}`, "INFO"); + log(`Environment: ${options.environment || "(default)"}`, "INFO"); + + const startTime = Date.now(); + const [successfulFiles, failedFiles] = await fileSyncer.pull( + options.path, + options.environment, + ); + const duration = Date.now() - startTime; + + // Always show operation result + const isSuccessful = failedFiles.length === 0; + log(`Pull completed in ${duration}ms`, isSuccessful ? "SUCCESS" : "ERROR"); + + // Only suppress successful files output if quiet flag is set + if (successfulFiles.length > 0 && !options.quiet) { + console.log(); // Empty line + log(`Successfully pulled ${successfulFiles.length} files:`, "SUCCESS"); + for (const file of successfulFiles) { + log(` ✓ ${file}`, "SUCCESS"); + } + } + + // Always show failed files + if (failedFiles.length > 0) { + console.log(); // Empty line + log(`Failed to pull ${failedFiles.length} files:`, "ERROR"); + for (const file of failedFiles) { + log(` ✗ ${file}`, "ERROR"); + } + } + }), +); + +program.parse(process.argv); diff --git a/src/humanloop.client.ts b/src/humanloop.client.ts index ac7cb197..998632a2 100644 --- a/src/humanloop.client.ts +++ b/src/humanloop.client.ts @@ -8,10 +8,6 @@ import { OpenAIInstrumentation } from "@traceloop/instrumentation-openai"; import { HumanloopClient as BaseHumanloopClient } from "./Client"; import { ChatMessage } from "./api"; import { Evaluations as BaseEvaluations } from "./api/resources/evaluations/client/Client"; -import { Evaluators } from "./api/resources/evaluators/client/Client"; -import { Flows } from "./api/resources/flows/client/Client"; -import { Prompts } from "./api/resources/prompts/client/Client"; -import { Tools } from "./api/resources/tools/client/Client"; import { ToolKernelRequest } from "./api/types/ToolKernelRequest"; import { flowUtilityFactory } from "./decorators/flow"; import { promptDecoratorFactory } from "./decorators/prompt"; @@ -28,7 +24,8 @@ import { } from "./evals/types"; import { HumanloopSpanExporter } from "./otel/exporter"; import { HumanloopSpanProcessor } from "./otel/processor"; -import { overloadCall, overloadLog } from "./overload"; +import { overloadClient } from "./overload"; +import { FileSyncer } from "./sync"; import { SDK_VERSION } from "./version"; const RED = "\x1b[91m"; @@ -199,17 +196,48 @@ class HumanloopTracerSingleton { } } +export interface HumanloopClientOptions extends BaseHumanloopClient.Options { + /** + * Whether to use local files for prompts and agents + */ + useLocalFiles?: boolean; + + /** + * Base directory where local prompt and agent files are stored (default: "humanloop"). + * This is relative to the current working directory. For example: + * - "humanloop" will look for files in "./humanloop/" + * - "data/humanloop" will look for files in "./data/humanloop/" + * When using paths in the API, they must be relative to this directory. For example, + * if localFilesDirectory="humanloop" and you have a file at "humanloop/samples/test.prompt", + * you would reference it as "samples/test" in your code. + */ + localFilesDirectory?: string; + + /** + * Maximum number of files to cache when useLocalFiles is true (default: DEFAULT_CACHE_SIZE). + * This parameter has no effect if useLocalFiles is false. + */ + cacheSize?: number; + + /** + * LLM provider modules to instrument. Allows the prompt decorator to spy on provider calls and log them to Humanloop + */ + instrumentProviders?: { + OpenAI?: any; + Anthropic?: any; + CohereAI?: any; + }; +} + export class HumanloopClient extends BaseHumanloopClient { protected readonly _evaluations: ExtendedEvaluations; - protected readonly _prompts_overloaded: Prompts; - protected readonly _flows_overloaded: Flows; - protected readonly _tools_overloaded: Tools; - protected readonly _evaluators_overloaded: Evaluators; protected readonly instrumentProviders: { OpenAI?: any; Anthropic?: any; CohereAI?: any; }; + protected readonly _fileSyncer: FileSyncer; + protected readonly useLocalFiles: boolean; protected get opentelemetryTracer(): Tracer { return HumanloopTracerSingleton.getInstance({ @@ -243,29 +271,32 @@ export class HumanloopClient extends BaseHumanloopClient { * const anthropic = new Anthropic({apiKey: process.env.ANTHROPIC_KEY}); * ``` */ - constructor( - _options: BaseHumanloopClient.Options & { - instrumentProviders?: { - OpenAI?: any; - Anthropic?: any; - CohereAI?: any; - }; - }, - ) { - super(_options); + constructor(options: HumanloopClientOptions = {}) { + super(options); - this.instrumentProviders = _options.instrumentProviders || {}; + this.useLocalFiles = options.useLocalFiles || false; - this._prompts_overloaded = overloadLog(super.prompts); - this._prompts_overloaded = overloadCall(this._prompts_overloaded); + // Warn user if cacheSize is non-default but useLocalFiles is false + if (!this.useLocalFiles && options.cacheSize !== undefined) { + console.warn( + `The specified cacheSize=${options.cacheSize} will have no effect because useLocalFiles=false. ` + + `File caching is only active when local files are enabled.`, + ); + } - this._tools_overloaded = overloadLog(super.tools); + this._fileSyncer = new FileSyncer(this, { + baseDir: options.localFilesDirectory || "humanloop", + cacheSize: options.cacheSize, + }); - this._flows_overloaded = overloadLog(super.flows); + this.instrumentProviders = options.instrumentProviders || {}; - this._evaluators_overloaded = overloadLog(super.evaluators); + overloadClient(super.prompts, this._fileSyncer, this.useLocalFiles); + overloadClient(super.flows, this._fileSyncer, this.useLocalFiles); + overloadClient(super.tools, this._fileSyncer, this.useLocalFiles); + overloadClient(super.evaluators, this._fileSyncer, this.useLocalFiles); - this._evaluations = new ExtendedEvaluations(_options, this); + this._evaluations = new ExtendedEvaluations(options, this); // Initialize the tracer singleton HumanloopTracerSingleton.getInstance({ @@ -359,14 +390,14 @@ ${RESET}`, * temperature: 0.5, * }); * const openaiContent = openaiResponse.choices[0].message.content; - * + * const anthropicClient = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY }); * const anthropicResponse = await anthropicClient.messages.create({ * model: "claude-3-5-sonnet-20240620", * temperature: 0.5, * }); * const anthropicContent = anthropicResponse.content; - * + * return { openaiContent, anthropicContent }; * } * }); @@ -560,23 +591,59 @@ ${RESET}`, ); } - public get evaluations(): ExtendedEvaluations { - return this._evaluations; - } - - public get prompts(): Prompts { - return this._prompts_overloaded; - } - - public get flows(): Flows { - return this._flows_overloaded; - } - - public get tools(): Tools { - return this._tools_overloaded; + /** + * Pull Prompt and Agent files from Humanloop to local filesystem. + * + * This method will: + * 1. Fetch Prompt and Agent files from your Humanloop workspace + * 2. Save them to your local filesystem (directory specified by `localFilesDirectory`, default: "humanloop") + * 3. Maintain the same directory structure as in Humanloop + * 4. Add appropriate file extensions (`.prompt` or `.agent`) + * + * The path parameter can be used in two ways: + * - If it points to a specific file (e.g. "path/to/file.prompt" or "path/to/file.agent"), only that file will be pulled + * - If it points to a directory (e.g. "path/to/directory"), all Prompt and Agent files in that directory and its subdirectories will be pulled + * - If no path is provided, all Prompt and Agent files will be pulled + * + * The operation will overwrite existing files with the latest version from Humanloop + * but will not delete local files that don't exist in the remote workspace. + * + * Currently only supports syncing Prompt and Agent files. Other file types will be skipped. + * + * For example, with the default `localFilesDirectory="humanloop"`, files will be saved as: + * ``` + * ./humanloop/ + * ├── my_project/ + * │ ├── prompts/ + * │ │ ├── my_prompt.prompt + * │ │ └── nested/ + * │ │ └── another_prompt.prompt + * │ └── agents/ + * │ └── my_agent.agent + * └── another_project/ + * └── prompts/ + * └── other_prompt.prompt + * ``` + * + * If you specify `localFilesDirectory="data/humanloop"`, files will be saved in ./data/humanloop/ instead. + * + * @param path - Optional path to either a specific file (e.g. "path/to/file.prompt") or a directory (e.g. "path/to/directory"). + * If not provided, all Prompt and Agent files will be pulled. + * @param environment - The environment to pull the files from. + * @returns An array containing two string arrays: + * - First array contains paths of successfully synced files + * - Second array contains paths of files that failed to sync (due to API errors, missing content, + * or filesystem issues) + * @throws HumanloopRuntimeError If there's an error communicating with the API + */ + public async pull( + path?: string, + environment?: string, + ): Promise<[string[], string[]]> { + return this._fileSyncer.pull(path, environment); } - public get evaluators(): Evaluators { - return this._evaluators_overloaded; + public get evaluations(): ExtendedEvaluations { + return this._evaluations; } } diff --git a/src/overload.ts b/src/overload.ts index dd66643a..5dff103b 100644 --- a/src/overload.ts +++ b/src/overload.ts @@ -1,44 +1,73 @@ +import path from "path"; + import { CreateEvaluatorLogRequest, + FileType, FlowLogRequest, - PromptCallResponse, PromptLogRequest, ToolLogRequest, } from "./api"; +import { Agents } from "./api/resources/agents/client/Client"; +import { Datasets } from "./api/resources/datasets/client/Client"; import { Evaluators } from "./api/resources/evaluators/client/Client"; import { Flows } from "./api/resources/flows/client/Client"; import { Prompts } from "./api/resources/prompts/client/Client"; import { Tools } from "./api/resources/tools/client/Client"; import { getDecoratorContext, getEvaluationContext, getTraceId } from "./context"; import { HumanloopRuntimeError } from "./error"; +import FileSyncer, { + SERIALIZABLE_FILE_TYPES, + SerializableFileType, +} from "./sync/FileSyncer"; -export function overloadLog( - client: T, +type ClientType = Flows | Agents | Prompts | Tools | Evaluators | Datasets; +type LogRequestType = + | FlowLogRequest + | PromptLogRequest + | ToolLogRequest + | CreateEvaluatorLogRequest; + +/** + * Get the file type based on the client type. + * + * @param client Client instance to check + * @returns The file type corresponding to the client, or null if not a file type that supports local files + */ +function getFileTypeFromClient(client: ClientType): SerializableFileType | null { + if (client instanceof Prompts) { + return "prompt"; + } else if (client instanceof Agents) { + return "agent"; + } else if (client instanceof Tools) { + return null; // Tools don't support local files + } else if (client instanceof Flows) { + return null; // Flows don't support local files + } else if (client instanceof Evaluators) { + return null; // Evaluators don't support local files + } else if (client instanceof Datasets) { + return null; // Datasets don't support local files + } else { + throw new HumanloopRuntimeError( + // @ts-ignore Client shouldn't be of a type other than those checked above, but included as a safeguard + `Unsupported client type: ${client.constructor.name}`, + ); + } +} + +/** + * Handle tracing context for both log and call methods. + * + * @param request The API request + * @param client The client making the request + * @returns The updated request with tracing context applied + */ +function handleTracingContext( + request: T, + client: ClientType, ): T { - const originalLog = client.log.bind(client); - - const _overloadedLog = async ( - request: T extends Flows - ? FlowLogRequest - : T extends Prompts - ? PromptLogRequest - : T extends Tools - ? ToolLogRequest - : T extends Evaluators - ? CreateEvaluatorLogRequest - : never, - options?: T extends Flows - ? Flows.RequestOptions - : T extends Prompts - ? Prompts.RequestOptions - : T extends Tools - ? Tools.RequestOptions - : T extends Evaluators - ? Evaluators.RequestOptions - : never, - ) => { - const traceId = getTraceId(); - if (traceId !== undefined && client instanceof Flows) { + const traceId = getTraceId(); + if (traceId !== undefined) { + if (client instanceof Flows) { const context = getDecoratorContext(); if (context === undefined) { throw new HumanloopRuntimeError( @@ -46,85 +75,291 @@ export function overloadLog( ); } throw new HumanloopRuntimeError( - `Using flows.log() is not allowed: Flow decorator for File ${context.path} manages the tracing and trace completion.`, + `Using \`flows.log()\` is not allowed: Flow decorator ` + + `for File ${context.path} manages the tracing and trace completion.`, ); } - if (traceId !== undefined) { - if ("traceParentId" in request) { - console.warn( - "Ignoring trace_parent_id argument: the Flow decorator manages tracing.", + if ("traceParentId" in request) { + console.warn( + "Ignoring trace_parent_id argument: the Flow decorator manages tracing.", + ); + } + return { + ...request, + traceParentId: traceId, + }; + } + return request; +} + +/** + * Load prompt/agent file content from local filesystem into API request. + * + * Retrieves the file content at the specified path and adds it to request + * under the appropriate field ('prompt' or 'agent'), allowing local files + * to be used in API calls instead of fetching from Humanloop API. + * + * @param request API request object + * @param client Client instance making the call + * @param fileSyncer FileSyncer handling local file operations + * @returns Updated request with file content in the appropriate field + * @throws HumanloopRuntimeError On validation or file loading failures. + * For example, an invalid path format (absolute paths, leading/trailing slashes, etc.) + * or a file not being found. + */ +function handleLocalFiles( + request: T, + client: ClientType, + fileSyncer: FileSyncer, +): T { + // Validate request has either id or path, but not both + if ("id" in request && "path" in request) { + throw new HumanloopRuntimeError("Can only specify one of `id` or `path`"); + } + if (!("id" in request) && !("path" in request)) { + throw new HumanloopRuntimeError("Must specify either `id` or `path`"); + } + + // If using id, we can't use local files + if ("id" in request) { + return request; + } + + const filePath = request.path?.trim(); + if (!filePath) { + throw new HumanloopRuntimeError("Path cannot be empty"); + } + + // First check for path format issues (absolute paths or leading/trailing slashes) + const normalizedPath = filePath.trim().replace(/^\/+|\/+$/g, ""); + if (path.isAbsolute(filePath) || filePath !== normalizedPath) { + throw new HumanloopRuntimeError( + `Path '${filePath}' format is invalid. ` + + `Paths must follow the standard API format 'path/to/resource' without leading or trailing slashes. ` + + `Please use '${normalizedPath}' instead.`, + ); + } + + // Then check for file extensions + if (fileSyncer.isFile(filePath)) { + const pathWithoutExtension = path.join( + path.dirname(filePath), + path.basename(filePath, path.extname(filePath)), + ); + throw new HumanloopRuntimeError( + `Path '${filePath}' should not include any file extensions in API calls. ` + + `When referencing files via the \`path\` parameter, use the path without extensions: '${pathWithoutExtension}'. ` + + `Note: File extensions are only used when pulling specific files via the CLI.`, + ); + } + + // Check if version_id or environment is specified + const useRemote = "versionId" in request || "environment" in request; + if (useRemote) { + throw new HumanloopRuntimeError( + `Cannot use local file for \`${filePath}\` as version_id or environment was specified. ` + + `Please either remove version_id/environment to use local files, or set use_local_files=False to use remote files.`, + ); + } + + const fileType = getFileTypeFromClient(client); + if (!fileType || !SERIALIZABLE_FILE_TYPES.has(fileType)) { + throw new HumanloopRuntimeError( + `Local files are not supported for \`${fileType?.charAt(0).toUpperCase()}${fileType?.slice(1)}\` files: '${filePath}'.`, + ); + } + + // If file_type is already specified in request, prioritize user-provided value + if (fileType in request && typeof request[fileType as keyof T] !== "string") { + console.warn( + `Ignoring local file for \`${filePath}\` as ${fileType} parameters were directly provided. ` + + `Using provided parameters instead.`, + ); + return request; + } + + try { + const fileContent = fileSyncer.getFileContent(filePath, fileType); + return { + ...request, + [fileType]: fileContent, + } as T; + } catch (error) { + throw new HumanloopRuntimeError( + `Failed to use local file for \`${filePath}\`: ${error}`, + ); + } +} + +/** + * Handle evaluation context for logging. + * + * @param request The API request + * @returns Tuple of [updated request, callback function] + */ +function handleEvaluationContext( + request: T, +): [T, ((id: string) => Promise) | null] { + const evaluationContext = getEvaluationContext(); + if (evaluationContext !== undefined) { + const [newRequest, callback] = evaluationContext.logArgsWithContext({ + logArgs: request, + forOtel: true, + path: request.path, + }); + return [newRequest as T, callback]; + } + return [request, null]; +} + +/** + * Overloaded log method implementation. + * Handles tracing context, local file loading, and evaluation context. + * + * @param self The client instance + * @param fileSyncer Optional FileSyncer for local file operations + * @param useLocalFiles Whether to use local files + * @param request The log request + * @param options Additional options + * @returns The log response + */ +async function overloadedLog( + self: T, + fileSyncer: FileSyncer | undefined, + useLocalFiles: boolean, + request: LogRequestType, + options?: any, +) { + try { + // Special handling for flows - prevent direct log usage + if (self instanceof Flows && getTraceId() !== undefined) { + const context = getDecoratorContext(); + if (context === undefined) { + throw new HumanloopRuntimeError( + "Internal error: trace_id context is set outside a decorator context.", ); } - request = { - ...request, - traceParentId: traceId, - }; + throw new HumanloopRuntimeError( + `Using \`flows.log()\` is not allowed: Flow decorator ` + + `for File ${context.path} manages the tracing and trace completion.`, + ); } - const evaluationContext = getEvaluationContext(); - if (evaluationContext !== undefined) { - const [kwargsEval, evalCallback] = evaluationContext.logArgsWithContext({ - logArgs: request, - forOtel: true, - path: request.path, - }); - try { - // @ts-ignore Polymorphism alarms the type checker - const response = await originalLog(kwargsEval, options); - if (evalCallback !== null) { - await evalCallback(response.id); - } - return response; - } catch (e) { - throw new HumanloopRuntimeError(String(e)); - } - } else { - try { - // @ts-ignore Polymorphism alarms the type checker - return await originalLog(request, options); - } catch (e) { - throw new HumanloopRuntimeError(String(e)); + request = handleTracingContext(request, self); + + // Handle loading files from local filesystem when using Prompt and Agent clients + if ( + useLocalFiles && + (self instanceof Prompts || self instanceof Agents) + ) { + if (!fileSyncer) { + throw new HumanloopRuntimeError( + "SDK initialization error: fileSyncer is missing but required for local file operations. " + + "This is likely a bug in the SDK initialization - please report this issue to the Humanloop team.", + ); } + request = handleLocalFiles(request, self, fileSyncer); } - }; - - // @ts-ignore - client.log = _overloadedLog.bind(client); - // @ts-ignore - client._log = originalLog.bind(client); - return client; + const [evalRequest, evalCallback] = handleEvaluationContext(request); + const response = await (self as any)._log(evalRequest, options); + + if (evalCallback !== null) { + await evalCallback(response.id); + } + return response; + } catch (error) { + if (error instanceof HumanloopRuntimeError) { + throw error; + } + throw new HumanloopRuntimeError(String(error)); + } } -export function overloadCall(client: Prompts): Prompts { - const originalCall = client.call.bind(client); - - const _overloadedCall = async ( - request: PromptLogRequest, - options?: Prompts.RequestOptions, - ): Promise => { - const traceId = getTraceId(); - if (traceId !== undefined) { - if ("traceParentId" in request) { - console.warn( - "Ignoring trace_parent_id argument: the Flow decorator manages tracing.", +/** + * Overloaded call method implementation. + * Handles tracing context and local file loading. + * + * @param self The client instance + * @param fileSyncer Optional FileSyncer for local file operations + * @param useLocalFiles Whether to use local files + * @param request The call request + * @param options Additional options + * @returns The call response + */ +async function overloadedCall( + self: T, + fileSyncer: FileSyncer | undefined, + useLocalFiles: boolean, + request: any, + options?: any, +) { + try { + request = handleTracingContext(request, self); + + // If `useLocalFiles` flag is True, we should use local file content for + // `call` operations on Prompt and Agent clients. + if (useLocalFiles && (self instanceof Prompts || self instanceof Agents)) { + if (!fileSyncer) { + throw new HumanloopRuntimeError( + "fileSyncer is required for clients that support call operations", ); } - request = { - ...request, - traceParentId: traceId, - }; + request = handleLocalFiles(request, self, fileSyncer); } - - try { - return await originalCall(request, options); - } catch (e) { - throw new HumanloopRuntimeError(String(e)); + + return await (self as any)._call(request, options); + } catch (error) { + if (error instanceof HumanloopRuntimeError) { + throw error; } - }; + throw new HumanloopRuntimeError(String(error)); + } +} - client.call = _overloadedCall.bind(client); +/** + * Overloads client methods to add tracing, local file handling, and evaluation context. + * + * This function enhances clients by: + * 1. Adding tracing context to requests for Flow integration + * 2. Supporting local file loading for Prompt and Agent clients + * 3. Handling evaluation context for logging + * + * @param client The client to overload + * @param fileSyncer Optional FileSyncer for local file operations + * @param useLocalFiles Whether to use local files (default: false) + * @returns The overloaded client + * @throws HumanloopRuntimeError If fileSyncer is missing but required + */ +export function overloadClient( + client: T, + fileSyncer?: FileSyncer, + useLocalFiles: boolean = false, +): T { + // Handle log method if it exists + if ("log" in client) { + const originalLog = (client as any).log.bind(client); + (client as any)._log = originalLog; + (client as any).log = async (request: LogRequestType, options?: any) => { + return overloadedLog(client, fileSyncer, useLocalFiles, request, options); + }; + } + + // Handle call method if it exists (for Prompts and Agents) + if (client instanceof Prompts || client instanceof Agents) { + // Verify fileSyncer is provided if needed + if (fileSyncer === undefined && useLocalFiles) { + console.error("fileSyncer is undefined but client has call method and useLocalFiles=%s", useLocalFiles); + throw new HumanloopRuntimeError("fileSyncer is required for clients that support call operations"); + } + + const originalCall = (client as any).call.bind(client); + (client as any)._call = originalCall; + (client as any).call = async (request: any, options?: any) => { + return overloadedCall(client, fileSyncer, useLocalFiles, request, options); + }; + } return client; -} +} \ No newline at end of file diff --git a/src/pathUtils.ts b/src/pathUtils.ts new file mode 100644 index 00000000..5a2ba125 --- /dev/null +++ b/src/pathUtils.ts @@ -0,0 +1,47 @@ +import * as path from "path"; + +/** + * Normalize a path to the standard Humanloop API format. + * + * This function is primarily used when interacting with the Humanloop API to ensure paths + * follow the standard format: 'path/to/resource' without leading/trailing slashes. + * It's used when pulling files from Humanloop to local filesystem (see FileSyncer.pull) + * + * The function: + * - Converts Windows backslashes to forward slashes + * - Normalizes consecutive slashes + * - Optionally strips file extensions (e.g. .prompt, .agent) + * - Removes leading/trailing slashes to match API conventions + * + * Leading/trailing slashes are stripped because the Humanloop API expects paths in the + * format 'path/to/resource' without them. This is consistent with how the API stores + * and references files, and ensures paths work correctly in both API calls and local + * filesystem operations. + * + * @param pathStr - The path to normalize. Can be a Windows or Unix-style path. + * @param stripExtension - If true, removes the file extension (e.g. .prompt, .agent) + * @returns Normalized path string in the format 'path/to/resource' + */ +export function normalizePath( + pathStr: string, + stripExtension: boolean = false, +): string { + // Convert Windows backslashes to forward slashes + let normalizedPath = pathStr.replace(/\\/g, "/"); + + // Use path.posix to handle path normalization (handles consecutive slashes and . /..) + normalizedPath = path.posix.normalize(normalizedPath); + + // Remove leading/trailing slashes + normalizedPath = normalizedPath.replace(/^\/+|\/+$/g, ""); + + // Strip extension if requested + if (stripExtension && normalizedPath.includes(".")) { + normalizedPath = path.posix.join( + path.posix.dirname(normalizedPath), + path.posix.basename(normalizedPath, path.posix.extname(normalizedPath)), + ); + } + + return normalizedPath; +} diff --git a/src/serialization/resources/agents/client/requests/AgentLogRequest.ts b/src/serialization/resources/agents/client/requests/AgentLogRequest.ts index 84babd7f..2e251af8 100644 --- a/src/serialization/resources/agents/client/requests/AgentLogRequest.ts +++ b/src/serialization/resources/agents/client/requests/AgentLogRequest.ts @@ -7,7 +7,7 @@ import * as Humanloop from "../../../../../api/index"; import * as core from "../../../../../core"; import { ChatMessage } from "../../../../types/ChatMessage"; import { AgentLogRequestToolChoice } from "../../types/AgentLogRequestToolChoice"; -import { AgentKernelRequest } from "../../../../types/AgentKernelRequest"; +import { AgentLogRequestAgent } from "../../types/AgentLogRequestAgent"; import { LogStatus } from "../../../../types/LogStatus"; export const AgentLogRequest: core.serialization.Schema< @@ -26,7 +26,7 @@ export const AgentLogRequest: core.serialization.Schema< finishReason: core.serialization.property("finish_reason", core.serialization.string().optional()), messages: core.serialization.list(ChatMessage).optional(), toolChoice: core.serialization.property("tool_choice", AgentLogRequestToolChoice.optional()), - agent: AgentKernelRequest.optional(), + agent: AgentLogRequestAgent.optional(), startTime: core.serialization.property("start_time", core.serialization.date().optional()), endTime: core.serialization.property("end_time", core.serialization.date().optional()), output: core.serialization.string().optional(), @@ -68,7 +68,7 @@ export declare namespace AgentLogRequest { finish_reason?: string | null; messages?: ChatMessage.Raw[] | null; tool_choice?: AgentLogRequestToolChoice.Raw | null; - agent?: AgentKernelRequest.Raw | null; + agent?: AgentLogRequestAgent.Raw | null; start_time?: string | null; end_time?: string | null; output?: string | null; diff --git a/src/serialization/resources/agents/client/requests/AgentsCallRequest.ts b/src/serialization/resources/agents/client/requests/AgentsCallRequest.ts index a64a7932..e8a18d42 100644 --- a/src/serialization/resources/agents/client/requests/AgentsCallRequest.ts +++ b/src/serialization/resources/agents/client/requests/AgentsCallRequest.ts @@ -7,7 +7,7 @@ import * as Humanloop from "../../../../../api/index"; import * as core from "../../../../../core"; import { ChatMessage } from "../../../../types/ChatMessage"; import { AgentsCallRequestToolChoice } from "../../types/AgentsCallRequestToolChoice"; -import { AgentKernelRequest } from "../../../../types/AgentKernelRequest"; +import { AgentsCallRequestAgent } from "../../types/AgentsCallRequestAgent"; import { LogStatus } from "../../../../types/LogStatus"; import { ProviderApiKeys } from "../../../../types/ProviderApiKeys"; @@ -19,7 +19,7 @@ export const AgentsCallRequest: core.serialization.Schema< id: core.serialization.string().optional(), messages: core.serialization.list(ChatMessage).optional(), toolChoice: core.serialization.property("tool_choice", AgentsCallRequestToolChoice.optional()), - agent: AgentKernelRequest.optional(), + agent: AgentsCallRequestAgent.optional(), inputs: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(), source: core.serialization.string().optional(), metadata: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(), @@ -46,7 +46,7 @@ export declare namespace AgentsCallRequest { id?: string | null; messages?: ChatMessage.Raw[] | null; tool_choice?: AgentsCallRequestToolChoice.Raw | null; - agent?: AgentKernelRequest.Raw | null; + agent?: AgentsCallRequestAgent.Raw | null; inputs?: Record | null; source?: string | null; metadata?: Record | null; diff --git a/src/serialization/resources/agents/client/requests/AgentsCallStreamRequest.ts b/src/serialization/resources/agents/client/requests/AgentsCallStreamRequest.ts index b0557ace..7ca3e451 100644 --- a/src/serialization/resources/agents/client/requests/AgentsCallStreamRequest.ts +++ b/src/serialization/resources/agents/client/requests/AgentsCallStreamRequest.ts @@ -7,7 +7,7 @@ import * as Humanloop from "../../../../../api/index"; import * as core from "../../../../../core"; import { ChatMessage } from "../../../../types/ChatMessage"; import { AgentsCallStreamRequestToolChoice } from "../../types/AgentsCallStreamRequestToolChoice"; -import { AgentKernelRequest } from "../../../../types/AgentKernelRequest"; +import { AgentsCallStreamRequestAgent } from "../../types/AgentsCallStreamRequestAgent"; import { LogStatus } from "../../../../types/LogStatus"; import { ProviderApiKeys } from "../../../../types/ProviderApiKeys"; @@ -19,7 +19,7 @@ export const AgentsCallStreamRequest: core.serialization.Schema< id: core.serialization.string().optional(), messages: core.serialization.list(ChatMessage).optional(), toolChoice: core.serialization.property("tool_choice", AgentsCallStreamRequestToolChoice.optional()), - agent: AgentKernelRequest.optional(), + agent: AgentsCallStreamRequestAgent.optional(), inputs: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(), source: core.serialization.string().optional(), metadata: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(), @@ -49,7 +49,7 @@ export declare namespace AgentsCallStreamRequest { id?: string | null; messages?: ChatMessage.Raw[] | null; tool_choice?: AgentsCallStreamRequestToolChoice.Raw | null; - agent?: AgentKernelRequest.Raw | null; + agent?: AgentsCallStreamRequestAgent.Raw | null; inputs?: Record | null; source?: string | null; metadata?: Record | null; diff --git a/src/serialization/resources/agents/types/AgentLogRequestAgent.ts b/src/serialization/resources/agents/types/AgentLogRequestAgent.ts new file mode 100644 index 00000000..f77f6e2e --- /dev/null +++ b/src/serialization/resources/agents/types/AgentLogRequestAgent.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as Humanloop from "../../../../api/index"; +import * as core from "../../../../core"; +import { AgentKernelRequest } from "../../../types/AgentKernelRequest"; + +export const AgentLogRequestAgent: core.serialization.Schema< + serializers.AgentLogRequestAgent.Raw, + Humanloop.AgentLogRequestAgent +> = core.serialization.undiscriminatedUnion([AgentKernelRequest, core.serialization.string()]); + +export declare namespace AgentLogRequestAgent { + export type Raw = AgentKernelRequest.Raw | string; +} diff --git a/src/serialization/resources/agents/types/AgentsCallRequestAgent.ts b/src/serialization/resources/agents/types/AgentsCallRequestAgent.ts new file mode 100644 index 00000000..aabc0c14 --- /dev/null +++ b/src/serialization/resources/agents/types/AgentsCallRequestAgent.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as Humanloop from "../../../../api/index"; +import * as core from "../../../../core"; +import { AgentKernelRequest } from "../../../types/AgentKernelRequest"; + +export const AgentsCallRequestAgent: core.serialization.Schema< + serializers.AgentsCallRequestAgent.Raw, + Humanloop.AgentsCallRequestAgent +> = core.serialization.undiscriminatedUnion([AgentKernelRequest, core.serialization.string()]); + +export declare namespace AgentsCallRequestAgent { + export type Raw = AgentKernelRequest.Raw | string; +} diff --git a/src/serialization/resources/agents/types/AgentsCallStreamRequestAgent.ts b/src/serialization/resources/agents/types/AgentsCallStreamRequestAgent.ts new file mode 100644 index 00000000..61f637db --- /dev/null +++ b/src/serialization/resources/agents/types/AgentsCallStreamRequestAgent.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as Humanloop from "../../../../api/index"; +import * as core from "../../../../core"; +import { AgentKernelRequest } from "../../../types/AgentKernelRequest"; + +export const AgentsCallStreamRequestAgent: core.serialization.Schema< + serializers.AgentsCallStreamRequestAgent.Raw, + Humanloop.AgentsCallStreamRequestAgent +> = core.serialization.undiscriminatedUnion([AgentKernelRequest, core.serialization.string()]); + +export declare namespace AgentsCallStreamRequestAgent { + export type Raw = AgentKernelRequest.Raw | string; +} diff --git a/src/serialization/resources/agents/types/index.ts b/src/serialization/resources/agents/types/index.ts index 8a8a004f..1a1043c1 100644 --- a/src/serialization/resources/agents/types/index.ts +++ b/src/serialization/resources/agents/types/index.ts @@ -1,6 +1,9 @@ export * from "./AgentLogRequestToolChoice"; +export * from "./AgentLogRequestAgent"; export * from "./AgentsCallStreamRequestToolChoice"; +export * from "./AgentsCallStreamRequestAgent"; export * from "./AgentsCallRequestToolChoice"; +export * from "./AgentsCallRequestAgent"; export * from "./AgentRequestTemplate"; export * from "./AgentRequestStop"; export * from "./AgentRequestReasoningEffort"; diff --git a/src/serialization/resources/files/client/requests/BodyRetrieveByPathFilesRetrieveByPathPost.ts b/src/serialization/resources/files/client/requests/BodyRetrieveByPathFilesRetrieveByPathPost.ts index fefe408b..1f712089 100644 --- a/src/serialization/resources/files/client/requests/BodyRetrieveByPathFilesRetrieveByPathPost.ts +++ b/src/serialization/resources/files/client/requests/BodyRetrieveByPathFilesRetrieveByPathPost.ts @@ -8,7 +8,7 @@ import * as core from "../../../../../core"; export const BodyRetrieveByPathFilesRetrieveByPathPost: core.serialization.Schema< serializers.BodyRetrieveByPathFilesRetrieveByPathPost.Raw, - Omit + Omit > = core.serialization.object({ path: core.serialization.string(), }); diff --git a/src/serialization/resources/prompts/client/requests/PromptLogRequest.ts b/src/serialization/resources/prompts/client/requests/PromptLogRequest.ts index 4638bf24..832aef92 100644 --- a/src/serialization/resources/prompts/client/requests/PromptLogRequest.ts +++ b/src/serialization/resources/prompts/client/requests/PromptLogRequest.ts @@ -7,7 +7,7 @@ import * as Humanloop from "../../../../../api/index"; import * as core from "../../../../../core"; import { ChatMessage } from "../../../../types/ChatMessage"; import { PromptLogRequestToolChoice } from "../../types/PromptLogRequestToolChoice"; -import { PromptKernelRequest } from "../../../../types/PromptKernelRequest"; +import { PromptLogRequestPrompt } from "../../types/PromptLogRequestPrompt"; import { LogStatus } from "../../../../types/LogStatus"; export const PromptLogRequest: core.serialization.Schema< @@ -26,7 +26,7 @@ export const PromptLogRequest: core.serialization.Schema< finishReason: core.serialization.property("finish_reason", core.serialization.string().optional()), messages: core.serialization.list(ChatMessage).optional(), toolChoice: core.serialization.property("tool_choice", PromptLogRequestToolChoice.optional()), - prompt: PromptKernelRequest.optional(), + prompt: PromptLogRequestPrompt.optional(), startTime: core.serialization.property("start_time", core.serialization.date().optional()), endTime: core.serialization.property("end_time", core.serialization.date().optional()), output: core.serialization.string().optional(), @@ -68,7 +68,7 @@ export declare namespace PromptLogRequest { finish_reason?: string | null; messages?: ChatMessage.Raw[] | null; tool_choice?: PromptLogRequestToolChoice.Raw | null; - prompt?: PromptKernelRequest.Raw | null; + prompt?: PromptLogRequestPrompt.Raw | null; start_time?: string | null; end_time?: string | null; output?: string | null; diff --git a/src/serialization/resources/prompts/client/requests/PromptsCallRequest.ts b/src/serialization/resources/prompts/client/requests/PromptsCallRequest.ts index 33e757a3..08802ed1 100644 --- a/src/serialization/resources/prompts/client/requests/PromptsCallRequest.ts +++ b/src/serialization/resources/prompts/client/requests/PromptsCallRequest.ts @@ -7,7 +7,7 @@ import * as Humanloop from "../../../../../api/index"; import * as core from "../../../../../core"; import { ChatMessage } from "../../../../types/ChatMessage"; import { PromptsCallRequestToolChoice } from "../../types/PromptsCallRequestToolChoice"; -import { PromptKernelRequest } from "../../../../types/PromptKernelRequest"; +import { PromptsCallRequestPrompt } from "../../types/PromptsCallRequestPrompt"; import { LogStatus } from "../../../../types/LogStatus"; import { ProviderApiKeys } from "../../../../types/ProviderApiKeys"; @@ -19,7 +19,7 @@ export const PromptsCallRequest: core.serialization.Schema< id: core.serialization.string().optional(), messages: core.serialization.list(ChatMessage).optional(), toolChoice: core.serialization.property("tool_choice", PromptsCallRequestToolChoice.optional()), - prompt: PromptKernelRequest.optional(), + prompt: PromptsCallRequestPrompt.optional(), inputs: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(), source: core.serialization.string().optional(), metadata: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(), @@ -45,7 +45,7 @@ export declare namespace PromptsCallRequest { id?: string | null; messages?: ChatMessage.Raw[] | null; tool_choice?: PromptsCallRequestToolChoice.Raw | null; - prompt?: PromptKernelRequest.Raw | null; + prompt?: PromptsCallRequestPrompt.Raw | null; inputs?: Record | null; source?: string | null; metadata?: Record | null; diff --git a/src/serialization/resources/prompts/client/requests/PromptsCallStreamRequest.ts b/src/serialization/resources/prompts/client/requests/PromptsCallStreamRequest.ts index 905d9169..9a8f9648 100644 --- a/src/serialization/resources/prompts/client/requests/PromptsCallStreamRequest.ts +++ b/src/serialization/resources/prompts/client/requests/PromptsCallStreamRequest.ts @@ -7,7 +7,7 @@ import * as Humanloop from "../../../../../api/index"; import * as core from "../../../../../core"; import { ChatMessage } from "../../../../types/ChatMessage"; import { PromptsCallStreamRequestToolChoice } from "../../types/PromptsCallStreamRequestToolChoice"; -import { PromptKernelRequest } from "../../../../types/PromptKernelRequest"; +import { PromptsCallStreamRequestPrompt } from "../../types/PromptsCallStreamRequestPrompt"; import { LogStatus } from "../../../../types/LogStatus"; import { ProviderApiKeys } from "../../../../types/ProviderApiKeys"; @@ -19,7 +19,7 @@ export const PromptsCallStreamRequest: core.serialization.Schema< id: core.serialization.string().optional(), messages: core.serialization.list(ChatMessage).optional(), toolChoice: core.serialization.property("tool_choice", PromptsCallStreamRequestToolChoice.optional()), - prompt: PromptKernelRequest.optional(), + prompt: PromptsCallStreamRequestPrompt.optional(), inputs: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(), source: core.serialization.string().optional(), metadata: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(), @@ -48,7 +48,7 @@ export declare namespace PromptsCallStreamRequest { id?: string | null; messages?: ChatMessage.Raw[] | null; tool_choice?: PromptsCallStreamRequestToolChoice.Raw | null; - prompt?: PromptKernelRequest.Raw | null; + prompt?: PromptsCallStreamRequestPrompt.Raw | null; inputs?: Record | null; source?: string | null; metadata?: Record | null; diff --git a/src/serialization/resources/prompts/types/PromptLogRequestPrompt.ts b/src/serialization/resources/prompts/types/PromptLogRequestPrompt.ts new file mode 100644 index 00000000..792f5b7d --- /dev/null +++ b/src/serialization/resources/prompts/types/PromptLogRequestPrompt.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as Humanloop from "../../../../api/index"; +import * as core from "../../../../core"; +import { PromptKernelRequest } from "../../../types/PromptKernelRequest"; + +export const PromptLogRequestPrompt: core.serialization.Schema< + serializers.PromptLogRequestPrompt.Raw, + Humanloop.PromptLogRequestPrompt +> = core.serialization.undiscriminatedUnion([PromptKernelRequest, core.serialization.string()]); + +export declare namespace PromptLogRequestPrompt { + export type Raw = PromptKernelRequest.Raw | string; +} diff --git a/src/serialization/resources/prompts/types/PromptsCallRequestPrompt.ts b/src/serialization/resources/prompts/types/PromptsCallRequestPrompt.ts new file mode 100644 index 00000000..1053bfaf --- /dev/null +++ b/src/serialization/resources/prompts/types/PromptsCallRequestPrompt.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as Humanloop from "../../../../api/index"; +import * as core from "../../../../core"; +import { PromptKernelRequest } from "../../../types/PromptKernelRequest"; + +export const PromptsCallRequestPrompt: core.serialization.Schema< + serializers.PromptsCallRequestPrompt.Raw, + Humanloop.PromptsCallRequestPrompt +> = core.serialization.undiscriminatedUnion([PromptKernelRequest, core.serialization.string()]); + +export declare namespace PromptsCallRequestPrompt { + export type Raw = PromptKernelRequest.Raw | string; +} diff --git a/src/serialization/resources/prompts/types/PromptsCallStreamRequestPrompt.ts b/src/serialization/resources/prompts/types/PromptsCallStreamRequestPrompt.ts new file mode 100644 index 00000000..3c58225f --- /dev/null +++ b/src/serialization/resources/prompts/types/PromptsCallStreamRequestPrompt.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as serializers from "../../../index"; +import * as Humanloop from "../../../../api/index"; +import * as core from "../../../../core"; +import { PromptKernelRequest } from "../../../types/PromptKernelRequest"; + +export const PromptsCallStreamRequestPrompt: core.serialization.Schema< + serializers.PromptsCallStreamRequestPrompt.Raw, + Humanloop.PromptsCallStreamRequestPrompt +> = core.serialization.undiscriminatedUnion([PromptKernelRequest, core.serialization.string()]); + +export declare namespace PromptsCallStreamRequestPrompt { + export type Raw = PromptKernelRequest.Raw | string; +} diff --git a/src/serialization/resources/prompts/types/index.ts b/src/serialization/resources/prompts/types/index.ts index 8265b2f3..f8045c03 100644 --- a/src/serialization/resources/prompts/types/index.ts +++ b/src/serialization/resources/prompts/types/index.ts @@ -1,7 +1,10 @@ export * from "./PromptLogRequestToolChoice"; +export * from "./PromptLogRequestPrompt"; export * from "./PromptLogUpdateRequestToolChoice"; export * from "./PromptsCallStreamRequestToolChoice"; +export * from "./PromptsCallStreamRequestPrompt"; export * from "./PromptsCallRequestToolChoice"; +export * from "./PromptsCallRequestPrompt"; export * from "./PromptRequestTemplate"; export * from "./PromptRequestStop"; export * from "./PromptRequestReasoningEffort"; diff --git a/src/serialization/types/AgentResponse.ts b/src/serialization/types/AgentResponse.ts index f9b96ccf..f99e69dc 100644 --- a/src/serialization/types/AgentResponse.ts +++ b/src/serialization/types/AgentResponse.ts @@ -68,6 +68,7 @@ export const AgentResponse: core.serialization.ObjectSchema = +export const FileSortBy: core.serialization.Schema = core.serialization.enum_(["created_at", "updated_at", "name"]); -export declare namespace ProjectSortBy { +export declare namespace FileSortBy { export type Raw = "created_at" | "updated_at" | "name"; } diff --git a/src/serialization/types/PopulateTemplateResponse.ts b/src/serialization/types/PopulateTemplateResponse.ts index 89574558..ceb42436 100644 --- a/src/serialization/types/PopulateTemplateResponse.ts +++ b/src/serialization/types/PopulateTemplateResponse.ts @@ -72,6 +72,7 @@ export const PopulateTemplateResponse: core.serialization.ObjectSchema< "evaluator_aggregates", core.serialization.list(EvaluatorAggregate).optional(), ), + rawFileContent: core.serialization.property("raw_file_content", core.serialization.string().optional()), populatedTemplate: core.serialization.property( "populated_template", PopulateTemplateResponsePopulatedTemplate.optional(), @@ -120,6 +121,7 @@ export declare namespace PopulateTemplateResponse { inputs: InputResponse.Raw[]; evaluators?: serializers.MonitoringEvaluatorResponse.Raw[] | null; evaluator_aggregates?: EvaluatorAggregate.Raw[] | null; + raw_file_content?: string | null; populated_template?: PopulateTemplateResponsePopulatedTemplate.Raw | null; } } diff --git a/src/serialization/types/PromptResponse.ts b/src/serialization/types/PromptResponse.ts index 04764187..481fa317 100644 --- a/src/serialization/types/PromptResponse.ts +++ b/src/serialization/types/PromptResponse.ts @@ -69,6 +69,7 @@ export const PromptResponse: core.serialization.ObjectSchema([ + "prompt", + "agent", +]); + +export interface FileSyncerOptions { + baseDir?: string; + cacheSize?: number; + verbose?: boolean; +} + +// Simple logging with color and verbosity control +const LogType = { + DEBUG: "\x1b[90m", // gray + INFO: "\x1b[96m", // cyan + WARN: "\x1b[93m", // yellow + ERROR: "\x1b[91m", // red + RESET: "\x1b[0m", +} as const; + +function log( + message: string, + type: keyof typeof LogType, + verbose: boolean = false, +): void { + // Only show debug/info if verbose is true + if ((type === "DEBUG" || type === "INFO") && !verbose) return; + console.log(`${LogType[type]}${message}${LogType.RESET}`); +} + +/** + * Format API error messages to be more user-friendly. + */ +function formatApiError(error: Error, verbose: boolean = false): string { + const errorMsg = error.message || String(error); + try { + const detail = JSON.parse(errorMsg); + if (typeof detail === "string") { + return detail; + } else if (typeof detail === "object") { + return detail.description || detail.msg || errorMsg; + } + return errorMsg; + } catch (e) { + log(`Failed to parse error message: ${e}`, "DEBUG", verbose); + return errorMsg; + } +} + +/** + * Client for synchronizing Prompt and Agent files between Humanloop workspace and local filesystem. + * + * This client enables a local development workflow by: + * 1. Pulling files from Humanloop workspace to local filesystem + * 2. Maintaining the same directory structure locally as in Humanloop + * 3. Storing files in human-readable, version-control friendly formats (.prompt and .agent) + * 4. Supporting local file access in the SDK when configured with use_local_files=true + * + * Files maintain their relative paths from the Humanloop workspace (with appropriate extensions added), + * allowing for seamless reference between local and remote environments using the same path identifiers. + */ +export default class FileSyncer { + // Default page size for API pagination when listing Files + private static readonly PAGE_SIZE = 100; + + private readonly client: HumanloopClient; + private readonly baseDir: string; + private readonly cacheSize: number; + private readonly fileContentCache: LRUCache; + private readonly verbose: boolean; + + constructor(client: HumanloopClient, options: FileSyncerOptions = {}) { + this.client = client; + this.baseDir = options.baseDir || "humanloop"; + this.cacheSize = options.cacheSize || DEFAULT_CACHE_SIZE; + this.fileContentCache = new LRUCache(this.cacheSize); + this.verbose = options.verbose || false; + } + + /** + * Implementation of get_file_content without the cache decorator. + * + * This is the actual implementation that gets wrapped by LRU cache. + * + * @param filePath The API path to the file (e.g. `path/to/file`) + * @param fileType The type of file to get the content of (SerializableFileType) + * @returns The raw file content + * @throws HumanloopRuntimeError If the file doesn't exist or can't be read + */ + private _getFileContentImplementation( + filePath: string, + fileType: SerializableFileType, + ): string { + const fullPath = path.join(this.baseDir, `${filePath}.${fileType}`); + try { + // Read the raw file content + const fileContent = fs.readFileSync(fullPath, "utf8"); + log(`Using local file content from ${fullPath}`, "DEBUG", this.verbose); + return fileContent; + } catch (error) { + throw new HumanloopRuntimeError( + `Failed to read ${fileType} ${filePath} from disk: ${error}`, + ); + } + } + + /** + * Get the raw file content of a file from cache or filesystem. + * + * This method uses an LRU cache to store file contents. When the cache is full, + * the least recently accessed files are automatically removed to make space. + * + * @param filePath The normalized path to the file (without extension) + * @param fileType The type of file (Prompt or Agent) + * @returns The raw file content + * @throws HumanloopRuntimeError If the file doesn't exist or can't be read + */ + public getFileContent(filePath: string, fileType: SerializableFileType): string { + const cacheKey = `${filePath}:${fileType}`; + + // Check if in cache + const cachedContent = this.fileContentCache.get(cacheKey); + if (cachedContent !== undefined) { + log( + `Using cached file content for ${filePath}.${fileType}`, + "DEBUG", + this.verbose, + ); + return cachedContent; + } + + // Not in cache, get from filesystem + const content = this._getFileContentImplementation(filePath, fileType); + + // Add to cache + this.fileContentCache.set(cacheKey, content); + + return content; + } + + /** + * Clear the LRU cache. + */ + public clearCache(): void { + this.fileContentCache.clear(); + } + + /** + * Check if the path is a file by checking for .{fileType} extension for serializable file types. + * + * Files are identified by having a supported extension (.prompt or .agent). + * This method performs case-insensitive comparison and handles whitespace. + * + * @returns True if the path ends with a supported file extension + */ + public isFile(filePath: string): boolean { + const cleanPath = filePath.trim().toLowerCase(); // Convert to lowercase for case-insensitive comparison + return Array.from(SERIALIZABLE_FILE_TYPES).some((fileType) => + cleanPath.endsWith(`.${fileType}`), + ); + } + + /** + * Save serialized file to local filesystem. + */ + private _saveSerializedFile( + serializedContent: string, + filePath: string, + fileType: SerializableFileType, + ): void { + try { + // Create full path including baseDir prefix + const fullPath = path.join(this.baseDir, filePath); + const directory = path.dirname(fullPath); + const fileName = path.basename(fullPath, path.extname(fullPath)); + + // Create directory if it doesn't exist + fs.mkdirSync(directory, { recursive: true }); + + // Add file type extension + const newPath = path.join(directory, `${fileName}.${fileType}`); + + // Write raw file content to file + fs.writeFileSync(newPath, serializedContent); + log(`Writing ${fileType} ${filePath} to disk`, "DEBUG", this.verbose); + } catch (error) { + log(`Failed to write ${fileType} ${filePath} to disk: ${error}`, "ERROR"); + throw error; + } + } + + /** + * Pull a specific file from Humanloop to local filesystem. + * + * @returns True if the file was successfully pulled, False otherwise (e.g. if the file was not found) + */ + private async _pullFile(filePath: string, environment?: string): Promise { + try { + const file = await this.client.files.retrieveByPath({ + path: filePath, + environment, + includeRawFileContent: true, + }); + + if (!SERIALIZABLE_FILE_TYPES.has(file.type as SerializableFileType)) { + log(`Unsupported file type: ${file.type}`, "ERROR"); + return false; + } + + const rawContent = (file as any).rawFileContent; + if (!rawContent) { + log(`No content found for ${file.type} ${filePath}`, "ERROR"); + return false; + } + + this._saveSerializedFile( + rawContent, + file.path, + file.type as SerializableFileType, + ); + return true; + } catch (error) { + log(`Failed to pull file ${filePath}: ${error}`, "ERROR"); + return false; + } + } + + /** + * Sync Prompt and Agent files from Humanloop to local filesystem. + * + * @returns An array containing two string arrays: + * - First array contains paths of successfully pulled files + * - Second array contains paths of files that failed to pull. + * Failures can occur due to missing content in the response or errors during local file writing. + * @throws HumanloopRuntimeError If there's an error communicating with the API + */ + private async _pullDirectory( + dirPath?: string, + environment?: string, + ): Promise<[string[], string[]]> { + const successfulFiles: string[] = []; + const failedFiles: string[] = []; + let page = 1; + let totalPages = 0; + + log( + `Fetching files from ${dirPath || "root"} (environment: ${environment || "default"})`, + "INFO", + this.verbose, + ); + + while (true) { + try { + const response = await this.client.files.listFiles({ + type: Array.from(SERIALIZABLE_FILE_TYPES), + page, + size: FileSyncer.PAGE_SIZE, + includeRawFileContent: true, + environment, + path: dirPath, + }); + + // Calculate total pages on first response + if (page === 1) { + const actualPageSize = response.size || FileSyncer.PAGE_SIZE; + totalPages = Math.ceil(response.total / actualPageSize); + } + + if (response.records.length === 0) { + break; + } + + log( + `Reading page ${page}/${totalPages} (${response.records.length} Files)`, + "DEBUG", + this.verbose, + ); + + // Process each file + for (const file of response.records) { + if ( + !SERIALIZABLE_FILE_TYPES.has(file.type as SerializableFileType) + ) { + log(`Skipping unsupported file type: ${file.type}`, "WARN"); + continue; + } + + const fileType = file.type as SerializableFileType; + const rawContent = (file as any).rawFileContent; + if (!rawContent) { + log(`No content found for ${file.type} ${file.path}`, "WARN"); + failedFiles.push(file.path); + continue; + } + + try { + this._saveSerializedFile(rawContent, file.path, fileType); + successfulFiles.push(file.path); + } catch (error) { + failedFiles.push(file.path); + log(`Failed to save ${file.path}: ${error}`, "ERROR"); + } + } + + // Check if we've reached the last page + if (page >= totalPages) { + break; + } + page += 1; + } catch (error) { + const formattedError = formatApiError(error as Error, this.verbose); + throw new HumanloopRuntimeError( + `Failed to fetch page ${page}: ${formattedError}`, + ); + } + } + + if (failedFiles.length > 0) { + log(`Failed to pull ${failedFiles.length} files`, "WARN"); + } + + return [successfulFiles, failedFiles]; + } + + /** + * Pull files from Humanloop to local filesystem. + * + * If the path ends with `.prompt` or `.agent`, pulls that specific file. + * Otherwise, pulls all files under the specified path. + * If no path is provided, pulls all files from the root. + * + * @param filePath The path to pull from. Can be: + * - A specific file with extension (e.g. "path/to/file.prompt") + * - A directory without extension (e.g. "path/to/directory") + * - None to pull all files from root + * + * Paths should not contain leading or trailing slashes + * @param environment The environment to pull from + * @returns An array containing two string arrays: + * - First array contains paths of successfully pulled files + * - Second array contains paths of files that failed to pull (e.g. failed to write to disk or missing raw content) + * @throws HumanloopRuntimeError If there's an error communicating with the API + */ + public async pull( + filePath?: string, + environment?: string, + ): Promise<[string[], string[]]> { + const startTime = Date.now(); + + let apiPath: string | undefined; + let isFilePath: boolean; + + if (filePath === undefined) { + apiPath = undefined; + isFilePath = false; + } else { + filePath = filePath.trim(); + // Check if path has leading/trailing slashes + if (filePath !== filePath.trim().replace(/^\/+|\/+$/g, "")) { + throw new HumanloopRuntimeError( + `Invalid path: ${filePath}. Path should not contain leading/trailing slashes. ` + + `Valid examples: "path/to/file.prompt" or "path/to/directory"`, + ); + } + + // Check if it's a file path (has extension) + isFilePath = this.isFile(filePath); + + // For API communication, we need path without extension + apiPath = pathUtils.normalizePath(filePath, true); + } + + try { + let successfulFiles: string[]; + let failedFiles: string[]; + + if (apiPath === undefined) { + [successfulFiles, failedFiles] = await this._pullDirectory( + undefined, + environment, + ); + } else { + if (isFilePath) { + if (await this._pullFile(apiPath, environment)) { + successfulFiles = [apiPath]; + failedFiles = []; + } else { + successfulFiles = []; + failedFiles = [apiPath]; + } + } else { + [successfulFiles, failedFiles] = await this._pullDirectory( + apiPath, + environment, + ); + } + } + + // Clear the cache at the end of each pull operation + this.clearCache(); + + const duration = Date.now() - startTime; + log( + `Successfully pulled ${successfulFiles.length} files in ${duration}ms`, + "INFO", + this.verbose, + ); + + return [successfulFiles, failedFiles]; + } catch (error) { + throw new HumanloopRuntimeError(`Pull operation failed: ${error}`); + } + } +} diff --git a/src/sync/index.ts b/src/sync/index.ts new file mode 100644 index 00000000..bf310919 --- /dev/null +++ b/src/sync/index.ts @@ -0,0 +1,7 @@ +/** + * File synchronization for Humanloop + * + * This module provides sync functionality between Humanloop and the local filesystem. + */ + +export { default as FileSyncer, FileSyncerOptions } from './FileSyncer'; \ No newline at end of file diff --git a/src/version.ts b/src/version.ts index e0c1405e..dda381be 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const SDK_VERSION = "0.8.21-beta1"; +export const SDK_VERSION = "0.8.21"; diff --git a/tests/custom.test.ts b/tests/custom.test.ts deleted file mode 100644 index 7f5e031c..00000000 --- a/tests/custom.test.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * This is a custom test file, if you wish to add more tests - * to your SDK. - * Be sure to mark this file in `.fernignore`. - * - * If you include example requests/responses in your fern definition, - * you will have tests automatically generated for you. - */ -describe("test", () => { - it("default", () => { - expect(true).toBe(true); - }); -}); diff --git a/tests/custom/FileSyncer.test.ts b/tests/custom/FileSyncer.test.ts new file mode 100644 index 00000000..ed003c95 --- /dev/null +++ b/tests/custom/FileSyncer.test.ts @@ -0,0 +1,364 @@ +import * as fs from "fs"; +import * as path from "path"; +import { v4 as uuidv4 } from "uuid"; + +import { HumanloopRuntimeError } from "../../src/error"; +import FileSyncer, { + SERIALIZABLE_FILE_TYPES, + SerializableFileType, +} from "../../src/sync/FileSyncer"; + +// Mock for HumanloopClient +class MockHumanloopClient { + files = { + retrieveByPath: jest.fn(), + listFiles: jest.fn(), + }; +} + +describe("FileSyncer", () => { + let mockClient: MockHumanloopClient; + let fileSyncer: FileSyncer; + let tempDir: string; + + beforeEach(() => { + mockClient = new MockHumanloopClient(); + tempDir = path.join(process.cwd(), "test-tmp", uuidv4()); + + // Create temporary directory + fs.mkdirSync(tempDir, { recursive: true }); + + fileSyncer = new FileSyncer(mockClient as any, { + baseDir: tempDir, + cacheSize: 10, + verbose: true, // Enable verbose logging for tests + }); + }); + + afterEach(() => { + // Clean up temporary files + if (fs.existsSync(tempDir)) { + fs.rmSync(tempDir, { recursive: true, force: true }); + } + + // Clear all mocks + jest.clearAllMocks(); + }); + + describe("initialization", () => { + it("should initialize with correct base directory, cache size and file types", () => { + // Check that the FileSyncer is initialized with the correct properties + expect(fileSyncer["baseDir"]).toBe(tempDir); + expect(fileSyncer["cacheSize"]).toBe(10); + expect(SERIALIZABLE_FILE_TYPES).toEqual(new Set(["prompt", "agent"])); + }); + }); + + describe("isFile", () => { + it("should correctly identify prompt and agent files with case insensitivity", () => { + // Standard lowercase extensions + expect(fileSyncer.isFile("test.prompt")).toBe(true); + expect(fileSyncer.isFile("test.agent")).toBe(true); + + // Uppercase extensions (case insensitivity) + expect(fileSyncer.isFile("test.PROMPT")).toBe(true); + expect(fileSyncer.isFile("test.AGENT")).toBe(true); + expect(fileSyncer.isFile("test.Prompt")).toBe(true); + expect(fileSyncer.isFile("test.Agent")).toBe(true); + + // With whitespace + expect(fileSyncer.isFile(" test.prompt ")).toBe(true); + expect(fileSyncer.isFile(" test.agent ")).toBe(true); + }); + + it("should return false for invalid or missing extensions", () => { + // Invalid file types + expect(fileSyncer.isFile("test.txt")).toBe(false); + expect(fileSyncer.isFile("test.json")).toBe(false); + expect(fileSyncer.isFile("test.py")).toBe(false); + + // No extension + expect(fileSyncer.isFile("test")).toBe(false); + expect(fileSyncer.isFile("prompt")).toBe(false); + expect(fileSyncer.isFile("agent")).toBe(false); + + // Partial extensions + expect(fileSyncer.isFile("test.prom")).toBe(false); + expect(fileSyncer.isFile("test.age")).toBe(false); + }); + }); + + describe("file operations", () => { + it("should save and read files correctly", () => { + // Given a file content and path + const content = "test content"; + const filePath = "test/path"; + const fileType: SerializableFileType = "prompt"; + + // When saving the file + fileSyncer["_saveSerializedFile"](content, filePath, fileType); + + // Then the file should exist on disk + const savedPath = path.join(tempDir, filePath + "." + fileType); + expect(fs.existsSync(savedPath)).toBe(true); + + // When reading the file + const readContent = fileSyncer.getFileContent(filePath, fileType); + + // Then the content should match + expect(readContent).toBe(content); + }); + + it("should throw an error when reading a nonexistent file", () => { + // When trying to read a nonexistent file + // Then a HumanloopRuntimeError should be raised + expect(() => { + fileSyncer.getFileContent("nonexistent", "prompt"); + }).toThrow(HumanloopRuntimeError); + + // Check that the error message contains expected text + expect(() => { + fileSyncer.getFileContent("nonexistent", "prompt"); + }).toThrow(/Failed to read/); + }); + + it("should return false when API calls fail during pull", async () => { + // Given an API error + mockClient.files.retrieveByPath.mockRejectedValue(new Error("API Error")); + + // When trying to pull a file + const result = await fileSyncer["_pullFile"]("test.prompt"); + + // Then it should return false + expect(result).toBe(false); + + // And the API method should have been called + expect(mockClient.files.retrieveByPath).toHaveBeenCalled(); + }); + }); + + describe("cache functionality", () => { + it("should cache file content and respect cache invalidation", () => { + // Given a test file + const content = "test content"; + const filePath = "test/path"; + const fileType: SerializableFileType = "prompt"; + fileSyncer["_saveSerializedFile"](content, filePath, fileType); + + // When reading the file for the first time + const firstRead = fileSyncer.getFileContent(filePath, fileType); + expect(firstRead).toBe(content); + + // When modifying the file on disk + const savedPath = path.join(tempDir, filePath + "." + fileType); + fs.writeFileSync(savedPath, "modified content"); + + // Then subsequent reads should use cache (and return the original content) + const secondRead = fileSyncer.getFileContent(filePath, fileType); + expect(secondRead).toBe(content); // Should return cached content, not modified + + // When clearing the cache + fileSyncer.clearCache(); + + // Then new content should be read from disk + const thirdRead = fileSyncer.getFileContent(filePath, fileType); + expect(thirdRead).toBe("modified content"); + }); + + it("should respect the cache size limit", () => { + // Create a file syncer with small cache + const smallCacheFileSyncer = new FileSyncer(mockClient as any, { + baseDir: tempDir, + cacheSize: 2, // Only 2 items in cache + }); + + // Save 3 different files + for (let i = 1; i <= 3; i++) { + const content = `content ${i}`; + const filePath = `test/path${i}`; + const fileType: SerializableFileType = "prompt"; + smallCacheFileSyncer["_saveSerializedFile"]( + content, + filePath, + fileType, + ); + + // Read to put in cache + smallCacheFileSyncer.getFileContent(filePath, fileType); + } + + // Modify the first file (which should have been evicted from cache) + const firstPath = "test/path1"; + const savedPath = path.join(tempDir, firstPath + ".prompt"); + fs.writeFileSync(savedPath, "modified content"); + + // Reading the first file should get the modified content (not cached) + const newContent = smallCacheFileSyncer.getFileContent(firstPath, "prompt"); + expect(newContent).toBe("modified content"); + + // But reading the 2nd and 3rd files should still use cache + expect(smallCacheFileSyncer.getFileContent("test/path2", "prompt")).toBe( + "content 2", + ); + expect(smallCacheFileSyncer.getFileContent("test/path3", "prompt")).toBe( + "content 3", + ); + }); + }); + + describe("pull operations", () => { + it("should handle successful file pull", async () => { + // Mock successful file pull response + mockClient.files.retrieveByPath.mockResolvedValue({ + type: "prompt", + path: "test/path", + rawFileContent: "pulled content", + }); + + // When pulling a file + const result = await fileSyncer["_pullFile"]("test/path"); + + // Then it should return true + expect(result).toBe(true); + + // And the file should be saved to disk + const savedPath = path.join(tempDir, "test/path.prompt"); + expect(fs.existsSync(savedPath)).toBe(true); + expect(fs.readFileSync(savedPath, "utf8")).toBe("pulled content"); + }); + + it("should handle unsuccessful file pull due to missing content", async () => { + // Mock response with missing content + mockClient.files.retrieveByPath.mockResolvedValue({ + type: "prompt", + path: "test/path", + // missing rawFileContent + }); + + // When pulling a file + const result = await fileSyncer["_pullFile"]("test/path"); + + // Then it should return false + expect(result).toBe(false); + }); + + it("should handle unsuccessful file pull due to unsupported type", async () => { + // Mock response with unsupported type + mockClient.files.retrieveByPath.mockResolvedValue({ + type: "dataset", // Not a serializable type + path: "test/path", + rawFileContent: "content", + }); + + // When pulling a file + const result = await fileSyncer["_pullFile"]("test/path"); + + // Then it should return false + expect(result).toBe(false); + }); + + it("should pull a directory of files", async () => { + // Mock directory listing responses (paginated) + mockClient.files.listFiles.mockResolvedValueOnce({ + records: [ + { + type: "prompt", + path: "dir/file1", + rawFileContent: "content 1", + }, + { + type: "agent", + path: "dir/file2", + rawFileContent: "content 2", + }, + ], + page: 1, + size: 2, + total: 3, + }); + + mockClient.files.listFiles.mockResolvedValueOnce({ + records: [ + { + type: "prompt", + path: "dir/file3", + rawFileContent: "content 3", + }, + ], + page: 2, + size: 2, + total: 3, + }); + + // When pulling a directory + const [successful, failed] = await fileSyncer["_pullDirectory"]("dir"); + + // Then it should succeed for all files + expect(successful.length).toBe(3); + expect(failed.length).toBe(0); + + // And all files should exist on disk + expect(fs.existsSync(path.join(tempDir, "dir/file1.prompt"))).toBe(true); + expect(fs.existsSync(path.join(tempDir, "dir/file2.agent"))).toBe(true); + expect(fs.existsSync(path.join(tempDir, "dir/file3.prompt"))).toBe(true); + }); + + it("should handle the main pull method with different path types", async () => { + // Mock methods that are called by pull + jest.spyOn(fileSyncer, "isFile").mockImplementation((p) => + p.endsWith(".prompt"), + ); + jest.spyOn(fileSyncer as any, "_pullFile").mockResolvedValue(true); + jest.spyOn(fileSyncer as any, "_pullDirectory").mockResolvedValue([ + ["dir/file1"], + [], + ]); + + // Test with file path + await fileSyncer.pull("test/path.prompt"); + expect(fileSyncer["_pullFile"]).toHaveBeenCalledWith( + "test/path", + undefined, + ); + + // Reset mocks + jest.clearAllMocks(); + + // Test with directory path + await fileSyncer.pull("test/dir"); + expect(fileSyncer["_pullDirectory"]).toHaveBeenCalledWith( + "test/dir", + undefined, + ); + + // Reset mocks + jest.clearAllMocks(); + + // Test with no path (root) + await fileSyncer.pull(); + expect(fileSyncer["_pullDirectory"]).toHaveBeenCalledWith( + undefined, + undefined, + ); + + // Test with environment parameter + await fileSyncer.pull("test/path.prompt", "staging"); + expect(fileSyncer["_pullFile"]).toHaveBeenCalledWith( + "test/path", + "staging", + ); + }); + + it("should reject paths with leading or trailing slashes", async () => { + // Test with leading slash + await expect(fileSyncer.pull("/test/path")).rejects.toThrow( + HumanloopRuntimeError, + ); + + // Test with trailing slash + await expect(fileSyncer.pull("test/path/")).rejects.toThrow( + HumanloopRuntimeError, + ); + }); + }); +}); diff --git a/tests/custom/fixtures.ts b/tests/custom/fixtures.ts new file mode 100644 index 00000000..9909abc4 --- /dev/null +++ b/tests/custom/fixtures.ts @@ -0,0 +1,21 @@ +import * as fs from "fs"; +import * as path from "path"; +import { v4 as uuidv4 } from "uuid"; + +/** + * Creates a temporary directory for tests + * @param prefix Optional prefix for the directory name + * @returns Path to the created directory and a cleanup function + */ +export function createTempDir(prefix = "test") { + const tempDir = path.join(process.cwd(), "test-tmp", `${prefix}-${uuidv4()}`); + fs.mkdirSync(tempDir, { recursive: true }); + + const cleanup = () => { + if (fs.existsSync(tempDir)) { + fs.rmSync(tempDir, { recursive: true, force: true }); + } + }; + + return { tempDir, cleanup }; +} diff --git a/tests/custom/integration/FileSyncer.test.ts b/tests/custom/integration/FileSyncer.test.ts new file mode 100644 index 00000000..15120e18 --- /dev/null +++ b/tests/custom/integration/FileSyncer.test.ts @@ -0,0 +1,160 @@ +import * as fs from "fs"; +import * as path from "path"; +import { v4 as uuidv4 } from "uuid"; + +import { FileType } from "../../../src/api"; +import { HumanloopRuntimeError } from "../../../src/error"; +import { HumanloopClient } from "../../../src/humanloop.client"; +import { createTempDir } from "../fixtures"; +import { + SyncableFile, + TestSetup, + cleanupTestEnvironment, + createSyncableFilesFixture, + setupTestEnvironment, +} from "./fixtures"; + +describe("FileSyncer Integration Tests", () => { + let testSetup: TestSetup; + let syncableFiles: SyncableFile[] = []; + let tempDirInfo: { tempDir: string; cleanup: () => void }; + + beforeAll(async () => { + // Set up test environment + testSetup = await setupTestEnvironment("file_sync"); + tempDirInfo = createTempDir("file-sync-integration"); + + // Create test files in Humanloop for syncing + syncableFiles = await createSyncableFilesFixture(testSetup); + }); + + afterAll(async () => { + // Clean up resources only if they were created + if (tempDirInfo) { + tempDirInfo.cleanup(); + } + if (testSetup) { + await cleanupTestEnvironment( + testSetup, + syncableFiles.map((file) => ({ + type: file.type as FileType, + id: file.id as string, + })), + ); + } + }); + + test("pull_basic: should pull all files from remote to local filesystem", async () => { + // GIVEN a set of files in the remote system (from syncableFiles) + const client = new HumanloopClient({ + apiKey: process.env.HUMANLOOP_API_KEY, + localFilesDirectory: tempDirInfo.tempDir, + useLocalFiles: true, + }); + + // WHEN running the pull operation + await client.pull(); + + // THEN our local filesystem should mirror the remote filesystem in the HL Workspace + for (const file of syncableFiles) { + const extension = `.${file.type}`; + const localPath = path.join( + tempDirInfo.tempDir, + `${file.path}${extension}`, + ); + + // THEN the file and its directory should exist + expect(fs.existsSync(localPath)).toBe(true); + expect(fs.existsSync(path.dirname(localPath))).toBe(true); + + // THEN the file should not be empty + const content = fs.readFileSync(localPath, "utf8"); + expect(content).toBeTruthy(); + } + }); + + test("pull_with_invalid_path: should handle error when path doesn't exist", async () => { + // GIVEN a client + const client = new HumanloopClient({ + apiKey: process.env.HUMANLOOP_API_KEY, + localFilesDirectory: tempDirInfo.tempDir, + useLocalFiles: true, + }); + + const nonExistentPath = `${testSetup.sdkTestDir.path}/non_existent_directory`; + + // WHEN/THEN pulling with an invalid path should throw an error + await expect(client.pull(nonExistentPath)).rejects.toThrow( + HumanloopRuntimeError, + ); + // The error message might be different in TypeScript, so we don't assert on the exact message + }); + + test("pull_with_invalid_environment: should handle error when environment doesn't exist", async () => { + // GIVEN a client + const client = new HumanloopClient({ + apiKey: process.env.HUMANLOOP_API_KEY, + localFilesDirectory: tempDirInfo.tempDir, + useLocalFiles: true, + }); + + // WHEN/THEN pulling with an invalid environment should throw an error + await expect(client.pull(undefined, "invalid_environment")).rejects.toThrow( + HumanloopRuntimeError, + ); + }); + + test("pull_with_path_filter: should only pull files from specified path", async () => { + // GIVEN a client and a clean temp directory + const pathFilterTempDir = createTempDir("file-sync-path-filter"); + + const client = new HumanloopClient({ + apiKey: process.env.HUMANLOOP_API_KEY, + localFilesDirectory: pathFilterTempDir.tempDir, + useLocalFiles: true, + }); + + // WHEN pulling only files from the testSetup.sdkTestDir.path + await client.pull(testSetup.sdkTestDir.path); + + // THEN count the total number of files pulled + let pulledFileCount = 0; + + // Collect expected file paths (relative to sdkTestDir.path) + const expectedFiles = new Set( + syncableFiles.map((file) => + path.join( + pathFilterTempDir.tempDir, + file.path + (file.type === "prompt" ? ".prompt" : ".agent"), + ), + ), + ); + + const foundFiles = new Set(); + + function countFilesRecursive(dirPath: string): void { + const entries = fs.readdirSync(dirPath, { withFileTypes: true }); + for (const entry of entries) { + const fullPath = path.join(dirPath, entry.name); + if (entry.isDirectory()) { + countFilesRecursive(fullPath); + } else if (entry.isFile()) { + if (expectedFiles.has(fullPath)) { + const content = fs.readFileSync(fullPath, "utf8"); + expect(content).toBeTruthy(); + foundFiles.add(fullPath); + } + } + } + } + + if (fs.existsSync(pathFilterTempDir.tempDir)) { + countFilesRecursive(pathFilterTempDir.tempDir); + } + + expect(foundFiles.size).toBe(expectedFiles.size); + + // Clean up + pathFilterTempDir.cleanup(); + }); +}); diff --git a/tests/custom/integration/cli.test.ts b/tests/custom/integration/cli.test.ts new file mode 100644 index 00000000..be710dc4 --- /dev/null +++ b/tests/custom/integration/cli.test.ts @@ -0,0 +1,295 @@ +import * as fs from "fs"; +import * as path from "path"; +import { spawn } from "child_process"; + +import { createTempDir } from "../fixtures"; +import { + TestSetup, + cleanupTestEnvironment, + createSyncableFilesFixture, + setupTestEnvironment, +} from "./fixtures"; + +// Helper function to run CLI commands with TypeScript +async function runCli( + args: string[], +): Promise<{ stdout: string; stderr: string; exitCode: number }> { + return new Promise((resolve) => { + const packageRoot = path.resolve(__dirname, "../../../"); + const cliPath = path.join(packageRoot, "dist/cli.js"); + + // Use spawn to avoid shell interpretation issues + const childProcess = spawn("node", [cliPath, ...args], { + stdio: ["ignore", "pipe", "pipe"], + }); + + let stdout = ""; + let stderr = ""; + + childProcess.stdout?.on("data", (data) => { + stdout += data.toString(); + }); + + childProcess.stderr?.on("data", (data) => { + stderr += data.toString(); + }); + + childProcess.on("close", (code) => { + resolve({ + stdout, + stderr, + exitCode: code !== null ? code : 0, + }); + }); + }); +} + +describe("CLI Integration Tests", () => { + let testSetup: TestSetup; + let syncableFiles: any[] = []; + + beforeAll(async () => { + // Increase timeout for setup operations + jest.setTimeout(40000); // 40 seconds + + // Set up test environment + testSetup = await setupTestEnvironment("cli_test"); + + // Create test files in Humanloop for syncing + syncableFiles = await createSyncableFilesFixture(testSetup); + }, 30000); + + afterAll(async () => { + await cleanupTestEnvironment( + testSetup, + syncableFiles.map((file) => ({ + type: file.type as any, + id: file.id as string, + })), + ); + }, 30000); + + /** + * NOTE: This test is currently skipped due to issues with CLI environment isolation. + * + * The test attempts to verify behavior when no API key is available, but faces + * challenges with how Node.js handles process execution during tests: + * + * 1. When executed via child_process.exec, the path to nonexistent env files + * causes Node to return exit code 9 (SIGKILL) instead of the expected code 1 + * 2. Shell interpretation of arguments makes it difficult to reliably test this edge case + * + * If this functionality needs testing, consider: + * - Using child_process.spawn for better argument handling + * - Unit testing the API key validation logic directly + * - Moving this test to a separate process with full environment isolation + * + * @see https://nodejs.org/api/child_process.html for more info on process execution + */ + test.skip("pull_without_api_key: should show error when no API key is available", async () => { + // GIVEN a temporary directory and no API key + const { tempDir, cleanup } = createTempDir("cli-no-api-key"); + + // Create a path to a file that definitely doesn't exist + const nonExistentEnvFile = path.join(tempDir, "__DOES_NOT_EXIST__.env"); + + // WHEN running pull command without API key + const originalApiKey = process.env.HUMANLOOP_API_KEY; + delete process.env.HUMANLOOP_API_KEY; + + const result = await runCli([ + "pull", + "--local-files-directory", + tempDir, + "--env-file", + `"${nonExistentEnvFile}"`, + ]); + + // Restore API key + process.env.HUMANLOOP_API_KEY = originalApiKey; + + // THEN it should fail with appropriate error message + expect(result.exitCode).not.toBe(0); + expect(result.stderr + result.stdout).toContain( + "Failed to load environment file", + ); + + cleanup(); + }); + + test("pull_basic: should pull all files successfully", async () => { + // Increase timeout for this test + jest.setTimeout(30000); // 30 seconds + + // GIVEN a base directory for pulled files + const { tempDir, cleanup } = createTempDir("cli-basic-pull"); + + // WHEN running pull command + const result = await runCli([ + "pull", + "--local-files-directory", + tempDir, + "--verbose", + "--api-key", + process.env.HUMANLOOP_API_KEY || "", + ]); + + // THEN it should succeed + expect(result.exitCode).toBe(0); + expect(result.stdout).toContain("Pulling files from Humanloop"); + expect(result.stdout).toContain("Pull completed"); + + // THEN the files should exist locally + for (const file of syncableFiles) { + const extension = `.${file.type}`; + const localPath = path.join(tempDir, `${file.path}${extension}`); + + expect(fs.existsSync(localPath)).toBe(true); + expect(fs.existsSync(path.dirname(localPath))).toBe(true); + + const content = fs.readFileSync(localPath, "utf8"); + expect(content).toBeTruthy(); + } + + cleanup(); + }, 30000); + + test("pull_with_specific_path: should pull files from a specific path", async () => { + // GIVEN a base directory and specific path + const { tempDir, cleanup } = createTempDir("cli-path-pull"); + + // Get the prefix of the first file's path (test directory) + const testPath = syncableFiles[0].path.split("/")[0]; + + // WHEN running pull command with path + const result = await runCli([ + "pull", + "--local-files-directory", + tempDir, + "--path", + testPath, + "--verbose", + "--api-key", + process.env.HUMANLOOP_API_KEY || "", + ]); + + // THEN it should succeed and show the path + expect(result.exitCode).toBe(0); + expect(result.stdout).toContain(`Path: ${testPath}`); + + // THEN only files from that path should exist locally + for (const file of syncableFiles) { + const extension = `.${file.type}`; + const localPath = path.join(tempDir, `${file.path}${extension}`); + + if (file.path.startsWith(testPath)) { + expect(fs.existsSync(localPath)).toBe(true); + } else { + expect(fs.existsSync(localPath)).toBe(false); + } + } + + cleanup(); + }); + + test("pull_with_environment: should pull files from a specific environment", async () => { + // Increase timeout for this test + jest.setTimeout(30000); // 30 seconds + + // GIVEN a base directory and environment + const { tempDir, cleanup } = createTempDir("cli-env-pull"); + + // WHEN running pull command with environment + const result = await runCli([ + "pull", + "--local-files-directory", + tempDir, + "--environment", + "staging", + "--verbose", + "--api-key", + process.env.HUMANLOOP_API_KEY || "", + ]); + + // THEN it should succeed and show the environment + expect(result.exitCode).toBe(0); + expect(result.stdout).toContain("Environment: staging"); + + cleanup(); + }, 30000); + + test("pull_with_quiet_mode: should pull files with quiet mode enabled", async () => { + // GIVEN a base directory and quiet mode + const { tempDir, cleanup } = createTempDir("cli-quiet-pull"); + + // WHEN running pull command with quiet mode + const result = await runCli([ + "pull", + "--local-files-directory", + tempDir, + "--quiet", + "--api-key", + process.env.HUMANLOOP_API_KEY || "", + ]); + + // THEN it should succeed but not show file list + expect(result.exitCode).toBe(0); + expect(result.stdout).not.toContain("Successfully pulled"); + + // THEN files should still be pulled + for (const file of syncableFiles) { + const extension = `.${file.type}`; + const localPath = path.join(tempDir, `${file.path}${extension}`); + expect(fs.existsSync(localPath)).toBe(true); + } + + cleanup(); + }); + + test("pull_with_invalid_path: should handle error when pulling from an invalid path", async () => { + // GIVEN an invalid path + const { tempDir, cleanup } = createTempDir("cli-invalid-path"); + const path = "nonexistent/path"; + + // WHEN running pull command + const result = await runCli([ + "pull", + "--local-files-directory", + tempDir, + "--path", + path, + "--api-key", + process.env.HUMANLOOP_API_KEY || "", + ]); + + // THEN it should fail + expect(result.exitCode).toBe(1); + expect(result.stderr + result.stdout).toContain("Error"); + + cleanup(); + }); + + test("pull_with_invalid_environment: should handle error when pulling from an invalid environment", async () => { + // GIVEN an invalid environment + const { tempDir, cleanup } = createTempDir("cli-invalid-env"); + const environment = "nonexistent"; + + // WHEN running pull command + const result = await runCli([ + "pull", + "--local-files-directory", + tempDir, + "--environment", + environment, + "--verbose", + "--api-key", + process.env.HUMANLOOP_API_KEY || "", + ]); + + // THEN it should fail + expect(result.exitCode).toBe(1); + expect(result.stderr + result.stdout).toContain("Error"); + + cleanup(); + }); +}); diff --git a/tests/integration/decorators.test.ts b/tests/custom/integration/decorators.test.ts similarity index 99% rename from tests/integration/decorators.test.ts rename to tests/custom/integration/decorators.test.ts index 0cddc948..ef9e22a0 100644 --- a/tests/integration/decorators.test.ts +++ b/tests/custom/integration/decorators.test.ts @@ -1,7 +1,7 @@ import OpenAI from "openai"; -import { PromptRequest } from "../../src/api"; -import { HumanloopRuntimeError } from "../../src/error"; +import { PromptRequest } from "../../../src/api"; +import { HumanloopRuntimeError } from "../../../src/error"; import { CleanupResources, TestPrompt, diff --git a/tests/integration/evals.test.ts b/tests/custom/integration/evals.test.ts similarity index 99% rename from tests/integration/evals.test.ts rename to tests/custom/integration/evals.test.ts index 17d8a399..09e3b9bf 100644 --- a/tests/integration/evals.test.ts +++ b/tests/custom/integration/evals.test.ts @@ -1,6 +1,6 @@ -import { FlowResponse } from "../../src/api"; -import { HumanloopRuntimeError } from "../../src/error"; -import { HumanloopClient } from "../../src/humanloop.client"; +import { FlowResponse } from "../../../src/api"; +import { HumanloopRuntimeError } from "../../../src/error"; +import { HumanloopClient } from "../../../src/humanloop.client"; import { cleanupTestEnvironment, readEnvironment, diff --git a/tests/integration/fixtures.ts b/tests/custom/integration/fixtures.ts similarity index 55% rename from tests/integration/fixtures.ts rename to tests/custom/integration/fixtures.ts index 41ccf486..c7ba73b9 100644 --- a/tests/integration/fixtures.ts +++ b/tests/custom/integration/fixtures.ts @@ -2,10 +2,10 @@ import dotenv from "dotenv"; import { OpenAI } from "openai"; import { v4 as uuidv4 } from "uuid"; -import { FileType, PromptRequest, PromptResponse } from "../../src/api"; -import { HumanloopClient } from "../../src/humanloop.client"; +import { FileType, PromptRequest, PromptResponse } from "../../../src/api"; +import { HumanloopClient } from "../../../src/humanloop.client"; -export interface TestIdentifiers { +export interface ResourceIdentifiers { id: string; path: string; } @@ -16,15 +16,23 @@ export interface TestPrompt { response: PromptResponse; } +export interface SyncableFile { + path: string; + type: "prompt" | "agent"; + model: string; + id?: string; + versionId?: string; +} + export interface TestSetup { - sdkTestDir: TestIdentifiers; + sdkTestDir: ResourceIdentifiers; testPromptConfig: PromptRequest; openaiApiKey: string; humanloopClient: HumanloopClient; - evalDataset: TestIdentifiers; - evalPrompt: TestIdentifiers; + evalDataset: ResourceIdentifiers; + evalPrompt: ResourceIdentifiers; stagingEnvironmentId: string; - outputNotNullEvaluator: TestIdentifiers; + outputNotNullEvaluator: ResourceIdentifiers; } export interface CleanupResources { @@ -197,50 +205,141 @@ export async function cleanupTestEnvironment( // First clean up any additional resources if (resources) { for (const resource of resources) { - const subclient = getSubclient(setup.humanloopClient, resource.type); - if (resource.id) { - await subclient.delete(resource.id); + try { + const subclient = getSubclient( + setup.humanloopClient, + resource.type, + ); + if (resource.id) { + await subclient.delete(resource.id); + } + } catch (error) { + console.warn( + `Failed to delete ${resource.type} ${resource.id}:`, + error, + ); } } } - // Clean up fixed test resources - if (setup.outputNotNullEvaluator?.id) { - try { - await setup.humanloopClient.evaluators.delete( - setup.outputNotNullEvaluator.id, - ); - } catch (error) { - console.warn( - `Failed to delete evaluator ${setup.outputNotNullEvaluator.id}:`, - error, - ); + // Sleep a bit to let API operations settle + await new Promise((resolve) => setTimeout(resolve, 3000)); + + // Recursively clean up the test directory + try { + if (setup.sdkTestDir.id) { + await cleanupDirectory(setup.humanloopClient, setup.sdkTestDir.id); } + } catch (error) { + console.warn(`Failed to clean up test directory: ${error}`); } + } catch (error) { + console.error("Error during cleanup:", error); + } +} - if (setup.evalDataset?.id) { - try { - await setup.humanloopClient.datasets.delete(setup.evalDataset.id); - } catch (error) { - console.warn( - `Failed to delete dataset ${setup.evalDataset.id}:`, - error, - ); - } +/** + * Recursively cleans up a directory and all its contents + * Mirrors the Python SDK's cleanup_directory function + * @param client The Humanloop client + * @param directoryId ID of the directory to clean + */ +async function cleanupDirectory( + client: HumanloopClient, + directoryId: string, +): Promise { + try { + // Get directory details + const directory = await client.directories.get(directoryId); + + // First, recursively clean up subdirectories + for (const subdirectory of directory.subdirectories) { + await cleanupDirectory(client, subdirectory.id); } - // Finally, clean up the test directory - if (setup.sdkTestDir.id) { + // Then delete all files in this directory + for (const file of directory.files) { try { - await setup.humanloopClient.directories.delete(setup.sdkTestDir.id); + const subclient = getSubclient(client, file.type as FileType); + await subclient.delete(file.id); } catch (error) { - console.warn( - `Failed to delete directory ${setup.sdkTestDir.id}:`, - error, - ); + console.warn(`Failed to delete ${file.type} ${file.id}: ${error}`); } } + + // Finally delete this directory + await client.directories.delete(directoryId); } catch (error) { - console.error("Error during cleanup:", error); + console.warn(`Error cleaning directory ${directoryId}: ${error}`); } } + +/** + * Creates a predefined structure of files in Humanloop for testing sync + */ +export async function createSyncableFilesFixture( + testSetup: TestSetup, +): Promise { + const fileDefinitions: SyncableFile[] = [ + { + path: "prompts/gpt-4", + type: "prompt", + model: "gpt-4o-mini", + }, + { + path: "prompts/gpt-4o", + type: "prompt", + model: "gpt-4o-mini", + }, + { + path: "prompts/nested/complex/gpt-4o", + type: "prompt", + model: "gpt-4o-mini", + }, + { + path: "agents/gpt-4", + type: "agent", + model: "gpt-4o-mini", + }, + { + path: "agents/gpt-4o", + type: "agent", + model: "gpt-4o-mini", + }, + ]; + + const createdFiles: SyncableFile[] = []; + + for (const file of fileDefinitions) { + const fullPath = `${testSetup.sdkTestDir.path}/${file.path}`; + let response; + + try { + if (file.type === "prompt") { + response = await testSetup.humanloopClient.prompts.upsert({ + path: fullPath, + model: file.model, + }); + } else if (file.type === "agent") { + response = await testSetup.humanloopClient.agents.upsert({ + path: fullPath, + model: file.model, + }); + } + + if (response) { + createdFiles.push({ + path: fullPath, + type: file.type, + model: file.model, + id: response.id, + versionId: response.versionId, + }); + } + } catch (error) { + console.warn(`Failed to create ${file.type} at ${fullPath}: ${error}`); + } + } + + return createdFiles; +} diff --git a/tests/custom/integration/localFileOperations.test.ts b/tests/custom/integration/localFileOperations.test.ts new file mode 100644 index 00000000..4f5da986 --- /dev/null +++ b/tests/custom/integration/localFileOperations.test.ts @@ -0,0 +1,404 @@ +import * as fs from "fs"; +import * as path from "path"; + +import { ChatMessage } from "../../../src/api"; +import { HumanloopRuntimeError } from "../../../src/error"; +import { HumanloopClient } from "../../../src/humanloop.client"; +import { createTempDir } from "../fixtures"; +import { + TestSetup, + cleanupTestEnvironment, + createSyncableFilesFixture, + setupTestEnvironment, +} from "./fixtures"; + +// Define SyncableFile interface to match Python version +interface SyncableFile { + path: string; + type: "prompt" | "agent"; + model: string; + id?: string; + versionId?: string; +} + +interface PathTestCase { + name: string; + pathGenerator: (file: SyncableFile) => string; + shouldPass: boolean; + expectedError?: string; // Only required when shouldPass is false +} + +describe("Local File Operations Integration Tests", () => { + let testSetup: TestSetup; + let syncableFiles: SyncableFile[] = []; + let tempDirInfo: { tempDir: string; cleanup: () => void }; + + beforeAll(async () => { + // Increase timeout for setup operations + jest.setTimeout(30000); // 30 seconds + + // Set up test environment + testSetup = await setupTestEnvironment("local_file_ops"); + tempDirInfo = createTempDir("local-file-integration"); + + // Create test files in Humanloop for syncing + syncableFiles = await createSyncableFilesFixture(testSetup); + + // Pull files for tests that need them pre-pulled + const setupClient = new HumanloopClient({ + apiKey: process.env.HUMANLOOP_API_KEY, + localFilesDirectory: tempDirInfo.tempDir, + useLocalFiles: true, + }); + + await setupClient.pull(); + }, 30000); + + afterAll(async () => { + // Clean up resources + tempDirInfo.cleanup(); + await cleanupTestEnvironment( + testSetup, + syncableFiles.map((file) => ({ + type: file.type as any, + id: file.id as string, + })), + ); + }, 30000); + + describe("Path Validation", () => { + // Path validation test cases + const pathTestCases = [ + // Basic path test cases + { + name: "With whitespace", + pathGenerator: (file: SyncableFile) => ` ${file.path} `, + shouldPass: true, + }, + { + name: "Standard extension", + pathGenerator: (file: SyncableFile) => `${file.path}.${file.type}`, + expectedError: "should not include any file extension", + }, + { + name: "Uppercase extension", + pathGenerator: (file: SyncableFile) => + `${file.path}.${file.type.toUpperCase()}`, + expectedError: "should not include any file extension", + }, + { + name: "Mixed case extension", + pathGenerator: (file: SyncableFile) => + `${file.path}.${file.type.charAt(0).toUpperCase() + file.type.slice(1)}`, + expectedError: "should not include any file extension", + }, + // Slash path test cases + { + name: "Trailing slash", + pathGenerator: (file: SyncableFile) => `${file.path}/`, + expectedError: "Path .* format is invalid", + }, + { + name: "Leading slash", + pathGenerator: (file: SyncableFile) => `/${file.path}`, + expectedError: "Path .* format is invalid", + }, + { + name: "Both leading and trailing slashes", + pathGenerator: (file: SyncableFile) => `/${file.path}/`, + expectedError: "Path .* format is invalid", + }, + { + name: "Multiple leading and trailing slashes", + pathGenerator: (file: SyncableFile) => `//${file.path}//`, + expectedError: "Path .* format is invalid", + }, + // Combined path test cases + { + name: "Extension and trailing slash", + pathGenerator: (file: SyncableFile) => `${file.path}.${file.type}/`, + expectedError: "Path .* format is invalid", + }, + { + name: "Extension and leading slash", + pathGenerator: (file: SyncableFile) => `/${file.path}.${file.type}`, + expectedError: "Path .* format is invalid", + }, + ]; + + // Test all path validation cases + test.each(pathTestCases)( + "should $shouldPass ? 'accept' : 'reject' $name path format", + async ({ pathGenerator, expectedError, shouldPass }) => { + // GIVEN a client with local files enabled and a test file + const client = new HumanloopClient({ + apiKey: process.env.HUMANLOOP_API_KEY, + localFilesDirectory: tempDirInfo.tempDir, + useLocalFiles: true, + }); + + const testFile = syncableFiles[0]; + const testPath = pathGenerator(testFile); + const testMessage: ChatMessage[] = [ + { role: "user", content: "Testing" }, + ]; + + // WHEN using the path + if (shouldPass) { + // THEN it should work (just trimming whitespace) + if (testFile.type === "prompt") { + await expect( + client.prompts.call({ + path: testPath, + messages: testMessage, + }), + ).resolves.toBeDefined(); + } else if (testFile.type === "agent") { + await expect( + client.agents.call({ + path: testPath, + messages: testMessage, + }), + ).resolves.toBeDefined(); + } + } else { + // Type guard to ensure expectedError is defined when shouldPass is false + if (!expectedError) { + throw new Error( + "expectedError must be defined when shouldPass is false", + ); + } + + // THEN appropriate error should be raised + if (testFile.type === "prompt") { + await expect( + client.prompts.call({ + path: testPath, + messages: testMessage, + }), + ).rejects.toThrow(new RegExp(expectedError)); + } else if (testFile.type === "agent") { + await expect( + client.agents.call({ + path: testPath, + messages: testMessage, + }), + ).rejects.toThrow(new RegExp(expectedError)); + } + } + }, + ); + }); + + test("local_file_call: should call API with local prompt file", async () => { + // GIVEN a local prompt file with proper system tag + const promptContent = `--- +model: gpt-4o-mini +temperature: 1.0 +max_tokens: -1 +top_p: 1.0 +presence_penalty: 0.0 +frequency_penalty: 0.0 +provider: openai +endpoint: chat +tools: [] +--- + + +You are a helpful assistant that provides concise answers. When asked about capitals of countries, +you respond with just the capital name, lowercase, with no punctuation or additional text. + +`; + + // Create local file structure in temporary directory + const testPath = `${testSetup.sdkTestDir.path}/capital_prompt`; + const filePath = path.join(tempDirInfo.tempDir, `${testPath}.prompt`); + fs.mkdirSync(path.dirname(filePath), { recursive: true }); + fs.writeFileSync(filePath, promptContent); + + // GIVEN a client with local files enabled + const client = new HumanloopClient({ + apiKey: process.env.HUMANLOOP_API_KEY, + localFilesDirectory: tempDirInfo.tempDir, + useLocalFiles: true, + }); + + // WHEN calling the API with the local file path (without extension) + const callMessages: ChatMessage[] = [ + { role: "user", content: "What is the capital of France?" }, + ]; + const response = await client.prompts.call({ + path: testPath, + messages: callMessages, + }); + + // THEN the response should be successful + expect(response).toBeDefined(); + expect(response.logs).toBeDefined(); + expect(response.logs?.length).toBeGreaterThan(0); + + // AND the response should contain the expected output format (lowercase city name) + const output = response.logs?.[0].output; + expect(output).toBeDefined(); + expect(output?.toLowerCase()).toContain("paris"); + + // AND the prompt used should match our expected path + expect(response.prompt).toBeDefined(); + expect(response.prompt?.path).toBe(testPath); + }); + + test("local_file_log: should log data with local prompt file", async () => { + // GIVEN a local prompt file with proper system tag + const promptContent = `--- +model: gpt-4o-mini +temperature: 1.0 +max_tokens: -1 +top_p: 1.0 +presence_penalty: 0.0 +frequency_penalty: 0.0 +provider: openai +endpoint: chat +tools: [] +--- + + +You are a helpful assistant that answers questions about geography. + +`; + + // Create local file structure in temporary directory + const testPath = `${testSetup.sdkTestDir.path}/geography_prompt`; + const filePath = path.join(tempDirInfo.tempDir, `${testPath}.prompt`); + fs.mkdirSync(path.dirname(filePath), { recursive: true }); + fs.writeFileSync(filePath, promptContent); + + // GIVEN a client with local files enabled + const client = new HumanloopClient({ + apiKey: process.env.HUMANLOOP_API_KEY, + localFilesDirectory: tempDirInfo.tempDir, + useLocalFiles: true, + }); + + // GIVEN message content to log + const testOutput = "Paris is the capital of France."; + + // WHEN logging the data with the local file path + const messages: ChatMessage[] = [ + { role: "user", content: "What is the capital of France?" }, + ]; + const response = await client.prompts.log({ + path: testPath, + messages: messages, + output: testOutput, + }); + + // THEN the log should be successful + expect(response).toBeDefined(); + expect(response.promptId).toBeDefined(); + expect(response.id).toBeDefined(); // log ID + + // WHEN retrieving the logged prompt details + const promptDetails = await client.prompts.get(response.promptId); + + // THEN the details should match our expected path + expect(promptDetails).toBeDefined(); + expect(promptDetails.path).toContain(testPath); + }); + + test("overload_version_environment_handling: should handle version_id and environment parameters", async () => { + // GIVEN a client with local files enabled + const client = new HumanloopClient({ + apiKey: process.env.HUMANLOOP_API_KEY, + localFilesDirectory: tempDirInfo.tempDir, + useLocalFiles: true, + }); + + const testMessage: ChatMessage[] = [{ role: "user", content: "Testing" }]; + + // GIVEN a test file that exists locally + const testFile = syncableFiles[0]; + const extension = `.${testFile.type}`; + const localPath = path.join( + tempDirInfo.tempDir, + `${testFile.path}${extension}`, + ); + + // THEN the file should exist locally + expect(fs.existsSync(localPath)).toBe(true); + expect(fs.existsSync(path.dirname(localPath))).toBe(true); + + // WHEN calling with version_id + // THEN a HumanloopRuntimeError should be raised + if (testFile.type === "prompt") { + await expect( + client.prompts.call({ + path: testFile.path, + versionId: testFile.versionId, + messages: testMessage, + }), + ).rejects.toThrow( + /Cannot use local file.*version_id or environment was specified/, + ); + } else if (testFile.type === "agent") { + await expect( + client.agents.call({ + path: testFile.path, + versionId: testFile.versionId, + messages: testMessage, + }), + ).rejects.toThrow( + /Cannot use local file.*version_id or environment was specified/, + ); + } + + // WHEN calling with environment + // THEN a HumanloopRuntimeError should be raised + if (testFile.type === "prompt") { + await expect( + client.prompts.call({ + path: testFile.path, + environment: "production", + messages: testMessage, + }), + ).rejects.toThrow( + /Cannot use local file.*version_id or environment was specified/, + ); + } else if (testFile.type === "agent") { + await expect( + client.agents.call({ + path: testFile.path, + environment: "production", + messages: testMessage, + }), + ).rejects.toThrow( + /Cannot use local file.*version_id or environment was specified/, + ); + } + + // WHEN calling with both version_id and environment + // THEN a HumanloopRuntimeError should be raised + if (testFile.type === "prompt") { + await expect( + client.prompts.call({ + path: testFile.path, + versionId: testFile.versionId, + environment: "staging", + messages: testMessage, + }), + ).rejects.toThrow( + /Cannot use local file.*version_id or environment was specified/, + ); + } else if (testFile.type === "agent") { + await expect( + client.agents.call({ + path: testFile.path, + versionId: testFile.versionId, + environment: "staging", + messages: testMessage, + }), + ).rejects.toThrow( + /Cannot use local file.*version_id or environment was specified/, + ); + } + }); +}); diff --git a/tests/custom/unit/LRUCache.test.ts b/tests/custom/unit/LRUCache.test.ts new file mode 100644 index 00000000..f377165c --- /dev/null +++ b/tests/custom/unit/LRUCache.test.ts @@ -0,0 +1,61 @@ +import LRUCache from "../../../src/cache/LRUCache"; + +describe("LRUCache", () => { + let cache: LRUCache; + + beforeEach(() => { + cache = new LRUCache(3); // Test with small capacity + }); + + describe("basic operations", () => { + it("should set and get values", () => { + cache.set("key1", 1); + expect(cache.get("key1")).toBe(1); + }); + + it("should return undefined for non-existent keys", () => { + expect(cache.get("nonexistent")).toBeUndefined(); + }); + + it("should handle setting same key multiple times", () => { + cache.set("key1", 1); + cache.set("key1", 2); + expect(cache.get("key1")).toBe(2); + }); + }); + + describe("capacity and eviction", () => { + it("should evict least recently used item when capacity is reached", () => { + cache.set("key1", 1); + cache.set("key2", 2); + cache.set("key3", 3); + cache.set("key4", 4); // Should evict key1 + + expect(cache.get("key1")).toBeUndefined(); + expect(cache.get("key4")).toBe(4); + }); + + it("should update LRU order on get operations", () => { + cache.set("key1", 1); + cache.set("key2", 2); + cache.set("key3", 3); + + cache.get("key1"); // Make key1 most recently used + cache.set("key4", 4); // Should evict key2, not key1 + + expect(cache.get("key1")).toBe(1); + expect(cache.get("key2")).toBeUndefined(); + }); + }); + + describe("clear operation", () => { + it("should clear all items from cache", () => { + cache.set("key1", 1); + cache.set("key2", 2); + cache.clear(); + + expect(cache.get("key1")).toBeUndefined(); + expect(cache.get("key2")).toBeUndefined(); + }); + }); +}); diff --git a/tests/custom/unit/pathUtils.test.ts b/tests/custom/unit/pathUtils.test.ts new file mode 100644 index 00000000..db71121e --- /dev/null +++ b/tests/custom/unit/pathUtils.test.ts @@ -0,0 +1,78 @@ +import { normalizePath } from "../../../src/pathUtils"; + +describe("normalizePath", () => { + const testCases = [ + // Basic cases + { + input: "path/to/file.prompt", + expectedWithExtension: "path/to/file.prompt", + expectedWithoutExtension: "path/to/file", + }, + { + input: "path\\to\\file.agent", + expectedWithExtension: "path/to/file.agent", + expectedWithoutExtension: "path/to/file", + }, + { + input: "/leading/slashes/file.prompt", + expectedWithExtension: "leading/slashes/file.prompt", + expectedWithoutExtension: "leading/slashes/file", + }, + { + input: "trailing/slashes/file.agent/", + expectedWithExtension: "trailing/slashes/file.agent", + expectedWithoutExtension: "trailing/slashes/file", + }, + { + input: "multiple//slashes//file.prompt", + expectedWithExtension: "multiple/slashes/file.prompt", + expectedWithoutExtension: "multiple/slashes/file", + }, + // Edge cases + { + input: "path/to/file with spaces.prompt", + expectedWithExtension: "path/to/file with spaces.prompt", + expectedWithoutExtension: "path/to/file with spaces", + }, + { + input: "path/to/file\\with\\backslashes.prompt", + expectedWithExtension: "path/to/file/with/backslashes.prompt", + expectedWithoutExtension: "path/to/file/with/backslashes", + }, + { + input: "path/to/unicode/文件.prompt", + expectedWithExtension: "path/to/unicode/文件.prompt", + expectedWithoutExtension: "path/to/unicode/文件", + }, + { + input: "path/to/special/chars/!@#$%^&*().prompt", + expectedWithExtension: "path/to/special/chars/!@#$%^&*().prompt", + expectedWithoutExtension: "path/to/special/chars/!@#$%^&*()", + }, + ]; + + test.each(testCases)( + "normalizes path '$input' correctly", + ({ input, expectedWithExtension, expectedWithoutExtension }) => { + // Test without stripping extension + const resultWithExtension = normalizePath(input, false); + expect(resultWithExtension).toBe(expectedWithExtension); + + // Test with extension stripping + const resultWithoutExtension = normalizePath(input, true); + expect(resultWithoutExtension).toBe(expectedWithoutExtension); + + // Add custom failure messages if needed + if (resultWithExtension !== expectedWithExtension) { + throw new Error( + `Failed with stripExtension=false for '${input}'. Expected '${expectedWithExtension}', got '${resultWithExtension}'`, + ); + } + if (resultWithoutExtension !== expectedWithoutExtension) { + throw new Error( + `Failed with stripExtension=true for '${input}'. Expected '${expectedWithoutExtension}', got '${resultWithoutExtension}'`, + ); + } + }, + ); +}); diff --git a/yarn.lock b/yarn.lock index d6cee5a6..11e7c226 100644 --- a/yarn.lock +++ b/yarn.lock @@ -79,381 +79,381 @@ "@smithy/util-utf8" "^2.0.0" tslib "^2.6.2" -"@aws-sdk/client-cognito-identity@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.799.0.tgz#80fd73c4e664427e86026f9a302f6b646d935d46" - integrity sha512-gg1sncxYDpYWetey3v/nw9zSkL/Vj2potpeO9sYWY2brcm8SbGh106I6IM/gX6KnY9Y2Bre8xb+JoZGz6ntcnw== +"@aws-sdk/client-cognito-identity@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.812.0.tgz#d36174fa9dbbab1a00391bc99583f5208d090a85" + integrity sha512-LWkP+Vb2f6aNaway06XvFZG3altSXltAClzCz9cTFuOfKG6V2X+0VWsW9cnFRV4+MFFJW3iQAaPMQ1fBO9Rusg== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "3.799.0" - "@aws-sdk/credential-provider-node" "3.799.0" - "@aws-sdk/middleware-host-header" "3.775.0" - "@aws-sdk/middleware-logger" "3.775.0" - "@aws-sdk/middleware-recursion-detection" "3.775.0" - "@aws-sdk/middleware-user-agent" "3.799.0" - "@aws-sdk/region-config-resolver" "3.775.0" - "@aws-sdk/types" "3.775.0" - "@aws-sdk/util-endpoints" "3.787.0" - "@aws-sdk/util-user-agent-browser" "3.775.0" - "@aws-sdk/util-user-agent-node" "3.799.0" - "@smithy/config-resolver" "^4.1.0" - "@smithy/core" "^3.3.0" + "@aws-sdk/core" "3.812.0" + "@aws-sdk/credential-provider-node" "3.812.0" + "@aws-sdk/middleware-host-header" "3.804.0" + "@aws-sdk/middleware-logger" "3.804.0" + "@aws-sdk/middleware-recursion-detection" "3.804.0" + "@aws-sdk/middleware-user-agent" "3.812.0" + "@aws-sdk/region-config-resolver" "3.808.0" + "@aws-sdk/types" "3.804.0" + "@aws-sdk/util-endpoints" "3.808.0" + "@aws-sdk/util-user-agent-browser" "3.804.0" + "@aws-sdk/util-user-agent-node" "3.812.0" + "@smithy/config-resolver" "^4.1.2" + "@smithy/core" "^3.3.3" "@smithy/fetch-http-handler" "^5.0.2" "@smithy/hash-node" "^4.0.2" "@smithy/invalid-dependency" "^4.0.2" "@smithy/middleware-content-length" "^4.0.2" - "@smithy/middleware-endpoint" "^4.1.1" - "@smithy/middleware-retry" "^4.1.1" - "@smithy/middleware-serde" "^4.0.3" + "@smithy/middleware-endpoint" "^4.1.6" + "@smithy/middleware-retry" "^4.1.7" + "@smithy/middleware-serde" "^4.0.5" "@smithy/middleware-stack" "^4.0.2" - "@smithy/node-config-provider" "^4.0.2" + "@smithy/node-config-provider" "^4.1.1" "@smithy/node-http-handler" "^4.0.4" "@smithy/protocol-http" "^5.1.0" - "@smithy/smithy-client" "^4.2.1" + "@smithy/smithy-client" "^4.2.6" "@smithy/types" "^4.2.0" "@smithy/url-parser" "^4.0.2" "@smithy/util-base64" "^4.0.0" "@smithy/util-body-length-browser" "^4.0.0" "@smithy/util-body-length-node" "^4.0.0" - "@smithy/util-defaults-mode-browser" "^4.0.9" - "@smithy/util-defaults-mode-node" "^4.0.9" - "@smithy/util-endpoints" "^3.0.2" + "@smithy/util-defaults-mode-browser" "^4.0.14" + "@smithy/util-defaults-mode-node" "^4.0.14" + "@smithy/util-endpoints" "^3.0.4" "@smithy/util-middleware" "^4.0.2" - "@smithy/util-retry" "^4.0.2" + "@smithy/util-retry" "^4.0.3" "@smithy/util-utf8" "^4.0.0" tslib "^2.6.2" "@aws-sdk/client-sagemaker@^3.583.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sagemaker/-/client-sagemaker-3.799.0.tgz#b6b4481f707c7e5d2536fe307e6f341f995a5827" - integrity sha512-So85e7gS7VW64ePgeVJNCxbSMU2tINQk/f3TRe7yKfdxQVvyq53jx88AwJgk2WUZYJxlDgEK6fBDvimzwFKJDA== + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sagemaker/-/client-sagemaker-3.812.0.tgz#8fa4321143556a6059065206800adf13b5c20342" + integrity sha512-KX+/Iu8Cde32low/0c+MGx03CShRJ9PB57qJtPtG6qgz0PeZc8e+t6lBjyZt33iUKZ25/Mt9277tXaSmxGpktw== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "3.799.0" - "@aws-sdk/credential-provider-node" "3.799.0" - "@aws-sdk/middleware-host-header" "3.775.0" - "@aws-sdk/middleware-logger" "3.775.0" - "@aws-sdk/middleware-recursion-detection" "3.775.0" - "@aws-sdk/middleware-user-agent" "3.799.0" - "@aws-sdk/region-config-resolver" "3.775.0" - "@aws-sdk/types" "3.775.0" - "@aws-sdk/util-endpoints" "3.787.0" - "@aws-sdk/util-user-agent-browser" "3.775.0" - "@aws-sdk/util-user-agent-node" "3.799.0" - "@smithy/config-resolver" "^4.1.0" - "@smithy/core" "^3.3.0" + "@aws-sdk/core" "3.812.0" + "@aws-sdk/credential-provider-node" "3.812.0" + "@aws-sdk/middleware-host-header" "3.804.0" + "@aws-sdk/middleware-logger" "3.804.0" + "@aws-sdk/middleware-recursion-detection" "3.804.0" + "@aws-sdk/middleware-user-agent" "3.812.0" + "@aws-sdk/region-config-resolver" "3.808.0" + "@aws-sdk/types" "3.804.0" + "@aws-sdk/util-endpoints" "3.808.0" + "@aws-sdk/util-user-agent-browser" "3.804.0" + "@aws-sdk/util-user-agent-node" "3.812.0" + "@smithy/config-resolver" "^4.1.2" + "@smithy/core" "^3.3.3" "@smithy/fetch-http-handler" "^5.0.2" "@smithy/hash-node" "^4.0.2" "@smithy/invalid-dependency" "^4.0.2" "@smithy/middleware-content-length" "^4.0.2" - "@smithy/middleware-endpoint" "^4.1.1" - "@smithy/middleware-retry" "^4.1.1" - "@smithy/middleware-serde" "^4.0.3" + "@smithy/middleware-endpoint" "^4.1.6" + "@smithy/middleware-retry" "^4.1.7" + "@smithy/middleware-serde" "^4.0.5" "@smithy/middleware-stack" "^4.0.2" - "@smithy/node-config-provider" "^4.0.2" + "@smithy/node-config-provider" "^4.1.1" "@smithy/node-http-handler" "^4.0.4" "@smithy/protocol-http" "^5.1.0" - "@smithy/smithy-client" "^4.2.1" + "@smithy/smithy-client" "^4.2.6" "@smithy/types" "^4.2.0" "@smithy/url-parser" "^4.0.2" "@smithy/util-base64" "^4.0.0" "@smithy/util-body-length-browser" "^4.0.0" "@smithy/util-body-length-node" "^4.0.0" - "@smithy/util-defaults-mode-browser" "^4.0.9" - "@smithy/util-defaults-mode-node" "^4.0.9" - "@smithy/util-endpoints" "^3.0.2" + "@smithy/util-defaults-mode-browser" "^4.0.14" + "@smithy/util-defaults-mode-node" "^4.0.14" + "@smithy/util-endpoints" "^3.0.4" "@smithy/util-middleware" "^4.0.2" - "@smithy/util-retry" "^4.0.2" + "@smithy/util-retry" "^4.0.3" "@smithy/util-utf8" "^4.0.0" "@smithy/util-waiter" "^4.0.3" "@types/uuid" "^9.0.1" tslib "^2.6.2" uuid "^9.0.1" -"@aws-sdk/client-sso@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.799.0.tgz#4e1e0831100a93147e9cfb8b29bcee88344effa0" - integrity sha512-/i/LG7AiWPmPxKCA2jnR2zaf7B3HYSTbxaZI21ElIz9wASlNAsKr8CnLY7qb50kOyXiNfQ834S5Q3Gl8dX9o3Q== +"@aws-sdk/client-sso@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.812.0.tgz#9d78a2ed62c241cf7d3e6d14e599d14dfd9d17c3" + integrity sha512-O//smQRj1+RXELB7xX54s5pZB0V69KHXpUZmz8V+8GAYO1FKTHfbpUgK+zyMNb+lFZxG9B69yl8pWPZ/K8bvxA== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "3.799.0" - "@aws-sdk/middleware-host-header" "3.775.0" - "@aws-sdk/middleware-logger" "3.775.0" - "@aws-sdk/middleware-recursion-detection" "3.775.0" - "@aws-sdk/middleware-user-agent" "3.799.0" - "@aws-sdk/region-config-resolver" "3.775.0" - "@aws-sdk/types" "3.775.0" - "@aws-sdk/util-endpoints" "3.787.0" - "@aws-sdk/util-user-agent-browser" "3.775.0" - "@aws-sdk/util-user-agent-node" "3.799.0" - "@smithy/config-resolver" "^4.1.0" - "@smithy/core" "^3.3.0" + "@aws-sdk/core" "3.812.0" + "@aws-sdk/middleware-host-header" "3.804.0" + "@aws-sdk/middleware-logger" "3.804.0" + "@aws-sdk/middleware-recursion-detection" "3.804.0" + "@aws-sdk/middleware-user-agent" "3.812.0" + "@aws-sdk/region-config-resolver" "3.808.0" + "@aws-sdk/types" "3.804.0" + "@aws-sdk/util-endpoints" "3.808.0" + "@aws-sdk/util-user-agent-browser" "3.804.0" + "@aws-sdk/util-user-agent-node" "3.812.0" + "@smithy/config-resolver" "^4.1.2" + "@smithy/core" "^3.3.3" "@smithy/fetch-http-handler" "^5.0.2" "@smithy/hash-node" "^4.0.2" "@smithy/invalid-dependency" "^4.0.2" "@smithy/middleware-content-length" "^4.0.2" - "@smithy/middleware-endpoint" "^4.1.1" - "@smithy/middleware-retry" "^4.1.1" - "@smithy/middleware-serde" "^4.0.3" + "@smithy/middleware-endpoint" "^4.1.6" + "@smithy/middleware-retry" "^4.1.7" + "@smithy/middleware-serde" "^4.0.5" "@smithy/middleware-stack" "^4.0.2" - "@smithy/node-config-provider" "^4.0.2" + "@smithy/node-config-provider" "^4.1.1" "@smithy/node-http-handler" "^4.0.4" "@smithy/protocol-http" "^5.1.0" - "@smithy/smithy-client" "^4.2.1" + "@smithy/smithy-client" "^4.2.6" "@smithy/types" "^4.2.0" "@smithy/url-parser" "^4.0.2" "@smithy/util-base64" "^4.0.0" "@smithy/util-body-length-browser" "^4.0.0" "@smithy/util-body-length-node" "^4.0.0" - "@smithy/util-defaults-mode-browser" "^4.0.9" - "@smithy/util-defaults-mode-node" "^4.0.9" - "@smithy/util-endpoints" "^3.0.2" + "@smithy/util-defaults-mode-browser" "^4.0.14" + "@smithy/util-defaults-mode-node" "^4.0.14" + "@smithy/util-endpoints" "^3.0.4" "@smithy/util-middleware" "^4.0.2" - "@smithy/util-retry" "^4.0.2" + "@smithy/util-retry" "^4.0.3" "@smithy/util-utf8" "^4.0.0" tslib "^2.6.2" -"@aws-sdk/core@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.799.0.tgz#383f903ede137df108dcd5f817074515d2b1242e" - integrity sha512-hkKF3Zpc6+H8GI1rlttYVRh9uEE77cqAzLmLpY3iu7sql8cZgPERRBfaFct8p1SaDyrksLNiboD1vKW58mbsYg== +"@aws-sdk/core@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/core/-/core-3.812.0.tgz#4bcc37d1edd5639454db86058299105b114f64d4" + integrity sha512-myWA9oHMBVDObKrxG+puAkIGs8igcWInQ1PWCRTS/zN4BkhUMFjjh/JPV/4Vzvtvj5E36iujq2WtlrDLl1PpOw== dependencies: - "@aws-sdk/types" "3.775.0" - "@smithy/core" "^3.3.0" - "@smithy/node-config-provider" "^4.0.2" + "@aws-sdk/types" "3.804.0" + "@smithy/core" "^3.3.3" + "@smithy/node-config-provider" "^4.1.1" "@smithy/property-provider" "^4.0.2" "@smithy/protocol-http" "^5.1.0" "@smithy/signature-v4" "^5.1.0" - "@smithy/smithy-client" "^4.2.1" + "@smithy/smithy-client" "^4.2.6" "@smithy/types" "^4.2.0" "@smithy/util-middleware" "^4.0.2" fast-xml-parser "4.4.1" tslib "^2.6.2" -"@aws-sdk/credential-provider-cognito-identity@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.799.0.tgz#eba1a19bb7bacd37371e2e0dbd3f126145ef9d88" - integrity sha512-qHOqGsvt/z1bvjJRzndW8VaRfbGBhoETZpoRYNbfCbrNH2IRM98KRUlYH1EJ1wFFkT0gUDJr+oIOUCvRlgRW1Q== +"@aws-sdk/credential-provider-cognito-identity@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.812.0.tgz#2d25a5e2cea1dee7d068381fe10e471ef226be16" + integrity sha512-SrEGXP1zs2Cy3jjOwM8eh+UZkr28z7rvjF+cgV4bpOti5F/mzPyVoIxDkG8BQ2sZdAwa9rgEhhOl4CcKjoJoTA== dependencies: - "@aws-sdk/client-cognito-identity" "3.799.0" - "@aws-sdk/types" "3.775.0" + "@aws-sdk/client-cognito-identity" "3.812.0" + "@aws-sdk/types" "3.804.0" "@smithy/property-provider" "^4.0.2" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-env@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.799.0.tgz#d933265b54b18ef1232762c318ff0d75bc7785f9" - integrity sha512-vT/SSWtbUIOW/U21qgEySmmO44SFWIA7WeQPX1OrI8WJ5n7OEI23JWLHjLvHTkYmuZK6z1rPcv7HzRgmuGRibA== +"@aws-sdk/credential-provider-env@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-env/-/credential-provider-env-3.812.0.tgz#97485f4e1351b6322e0fd01c4702641c702ced58" + integrity sha512-Ge7IEu06ANurGBZx39q9CNN/ncqb1K8lpKZCY969uNWO0/7YPhnplrRJGMZYIS35nD2mBm3ortEKjY/wMZZd5g== dependencies: - "@aws-sdk/core" "3.799.0" - "@aws-sdk/types" "3.775.0" + "@aws-sdk/core" "3.812.0" + "@aws-sdk/types" "3.804.0" "@smithy/property-provider" "^4.0.2" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-http@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.799.0.tgz#9286235bb30c4f22fbeac0ecf2fe5e5f99aaa282" - integrity sha512-2CjBpOWmhaPAExOgHnIB5nOkS5ef+mfRlJ1JC4nsnjAx0nrK4tk0XRE0LYz11P3+ue+a86cU8WTmBo+qjnGxPQ== +"@aws-sdk/credential-provider-http@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-http/-/credential-provider-http-3.812.0.tgz#ee2e024ec8137ef26897cbe70abd5705b1c63b68" + integrity sha512-Vux2U42vPGXeE407Lp6v3yVA65J7hBO9rB67LXshyGVi7VZLAYWc4mrZxNJNqabEkjcDEmMQQakLPT6zc5SvFw== dependencies: - "@aws-sdk/core" "3.799.0" - "@aws-sdk/types" "3.775.0" + "@aws-sdk/core" "3.812.0" + "@aws-sdk/types" "3.804.0" "@smithy/fetch-http-handler" "^5.0.2" "@smithy/node-http-handler" "^4.0.4" "@smithy/property-provider" "^4.0.2" "@smithy/protocol-http" "^5.1.0" - "@smithy/smithy-client" "^4.2.1" + "@smithy/smithy-client" "^4.2.6" "@smithy/types" "^4.2.0" "@smithy/util-stream" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-ini@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.799.0.tgz#89ed328e40d2bf0c37453c26b1dd74201c61da2c" - integrity sha512-M9ubILFxerqw4QJwk83MnjtZyoA2eNCiea5V+PzZeHlwk2PON/EnawKqy65x9/hMHGoSvvNuby7iMAmPptu7yw== - dependencies: - "@aws-sdk/core" "3.799.0" - "@aws-sdk/credential-provider-env" "3.799.0" - "@aws-sdk/credential-provider-http" "3.799.0" - "@aws-sdk/credential-provider-process" "3.799.0" - "@aws-sdk/credential-provider-sso" "3.799.0" - "@aws-sdk/credential-provider-web-identity" "3.799.0" - "@aws-sdk/nested-clients" "3.799.0" - "@aws-sdk/types" "3.775.0" - "@smithy/credential-provider-imds" "^4.0.2" +"@aws-sdk/credential-provider-ini@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.812.0.tgz#a4563a9b942e249b1c0424ef007e6c94d7aeee61" + integrity sha512-oltqGvQ488xtPY5wrNjbD+qQYYkuCjn30IDE1qKMxJ58EM6UVTQl3XV44Xq07xfF5gKwVJQkfIyOkRAguOVybg== + dependencies: + "@aws-sdk/core" "3.812.0" + "@aws-sdk/credential-provider-env" "3.812.0" + "@aws-sdk/credential-provider-http" "3.812.0" + "@aws-sdk/credential-provider-process" "3.812.0" + "@aws-sdk/credential-provider-sso" "3.812.0" + "@aws-sdk/credential-provider-web-identity" "3.812.0" + "@aws-sdk/nested-clients" "3.812.0" + "@aws-sdk/types" "3.804.0" + "@smithy/credential-provider-imds" "^4.0.4" "@smithy/property-provider" "^4.0.2" "@smithy/shared-ini-file-loader" "^4.0.2" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-node@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.799.0.tgz#45e646a24f105782dbaf3c55951dbae32ae73074" - integrity sha512-nd9fSJc0wUlgKUkIr2ldJhcIIrzJFS29AGZoyY22J3xih63nNDv61eTGVMsDZzHlV21XzMlPEljTR7axiimckg== - dependencies: - "@aws-sdk/credential-provider-env" "3.799.0" - "@aws-sdk/credential-provider-http" "3.799.0" - "@aws-sdk/credential-provider-ini" "3.799.0" - "@aws-sdk/credential-provider-process" "3.799.0" - "@aws-sdk/credential-provider-sso" "3.799.0" - "@aws-sdk/credential-provider-web-identity" "3.799.0" - "@aws-sdk/types" "3.775.0" - "@smithy/credential-provider-imds" "^4.0.2" +"@aws-sdk/credential-provider-node@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-node/-/credential-provider-node-3.812.0.tgz#47729e73a516b53e9c04c1d9ee3e6a4174ac9945" + integrity sha512-SnvSWBP6cr9nqx784eETnL2Zl7ZnMB/oJgFVEG1aejAGbT1H9gTpMwuUsBXk4u/mEYe3f1lh1Wqo+HwDgNkfrg== + dependencies: + "@aws-sdk/credential-provider-env" "3.812.0" + "@aws-sdk/credential-provider-http" "3.812.0" + "@aws-sdk/credential-provider-ini" "3.812.0" + "@aws-sdk/credential-provider-process" "3.812.0" + "@aws-sdk/credential-provider-sso" "3.812.0" + "@aws-sdk/credential-provider-web-identity" "3.812.0" + "@aws-sdk/types" "3.804.0" + "@smithy/credential-provider-imds" "^4.0.4" "@smithy/property-provider" "^4.0.2" "@smithy/shared-ini-file-loader" "^4.0.2" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-process@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.799.0.tgz#34e8b3d7c889bbb87dfe7c171255a8b99a34df25" - integrity sha512-g8jmNs2k98WNHMYcea1YKA+7ao2Ma4w0P42Dz4YpcI155pQHxHx25RwbOG+rsAKuo3bKwkW53HVE/ZTKhcWFgw== +"@aws-sdk/credential-provider-process@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-process/-/credential-provider-process-3.812.0.tgz#ef3f612c6f19e0133fc5ad199217bbe4e2e02ac8" + integrity sha512-YI8bb153XeEOb59F9KtTZEwDAc14s2YHZz58+OFiJ2udnKsPV87mNiFhJPW6ba9nmOLXVat5XDcwtVT1b664wg== dependencies: - "@aws-sdk/core" "3.799.0" - "@aws-sdk/types" "3.775.0" + "@aws-sdk/core" "3.812.0" + "@aws-sdk/types" "3.804.0" "@smithy/property-provider" "^4.0.2" "@smithy/shared-ini-file-loader" "^4.0.2" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-sso@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.799.0.tgz#535dd1d1abe5f2567551514444f18b79993ac92e" - integrity sha512-lQv27QkNU9FJFZqEf5DIEN3uXEN409Iaym9WJzhOouGtxvTIAWiD23OYh1u8PvBdrordJGS2YddfQvhcmq9akw== +"@aws-sdk/credential-provider-sso@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.812.0.tgz#7af71c1c0ee7473cbf9377c0b37abfd92161bcc2" + integrity sha512-ODsPcNhgiO6GOa82TVNskM97mml9rioe9Cbhemz48lkfDQPv1u06NaCR0o3FsvprX1sEhMvJTR3sE1fyEOzvJQ== dependencies: - "@aws-sdk/client-sso" "3.799.0" - "@aws-sdk/core" "3.799.0" - "@aws-sdk/token-providers" "3.799.0" - "@aws-sdk/types" "3.775.0" + "@aws-sdk/client-sso" "3.812.0" + "@aws-sdk/core" "3.812.0" + "@aws-sdk/token-providers" "3.812.0" + "@aws-sdk/types" "3.804.0" "@smithy/property-provider" "^4.0.2" "@smithy/shared-ini-file-loader" "^4.0.2" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/credential-provider-web-identity@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.799.0.tgz#ddf6c4e6f692289ba9e5db3ba9c63564742e5533" - integrity sha512-8k1i9ut+BEg0QZ+I6UQMxGNR1T8paLmAOAZXU+nLQR0lcxS6lr8v+dqofgzQPuHLBkWNCr1Av1IKeL3bJjgU7g== +"@aws-sdk/credential-provider-web-identity@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.812.0.tgz#d27b42f5a39918cf36ee40870b3f3fa896d1010e" + integrity sha512-E9Bmiujvm/Hp9DM/Vc1S+D0pQbx8/x4dR/zyAEZU9EoRq0duQOQ1reWYWbebYmL1OklcVpTfKV0a/VCwuAtGSg== dependencies: - "@aws-sdk/core" "3.799.0" - "@aws-sdk/nested-clients" "3.799.0" - "@aws-sdk/types" "3.775.0" + "@aws-sdk/core" "3.812.0" + "@aws-sdk/nested-clients" "3.812.0" + "@aws-sdk/types" "3.804.0" "@smithy/property-provider" "^4.0.2" "@smithy/types" "^4.2.0" tslib "^2.6.2" "@aws-sdk/credential-providers@^3.583.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/credential-providers/-/credential-providers-3.799.0.tgz#f86cff0bdaef9762b56132977186c4ec1e3249cd" - integrity sha512-Gk10skoEri6zsCPxn34Zpu6Z1B5R3RLwqDw1krNl+B1P749gB6i7XULXZUOotqpum0T0q4euOwAB8XWuTOkKew== - dependencies: - "@aws-sdk/client-cognito-identity" "3.799.0" - "@aws-sdk/core" "3.799.0" - "@aws-sdk/credential-provider-cognito-identity" "3.799.0" - "@aws-sdk/credential-provider-env" "3.799.0" - "@aws-sdk/credential-provider-http" "3.799.0" - "@aws-sdk/credential-provider-ini" "3.799.0" - "@aws-sdk/credential-provider-node" "3.799.0" - "@aws-sdk/credential-provider-process" "3.799.0" - "@aws-sdk/credential-provider-sso" "3.799.0" - "@aws-sdk/credential-provider-web-identity" "3.799.0" - "@aws-sdk/nested-clients" "3.799.0" - "@aws-sdk/types" "3.775.0" - "@smithy/config-resolver" "^4.1.0" - "@smithy/core" "^3.3.0" - "@smithy/credential-provider-imds" "^4.0.2" - "@smithy/node-config-provider" "^4.0.2" + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/credential-providers/-/credential-providers-3.812.0.tgz#b07044d8df183c5d909097d342a8a75e0c37b17f" + integrity sha512-hT7Kr8Ao+NS9b8KCB/U8cmpr0DcWOZNZNRBGAOc4eq65JpsRv177QmSqjh75vhM9BzchH3VymcP4GeMoy4SuvA== + dependencies: + "@aws-sdk/client-cognito-identity" "3.812.0" + "@aws-sdk/core" "3.812.0" + "@aws-sdk/credential-provider-cognito-identity" "3.812.0" + "@aws-sdk/credential-provider-env" "3.812.0" + "@aws-sdk/credential-provider-http" "3.812.0" + "@aws-sdk/credential-provider-ini" "3.812.0" + "@aws-sdk/credential-provider-node" "3.812.0" + "@aws-sdk/credential-provider-process" "3.812.0" + "@aws-sdk/credential-provider-sso" "3.812.0" + "@aws-sdk/credential-provider-web-identity" "3.812.0" + "@aws-sdk/nested-clients" "3.812.0" + "@aws-sdk/types" "3.804.0" + "@smithy/config-resolver" "^4.1.2" + "@smithy/core" "^3.3.3" + "@smithy/credential-provider-imds" "^4.0.4" + "@smithy/node-config-provider" "^4.1.1" "@smithy/property-provider" "^4.0.2" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/middleware-host-header@3.775.0": - version "3.775.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.775.0.tgz#1bf8160b8f4f96ba30c19f9baa030a6c9bd5f94d" - integrity sha512-tkSegM0Z6WMXpLB8oPys/d+umYIocvO298mGvcMCncpRl77L9XkvSLJIFzaHes+o7djAgIduYw8wKIMStFss2w== +"@aws-sdk/middleware-host-header@3.804.0": + version "3.804.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-host-header/-/middleware-host-header-3.804.0.tgz#e4c2180cfc75f19c697974383324509fa104d7a3" + integrity sha512-bum1hLVBrn2lJCi423Z2fMUYtsbkGI2s4N+2RI2WSjvbaVyMSv/WcejIrjkqiiMR+2Y7m5exgoKeg4/TODLDPQ== dependencies: - "@aws-sdk/types" "3.775.0" + "@aws-sdk/types" "3.804.0" "@smithy/protocol-http" "^5.1.0" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/middleware-logger@3.775.0": - version "3.775.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.775.0.tgz#df1909d441cd4bade8d6c7d24c41532808db0e81" - integrity sha512-FaxO1xom4MAoUJsldmR92nT1G6uZxTdNYOFYtdHfd6N2wcNaTuxgjIvqzg5y7QIH9kn58XX/dzf1iTjgqUStZw== +"@aws-sdk/middleware-logger@3.804.0": + version "3.804.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-logger/-/middleware-logger-3.804.0.tgz#9b7860d0193ec8647a1102aa6ffad070e3260513" + integrity sha512-w/qLwL3iq0KOPQNat0Kb7sKndl9BtceigINwBU7SpkYWX9L/Lem6f8NPEKrC9Tl4wDBht3Yztub4oRTy/horJA== dependencies: - "@aws-sdk/types" "3.775.0" + "@aws-sdk/types" "3.804.0" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/middleware-recursion-detection@3.775.0": - version "3.775.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.775.0.tgz#36a40f467754d7c86424d12ef45c05e96ce3475b" - integrity sha512-GLCzC8D0A0YDG5u3F5U03Vb9j5tcOEFhr8oc6PDk0k0vm5VwtZOE6LvK7hcCSoAB4HXyOUM0sQuXrbaAh9OwXA== +"@aws-sdk/middleware-recursion-detection@3.804.0": + version "3.804.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.804.0.tgz#797bbe72c765e83a1d4c259db9799b77831e1fbb" + integrity sha512-zqHOrvLRdsUdN/ehYfZ9Tf8svhbiLLz5VaWUz22YndFv6m9qaAcijkpAOlKexsv3nLBMJdSdJ6GUTAeIy3BZzw== dependencies: - "@aws-sdk/types" "3.775.0" + "@aws-sdk/types" "3.804.0" "@smithy/protocol-http" "^5.1.0" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/middleware-user-agent@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.799.0.tgz#e120e6e1341bcba5427cee0385172170e4615186" - integrity sha512-TropQZanbOTxa+p+Nl4fWkzlRhgFwDfW+Wb6TR3jZN7IXHNlPpgGFpdrgvBExhW/RBhqr+94OsR8Ou58lp3hhA== +"@aws-sdk/middleware-user-agent@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.812.0.tgz#83e66aab15cfa988506d650e58eae646de90b517" + integrity sha512-r+HFwtSvnAs6Fydp4mijylrTX0og9p/xfxOcKsqhMuk3HpZAIcf9sSjRQI6MBusYklg7pnM4sGEnPAZIrdRotA== dependencies: - "@aws-sdk/core" "3.799.0" - "@aws-sdk/types" "3.775.0" - "@aws-sdk/util-endpoints" "3.787.0" - "@smithy/core" "^3.3.0" + "@aws-sdk/core" "3.812.0" + "@aws-sdk/types" "3.804.0" + "@aws-sdk/util-endpoints" "3.808.0" + "@smithy/core" "^3.3.3" "@smithy/protocol-http" "^5.1.0" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/nested-clients@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/nested-clients/-/nested-clients-3.799.0.tgz#a3b223cfa22f809cee28eedea2ce1f30175665f9" - integrity sha512-zILlWh7asrcQG9JYMYgnvEQBfwmWKfED0yWCf3UNAmQcfS9wkCAWCgicNy/y5KvNvEYnHidsU117STtyuUNG5g== +"@aws-sdk/nested-clients@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/nested-clients/-/nested-clients-3.812.0.tgz#d62cdc70796e7d19869385263cdba052caba5818" + integrity sha512-FS/fImbEpJU3cXtBGR9fyVd+CP51eNKlvTMi3f4/6lSk3RmHjudNC9yEF/og3jtpT3O+7vsNOUW9mHco5IjdQQ== dependencies: "@aws-crypto/sha256-browser" "5.2.0" "@aws-crypto/sha256-js" "5.2.0" - "@aws-sdk/core" "3.799.0" - "@aws-sdk/middleware-host-header" "3.775.0" - "@aws-sdk/middleware-logger" "3.775.0" - "@aws-sdk/middleware-recursion-detection" "3.775.0" - "@aws-sdk/middleware-user-agent" "3.799.0" - "@aws-sdk/region-config-resolver" "3.775.0" - "@aws-sdk/types" "3.775.0" - "@aws-sdk/util-endpoints" "3.787.0" - "@aws-sdk/util-user-agent-browser" "3.775.0" - "@aws-sdk/util-user-agent-node" "3.799.0" - "@smithy/config-resolver" "^4.1.0" - "@smithy/core" "^3.3.0" + "@aws-sdk/core" "3.812.0" + "@aws-sdk/middleware-host-header" "3.804.0" + "@aws-sdk/middleware-logger" "3.804.0" + "@aws-sdk/middleware-recursion-detection" "3.804.0" + "@aws-sdk/middleware-user-agent" "3.812.0" + "@aws-sdk/region-config-resolver" "3.808.0" + "@aws-sdk/types" "3.804.0" + "@aws-sdk/util-endpoints" "3.808.0" + "@aws-sdk/util-user-agent-browser" "3.804.0" + "@aws-sdk/util-user-agent-node" "3.812.0" + "@smithy/config-resolver" "^4.1.2" + "@smithy/core" "^3.3.3" "@smithy/fetch-http-handler" "^5.0.2" "@smithy/hash-node" "^4.0.2" "@smithy/invalid-dependency" "^4.0.2" "@smithy/middleware-content-length" "^4.0.2" - "@smithy/middleware-endpoint" "^4.1.1" - "@smithy/middleware-retry" "^4.1.1" - "@smithy/middleware-serde" "^4.0.3" + "@smithy/middleware-endpoint" "^4.1.6" + "@smithy/middleware-retry" "^4.1.7" + "@smithy/middleware-serde" "^4.0.5" "@smithy/middleware-stack" "^4.0.2" - "@smithy/node-config-provider" "^4.0.2" + "@smithy/node-config-provider" "^4.1.1" "@smithy/node-http-handler" "^4.0.4" "@smithy/protocol-http" "^5.1.0" - "@smithy/smithy-client" "^4.2.1" + "@smithy/smithy-client" "^4.2.6" "@smithy/types" "^4.2.0" "@smithy/url-parser" "^4.0.2" "@smithy/util-base64" "^4.0.0" "@smithy/util-body-length-browser" "^4.0.0" "@smithy/util-body-length-node" "^4.0.0" - "@smithy/util-defaults-mode-browser" "^4.0.9" - "@smithy/util-defaults-mode-node" "^4.0.9" - "@smithy/util-endpoints" "^3.0.2" + "@smithy/util-defaults-mode-browser" "^4.0.14" + "@smithy/util-defaults-mode-node" "^4.0.14" + "@smithy/util-endpoints" "^3.0.4" "@smithy/util-middleware" "^4.0.2" - "@smithy/util-retry" "^4.0.2" + "@smithy/util-retry" "^4.0.3" "@smithy/util-utf8" "^4.0.0" tslib "^2.6.2" @@ -465,13 +465,13 @@ "@smithy/protocol-http" "^1.1.0" tslib "^2.5.0" -"@aws-sdk/region-config-resolver@3.775.0": - version "3.775.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.775.0.tgz#592b52498e68501fe46480be3dfb185e949d1eab" - integrity sha512-40iH3LJjrQS3LKUJAl7Wj0bln7RFPEvUYKFxtP8a+oKFDO0F65F52xZxIJbPn6sHkxWDAnZlGgdjZXM3p2g5wQ== +"@aws-sdk/region-config-resolver@3.808.0": + version "3.808.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/region-config-resolver/-/region-config-resolver-3.808.0.tgz#76b037215c39b01361b9c34b7205f0b52513607c" + integrity sha512-9x2QWfphkARZY5OGkl9dJxZlSlYM2l5inFeo2bKntGuwg4A4YUe5h7d5yJ6sZbam9h43eBrkOdumx03DAkQF9A== dependencies: - "@aws-sdk/types" "3.775.0" - "@smithy/node-config-provider" "^4.0.2" + "@aws-sdk/types" "3.804.0" + "@smithy/node-config-provider" "^4.1.1" "@smithy/types" "^4.2.0" "@smithy/util-config-provider" "^4.0.0" "@smithy/util-middleware" "^4.0.2" @@ -485,61 +485,61 @@ "@smithy/signature-v4" "^1.0.1" tslib "^2.5.0" -"@aws-sdk/token-providers@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.799.0.tgz#7b2cc6aa5b1a1058490b780ff975de29218ef3a0" - integrity sha512-/8iDjnsJs/D8AhGbDAmdF5oSHzE4jsDsM2RIIxmBAKTZXkaaclQBNX9CmAqLKQmO3IUMZsDH2KENHLVAk/N/mw== +"@aws-sdk/token-providers@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/token-providers/-/token-providers-3.812.0.tgz#3a4c362a7ff6b2c80e7621fcc94493b1c0e051f1" + integrity sha512-dbVBaKxrxE708ub5uH3w+cmKIeRQas+2Xf6rpckhohYY+IiflGOdK6aLrp3T6dOQgr/FJ37iQtcYNonAG+yVBQ== dependencies: - "@aws-sdk/nested-clients" "3.799.0" - "@aws-sdk/types" "3.775.0" + "@aws-sdk/nested-clients" "3.812.0" + "@aws-sdk/types" "3.804.0" "@smithy/property-provider" "^4.0.2" "@smithy/shared-ini-file-loader" "^4.0.2" "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/types@3.775.0", "@aws-sdk/types@^3.222.0": - version "3.775.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.775.0.tgz#09863a9e68c080947db7c3d226d1c56b8f0f5150" - integrity sha512-ZoGKwa4C9fC9Av6bdfqcW6Ix5ot05F/S4VxWR2nHuMv7hzfmAjTOcUiWT7UR4hM/U0whf84VhDtXN/DWAk52KA== +"@aws-sdk/types@3.804.0", "@aws-sdk/types@^3.222.0": + version "3.804.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/types/-/types-3.804.0.tgz#b70a734fa721450cf8a513cec0c276001a5d154f" + integrity sha512-A9qnsy9zQ8G89vrPPlNG9d1d8QcKRGqJKqwyGgS0dclJpwy6d1EWgQLIolKPl6vcFpLoe6avLOLxr+h8ur5wpg== dependencies: "@smithy/types" "^4.2.0" tslib "^2.6.2" -"@aws-sdk/util-endpoints@3.787.0": - version "3.787.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.787.0.tgz#1398f0bd87f19e615ae920c73e16d9d5e5cb76d1" - integrity sha512-fd3zkiOkwnbdbN0Xp9TsP5SWrmv0SpT70YEdbb8wAj2DWQwiCmFszaSs+YCvhoCdmlR3Wl9Spu0pGpSAGKeYvQ== +"@aws-sdk/util-endpoints@3.808.0": + version "3.808.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-endpoints/-/util-endpoints-3.808.0.tgz#a3d269c4d5a6536d6387ba3cd66876f5b52ce913" + integrity sha512-N6Lic98uc4ADB7fLWlzx+1uVnq04VgVjngZvwHoujcRg9YDhIg9dUDiTzD5VZv13g1BrPYmvYP1HhsildpGV6w== dependencies: - "@aws-sdk/types" "3.775.0" + "@aws-sdk/types" "3.804.0" "@smithy/types" "^4.2.0" - "@smithy/util-endpoints" "^3.0.2" + "@smithy/util-endpoints" "^3.0.4" tslib "^2.6.2" "@aws-sdk/util-locate-window@^3.0.0": - version "3.723.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.723.0.tgz#174551bfdd2eb36d3c16e7023fd7e7ee96ad0fa9" - integrity sha512-Yf2CS10BqK688DRsrKI/EO6B8ff5J86NXe4C+VCysK7UOgN0l1zOTeTukZ3H8Q9tYYX3oaF1961o8vRkFm7Nmw== + version "3.804.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-locate-window/-/util-locate-window-3.804.0.tgz#a2ee8dc5d9c98276986e8e1ba03c0c84d9afb0f5" + integrity sha512-zVoRfpmBVPodYlnMjgVjfGoEZagyRF5IPn3Uo6ZvOZp24chnW/FRstH7ESDHDDRga4z3V+ElUQHKpFDXWyBW5A== dependencies: tslib "^2.6.2" -"@aws-sdk/util-user-agent-browser@3.775.0": - version "3.775.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.775.0.tgz#b69a1a5548ccc6db1acb3ec115967593ece927a1" - integrity sha512-txw2wkiJmZKVdDbscK7VBK+u+TJnRtlUjRTLei+elZg2ADhpQxfVAQl436FUeIv6AhB/oRHW6/K/EAGXUSWi0A== +"@aws-sdk/util-user-agent-browser@3.804.0": + version "3.804.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.804.0.tgz#0312fda0fd34958a1d89e7691c5b1cf41ad5549b" + integrity sha512-KfW6T6nQHHM/vZBBdGn6fMyG/MgX5lq82TDdX4HRQRRuHKLgBWGpKXqqvBwqIaCdXwWHgDrg2VQups6GqOWW2A== dependencies: - "@aws-sdk/types" "3.775.0" + "@aws-sdk/types" "3.804.0" "@smithy/types" "^4.2.0" bowser "^2.11.0" tslib "^2.6.2" -"@aws-sdk/util-user-agent-node@3.799.0": - version "3.799.0" - resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.799.0.tgz#8d0794add4efc79830143277f5faa27f16531c7a" - integrity sha512-iXBk38RbIWPF5Nq9O4AnktORAzXovSVqWYClvS1qbE7ILsnTLJbagU9HlU25O2iV5COVh1qZkwuP5NHQ2yTEyw== +"@aws-sdk/util-user-agent-node@3.812.0": + version "3.812.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.812.0.tgz#2ce37fe79922b1eb8097ac3ead3a2e5501aab36b" + integrity sha512-8pt+OkHhS2U0LDwnzwRnFxyKn8sjSe752OIZQCNv263odud8jQu9pYO2pKqb2kRBk9h9szynjZBDLXfnvSQ7Bg== dependencies: - "@aws-sdk/middleware-user-agent" "3.799.0" - "@aws-sdk/types" "3.775.0" - "@smithy/node-config-provider" "^4.0.2" + "@aws-sdk/middleware-user-agent" "3.812.0" + "@aws-sdk/types" "3.804.0" + "@smithy/node-config-provider" "^4.1.1" "@smithy/types" "^4.2.0" tslib "^2.6.2" @@ -559,10 +559,10 @@ js-tokens "^4.0.0" picocolors "^1.1.1" -"@babel/compat-data@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.27.1.tgz#db7cf122745e0a332c44e847ddc4f5e5221a43f6" - integrity sha512-Q+E+rd/yBzNQhXkG+zQnF58e4zoZfBedaxwzPmicKsiK3nt8iJYrSrDbjwFFDGC4f+rPafqRaPH6TsDoSvMf7A== +"@babel/compat-data@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.27.2.tgz#4183f9e642fd84e74e3eea7ffa93a412e3b102c9" + integrity sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ== "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": version "7.27.1" @@ -606,11 +606,11 @@ jsesc "^3.0.2" "@babel/helper-compilation-targets@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.1.tgz#eac1096c7374f161e4f33fc8ae38f4ddf122087a" - integrity sha512-2YaDd/Rd9E598B5+WIc8wJPmWETiiJXFYVE60oX8FDohv7rAUU3CQj+A1MgeEmcsk2+dQuEjIe/GDvig0SqL4g== + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d" + integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== dependencies: - "@babel/compat-data" "^7.27.1" + "@babel/compat-data" "^7.27.2" "@babel/helper-validator-option" "^7.27.1" browserslist "^4.24.0" lru-cache "^5.1.1" @@ -690,10 +690,10 @@ "@babel/template" "^7.27.1" "@babel/types" "^7.27.1" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.5", "@babel/parser@^7.20.7", "@babel/parser@^7.23.0", "@babel/parser@^7.23.9", "@babel/parser@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.1.tgz#c55d5bed74449d1223701f1869b9ee345cc94cc9" - integrity sha512-I0dZ3ZpCrJ1c04OqlNsQcKiZlsrXf/kkE4FXzID9rIOYICsAbA8mMDzhW/luRNAHdCNt7os/u8wenklZDlUVUQ== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.5", "@babel/parser@^7.20.7", "@babel/parser@^7.23.0", "@babel/parser@^7.23.9", "@babel/parser@^7.27.1", "@babel/parser@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.2.tgz#577518bedb17a2ce4212afd052e01f7df0941127" + integrity sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw== dependencies: "@babel/types" "^7.27.1" @@ -817,12 +817,12 @@ "@babel/helper-plugin-utils" "^7.27.1" "@babel/template@^7.24.7", "@babel/template@^7.27.1", "@babel/template@^7.3.3": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.1.tgz#b9e4f55c17a92312774dfbdde1b3c01c547bbae2" - integrity sha512-Fyo3ghWMqkHHpHQCoBs2VnYjR4iWFFjguTDEqA5WgZDOrFesVjMhMM2FSqTKSoUSDO1VQtavj8NFpdRBEvJTtg== + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" + integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== dependencies: "@babel/code-frame" "^7.27.1" - "@babel/parser" "^7.27.1" + "@babel/parser" "^7.27.2" "@babel/types" "^7.27.1" "@babel/traverse@7.23.2": @@ -1198,9 +1198,9 @@ integrity sha512-lp4qAiMTD4sNWW4DbKLBkfiMZ4jbAboJIGOQr5DvciMRI494OapieI9qiODpOt0XBr1LjIDy1xAGAnVs5supTA== "@opentelemetry/semantic-conventions@^1.28.0", "@opentelemetry/semantic-conventions@^1.29.0": - version "1.32.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.32.0.tgz#a15e8f78f32388a7e4655e7f539570e40958ca3f" - integrity sha512-s0OpmpQFSfMrmedAn9Lhg4KWJELHCU6uU9dtIJ28N8UGhf9Y55im5X8fEzwhwDwiSqN+ZPSNrDJF7ivf/AuRPQ== + version "1.33.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.33.0.tgz#ec8ebd2ac768ab366aff94e0e7f27e8ae24fa49f" + integrity sha512-TIpZvE8fiEILFfTlfPnltpBaD3d9/+uQHVCyC3vfdh6WfCXKhNFzoP5RyDDIndfvZC5GrA4pyEDNyjPloJud+w== "@sinclair/typebox@^0.27.8": version "0.27.8" @@ -1221,48 +1221,48 @@ dependencies: "@sinonjs/commons" "^3.0.0" -"@smithy/abort-controller@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-4.0.2.tgz#36a23e8cc65fc03cacb6afa35dfbfd319c560c6b" - integrity sha512-Sl/78VDtgqKxN2+1qduaVE140XF+Xg+TafkncspwM4jFP/LHr76ZHmIY/y3V1M0mMLNk+Je6IGbzxy23RSToMw== +"@smithy/abort-controller@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@smithy/abort-controller/-/abort-controller-4.0.3.tgz#53a53dabc5a46fec70857acb07653d658c79b916" + integrity sha512-AqXFf6DXnuRBXy4SoK/n1mfgHaKaq36bmkphmD1KO0nHq6xK/g9KHSW4HEsPQUBCGdIEfuJifGHwxFXPIFay9Q== dependencies: - "@smithy/types" "^4.2.0" + "@smithy/types" "^4.3.0" tslib "^2.6.2" -"@smithy/config-resolver@^4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-4.1.0.tgz#de1043cbd75f05d99798b0fbcfdaf4b89b0f2f41" - integrity sha512-8smPlwhga22pwl23fM5ew4T9vfLUCeFXlcqNOCD5M5h8VmNPNUE9j6bQSuRXpDSV11L/E/SwEBQuW8hr6+nS1A== +"@smithy/config-resolver@^4.1.2", "@smithy/config-resolver@^4.1.3": + version "4.1.3" + resolved "https://registry.yarnpkg.com/@smithy/config-resolver/-/config-resolver-4.1.3.tgz#d883b2edaa05594cb7f002b2e1d4c5b495c1be42" + integrity sha512-N5e7ofiyYDmHxnPnqF8L4KtsbSDwyxFRfDK9bp1d9OyPO4ytRLd0/XxCqi5xVaaqB65v4woW8uey6jND6zxzxQ== dependencies: - "@smithy/node-config-provider" "^4.0.2" - "@smithy/types" "^4.2.0" + "@smithy/node-config-provider" "^4.1.2" + "@smithy/types" "^4.3.0" "@smithy/util-config-provider" "^4.0.0" - "@smithy/util-middleware" "^4.0.2" + "@smithy/util-middleware" "^4.0.3" tslib "^2.6.2" -"@smithy/core@^3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@smithy/core/-/core-3.3.0.tgz#a6b141733fa530cb2f9b49a8e70ae98169c92cf0" - integrity sha512-r6gvs5OfRq/w+9unPm7B3po4rmWaGh0CIL/OwHntGGux7+RhOOZLGuurbeMgWV6W55ZuyMTypJLeH0vn/ZRaWQ== +"@smithy/core@^3.3.3", "@smithy/core@^3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@smithy/core/-/core-3.4.0.tgz#e8f4c93d138e68bfc76d43a63429b2b276987d19" + integrity sha512-dDYISQo7k0Ml/rXlFIjkTmTcQze/LxhtIRAEmZ6HJ/EI0inVxVEVnrUXJ7jPx6ZP0GHUhFm40iQcCgS5apXIXA== dependencies: - "@smithy/middleware-serde" "^4.0.3" - "@smithy/protocol-http" "^5.1.0" - "@smithy/types" "^4.2.0" + "@smithy/middleware-serde" "^4.0.6" + "@smithy/protocol-http" "^5.1.1" + "@smithy/types" "^4.3.0" "@smithy/util-body-length-browser" "^4.0.0" - "@smithy/util-middleware" "^4.0.2" - "@smithy/util-stream" "^4.2.0" + "@smithy/util-middleware" "^4.0.3" + "@smithy/util-stream" "^4.2.1" "@smithy/util-utf8" "^4.0.0" tslib "^2.6.2" -"@smithy/credential-provider-imds@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.2.tgz#1ec34a04842fa69996b151a695b027f0486c69a8" - integrity sha512-32lVig6jCaWBHnY+OEQ6e6Vnt5vDHaLiydGrwYMW9tPqO688hPGTYRamYJ1EptxEC2rAwJrHWmPoKRBl4iTa8w== +"@smithy/credential-provider-imds@^4.0.4", "@smithy/credential-provider-imds@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.5.tgz#d44989d783300af37b2be2fc4ec29cdb67540c32" + integrity sha512-saEAGwrIlkb9XxX/m5S5hOtzjoJPEK6Qw2f9pYTbIsMPOFyGSXBBTw95WbOyru8A1vIS2jVCCU1Qhz50QWG3IA== dependencies: - "@smithy/node-config-provider" "^4.0.2" - "@smithy/property-provider" "^4.0.2" - "@smithy/types" "^4.2.0" - "@smithy/url-parser" "^4.0.2" + "@smithy/node-config-provider" "^4.1.2" + "@smithy/property-provider" "^4.0.3" + "@smithy/types" "^4.3.0" + "@smithy/url-parser" "^4.0.3" tslib "^2.6.2" "@smithy/eventstream-codec@^1.1.0": @@ -1275,33 +1275,33 @@ "@smithy/util-hex-encoding" "^1.1.0" tslib "^2.5.0" -"@smithy/fetch-http-handler@^5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.2.tgz#9d3cacf044aa9573ab933f445ab95cddb284813d" - integrity sha512-+9Dz8sakS9pe7f2cBocpJXdeVjMopUDLgZs1yWeu7h++WqSbjUYv/JAJwKwXw1HV6gq1jyWjxuyn24E2GhoEcQ== +"@smithy/fetch-http-handler@^5.0.2", "@smithy/fetch-http-handler@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.3.tgz#4db3296bbacd6ddfdc9f8b8b2a6fb52d201dace3" + integrity sha512-yBZwavI31roqTndNI7ONHqesfH01JmjJK6L3uUpZAhyAmr86LN5QiPzfyZGIxQmed8VEK2NRSQT3/JX5V1njfQ== dependencies: - "@smithy/protocol-http" "^5.1.0" - "@smithy/querystring-builder" "^4.0.2" - "@smithy/types" "^4.2.0" + "@smithy/protocol-http" "^5.1.1" + "@smithy/querystring-builder" "^4.0.3" + "@smithy/types" "^4.3.0" "@smithy/util-base64" "^4.0.0" tslib "^2.6.2" "@smithy/hash-node@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-4.0.2.tgz#a34fe5a33b067d754ca63302b9791778f003e437" - integrity sha512-VnTpYPnRUE7yVhWozFdlxcYknv9UN7CeOqSrMH+V877v4oqtVYuoqhIhtSjmGPvYrYnAkaM61sLMKHvxL138yg== + version "4.0.3" + resolved "https://registry.yarnpkg.com/@smithy/hash-node/-/hash-node-4.0.3.tgz#262367c0cb80f9975bdb96e945067dd1f04cdef2" + integrity sha512-W5Uhy6v/aYrgtjh9y0YP332gIQcwccQ+EcfWhllL0B9rPae42JngTTUpb8W6wuxaNFzqps4xq5klHckSSOy5fw== dependencies: - "@smithy/types" "^4.2.0" + "@smithy/types" "^4.3.0" "@smithy/util-buffer-from" "^4.0.0" "@smithy/util-utf8" "^4.0.0" tslib "^2.6.2" "@smithy/invalid-dependency@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-4.0.2.tgz#e9b1c5e407d795f10a03afba90e37bccdc3e38f7" - integrity sha512-GatB4+2DTpgWPday+mnUkoumP54u/MDM/5u44KF9hIu8jF0uafZtQLcdfIKkIcUNuF/fBojpLEHZS/56JqPeXQ== + version "4.0.3" + resolved "https://registry.yarnpkg.com/@smithy/invalid-dependency/-/invalid-dependency-4.0.3.tgz#045edee05cc380c06ffdf8cc1a81d54005c1e134" + integrity sha512-1Bo8Ur1ZGqxvwTqBmv6DZEn0rXtwJGeqiiO2/JFcCtz3nBakOqeXbJBElXJMMzd0ghe8+eB6Dkw98nMYctgizg== dependencies: - "@smithy/types" "^4.2.0" + "@smithy/types" "^4.3.0" tslib "^2.6.2" "@smithy/is-array-buffer@^1.1.0": @@ -1326,86 +1326,87 @@ tslib "^2.6.2" "@smithy/middleware-content-length@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-4.0.2.tgz#ff78658e8047ad7038f58478cf8713ee2f6ef647" - integrity sha512-hAfEXm1zU+ELvucxqQ7I8SszwQ4znWMbNv6PLMndN83JJN41EPuS93AIyh2N+gJ6x8QFhzSO6b7q2e6oClDI8A== + version "4.0.3" + resolved "https://registry.yarnpkg.com/@smithy/middleware-content-length/-/middleware-content-length-4.0.3.tgz#6ca78cda6569e9c0a2b4f788729f874a461b8554" + integrity sha512-NE/Zph4BP5u16bzYq2csq9qD0T6UBLeg4AuNrwNJ7Gv9uLYaGEgelZUOdRndGdMGcUfSGvNlXGb2aA2hPCwJ6g== dependencies: - "@smithy/protocol-http" "^5.1.0" - "@smithy/types" "^4.2.0" + "@smithy/protocol-http" "^5.1.1" + "@smithy/types" "^4.3.0" tslib "^2.6.2" -"@smithy/middleware-endpoint@^4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.1.tgz#d210cac102a645ea35541c17fda52c73f0b56304" - integrity sha512-z5RmcHxjvScL+LwEDU2mTNCOhgUs4lu5PGdF1K36IPRmUHhNFxNxgenSB7smyDiYD4vdKQ7CAZtG5cUErqib9w== - dependencies: - "@smithy/core" "^3.3.0" - "@smithy/middleware-serde" "^4.0.3" - "@smithy/node-config-provider" "^4.0.2" - "@smithy/shared-ini-file-loader" "^4.0.2" - "@smithy/types" "^4.2.0" - "@smithy/url-parser" "^4.0.2" - "@smithy/util-middleware" "^4.0.2" +"@smithy/middleware-endpoint@^4.1.6", "@smithy/middleware-endpoint@^4.1.7": + version "4.1.7" + resolved "https://registry.yarnpkg.com/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.7.tgz#7b15fc81171dc879c9d9c8f5297d4939d0f6a234" + integrity sha512-KDzM7Iajo6K7eIWNNtukykRT4eWwlHjCEsULZUaSfi/SRSBK8BPRqG5FsVfp58lUxcvre8GT8AIPIqndA0ERKw== + dependencies: + "@smithy/core" "^3.4.0" + "@smithy/middleware-serde" "^4.0.6" + "@smithy/node-config-provider" "^4.1.2" + "@smithy/shared-ini-file-loader" "^4.0.3" + "@smithy/types" "^4.3.0" + "@smithy/url-parser" "^4.0.3" + "@smithy/util-middleware" "^4.0.3" tslib "^2.6.2" -"@smithy/middleware-retry@^4.1.1": - version "4.1.1" - resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-4.1.1.tgz#8c65dec6fca1f4883a10f724f9d6cafea19d0ba4" - integrity sha512-mBJOxn9aUYwcBUPQpKv9ifzrCn4EbhPUFguEZv3jB57YOMh0caS4P8HoLvUeNUI1nx4bIVH2SIbogbDfFI9DUA== - dependencies: - "@smithy/node-config-provider" "^4.0.2" - "@smithy/protocol-http" "^5.1.0" - "@smithy/service-error-classification" "^4.0.2" - "@smithy/smithy-client" "^4.2.1" - "@smithy/types" "^4.2.0" - "@smithy/util-middleware" "^4.0.2" - "@smithy/util-retry" "^4.0.2" +"@smithy/middleware-retry@^4.1.7": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@smithy/middleware-retry/-/middleware-retry-4.1.8.tgz#1b6123ef5ad4ea9e55d6e4a0d1912c238d019e05" + integrity sha512-e2OtQgFzzlSG0uCjcJmi02QuFSRTrpT11Eh2EcqqDFy7DYriteHZJkkf+4AsxsrGDugAtPFcWBz1aq06sSX5fQ== + dependencies: + "@smithy/node-config-provider" "^4.1.2" + "@smithy/protocol-http" "^5.1.1" + "@smithy/service-error-classification" "^4.0.4" + "@smithy/smithy-client" "^4.3.0" + "@smithy/types" "^4.3.0" + "@smithy/util-middleware" "^4.0.3" + "@smithy/util-retry" "^4.0.4" tslib "^2.6.2" uuid "^9.0.1" -"@smithy/middleware-serde@^4.0.3": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-4.0.3.tgz#b90ef1065ad9dc0b54c561fae73c8a5792d145e3" - integrity sha512-rfgDVrgLEVMmMn0BI8O+8OVr6vXzjV7HZj57l0QxslhzbvVfikZbVfBVthjLHqib4BW44QhcIgJpvebHlRaC9A== +"@smithy/middleware-serde@^4.0.5", "@smithy/middleware-serde@^4.0.6": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@smithy/middleware-serde/-/middleware-serde-4.0.6.tgz#76e8523b48f2402ccef97b6764d9cfe35e7df669" + integrity sha512-YECyl7uNII+jCr/9qEmCu8xYL79cU0fqjo0qxpcVIU18dAPHam/iYwcknAu4Jiyw1uN+sAx7/SMf/Kmef/Jjsg== dependencies: - "@smithy/types" "^4.2.0" + "@smithy/protocol-http" "^5.1.1" + "@smithy/types" "^4.3.0" tslib "^2.6.2" -"@smithy/middleware-stack@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-4.0.2.tgz#ca7bc3eedc7c1349e2cf94e0dc92a68d681bef18" - integrity sha512-eSPVcuJJGVYrFYu2hEq8g8WWdJav3sdrI4o2c6z/rjnYDd3xH9j9E7deZQCzFn4QvGPouLngH3dQ+QVTxv5bOQ== +"@smithy/middleware-stack@^4.0.2", "@smithy/middleware-stack@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@smithy/middleware-stack/-/middleware-stack-4.0.3.tgz#4231f41e05f63d088644bc829b182850f5a9ee59" + integrity sha512-baeV7t4jQfQtFxBADFmnhmqBmqR38dNU5cvEgHcMK/Kp3D3bEI0CouoX2Sr/rGuntR+Eg0IjXdxnGGTc6SbIkw== dependencies: - "@smithy/types" "^4.2.0" + "@smithy/types" "^4.3.0" tslib "^2.6.2" -"@smithy/node-config-provider@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-4.0.2.tgz#017ba626828bced0fa588e795246e5468632f3ef" - integrity sha512-WgCkILRZfJwJ4Da92a6t3ozN/zcvYyJGUTmfGbgS/FkCcoCjl7G4FJaCDN1ySdvLvemnQeo25FdkyMSTSwulsw== +"@smithy/node-config-provider@^4.1.1", "@smithy/node-config-provider@^4.1.2": + version "4.1.2" + resolved "https://registry.yarnpkg.com/@smithy/node-config-provider/-/node-config-provider-4.1.2.tgz#6397998db6741ada1f9ee1bf6665190b02d68084" + integrity sha512-SUvNup8iU1v7fmM8XPk+27m36udmGCfSz+VZP5Gb0aJ3Ne0X28K/25gnsrg3X1rWlhcnhzNUUysKW/Ied46ivQ== dependencies: - "@smithy/property-provider" "^4.0.2" - "@smithy/shared-ini-file-loader" "^4.0.2" - "@smithy/types" "^4.2.0" + "@smithy/property-provider" "^4.0.3" + "@smithy/shared-ini-file-loader" "^4.0.3" + "@smithy/types" "^4.3.0" tslib "^2.6.2" -"@smithy/node-http-handler@^4.0.4": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-4.0.4.tgz#aa583d201c1ee968170b65a07f06d633c214b7a1" - integrity sha512-/mdqabuAT3o/ihBGjL94PUbTSPSRJ0eeVTdgADzow0wRJ0rN4A27EOrtlK56MYiO1fDvlO3jVTCxQtQmK9dZ1g== +"@smithy/node-http-handler@^4.0.4", "@smithy/node-http-handler@^4.0.5": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@smithy/node-http-handler/-/node-http-handler-4.0.5.tgz#7d825f35d8e006a2662b7237eb7d369430883140" + integrity sha512-T7QglZC1vS7SPT44/1qSIAQEx5bFKb3LfO6zw/o4Xzt1eC5HNoH1TkS4lMYA9cWFbacUhx4hRl/blLun4EOCkg== dependencies: - "@smithy/abort-controller" "^4.0.2" - "@smithy/protocol-http" "^5.1.0" - "@smithy/querystring-builder" "^4.0.2" - "@smithy/types" "^4.2.0" + "@smithy/abort-controller" "^4.0.3" + "@smithy/protocol-http" "^5.1.1" + "@smithy/querystring-builder" "^4.0.3" + "@smithy/types" "^4.3.0" tslib "^2.6.2" -"@smithy/property-provider@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-4.0.2.tgz#4572c10415c9d4215f3df1530ba61b0319b17b55" - integrity sha512-wNRoQC1uISOuNc2s4hkOYwYllmiyrvVXWMtq+TysNRVQaHm4yoafYQyjN/goYZS+QbYlPIbb/QRjaUZMuzwQ7A== +"@smithy/property-provider@^4.0.2", "@smithy/property-provider@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@smithy/property-provider/-/property-provider-4.0.3.tgz#cefeb7bc7a8baaeec9f68e82c3164141703a15d5" + integrity sha512-Wcn17QNdawJZcZZPBuMuzyBENVi1AXl4TdE0jvzo4vWX2x5df/oMlmr/9M5XAAC6+yae4kWZlOYIsNsgDrMU9A== dependencies: - "@smithy/types" "^4.2.0" + "@smithy/types" "^4.3.0" tslib "^2.6.2" "@smithy/protocol-http@^1.1.0": @@ -1416,44 +1417,44 @@ "@smithy/types" "^1.2.0" tslib "^2.5.0" -"@smithy/protocol-http@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-5.1.0.tgz#ad34e336a95944785185234bebe2ec8dbe266936" - integrity sha512-KxAOL1nUNw2JTYrtviRRjEnykIDhxc84qMBzxvu1MUfQfHTuBlCG7PA6EdVwqpJjH7glw7FqQoFxUJSyBQgu7g== +"@smithy/protocol-http@^5.1.0", "@smithy/protocol-http@^5.1.1": + version "5.1.1" + resolved "https://registry.yarnpkg.com/@smithy/protocol-http/-/protocol-http-5.1.1.tgz#95d998526cd806b7902b0440c3f25188945a2e2c" + integrity sha512-Vsay2mzq05DwNi9jK01yCFtfvu9HimmgC7a4HTs7lhX12Sx8aWsH0mfz6q/02yspSp+lOB+Q2HJwi4IV2GKz7A== dependencies: - "@smithy/types" "^4.2.0" + "@smithy/types" "^4.3.0" tslib "^2.6.2" -"@smithy/querystring-builder@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-4.0.2.tgz#834cea95bf413ab417bf9c166d60fd80d2cb3016" - integrity sha512-NTOs0FwHw1vimmQM4ebh+wFQvOwkEf/kQL6bSM1Lock+Bv4I89B3hGYoUEPkmvYPkDKyp5UdXJYu+PoTQ3T31Q== +"@smithy/querystring-builder@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@smithy/querystring-builder/-/querystring-builder-4.0.3.tgz#056a17082e0a0ab10c817380d96321a8bba588fd" + integrity sha512-UUzIWMVfPmDZcOutk2/r1vURZqavvQW0OHvgsyNV0cKupChvqg+/NKPRMaMEe+i8tP96IthMFeZOZWpV+E4RAw== dependencies: - "@smithy/types" "^4.2.0" + "@smithy/types" "^4.3.0" "@smithy/util-uri-escape" "^4.0.0" tslib "^2.6.2" -"@smithy/querystring-parser@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-4.0.2.tgz#d80c5afb740e12ad8b4d4f58415e402c69712479" - integrity sha512-v6w8wnmZcVXjfVLjxw8qF7OwESD9wnpjp0Dqry/Pod0/5vcEA3qxCr+BhbOHlxS8O+29eLpT3aagxXGwIoEk7Q== +"@smithy/querystring-parser@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@smithy/querystring-parser/-/querystring-parser-4.0.3.tgz#ac8b26a23b7b9423734620cd025b5963bad764ae" + integrity sha512-K5M4ZJQpFCblOJ5Oyw7diICpFg1qhhR47m2/5Ef1PhGE19RaIZf50tjYFrxa6usqcuXyTiFPGo4d1geZdH4YcQ== dependencies: - "@smithy/types" "^4.2.0" + "@smithy/types" "^4.3.0" tslib "^2.6.2" -"@smithy/service-error-classification@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-4.0.2.tgz#96740ed8be7ac5ad7d6f296d4ddf3f66444b8dcc" - integrity sha512-LA86xeFpTKn270Hbkixqs5n73S+LVM0/VZco8dqd+JT75Dyx3Lcw/MraL7ybjmz786+160K8rPOmhsq0SocoJQ== +"@smithy/service-error-classification@^4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@smithy/service-error-classification/-/service-error-classification-4.0.4.tgz#63aef3b40db39ef7f04f4ffcca8bf4ef57ff5b23" + integrity sha512-W5ScbQ1bTzgH91kNEE2CvOzM4gXlDOqdow4m8vMFSIXCel2scbHwjflpVNnC60Y3F1m5i7w2gQg9lSnR+JsJAA== dependencies: - "@smithy/types" "^4.2.0" + "@smithy/types" "^4.3.0" -"@smithy/shared-ini-file-loader@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.2.tgz#15043f0516fe09ff4b22982bc5f644dc701ebae5" - integrity sha512-J9/gTWBGVuFZ01oVA6vdb4DAjf1XbDhK6sLsu3OS9qmLrS6KB5ygpeHiM3miIbj1qgSJ96GYszXFWv6ErJ8QEw== +"@smithy/shared-ini-file-loader@^4.0.2", "@smithy/shared-ini-file-loader@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.3.tgz#23fab0e773630b0817846c52c54b435ac32a4dd0" + integrity sha512-vHwlrqhZGIoLwaH8vvIjpHnloShqdJ7SUPNM2EQtEox+yEDFTVQ7E+DLZ+6OhnYEgFUwPByJyz6UZaOu2tny6A== dependencies: - "@smithy/types" "^4.2.0" + "@smithy/types" "^4.3.0" tslib "^2.6.2" "@smithy/signature-v4@^1.0.1": @@ -1471,30 +1472,30 @@ tslib "^2.5.0" "@smithy/signature-v4@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-5.1.0.tgz#2c56e5b278482b04383d84ea2c07b7f0a8eb8f63" - integrity sha512-4t5WX60sL3zGJF/CtZsUQTs3UrZEDO2P7pEaElrekbLqkWPYkgqNW1oeiNYC6xXifBnT9dVBOnNQRvOE9riU9w== + version "5.1.1" + resolved "https://registry.yarnpkg.com/@smithy/signature-v4/-/signature-v4-5.1.1.tgz#c9f6522936a427c689dd78d7ebf2e69faf286206" + integrity sha512-zy8Repr5zvT0ja+Tf5wjV/Ba6vRrhdiDcp/ww6cvqYbSEudIkziDe3uppNRlFoCViyJXdPnLcwyZdDLA4CHzSg== dependencies: "@smithy/is-array-buffer" "^4.0.0" - "@smithy/protocol-http" "^5.1.0" - "@smithy/types" "^4.2.0" + "@smithy/protocol-http" "^5.1.1" + "@smithy/types" "^4.3.0" "@smithy/util-hex-encoding" "^4.0.0" - "@smithy/util-middleware" "^4.0.2" + "@smithy/util-middleware" "^4.0.3" "@smithy/util-uri-escape" "^4.0.0" "@smithy/util-utf8" "^4.0.0" tslib "^2.6.2" -"@smithy/smithy-client@^4.2.1": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-4.2.1.tgz#21055bc038824de93aee778d040cdf9864e6114d" - integrity sha512-fbniZef60QdsBc4ZY0iyI8xbFHIiC/QRtPi66iE4ufjiE/aaz7AfUXzcWMkpO8r+QhLeNRIfmPchIG+3/QDZ6g== - dependencies: - "@smithy/core" "^3.3.0" - "@smithy/middleware-endpoint" "^4.1.1" - "@smithy/middleware-stack" "^4.0.2" - "@smithy/protocol-http" "^5.1.0" - "@smithy/types" "^4.2.0" - "@smithy/util-stream" "^4.2.0" +"@smithy/smithy-client@^4.2.6", "@smithy/smithy-client@^4.3.0": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@smithy/smithy-client/-/smithy-client-4.3.0.tgz#05d2fa958ffbb9256c777a11b380aeba199295b3" + integrity sha512-DNsRA38pN6tYHUjebmwD9e4KcgqTLldYQb2gC6K+oxXYdCTxPn6wV9+FvOa6wrU2FQEnGJoi+3GULzOTKck/tg== + dependencies: + "@smithy/core" "^3.4.0" + "@smithy/middleware-endpoint" "^4.1.7" + "@smithy/middleware-stack" "^4.0.3" + "@smithy/protocol-http" "^5.1.1" + "@smithy/types" "^4.3.0" + "@smithy/util-stream" "^4.2.1" tslib "^2.6.2" "@smithy/types@^1.2.0": @@ -1504,20 +1505,20 @@ dependencies: tslib "^2.5.0" -"@smithy/types@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@smithy/types/-/types-4.2.0.tgz#e7998984cc54b1acbc32e6d4cf982c712e3d26b6" - integrity sha512-7eMk09zQKCO+E/ivsjQv+fDlOupcFUCSC/L2YUPgwhvowVGWbPQHjEFcmjt7QQ4ra5lyowS92SV53Zc6XD4+fg== +"@smithy/types@^4.2.0", "@smithy/types@^4.3.0": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@smithy/types/-/types-4.3.0.tgz#80a0da5ac907cfe9e97e89814bc7502626451580" + integrity sha512-+1iaIQHthDh9yaLhRzaoQxRk+l9xlk+JjMFxGRhNLz+m9vKOkjNeU8QuB4w3xvzHyVR/BVlp/4AXDHjoRIkfgQ== dependencies: tslib "^2.6.2" -"@smithy/url-parser@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-4.0.2.tgz#a316f7d8593ffab796348bc5df96237833880713" - integrity sha512-Bm8n3j2ScqnT+kJaClSVCMeiSenK6jVAzZCNewsYWuZtnBehEz4r2qP0riZySZVfzB+03XZHJeqfmJDkeeSLiQ== +"@smithy/url-parser@^4.0.2", "@smithy/url-parser@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@smithy/url-parser/-/url-parser-4.0.3.tgz#ab0920cc98205f438a3064fb85161bc3c50625b4" + integrity sha512-n5/DnosDu/tweOqUUNtUbu7eRIR4J/Wz9nL7V5kFYQQVb8VYdj7a4G5NJHCw6o21ul7CvZoJkOpdTnsQDLT0tQ== dependencies: - "@smithy/querystring-parser" "^4.0.2" - "@smithy/types" "^4.2.0" + "@smithy/querystring-parser" "^4.0.3" + "@smithy/types" "^4.3.0" tslib "^2.6.2" "@smithy/util-base64@^4.0.0": @@ -1574,37 +1575,37 @@ dependencies: tslib "^2.6.2" -"@smithy/util-defaults-mode-browser@^4.0.9": - version "4.0.9" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.9.tgz#b70915229126eee4c1df18cd8f1e8edabade9c41" - integrity sha512-B8j0XsElvyhv6+5hlFf6vFV/uCSyLKcInpeXOGnOImX2mGXshE01RvPoGipTlRpIk53e6UfYj7WdDdgbVfXDZw== +"@smithy/util-defaults-mode-browser@^4.0.14": + version "4.0.15" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.15.tgz#4a76a59f2af347189bef0f49295004e0156667ac" + integrity sha512-bJJ/B8owQbHAflatSq92f9OcV8858DJBQF1Y3GRjB8psLyUjbISywszYPFw16beREHO/C3I3taW4VGH+tOuwrQ== dependencies: - "@smithy/property-provider" "^4.0.2" - "@smithy/smithy-client" "^4.2.1" - "@smithy/types" "^4.2.0" + "@smithy/property-provider" "^4.0.3" + "@smithy/smithy-client" "^4.3.0" + "@smithy/types" "^4.3.0" bowser "^2.11.0" tslib "^2.6.2" -"@smithy/util-defaults-mode-node@^4.0.9": - version "4.0.9" - resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.9.tgz#2d50bcb178a214878a86563616a0b3499550a9d2" - integrity sha512-wTDU8P/zdIf9DOpV5qm64HVgGRXvqjqB/fJZTEQbrz3s79JHM/E7XkMm/876Oq+ZLHJQgnXM9QHDo29dlM62eA== - dependencies: - "@smithy/config-resolver" "^4.1.0" - "@smithy/credential-provider-imds" "^4.0.2" - "@smithy/node-config-provider" "^4.0.2" - "@smithy/property-provider" "^4.0.2" - "@smithy/smithy-client" "^4.2.1" - "@smithy/types" "^4.2.0" +"@smithy/util-defaults-mode-node@^4.0.14": + version "4.0.15" + resolved "https://registry.yarnpkg.com/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.15.tgz#60383794aa743776db1ac9e24d2e03aefae508d4" + integrity sha512-8CUrEW2Ni5q+NmYkj8wsgkfqoP7l4ZquptFbq92yQE66xevc4SxqP2zH6tMtN158kgBqBDsZ+qlrRwXWOjCR8A== + dependencies: + "@smithy/config-resolver" "^4.1.3" + "@smithy/credential-provider-imds" "^4.0.5" + "@smithy/node-config-provider" "^4.1.2" + "@smithy/property-provider" "^4.0.3" + "@smithy/smithy-client" "^4.3.0" + "@smithy/types" "^4.3.0" tslib "^2.6.2" -"@smithy/util-endpoints@^3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-3.0.2.tgz#6933a0d6d4a349523ef71ca9540c9c0b222b559e" - integrity sha512-6QSutU5ZyrpNbnd51zRTL7goojlcnuOB55+F9VBD+j8JpRY50IGamsjlycrmpn8PQkmJucFW8A0LSfXj7jjtLQ== +"@smithy/util-endpoints@^3.0.4": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@smithy/util-endpoints/-/util-endpoints-3.0.5.tgz#92ce03a97c29f60b2e46df161797df88ec262f2d" + integrity sha512-PjDpqLk24/vAl340tmtCA++Q01GRRNH9cwL9qh46NspAX9S+IQVcK+GOzPt0GLJ6KYGyn8uOgo2kvJhiThclJw== dependencies: - "@smithy/node-config-provider" "^4.0.2" - "@smithy/types" "^4.2.0" + "@smithy/node-config-provider" "^4.1.2" + "@smithy/types" "^4.3.0" tslib "^2.6.2" "@smithy/util-hex-encoding@^1.1.0": @@ -1628,31 +1629,31 @@ dependencies: tslib "^2.5.0" -"@smithy/util-middleware@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-4.0.2.tgz#272f1249664e27068ef0d5f967a233bf7b77962c" - integrity sha512-6GDamTGLuBQVAEuQ4yDQ+ti/YINf/MEmIegrEeg7DdB/sld8BX1lqt9RRuIcABOhAGTA50bRbPzErez7SlDtDQ== +"@smithy/util-middleware@^4.0.2", "@smithy/util-middleware@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@smithy/util-middleware/-/util-middleware-4.0.3.tgz#bb4176241ce0df21623a3c402ce55f94903f8161" + integrity sha512-iIsC6qZXxkD7V3BzTw3b1uK8RVC1M8WvwNxK1PKrH9FnxntCd30CSunXjL/8iJBE8Z0J14r2P69njwIpRG4FBQ== dependencies: - "@smithy/types" "^4.2.0" + "@smithy/types" "^4.3.0" tslib "^2.6.2" -"@smithy/util-retry@^4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-4.0.2.tgz#9b64cf460d63555884e641721d19e3c0abff8ee6" - integrity sha512-Qryc+QG+7BCpvjloFLQrmlSd0RsVRHejRXd78jNO3+oREueCjwG1CCEH1vduw/ZkM1U9TztwIKVIi3+8MJScGg== +"@smithy/util-retry@^4.0.3", "@smithy/util-retry@^4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@smithy/util-retry/-/util-retry-4.0.4.tgz#4e372f83aa83170eb95bc35a60be827555f90208" + integrity sha512-Aoqr9W2jDYGrI6OxljN8VmLDQIGO4VdMAUKMf9RGqLG8hn6or+K41NEy1Y5dtum9q8F7e0obYAuKl2mt/GnpZg== dependencies: - "@smithy/service-error-classification" "^4.0.2" - "@smithy/types" "^4.2.0" + "@smithy/service-error-classification" "^4.0.4" + "@smithy/types" "^4.3.0" tslib "^2.6.2" -"@smithy/util-stream@^4.2.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-4.2.0.tgz#85f85516b0042726162bf619caa3358332195652" - integrity sha512-Vj1TtwWnuWqdgQI6YTUF5hQ/0jmFiOYsc51CSMgj7QfyO+RF4EnT2HNjoviNlOOmgzgvf3f5yno+EiC4vrnaWQ== +"@smithy/util-stream@^4.2.0", "@smithy/util-stream@^4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@smithy/util-stream/-/util-stream-4.2.1.tgz#bc5358c4e1d5027b11411333f3190b7d5c104316" + integrity sha512-W3IR0x5DY6iVtjj5p902oNhD+Bz7vs5S+p6tppbPa509rV9BdeXZjGuRSCtVEad9FA0Mba+tNUtUmtnSI1nwUw== dependencies: - "@smithy/fetch-http-handler" "^5.0.2" - "@smithy/node-http-handler" "^4.0.4" - "@smithy/types" "^4.2.0" + "@smithy/fetch-http-handler" "^5.0.3" + "@smithy/node-http-handler" "^4.0.5" + "@smithy/types" "^4.3.0" "@smithy/util-base64" "^4.0.0" "@smithy/util-buffer-from" "^4.0.0" "@smithy/util-hex-encoding" "^4.0.0" @@ -1698,12 +1699,12 @@ tslib "^2.6.2" "@smithy/util-waiter@^4.0.3": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@smithy/util-waiter/-/util-waiter-4.0.3.tgz#ec5605ec123493259ccbf1c0b5c1951b3360f43b" - integrity sha512-JtaY3FxmD+te+KSI2FJuEcfNC9T/DGGVf551babM7fAaXhjJUt7oSYurH1Devxd2+BOSUACCgt3buinx4UnmEA== + version "4.0.4" + resolved "https://registry.yarnpkg.com/@smithy/util-waiter/-/util-waiter-4.0.4.tgz#f1a4ee2116286b0d58d4b3315e42c82ccb645404" + integrity sha512-73aeIvHjtSB6fd9I08iFaQIGTICKpLrI3EtlWAkStVENGo1ARMq9qdoD4QwkY0RUp6A409xlgbD9NCCfCF5ieg== dependencies: - "@smithy/abort-controller" "^4.0.2" - "@smithy/types" "^4.2.0" + "@smithy/abort-controller" "^4.0.3" + "@smithy/types" "^4.3.0" tslib "^2.6.2" "@tootallnate/once@2": @@ -1887,23 +1888,23 @@ form-data "^4.0.0" "@types/node@*": - version "22.15.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.3.tgz#b7fb9396a8ec5b5dfb1345d8ac2502060e9af68b" - integrity sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw== + version "22.15.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.19.tgz#ba9f321675243af0456d607fa82a4865931e0cef" + integrity sha512-3vMNr4TzNQyjHcRZadojpRaD9Ofr6LsonZAoQ+HMUa/9ORTPoxVIw0e0mpqWpdjj8xybyCM+oKOUH2vwFu/oEw== dependencies: undici-types "~6.21.0" "@types/node@^18.11.18", "@types/node@^18.19.70": - version "18.19.87" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.87.tgz#690f000cc51e3c7f48bc00f7e86fac6eb550b709" - integrity sha512-OIAAu6ypnVZHmsHCeJ+7CCSub38QNBS9uceMQeg7K5Ur0Jr+wG9wEOEvvMbhp09pxD5czIUy/jND7s7Tb6Nw7A== + version "18.19.101" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.101.tgz#6c08ca62bdbc745b60b885f3c38f571ea145ccff" + integrity sha512-Ykg7fcE3+cOQlLUv2Ds3zil6DVjriGQaSN/kEpl5HQ3DIGM6W0F2n9+GkWV4bRt7KjLymgzNdTnSKCbFUUJ7Kw== dependencies: undici-types "~5.26.4" "@types/qs@^6.9.17": - version "6.9.18" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.18.tgz#877292caa91f7c1b213032b34626505b746624c2" - integrity sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA== + version "6.14.0" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.14.0.tgz#d8b60cecf62f2db0fb68e5e006077b9178b85de5" + integrity sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ== "@types/readable-stream@^4.0.18": version "4.0.18" @@ -2113,7 +2114,7 @@ acorn-walk@^8.0.2: dependencies: acorn "^8.11.0" -acorn@^8.1.0, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.8.1, acorn@^8.8.2: +acorn@^8.1.0, acorn@^8.11.0, acorn@^8.14.0, acorn@^8.8.1: version "8.14.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb" integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== @@ -2306,14 +2307,14 @@ braces@^3.0.3: fill-range "^7.1.1" browserslist@^4.24.0: - version "4.24.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.4.tgz#c6b2865a3f08bcb860a0e827389003b9fe686e4b" - integrity sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A== + version "4.24.5" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.5.tgz#aa0f5b8560fe81fde84c6dcb38f759bafba0e11b" + integrity sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw== dependencies: - caniuse-lite "^1.0.30001688" - electron-to-chromium "^1.5.73" + caniuse-lite "^1.0.30001716" + electron-to-chromium "^1.5.149" node-releases "^2.0.19" - update-browserslist-db "^1.1.1" + update-browserslist-db "^1.1.3" bs-logger@^0.2.6: version "0.2.6" @@ -2373,10 +2374,10 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001688: - version "1.0.30001716" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001716.tgz#39220dfbc58c85d9d4519e7090b656aa11ca4b85" - integrity sha512-49/c1+x3Kwz7ZIWt+4DvK3aMJy9oYXXG6/97JKsnjdCk/6n9vVyWL8NAwVt95Lwt9eigI10Hl782kDfZUUlRXw== +caniuse-lite@^1.0.30001716: + version "1.0.30001718" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001718.tgz#dae13a9c80d517c30c6197515a96131c194d8f82" + integrity sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw== chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0: version "4.1.2" @@ -2470,6 +2471,11 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +commander@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-14.0.0.tgz#f244fc74a92343514e56229f16ef5c5e22ced5e9" + integrity sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA== + commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -2542,9 +2548,9 @@ data-urls@^3.0.2: whatwg-url "^11.0.0" debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.5: - version "4.4.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" - integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== + version "4.4.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" + integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== dependencies: ms "^2.1.3" @@ -2554,9 +2560,9 @@ decimal.js@^10.4.2: integrity sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw== dedent@^1.0.0: - version "1.5.3" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.3.tgz#99aee19eb9bae55a67327717b6e848d0bf777e5a" - integrity sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ== + version "1.6.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.6.0.tgz#79d52d6389b1ffa67d2bcef59ba51847a9d503b2" + integrity sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA== deepmerge@^4.2.2: version "4.3.1" @@ -2585,7 +2591,7 @@ domexception@^4.0.0: dependencies: webidl-conversions "^7.0.0" -dotenv@^16.4.6: +dotenv@^16.5.0: version "16.5.0" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.5.0.tgz#092b49f25f808f020050051d1ff258e404c78692" integrity sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg== @@ -2606,10 +2612,10 @@ ejs@^3.1.10: dependencies: jake "^10.8.5" -electron-to-chromium@^1.5.73: - version "1.5.145" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.145.tgz#abd50700ac2c809e40a4694584f66711ee937fb6" - integrity sha512-pZ5EcTWRq/055MvSBgoFEyKf2i4apwfoqJbK/ak2jnFq8oHjZ+vzc3AhRcz37Xn+ZJfL58R666FLJx0YOK9yTw== +electron-to-chromium@^1.5.149: + version "1.5.155" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.155.tgz#809dd0ae9ae1db87c358e0c0c17c09a2ffc432d1" + integrity sha512-ps5KcGGmwL8VaeJlvlDlu4fORQpv3+GIcF5I3f9tUKUlJ/wsysh6HU8P5L1XWRYeXfA0oJd4PyM8ds8zTFf6Ng== emittery@^0.13.1: version "0.13.1" @@ -3023,9 +3029,9 @@ ieee754@^1.2.1: integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== import-in-the-middle@^1.8.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.13.1.tgz#789651f9e93dd902a5a306f499ab51eb72b03a12" - integrity sha512-k2V9wNm9B+ysuelDTHjI9d5KPc4l8zAZTGqj+pcynvWkypZd857ryzN8jNC7Pg2YZXNMJcHRPpaDyCBbNyVRpA== + version "1.13.2" + resolved "https://registry.yarnpkg.com/import-in-the-middle/-/import-in-the-middle-1.13.2.tgz#b8d873708ab121996da6842fa7740ac5cd437f9e" + integrity sha512-Yjp9X7s2eHSXvZYQ0aye6UvwYPrVB5C2k47fuXjFKnYinAByaDZjh4t9MT2wEga9775n6WaIqyHnQhBxYtX2mg== dependencies: acorn "^8.14.0" acorn-import-attributes "^1.9.5" @@ -3832,9 +3838,9 @@ onetime@^5.1.2: mimic-fn "^2.1.0" openai@^4.74.0: - version "4.96.2" - resolved "https://registry.yarnpkg.com/openai/-/openai-4.96.2.tgz#a7d360597f273a5f6ed8dd22914e598013022fa4" - integrity sha512-R2XnxvMsizkROr7BV3uNp1q/3skwPZ7fmPjO1bXLnfB4Tu5xKxrT1EVwzjhxn0MZKBKAvOaGWS63jTMN6KrIXA== + version "4.100.0" + resolved "https://registry.yarnpkg.com/openai/-/openai-4.100.0.tgz#eb630a97f3531b7c91906b3a42920f9873efa392" + integrity sha512-9soq/wukv3utxcuD7TWFqKdKp0INWdeyhUCvxwrne5KwnxaCp4eHL4GdT/tMFhYolxgNhxFzg5GFwM331Z5CZg== dependencies: "@types/node" "^18.11.18" "@types/node-fetch" "^2.6.4" @@ -4102,10 +4108,10 @@ semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.4, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.7.1: - version "7.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" - integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== +semver@^7.3.4, semver@^7.5.2, semver@^7.5.3, semver@^7.5.4, semver@^7.7.2: + version "7.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" + integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== serialize-javascript@^6.0.2: version "6.0.2" @@ -4305,9 +4311,9 @@ symbol-tree@^3.2.4: integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== tapable@^2.1.1, tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + version "2.2.2" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.2.tgz#ab4984340d30cb9989a490032f086dbb8b56d872" + integrity sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg== terser-webpack-plugin@^5.3.11: version "5.3.14" @@ -4321,12 +4327,12 @@ terser-webpack-plugin@^5.3.11: terser "^5.31.1" terser@^5.31.1: - version "5.39.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.39.0.tgz#0e82033ed57b3ddf1f96708d123cca717d86ca3a" - integrity sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw== + version "5.39.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.39.2.tgz#5a1626030724a672e2e5b5c9cd9070308c20e8f9" + integrity sha512-yEPUmWve+VA78bI71BW70Dh0TuV4HHd+I5SHOAfS1+QBOmvmCiiffgjR8ryyEd3KIfvPGFqoADt8LdQ6XpXIvg== dependencies: "@jridgewell/source-map" "^0.3.3" - acorn "^8.8.2" + acorn "^8.14.0" commander "^2.20.0" source-map-support "~0.5.20" @@ -4379,9 +4385,9 @@ tr46@~0.0.3: integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== ts-jest@^29.1.1: - version "29.3.2" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.3.2.tgz#0576cdf0a507f811fe73dcd16d135ce89f8156cb" - integrity sha512-bJJkrWc6PjFVz5g2DGCNUo8z7oFEYaz1xP1NpeDU7KNLMWPpEyV8Chbpkn8xjzgRDpQhnGMyvyldoL7h8JXyug== + version "29.3.4" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.3.4.tgz#9354472aceae1d3867a80e8e02014ea5901aee41" + integrity sha512-Iqbrm8IXOmV+ggWHOTEbjwyCf2xZlUMv5npExksXohL+tk8va4Fjhb+X2+Rt9NBmgO7bJ8WpnMLOwih/DnMlFA== dependencies: bs-logger "^0.2.6" ejs "^3.1.10" @@ -4390,8 +4396,8 @@ ts-jest@^29.1.1: json5 "^2.2.3" lodash.memoize "^4.1.2" make-error "^1.3.6" - semver "^7.7.1" - type-fest "^4.39.1" + semver "^7.7.2" + type-fest "^4.41.0" yargs-parser "^21.1.1" ts-loader@^9.5.1: @@ -4425,10 +4431,10 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -type-fest@^4.39.1: - version "4.40.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.40.1.tgz#d78a09f08dd1081a434dd377967650cfd565401d" - integrity sha512-9YvLNnORDpI+vghLU/Nf+zSv0kL47KbVJ1o3sKgoTefl6i+zebxbiDQWoe/oWWqPhIgQdRZRT1KA9sCPL810SA== +type-fest@^4.41.0: + version "4.41.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" + integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== typescript@~5.7.2: version "5.7.3" @@ -4450,7 +4456,7 @@ universalify@^0.2.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== -update-browserslist-db@^1.1.1: +update-browserslist-db@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== @@ -4500,9 +4506,9 @@ walker@^1.0.8: makeerror "1.0.12" watchpack@^2.4.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" - integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== + version "2.4.3" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.3.tgz#110b3a600c525f6a39ab66cf354cf08b205c29dc" + integrity sha512-adBYQLivcg1jbdKEJeqScJJFvgm4qY9+3tXw+jdG6lkVeqRJEtiQmSWjmth8GKmDZuX7sYM4YFxQsf0AzMfGGw== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -4528,9 +4534,9 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.97.1: - version "5.99.7" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.99.7.tgz#60201c1ca66da046b07d006c2f6e0cc5e8a7bdba" - integrity sha512-CNqKBRMQjwcmKR0idID5va1qlhrqVUKpovi+Ec79ksW8ux7iS1+A6VqzfZXgVYCFRKl7XL5ap3ZoMpwBJxcg0w== + version "5.99.8" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.99.8.tgz#dd31a020b7c092d30c4c6d9a4edb95809e7f5946" + integrity sha512-lQ3CPiSTpfOnrEGeXDwoq5hIGzSjmwD72GdfVzF7CQAI7t47rJG9eDWvcEkEn3CUQymAElVvDg3YNTlCYj+qUQ== dependencies: "@types/eslint-scope" "^3.7.7" "@types/estree" "^1.0.6" @@ -4615,9 +4621,9 @@ write-file-atomic@^4.0.2: signal-exit "^3.0.7" ws@^8.11.0: - version "8.18.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb" - integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w== + version "8.18.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.2.tgz#42738b2be57ced85f46154320aabb51ab003705a" + integrity sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ== xml-name-validator@^4.0.0: version "4.0.0"