From 86f0225038624d9a6f7943dabf6b92348fbf6606 Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Fri, 7 Feb 2025 15:55:45 -0500 Subject: [PATCH 01/17] Added changeset Signed-off-by: Florian JUDITH --- workspaces/tech-insights/.changeset/cyan-ducks-mate.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 workspaces/tech-insights/.changeset/cyan-ducks-mate.md diff --git a/workspaces/tech-insights/.changeset/cyan-ducks-mate.md b/workspaces/tech-insights/.changeset/cyan-ducks-mate.md new file mode 100644 index 00000000000..c1b7b828a4f --- /dev/null +++ b/workspaces/tech-insights/.changeset/cyan-ducks-mate.md @@ -0,0 +1,5 @@ +--- +'@backstage-community/plugin-tech-insights-maturity': patch +--- + +Fixed entity page integration instructions From 348aec16528a45a8794dc7bb3165562d5ab8b8f8 Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Mon, 23 Mar 2026 19:57:08 -0400 Subject: [PATCH 02/17] feat(mcp-chat): initial implementation of llm provider backend modules Signed-off-by: Florian JUDITH --- .../mcp-chat/.changeset/silly-jars-happen.md | 11 + .../.eslintrc.js | 1 + .../README.md | 5 + .../config.d.ts | 52 + .../knip-report.md | 1 + .../package.json | 61 + .../report.api.md | 33 + .../src/ClaudeProvider.ts} | 12 +- .../src/index.ts | 24 + .../src/module.ts | 79 + .../tsconfig.json | 9 + .../.eslintrc.js | 1 + .../mcp-chat-backend-module-gemini/README.md | 5 + .../config.d.ts | 52 + .../knip-report.md | 1 + .../package.json | 62 + .../report.api.md | 36 + .../src/GeminiProvider.ts} | 24 +- .../src/index.ts | 24 + .../src/module.ts | 79 + .../tsconfig.json | 9 + .../.eslintrc.js | 1 + .../mcp-chat-backend-module-litellm/README.md | 5 + .../config.d.ts | 52 + .../knip-report.md | 1 + .../package.json | 60 + .../report.api.md | 33 + .../src/LiteLLMProvider.ts} | 32 +- .../src/index.ts | 24 + .../src/module.ts | 78 + .../tsconfig.json | 9 + .../.eslintrc.js | 1 + .../mcp-chat-backend-module-ollama/README.md | 5 + .../config.d.ts | 52 + .../knip-report.md | 1 + .../package.json | 61 + .../report.api.md | 35 + .../src/OllamaProvider.ts} | 16 +- .../src/index.ts | 24 + .../src/module.ts | 78 + .../tsconfig.json | 9 + .../.eslintrc.js | 1 + .../README.md | 10 + .../config.d.ts | 52 + .../package.json | 61 + .../report.api.md | 40 + .../src/OpenAIResponsesProvider.ts} | 54 +- .../src/index.ts | 24 + .../src/module.ts | 80 + .../tsconfig.json | 9 + .../.eslintrc.js | 1 + .../mcp-chat-backend-module-openai/README.md | 10 + .../config.d.ts | 52 + .../knip-report.md | 1 + .../package.json | 60 + .../report.api.md | 33 + .../src/OpenAIProvider.ts} | 11 +- .../src/index.ts | 24 + .../src/module.ts | 78 + .../tsconfig.json | 9 + .../plugins/mcp-chat-backend/config.d.ts | 8 +- .../plugins/mcp-chat-backend/dev/index.ts | 4 +- .../plugins/mcp-chat-backend/package.json | 16 +- .../plugins/mcp-chat-backend/report.api.md | 150 +- .../mcp-chat-backend/src/extensions.ts | 25 + .../plugins/mcp-chat-backend/src/index.ts | 21 +- .../mcp-chat-backend/src/plugin.test.ts | 28 + .../plugins/mcp-chat-backend/src/plugin.ts | 41 +- .../src/providers/base-provider.ts | 91 +- .../src/providers/gemini-provider.test.ts | 776 ---- .../mcp-chat-backend/src/providers/index.ts | 18 - .../src/providers/litellm-provider.test.ts | 339 -- .../src/providers/ollama-provider.test.ts | 709 --- .../openai-responses-provider.test.ts | 782 ---- .../src/providers/provider-factory.test.ts | 372 -- .../src/providers/provider-factory.ts | 189 - .../src/services/MCPClientServiceImpl.test.ts | 62 +- .../src/services/MCPClientServiceImpl.ts | 83 +- .../plugins/mcp-chat-backend/src/types.ts | 726 +--- .../plugins/mcp-chat-common/.eslintrc.js | 1 + .../plugins/mcp-chat-common/README.md | 5 + .../plugins/mcp-chat-common/package.json | 56 + .../mcp-chat-common/src/base-provider.ts | 105 + .../plugins/mcp-chat-common/src/index.ts | 74 + .../plugins/mcp-chat-common/src/setupTests.ts | 16 + .../plugins/mcp-chat-common/src/types.ts | 584 +++ .../plugins/mcp-chat-node/.eslintrc.js | 1 + .../mcp-chat/plugins/mcp-chat-node/README.md | 5 + .../plugins/mcp-chat-node/package.json | 55 + .../plugins/mcp-chat-node/src/extensions.ts | 44 + .../plugins/mcp-chat-node/src/index.ts | 26 + .../plugins/mcp-chat-node/src/setupTests.ts | 16 + workspaces/mcp-chat/yarn.lock | 3840 ++++++++++++++--- .../.changeset/cyan-ducks-mate.md | 5 - 94 files changed, 6071 insertions(+), 4970 deletions(-) create mode 100644 workspaces/mcp-chat/.changeset/silly-jars-happen.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/.eslintrc.js create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/README.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/config.d.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/knip-report.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/package.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/report.api.md rename workspaces/mcp-chat/plugins/{mcp-chat-backend/src/providers/claude-provider.ts => mcp-chat-backend-module-anthropic/src/ClaudeProvider.ts} (95%) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/index.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/module.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/tsconfig.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/.eslintrc.js create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/README.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/config.d.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/knip-report.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/package.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/report.api.md rename workspaces/mcp-chat/plugins/{mcp-chat-backend/src/providers/gemini-provider.ts => mcp-chat-backend-module-gemini/src/GeminiProvider.ts} (94%) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/index.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/module.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/tsconfig.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/.eslintrc.js create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/README.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/config.d.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/knip-report.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/package.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/report.api.md rename workspaces/mcp-chat/plugins/{mcp-chat-backend/src/providers/litellm-provider.ts => mcp-chat-backend-module-litellm/src/LiteLLMProvider.ts} (85%) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/index.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/module.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/tsconfig.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/.eslintrc.js create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/README.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/config.d.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/knip-report.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/package.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/report.api.md rename workspaces/mcp-chat/plugins/{mcp-chat-backend/src/providers/ollama-provider.ts => mcp-chat-backend-module-ollama/src/OllamaProvider.ts} (93%) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/index.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/module.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/tsconfig.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/.eslintrc.js create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/README.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/config.d.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/package.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/report.api.md rename workspaces/mcp-chat/plugins/{mcp-chat-backend/src/providers/openai-responses-provider.ts => mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.ts} (91%) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/index.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/module.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/tsconfig.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/.eslintrc.js create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/README.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/config.d.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/knip-report.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/package.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/report.api.md rename workspaces/mcp-chat/plugins/{mcp-chat-backend/src/providers/openai-provider.ts => mcp-chat-backend-module-openai/src/OpenAIProvider.ts} (93%) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/index.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/module.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/tsconfig.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/extensions.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/gemini-provider.test.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.test.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.test.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.test.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.test.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-common/.eslintrc.js create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-common/README.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-common/package.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-common/src/base-provider.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-common/src/index.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-common/src/setupTests.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-node/.eslintrc.js create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-node/README.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-node/package.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-node/src/extensions.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-node/src/index.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-node/src/setupTests.ts delete mode 100644 workspaces/tech-insights/.changeset/cyan-ducks-mate.md diff --git a/workspaces/mcp-chat/.changeset/silly-jars-happen.md b/workspaces/mcp-chat/.changeset/silly-jars-happen.md new file mode 100644 index 00000000000..d8578848796 --- /dev/null +++ b/workspaces/mcp-chat/.changeset/silly-jars-happen.md @@ -0,0 +1,11 @@ +--- +'@backstage-community/plugin-mcp-chat-backend': major +'@backstage-community/plugin-mcp-chat-backend-module-openai-responses': patch +'@backstage-community/plugin-mcp-chat-backend-module-anthropic': patch +'@backstage-community/plugin-mcp-chat-backend-module-litellm': patch +'@backstage-community/plugin-mcp-chat-backend-module-gemini': patch +'@backstage-community/plugin-mcp-chat-backend-module-ollama': patch +'@backstage-community/plugin-mcp-chat-backend-module-openai': patch +--- + +refactor the backend plugin to isolate llm providers in dedicated backend modules diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/.eslintrc.js new file mode 100644 index 00000000000..e2a53a6ad28 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/README.md new file mode 100644 index 00000000000..a79b0a7ed34 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/README.md @@ -0,0 +1,5 @@ +# @backstage-community/plugin-mcp-chat-backend-module-anthropic + +The anthropic backend module for the mcp-chat plugin. + +_This plugin was created through the Backstage CLI_ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/config.d.ts new file mode 100644 index 00000000000..65d61e8b043 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/config.d.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface Config { + /** Configuration options for the MCP Chat plugin */ + mcpChat?: { + /** + * AI/LLM providers configuration + * @visibility backend + */ + providers?: Array<{ + /** + * Unique identifier for the provider + * @visibility backend + */ + id: string; + /** + * API token for the provider + * @visibility secret + */ + token?: string; + /** + * Model name to use for this provider + * @visibility backend + */ + model: string; + /** + * Base URL for the provider's API + * @visibility backend + */ + baseUrl?: string; + /** + * Provider-specific authentication parameters (IAM, session tokens, etc.) + * @visibility secret + */ + auth?: { [key: string]: string }; + }>; + }; +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/knip-report.md new file mode 100644 index 00000000000..28921c328dd --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/knip-report.md @@ -0,0 +1 @@ +# Knip report diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/package.json new file mode 100644 index 00000000000..ab02cc2e276 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/package.json @@ -0,0 +1,61 @@ +{ + "name": "@backstage-community/plugin-mcp-chat-backend-module-anthropic", + "version": "0.1.0", + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module", + "pluginId": "mcp-chat", + "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", + "pluginPackages": [ + "@backstage-community/plugin-mcp-chat-backend-module-anthropic", + "@backstage-community/plugin-mcp-chat-backend" + ] + }, + "dependencies": { + "@backstage-community/plugin-mcp-chat-common": "workspace:^", + "@backstage-community/plugin-mcp-chat-node": "workspace:^", + "@backstage/backend-plugin-api": "^1.4.0", + "@backstage/config": "^1.3.0" + }, + "devDependencies": { + "@backstage/cli": "^0.33.0" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "files": [ + "dist", + "config.d.ts" + ], + "configSchema": "config.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/backstage/community-plugins", + "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic" + }, + "keywords": [ + "backstage", + "backstage-plugin", + "backstage-backend-module", + "anthropic", + "claude", + "llm", + "mcp", + "mcp-chat" + ], + "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic", + "bugs": "https://github.com/backstage/community-plugins/issues" +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/report.api.md new file mode 100644 index 00000000000..2c2addc9001 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/report.api.md @@ -0,0 +1,33 @@ +## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-anthropic" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-backend'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-backend'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-backend'; +import { Tool } from '@backstage-community/plugin-mcp-chat-backend'; + +// @public +export class ClaudeProvider extends LLMProvider { + // (undocumented) + protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; + // (undocumented) + protected getHeaders(): Record; + // (undocumented) + protected parseResponse(response: any): ChatResponse; + // (undocumented) + sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; + // (undocumented) + testConnection(): Promise<{ + connected: boolean; + models?: string[]; + error?: string; + }>; +} + +// @public +const _default: BackendFeature; +export default _default; +``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/claude-provider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.ts similarity index 95% rename from workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/claude-provider.ts rename to workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.ts index 87c58799af1..05a1312ae9f 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/claude-provider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.ts @@ -13,8 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { LLMProvider } from './base-provider'; -import { ChatMessage, Tool, ChatResponse, ToolCall } from '../types'; + +import { + LLMProvider, + type ChatMessage, + type Tool, + type ChatResponse, + type ToolCall, +} from '@backstage-community/plugin-mcp-chat-common'; /** * Anthropic Claude API provider. @@ -37,7 +43,7 @@ export class ClaudeProvider extends LLMProvider { error?: string; }> { try { - // Claude doesn't have a models endpoint, so we'll make a simple test request + // Claude doesn't have a models endpoint, so we make a simple test request const testMessages = [{ role: 'user' as const, content: 'Hello' }]; const requestBody = { model: this.model, diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/index.ts new file mode 100644 index 00000000000..5fe4a572a7c --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Backend module for the mcp-chat plugin that provides the Anthropic Claude LLM provider. + * + * @packageDocumentation + */ + +export { default } from './module'; +export { ClaudeProvider } from './ClaudeProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/module.ts new file mode 100644 index 00000000000..afa4cd025f3 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/module.ts @@ -0,0 +1,79 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createBackendModule, + coreServices, +} from '@backstage/backend-plugin-api'; +import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; +import type { Config } from '@backstage/config'; +import { ClaudeProvider } from './ClaudeProvider'; + +/** + * Reads the optional `auth` record from a provider config entry. + * @param entry - The config entry to read auth from + * @returns A record of string key-value pairs, or undefined if no auth config + */ +function readAuthRecord(entry: Config): Record | undefined { + const authConfig = entry.getOptionalConfig('auth'); + if (!authConfig) return undefined; + const result: Record = {}; + for (const key of authConfig.keys()) { + result[key] = authConfig.getString(key); + } + return result; +} + +/** + * Backend module that registers the Anthropic Claude LLM provider + * with the mcp-chat backend plugin. + * + * @public + */ +export default createBackendModule({ + pluginId: 'mcp-chat', + moduleId: 'anthropic', + register(reg) { + reg.registerInit({ + deps: { + config: coreServices.rootConfig, + llmProviders: llmProviderExtensionPoint, + }, + async init({ config, llmProviders }) { + const providers = + config.getOptionalConfigArray('mcpChat.providers') || []; + const entry = providers.find(p => p.getString('id') === 'claude'); + + if (!entry) return; // Skip registration if not configured + + const providerConfig = { + type: 'claude', + apiKey: entry.getOptionalString('token'), + baseUrl: + entry.getOptionalString('baseUrl') || + 'https://api.anthropic.com/v1', + model: entry.getString('model'), + auth: readAuthRecord(entry), + }; + + llmProviders.registerProvider( + 'claude', + new ClaudeProvider(providerConfig), + ); + }, + }); + }, +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/tsconfig.json new file mode 100644 index 00000000000..6364965a1a3 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@backstage/cli/config/tsconfig.json", + "include": ["src"], + "exclude": ["node_modules"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + } +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/.eslintrc.js new file mode 100644 index 00000000000..e2a53a6ad28 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/README.md new file mode 100644 index 00000000000..54e5bc73a45 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/README.md @@ -0,0 +1,5 @@ +# @backstage-community/plugin-mcp-chat-backend-module-gemini + +The gemini backend module for the mcp-chat plugin. + +_This plugin was created through the Backstage CLI_ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/config.d.ts new file mode 100644 index 00000000000..65d61e8b043 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/config.d.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface Config { + /** Configuration options for the MCP Chat plugin */ + mcpChat?: { + /** + * AI/LLM providers configuration + * @visibility backend + */ + providers?: Array<{ + /** + * Unique identifier for the provider + * @visibility backend + */ + id: string; + /** + * API token for the provider + * @visibility secret + */ + token?: string; + /** + * Model name to use for this provider + * @visibility backend + */ + model: string; + /** + * Base URL for the provider's API + * @visibility backend + */ + baseUrl?: string; + /** + * Provider-specific authentication parameters (IAM, session tokens, etc.) + * @visibility secret + */ + auth?: { [key: string]: string }; + }>; + }; +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/knip-report.md new file mode 100644 index 00000000000..28921c328dd --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/knip-report.md @@ -0,0 +1 @@ +# Knip report diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/package.json new file mode 100644 index 00000000000..fa503ddb8d7 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/package.json @@ -0,0 +1,62 @@ +{ + "name": "@backstage-community/plugin-mcp-chat-backend-module-gemini", + "version": "0.1.0", + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module", + "pluginId": "mcp-chat", + "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", + "pluginPackages": [ + "@backstage-community/plugin-mcp-chat-backend-module-gemini", + "@backstage-community/plugin-mcp-chat-backend" + ] + }, + "dependencies": { + "@backstage-community/plugin-mcp-chat-common": "workspace:^", + "@backstage-community/plugin-mcp-chat-node": "workspace:^", + "@backstage/backend-plugin-api": "^1.4.0", + "@backstage/config": "^1.3.0", + "@google/genai": "^1.41.0" + }, + "devDependencies": { + "@backstage/cli": "^0.33.0" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "files": [ + "dist", + "config.d.ts" + ], + "configSchema": "config.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/backstage/community-plugins", + "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini" + }, + "keywords": [ + "backstage", + "backstage-plugin", + "backstage-backend-module", + "gemini", + "google", + "llm", + "mcp", + "mcp-chat" + ], + "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini", + "bugs": "https://github.com/backstage/community-plugins/issues" +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/report.api.md new file mode 100644 index 00000000000..a9379a50f7c --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/report.api.md @@ -0,0 +1,36 @@ +## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-gemini" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-backend'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-backend'; +import { GenerateContentResult } from '@google/generative-ai'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-backend'; +import { ProviderConfig } from '@backstage-community/plugin-mcp-chat-backend'; +import { Tool } from '@backstage-community/plugin-mcp-chat-backend'; + +// @public +const _default: BackendFeature; +export default _default; + +// @public +export class GeminiProvider extends LLMProvider { + constructor(config: ProviderConfig); + // (undocumented) + protected formatRequest(_messages: ChatMessage[], _tools?: Tool[]): any; + // (undocumented) + protected getHeaders(): Record; + // (undocumented) + protected parseResponse(result: GenerateContentResult): ChatResponse; + // (undocumented) + sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; + // (undocumented) + testConnection(): Promise<{ + connected: boolean; + models?: string[]; + error?: string; + }>; +} +``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/gemini-provider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.ts similarity index 94% rename from workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/gemini-provider.ts rename to workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.ts index 2b3f08e269c..a1341d71c03 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/gemini-provider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.ts @@ -13,14 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { LLMProvider } from './base-provider'; + import { - ChatMessage, - Tool, - ChatResponse, - ToolCall, - ProviderConfig, -} from '../types'; + LLMProvider, + type ChatMessage, + type Tool, + type ChatResponse, + type ToolCall, + type ProviderConfig, +} from '@backstage-community/plugin-mcp-chat-common'; import { GenerateContentConfig, GoogleGenAI, @@ -137,10 +138,7 @@ export class GeminiProvider extends LLMProvider { error?: string; }> { try { - // Gemini doesn't have a models list endpoint in the same way - // We'll test by making a simple generateContent request - const response = await this.genAI.models.generateContent({ - model: this.model, + const result = await this.geminiModel.generateContent({ contents: [{ role: 'user', parts: [{ text: 'Hello' }] }], config: { ...this.baseModelConfig, @@ -148,11 +146,11 @@ export class GeminiProvider extends LLMProvider { }, }); - // If we get here without error, the connection is working + const response = await result.response; if (response) { return { connected: true, - models: [this.model], // Gemini doesn't list models, so return the configured one + models: [this.model], }; } return { diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/index.ts new file mode 100644 index 00000000000..a3738a61591 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Backend module for the mcp-chat plugin that provides the Google Gemini LLM provider. + * + * @packageDocumentation + */ + +export { default } from './module'; +export { GeminiProvider } from './GeminiProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/module.ts new file mode 100644 index 00000000000..340e43c240f --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/module.ts @@ -0,0 +1,79 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createBackendModule, + coreServices, +} from '@backstage/backend-plugin-api'; +import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; +import type { Config } from '@backstage/config'; +import { GeminiProvider } from './GeminiProvider'; + +/** + * Reads the optional `auth` record from a provider config entry. + * @param entry - The config entry to read auth from + * @returns A record of string key-value pairs, or undefined if no auth config + */ +function readAuthRecord(entry: Config): Record | undefined { + const authConfig = entry.getOptionalConfig('auth'); + if (!authConfig) return undefined; + const result: Record = {}; + for (const key of authConfig.keys()) { + result[key] = authConfig.getString(key); + } + return result; +} + +/** + * Backend module that registers the Google Gemini LLM provider + * with the mcp-chat backend plugin. + * + * @public + */ +export default createBackendModule({ + pluginId: 'mcp-chat', + moduleId: 'gemini', + register(reg) { + reg.registerInit({ + deps: { + config: coreServices.rootConfig, + llmProviders: llmProviderExtensionPoint, + }, + async init({ config, llmProviders }) { + const providers = + config.getOptionalConfigArray('mcpChat.providers') || []; + const entry = providers.find(p => p.getString('id') === 'gemini'); + + if (!entry) return; // Skip registration if not configured + + const providerConfig = { + type: 'gemini', + apiKey: entry.getOptionalString('token'), + baseUrl: + entry.getOptionalString('baseUrl') || + 'https://generativelanguage.googleapis.com', + model: entry.getString('model'), + auth: readAuthRecord(entry), + }; + + llmProviders.registerProvider( + 'gemini', + new GeminiProvider(providerConfig), + ); + }, + }); + }, +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/tsconfig.json new file mode 100644 index 00000000000..6364965a1a3 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@backstage/cli/config/tsconfig.json", + "include": ["src"], + "exclude": ["node_modules"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + } +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/.eslintrc.js new file mode 100644 index 00000000000..e2a53a6ad28 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/README.md new file mode 100644 index 00000000000..58a4f313c5d --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/README.md @@ -0,0 +1,5 @@ +# @backstage-community/plugin-mcp-chat-backend-module-litellm + +The litellm backend module for the mcp-chat plugin. + +_This plugin was created through the Backstage CLI_ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/config.d.ts new file mode 100644 index 00000000000..65d61e8b043 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/config.d.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface Config { + /** Configuration options for the MCP Chat plugin */ + mcpChat?: { + /** + * AI/LLM providers configuration + * @visibility backend + */ + providers?: Array<{ + /** + * Unique identifier for the provider + * @visibility backend + */ + id: string; + /** + * API token for the provider + * @visibility secret + */ + token?: string; + /** + * Model name to use for this provider + * @visibility backend + */ + model: string; + /** + * Base URL for the provider's API + * @visibility backend + */ + baseUrl?: string; + /** + * Provider-specific authentication parameters (IAM, session tokens, etc.) + * @visibility secret + */ + auth?: { [key: string]: string }; + }>; + }; +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/knip-report.md new file mode 100644 index 00000000000..28921c328dd --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/knip-report.md @@ -0,0 +1 @@ +# Knip report diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/package.json new file mode 100644 index 00000000000..b5648c581d5 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/package.json @@ -0,0 +1,60 @@ +{ + "name": "@backstage-community/plugin-mcp-chat-backend-module-litellm", + "version": "0.1.0", + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module", + "pluginId": "mcp-chat", + "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", + "pluginPackages": [ + "@backstage-community/plugin-mcp-chat-backend-module-litellm", + "@backstage-community/plugin-mcp-chat-backend" + ] + }, + "dependencies": { + "@backstage-community/plugin-mcp-chat-common": "workspace:^", + "@backstage-community/plugin-mcp-chat-node": "workspace:^", + "@backstage/backend-plugin-api": "^1.4.0", + "@backstage/config": "^1.3.0" + }, + "devDependencies": { + "@backstage/cli": "^0.33.0" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "files": [ + "dist", + "config.d.ts" + ], + "configSchema": "config.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/backstage/community-plugins", + "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm" + }, + "keywords": [ + "backstage", + "backstage-plugin", + "backstage-backend-module", + "litellm", + "llm", + "mcp", + "mcp-chat" + ], + "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm", + "bugs": "https://github.com/backstage/community-plugins/issues" +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/report.api.md new file mode 100644 index 00000000000..034d07aba20 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/report.api.md @@ -0,0 +1,33 @@ +## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-litellm" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-backend'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-backend'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-backend'; +import { Tool } from '@backstage-community/plugin-mcp-chat-backend'; + +// @public +const _default: BackendFeature; +export default _default; + +// @public +export class LiteLLMProvider extends LLMProvider { + // (undocumented) + protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; + // (undocumented) + protected getHeaders(): Record; + // (undocumented) + protected parseResponse(response: any): ChatResponse; + // (undocumented) + sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; + // (undocumented) + testConnection(): Promise<{ + connected: boolean; + models?: string[]; + error?: string; + }>; +} +``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.ts similarity index 85% rename from workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.ts rename to workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.ts index 07e2fdd5ecc..372378b1104 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.ts @@ -13,32 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { LLMProvider } from './base-provider'; -import { ChatMessage, Tool, ChatResponse } from '../types'; -/** - * LiteLLM Provider - * - * LiteLLM is a unified interface to 100+ LLM APIs including: - * - OpenAI, Azure OpenAI - * - Anthropic (Claude) - * - Google (Gemini, VertexAI) - * - AWS Bedrock - * - Cohere, Replicate, Huggingface - * - And many more... - * - * It uses the OpenAI-compatible format, making it easy to integrate. - * - * Configuration example in app-config.yaml: - * ```yaml - * mcpChat: - * providers: - * - id: litellm - * token: ${LITELLM_API_KEY} # Optional, depends on your LiteLLM setup - * baseUrl: 'http://localhost:4000' # Your LiteLLM proxy URL - * model: gpt-4 # Any model supported by your LiteLLM instance - * ``` - */ +import { + LLMProvider, + type ChatMessage, + type Tool, + type ChatResponse, +} from '@backstage-community/plugin-mcp-chat-common'; + /** * LiteLLM proxy provider. * Provides unified access to 100+ LLM APIs through LiteLLM. diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/index.ts new file mode 100644 index 00000000000..8dcd10d0b90 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Backend module for the mcp-chat plugin that provides the LiteLLM provider. + * + * @packageDocumentation + */ + +export { default } from './module'; +export { LiteLLMProvider } from './LiteLLMProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/module.ts new file mode 100644 index 00000000000..9f49588137a --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/module.ts @@ -0,0 +1,78 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createBackendModule, + coreServices, +} from '@backstage/backend-plugin-api'; +import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; +import type { Config } from '@backstage/config'; +import { LiteLLMProvider } from './LiteLLMProvider'; + +/** + * Reads the optional `auth` record from a provider config entry. + * @param entry - The config entry to read auth from + * @returns A record of string key-value pairs, or undefined if no auth config + */ +function readAuthRecord(entry: Config): Record | undefined { + const authConfig = entry.getOptionalConfig('auth'); + if (!authConfig) return undefined; + const result: Record = {}; + for (const key of authConfig.keys()) { + result[key] = authConfig.getString(key); + } + return result; +} + +/** + * Backend module that registers the LiteLLM provider + * with the mcp-chat backend plugin. + * + * @public + */ +export default createBackendModule({ + pluginId: 'mcp-chat', + moduleId: 'litellm', + register(reg) { + reg.registerInit({ + deps: { + config: coreServices.rootConfig, + llmProviders: llmProviderExtensionPoint, + }, + async init({ config, llmProviders }) { + const providers = + config.getOptionalConfigArray('mcpChat.providers') || []; + const entry = providers.find(p => p.getString('id') === 'litellm'); + + if (!entry) return; // Skip registration if not configured + + const providerConfig = { + type: 'litellm', + apiKey: entry.getOptionalString('token'), + baseUrl: + entry.getOptionalString('baseUrl') || 'http://localhost:4000', + model: entry.getString('model'), + auth: readAuthRecord(entry), + }; + + llmProviders.registerProvider( + 'litellm', + new LiteLLMProvider(providerConfig), + ); + }, + }); + }, +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/tsconfig.json new file mode 100644 index 00000000000..6364965a1a3 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@backstage/cli/config/tsconfig.json", + "include": ["src"], + "exclude": ["node_modules"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + } +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/.eslintrc.js new file mode 100644 index 00000000000..e2a53a6ad28 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/README.md new file mode 100644 index 00000000000..df5b1e958d7 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/README.md @@ -0,0 +1,5 @@ +# @backstage-community/plugin-mcp-chat-backend-module-ollama + +The ollama backend module for the mcp-chat plugin. + +_This plugin was created through the Backstage CLI_ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/config.d.ts new file mode 100644 index 00000000000..65d61e8b043 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/config.d.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface Config { + /** Configuration options for the MCP Chat plugin */ + mcpChat?: { + /** + * AI/LLM providers configuration + * @visibility backend + */ + providers?: Array<{ + /** + * Unique identifier for the provider + * @visibility backend + */ + id: string; + /** + * API token for the provider + * @visibility secret + */ + token?: string; + /** + * Model name to use for this provider + * @visibility backend + */ + model: string; + /** + * Base URL for the provider's API + * @visibility backend + */ + baseUrl?: string; + /** + * Provider-specific authentication parameters (IAM, session tokens, etc.) + * @visibility secret + */ + auth?: { [key: string]: string }; + }>; + }; +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/knip-report.md new file mode 100644 index 00000000000..28921c328dd --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/knip-report.md @@ -0,0 +1 @@ +# Knip report diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/package.json new file mode 100644 index 00000000000..4d3e62e88f4 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/package.json @@ -0,0 +1,61 @@ +{ + "name": "@backstage-community/plugin-mcp-chat-backend-module-ollama", + "version": "0.1.0", + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module", + "pluginId": "mcp-chat", + "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", + "pluginPackages": [ + "@backstage-community/plugin-mcp-chat-backend-module-ollama", + "@backstage-community/plugin-mcp-chat-backend" + ] + }, + "dependencies": { + "@backstage-community/plugin-mcp-chat-common": "workspace:^", + "@backstage-community/plugin-mcp-chat-node": "workspace:^", + "@backstage/backend-plugin-api": "^1.4.0", + "@backstage/config": "^1.3.0", + "ollama": "^0.6.0" + }, + "devDependencies": { + "@backstage/cli": "^0.33.0" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "files": [ + "dist", + "config.d.ts" + ], + "configSchema": "config.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/backstage/community-plugins", + "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama" + }, + "keywords": [ + "backstage", + "backstage-plugin", + "backstage-backend-module", + "ollama", + "llm", + "mcp", + "mcp-chat" + ], + "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama", + "bugs": "https://github.com/backstage/community-plugins/issues" +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/report.api.md new file mode 100644 index 00000000000..230d517badf --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/report.api.md @@ -0,0 +1,35 @@ +## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-ollama" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-backend'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-backend'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-backend'; +import { ProviderConfig } from '@backstage-community/plugin-mcp-chat-backend'; +import { Tool } from '@backstage-community/plugin-mcp-chat-backend'; + +// @public +const _default: BackendFeature; +export default _default; + +// @public +export class OllamaProvider extends LLMProvider { + constructor(config: ProviderConfig); + // (undocumented) + protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; + // (undocumented) + protected getHeaders(): Record; + // (undocumented) + protected parseResponse(response: any): ChatResponse; + // (undocumented) + sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; + // (undocumented) + testConnection(): Promise<{ + connected: boolean; + models?: string[]; + error?: string; + }>; +} +``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.ts similarity index 93% rename from workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.ts rename to workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.ts index 69829eb43db..ed6cc405c1f 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.ts @@ -13,8 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { LLMProvider } from './base-provider'; -import { ChatMessage, Tool, ChatResponse } from '../types'; + +import { + LLMProvider, + type ChatMessage, + type Tool, + type ChatResponse, + type ProviderConfig, +} from '@backstage-community/plugin-mcp-chat-common'; import { Ollama } from 'ollama'; /** @@ -25,7 +31,7 @@ import { Ollama } from 'ollama'; export class OllamaProvider extends LLMProvider { private ollama: Ollama; - constructor(config: any) { + constructor(config: ProviderConfig) { super(config); // Initialize Ollama client with the base URL this.ollama = new Ollama({ @@ -137,7 +143,7 @@ export class OllamaProvider extends LLMProvider { } protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any { - // This method is not used anymore since we're using the Ollama library directly + // This method is not used since we use the Ollama SDK directly const request: any = { model: this.model, messages, @@ -153,8 +159,6 @@ export class OllamaProvider extends LLMProvider { } protected parseResponse(response: any): ChatResponse { - // The Ollama library returns a response that should be compatible with OpenAI format - // But let's ensure it matches our expected ChatResponse format let toolCalls; if (response.message?.tool_calls) { // Convert Ollama tool calls to the expected format diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/index.ts new file mode 100644 index 00000000000..b55c8ad4d4a --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Backend module for the mcp-chat plugin that provides the Ollama LLM provider. + * + * @packageDocumentation + */ + +export { default } from './module'; +export { OllamaProvider } from './OllamaProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/module.ts new file mode 100644 index 00000000000..4bb8ea5b99e --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/module.ts @@ -0,0 +1,78 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createBackendModule, + coreServices, +} from '@backstage/backend-plugin-api'; +import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; +import type { Config } from '@backstage/config'; +import { OllamaProvider } from './OllamaProvider'; + +/** + * Reads the optional `auth` record from a provider config entry. + * @param entry - The config entry to read auth from + * @returns A record of string key-value pairs, or undefined if no auth config + */ +function readAuthRecord(entry: Config): Record | undefined { + const authConfig = entry.getOptionalConfig('auth'); + if (!authConfig) return undefined; + const result: Record = {}; + for (const key of authConfig.keys()) { + result[key] = authConfig.getString(key); + } + return result; +} + +/** + * Backend module that registers the Ollama LLM provider + * with the mcp-chat backend plugin. + * + * @public + */ +export default createBackendModule({ + pluginId: 'mcp-chat', + moduleId: 'ollama', + register(reg) { + reg.registerInit({ + deps: { + config: coreServices.rootConfig, + llmProviders: llmProviderExtensionPoint, + }, + async init({ config, llmProviders }) { + const providers = + config.getOptionalConfigArray('mcpChat.providers') || []; + const entry = providers.find(p => p.getString('id') === 'ollama'); + + if (!entry) return; // Skip registration if not configured + + const providerConfig = { + type: 'ollama', + apiKey: entry.getOptionalString('token'), + baseUrl: + entry.getOptionalString('baseUrl') || 'http://localhost:11434', + model: entry.getString('model'), + auth: readAuthRecord(entry), + }; + + llmProviders.registerProvider( + 'ollama', + new OllamaProvider(providerConfig), + ); + }, + }); + }, +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/tsconfig.json new file mode 100644 index 00000000000..6364965a1a3 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@backstage/cli/config/tsconfig.json", + "include": ["src"], + "exclude": ["node_modules"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + } +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/.eslintrc.js new file mode 100644 index 00000000000..e2a53a6ad28 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/README.md new file mode 100644 index 00000000000..03c3159b7a5 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/README.md @@ -0,0 +1,10 @@ +# @backstage-community/plugin-mcp-chat-backend-module-openai-responses + +The openai-responses backend module for the mcp-chat plugin. + +_This plugin was created through the Backstage CLI_ + +## Reponses API + +`openai-responses` backend module uses the newer Responses API (`/v1/responses`) which supports native MCP. +OpenAI's servers connect directly to MCP servers and execute tool calls themselves diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/config.d.ts new file mode 100644 index 00000000000..65d61e8b043 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/config.d.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface Config { + /** Configuration options for the MCP Chat plugin */ + mcpChat?: { + /** + * AI/LLM providers configuration + * @visibility backend + */ + providers?: Array<{ + /** + * Unique identifier for the provider + * @visibility backend + */ + id: string; + /** + * API token for the provider + * @visibility secret + */ + token?: string; + /** + * Model name to use for this provider + * @visibility backend + */ + model: string; + /** + * Base URL for the provider's API + * @visibility backend + */ + baseUrl?: string; + /** + * Provider-specific authentication parameters (IAM, session tokens, etc.) + * @visibility secret + */ + auth?: { [key: string]: string }; + }>; + }; +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/package.json new file mode 100644 index 00000000000..f6ee577a793 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/package.json @@ -0,0 +1,61 @@ +{ + "name": "@backstage-community/plugin-mcp-chat-backend-module-openai-responses", + "version": "0.1.0", + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module", + "pluginId": "mcp-chat", + "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", + "pluginPackages": [ + "@backstage-community/plugin-mcp-chat-backend-module-openai-responses", + "@backstage-community/plugin-mcp-chat-backend" + ] + }, + "dependencies": { + "@backstage-community/plugin-mcp-chat-common": "workspace:^", + "@backstage-community/plugin-mcp-chat-node": "workspace:^", + "@backstage/backend-plugin-api": "^1.4.0", + "@backstage/config": "^1.3.0" + }, + "devDependencies": { + "@backstage/cli": "^0.33.0" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "files": [ + "dist", + "config.d.ts" + ], + "configSchema": "config.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/backstage/community-plugins", + "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses" + }, + "keywords": [ + "backstage", + "backstage-plugin", + "backstage-backend-module", + "openai", + "openai-responses", + "llm", + "mcp", + "mcp-chat" + ], + "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses", + "bugs": "https://github.com/backstage/community-plugins/issues" +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/report.api.md new file mode 100644 index 00000000000..44d8318a34a --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/report.api.md @@ -0,0 +1,40 @@ +## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-openai-responses" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-backend'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-backend'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-backend'; +import { MCPServerFullConfig } from '@backstage-community/plugin-mcp-chat-backend'; +import { ResponsesApiResponse } from '@backstage-community/plugin-mcp-chat-backend'; +import { Tool } from '@backstage-community/plugin-mcp-chat-backend'; + +// @public +const _default: BackendFeature; +export default _default; + +// @public +export class OpenAIResponsesProvider extends LLMProvider { + // (undocumented) + protected formatRequest(messages: ChatMessage[], _tools?: Tool[]): any; + // (undocumented) + protected getHeaders(): Record; + getLastResponseOutput(): ResponsesApiResponse['output'] | null; + // (undocumented) + protected makeRequest(endpoint: string, body: any): Promise; + // (undocumented) + protected parseResponse(response: ResponsesApiResponse): ChatResponse; + // (undocumented) + sendMessage(messages: ChatMessage[], _tools?: Tool[]): Promise; + setMcpServerConfigs(configs: MCPServerFullConfig[]): void; + supportsNativeMcp(): boolean; + // (undocumented) + testConnection(): Promise<{ + connected: boolean; + models?: string[]; + error?: string; + }>; +} +``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.ts similarity index 91% rename from workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.ts rename to workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.ts index 1da2316b54d..0efa50992b9 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.ts @@ -13,18 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { LLMProvider } from './base-provider'; + import { - ChatMessage, - Tool, - ChatResponse, - MCPServerFullConfig, - ResponsesApiResponse, - ResponsesApiMcpTool, - ResponsesApiMcpCall, - ResponsesApiMessage, - ToolCall, -} from '../types'; + LLMProvider, + type ChatMessage, + type Tool, + type ChatResponse, + type MCPServerFullConfig, + type ResponsesApiResponse, + type ResponsesApiMcpTool, + type ResponsesApiMcpCall, + type ResponsesApiMessage, + type ToolCall, +} from '@backstage-community/plugin-mcp-chat-common'; /** * OpenAI Responses API provider with native MCP support. @@ -34,17 +35,29 @@ import { */ export class OpenAIResponsesProvider extends LLMProvider { private mcpServerConfigs: MCPServerFullConfig[] = []; + private lastResponseOutput: ResponsesApiResponse['output'] | null = null; + + /** Override to indicate this provider handles MCP natively. */ + supportsNativeMcp(): boolean { + return true; + } /** * Sets the MCP server configurations for native tool support. * These servers will be passed to the OpenAI Responses API. - * - * @param configs - Array of MCP server configurations */ setMcpServerConfigs(configs: MCPServerFullConfig[]): void { this.mcpServerConfigs = configs; } + /** + * Get the raw Responses API output for detailed tool execution information. + * Used by MCPClientServiceImpl to construct toolResponses. + */ + getLastResponseOutput(): ResponsesApiResponse['output'] | null { + return this.lastResponseOutput; + } + async sendMessage( messages: ChatMessage[], _tools?: Tool[], @@ -60,8 +73,6 @@ export class OpenAIResponsesProvider extends LLMProvider { error?: string; }> { try { - // For Responses API, we can test with a simple request - // Or we could check if the endpoint is reachable const response = await fetch(`${this.baseUrl}/responses`, { method: 'POST', headers: this.getHeaders(), @@ -176,7 +187,6 @@ export class OpenAIResponsesProvider extends LLMProvider { for (const event of response.output) { if (event.type === 'mcp_call') { const mcpCall = event as ResponsesApiMcpCall; - // Create a tool call in the standard format toolCalls.push({ id: mcpCall.id, type: 'function', @@ -187,7 +197,6 @@ export class OpenAIResponsesProvider extends LLMProvider { }); } else if (event.type === 'message') { const message = event as ResponsesApiMessage; - // Extract the final text content if (message.content && message.content.length > 0) { finalContent = message.content .map(part => part.text) @@ -197,7 +206,6 @@ export class OpenAIResponsesProvider extends LLMProvider { } } - // Return in standard ChatResponse format return { choices: [ { @@ -218,16 +226,6 @@ export class OpenAIResponsesProvider extends LLMProvider { }; } - /** - * Get the raw Responses API output for detailed tool execution information - * This is used by MCPClientServiceImpl to construct toolResponses - */ - getLastResponseOutput(): ResponsesApiResponse['output'] | null { - return this.lastResponseOutput; - } - - private lastResponseOutput: ResponsesApiResponse['output'] | null = null; - protected async makeRequest(endpoint: string, body: any): Promise { const url = `${this.baseUrl}${endpoint}`; this.logger?.debug(`[${this.type}] Request to ${url}`, { diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/index.ts new file mode 100644 index 00000000000..926ada24e30 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Backend module for the mcp-chat plugin that provides the OpenAI Responses API LLM provider. + * + * @packageDocumentation + */ + +export { default } from './module'; +export { OpenAIResponsesProvider } from './OpenAIResponsesProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/module.ts new file mode 100644 index 00000000000..2e42b959c8e --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/module.ts @@ -0,0 +1,80 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createBackendModule, + coreServices, +} from '@backstage/backend-plugin-api'; +import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; +import type { Config } from '@backstage/config'; +import { OpenAIResponsesProvider } from './OpenAIResponsesProvider'; + +/** + * Reads the optional `auth` record from a provider config entry. + * @param entry - The config entry to read auth from + * @returns A record of string key-value pairs, or undefined if no auth config + */ +function readAuthRecord(entry: Config): Record | undefined { + const authConfig = entry.getOptionalConfig('auth'); + if (!authConfig) return undefined; + const result: Record = {}; + for (const key of authConfig.keys()) { + result[key] = authConfig.getString(key); + } + return result; +} + +/** + * Backend module that registers the OpenAI Responses API LLM provider + * with the mcp-chat backend plugin. + * + * @public + */ +export default createBackendModule({ + pluginId: 'mcp-chat', + moduleId: 'openai-responses', + register(reg) { + reg.registerInit({ + deps: { + config: coreServices.rootConfig, + llmProviders: llmProviderExtensionPoint, + }, + async init({ config, llmProviders }) { + const providers = + config.getOptionalConfigArray('mcpChat.providers') || []; + const entry = providers.find( + p => p.getString('id') === 'openai-responses', + ); + + if (!entry) return; // Skip registration if not configured + + const providerConfig = { + type: 'openai-responses', + apiKey: entry.getOptionalString('token'), + baseUrl: + entry.getOptionalString('baseUrl') || 'https://api.openai.com/v1', + model: entry.getString('model'), + auth: readAuthRecord(entry), + }; + + llmProviders.registerProvider( + 'openai-responses', + new OpenAIResponsesProvider(providerConfig), + ); + }, + }); + }, +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/tsconfig.json new file mode 100644 index 00000000000..6364965a1a3 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@backstage/cli/config/tsconfig.json", + "include": ["src"], + "exclude": ["node_modules"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + } +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/.eslintrc.js new file mode 100644 index 00000000000..e2a53a6ad28 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/README.md new file mode 100644 index 00000000000..dc9e4db89df --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/README.md @@ -0,0 +1,10 @@ +# @backstage-community/plugin-mcp-chat-backend-module-openai + +The openai backend module for the mcp-chat plugin. + +_This plugin was created through the Backstage CLI_ + +## Chat Completions API + +`openai` backend module uses the standard Chat Completions API (`/v1/chat/completions`). +The classic request/response flow where MCP tool calls are handled by the Backstage backend (it receives tool call requests, executes them locally, sends results back). diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/config.d.ts new file mode 100644 index 00000000000..65d61e8b043 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/config.d.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface Config { + /** Configuration options for the MCP Chat plugin */ + mcpChat?: { + /** + * AI/LLM providers configuration + * @visibility backend + */ + providers?: Array<{ + /** + * Unique identifier for the provider + * @visibility backend + */ + id: string; + /** + * API token for the provider + * @visibility secret + */ + token?: string; + /** + * Model name to use for this provider + * @visibility backend + */ + model: string; + /** + * Base URL for the provider's API + * @visibility backend + */ + baseUrl?: string; + /** + * Provider-specific authentication parameters (IAM, session tokens, etc.) + * @visibility secret + */ + auth?: { [key: string]: string }; + }>; + }; +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/knip-report.md new file mode 100644 index 00000000000..28921c328dd --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/knip-report.md @@ -0,0 +1 @@ +# Knip report diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/package.json new file mode 100644 index 00000000000..12b05dc9fe7 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/package.json @@ -0,0 +1,60 @@ +{ + "name": "@backstage-community/plugin-mcp-chat-backend-module-openai", + "version": "0.1.0", + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module", + "pluginId": "mcp-chat", + "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", + "pluginPackages": [ + "@backstage-community/plugin-mcp-chat-backend-module-openai", + "@backstage-community/plugin-mcp-chat-backend" + ] + }, + "dependencies": { + "@backstage-community/plugin-mcp-chat-common": "workspace:^", + "@backstage-community/plugin-mcp-chat-node": "workspace:^", + "@backstage/backend-plugin-api": "^1.4.0", + "@backstage/config": "^1.3.0" + }, + "devDependencies": { + "@backstage/cli": "^0.33.0" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "files": [ + "dist", + "config.d.ts" + ], + "configSchema": "config.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/backstage/community-plugins", + "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai" + }, + "keywords": [ + "backstage", + "backstage-plugin", + "backstage-backend-module", + "openai", + "llm", + "mcp", + "mcp-chat" + ], + "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai", + "bugs": "https://github.com/backstage/community-plugins/issues" +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/report.api.md new file mode 100644 index 00000000000..53ded455763 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/report.api.md @@ -0,0 +1,33 @@ +## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-openai" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-backend'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-backend'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-backend'; +import { Tool } from '@backstage-community/plugin-mcp-chat-backend'; + +// @public +const _default: BackendFeature; +export default _default; + +// @public +export class OpenAIProvider extends LLMProvider { + // (undocumented) + protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; + // (undocumented) + protected getHeaders(): Record; + // (undocumented) + protected parseResponse(response: any): ChatResponse; + // (undocumented) + sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; + // (undocumented) + testConnection(): Promise<{ + connected: boolean; + models?: string[]; + error?: string; + }>; +} +``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-provider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.ts similarity index 93% rename from workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-provider.ts rename to workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.ts index 35fecffd9dc..9951e27b628 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-provider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.ts @@ -13,8 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { LLMProvider } from './base-provider'; -import { ChatMessage, Tool, ChatResponse } from '../types'; + +import { + LLMProvider, + type ChatMessage, + type Tool, + type ChatResponse, +} from '@backstage-community/plugin-mcp-chat-common'; /** * OpenAI Chat Completions API provider. @@ -52,14 +57,12 @@ export class OpenAIProvider extends LLMProvider { errorMessage = errorData.error.message; } } catch { - // If parsing fails, use the raw error text but truncate if too long errorMessage = errorText.length > 100 ? `${errorText.substring(0, 100)}...` : errorText; } - // Provide user-friendly messages for common errors if (response.status === 401) { errorMessage = 'Invalid API key. Please check your OpenAI API key configuration.'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/index.ts new file mode 100644 index 00000000000..2d75f3a63e9 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Backend module for the mcp-chat plugin that provides the OpenAI LLM provider. + * + * @packageDocumentation + */ + +export { default } from './module'; +export { OpenAIProvider } from './OpenAIProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/module.ts new file mode 100644 index 00000000000..62cbbf9b618 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/module.ts @@ -0,0 +1,78 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createBackendModule, + coreServices, +} from '@backstage/backend-plugin-api'; +import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; +import type { Config } from '@backstage/config'; +import { OpenAIProvider } from './OpenAIProvider'; + +/** + * Reads the optional `auth` record from a provider config entry. + * @param entry - The config entry to read auth from + * @returns A record of string key-value pairs, or undefined if no auth config + */ +function readAuthRecord(entry: Config): Record | undefined { + const authConfig = entry.getOptionalConfig('auth'); + if (!authConfig) return undefined; + const result: Record = {}; + for (const key of authConfig.keys()) { + result[key] = authConfig.getString(key); + } + return result; +} + +/** + * Backend module that registers the OpenAI LLM provider + * with the mcp-chat backend plugin. + * + * @public + */ +export default createBackendModule({ + pluginId: 'mcp-chat', + moduleId: 'openai', + register(reg) { + reg.registerInit({ + deps: { + config: coreServices.rootConfig, + llmProviders: llmProviderExtensionPoint, + }, + async init({ config, llmProviders }) { + const providers = + config.getOptionalConfigArray('mcpChat.providers') || []; + const entry = providers.find(p => p.getString('id') === 'openai'); + + if (!entry) return; // Skip registration if not configured + + const providerConfig = { + type: 'openai', + apiKey: entry.getOptionalString('token'), + baseUrl: + entry.getOptionalString('baseUrl') || 'https://api.openai.com/v1', + model: entry.getString('model'), + auth: readAuthRecord(entry), + }; + + llmProviders.registerProvider( + 'openai', + new OpenAIProvider(providerConfig), + ); + }, + }); + }, +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/tsconfig.json new file mode 100644 index 00000000000..6364965a1a3 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@backstage/cli/config/tsconfig.json", + "include": ["src"], + "exclude": ["node_modules"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + } +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/config.d.ts index 5188617fcf6..ce8ccf96b72 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/config.d.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/config.d.ts @@ -25,9 +25,8 @@ export interface Config { /** * Unique identifier for the provider * @visibility backend - * @enum { 'openai' | 'claude' | 'gemini' | 'ollama' } */ - id: 'openai' | 'claude' | 'gemini' | 'ollama'; + id: string; /** * API token for the provider * @visibility secret @@ -43,6 +42,11 @@ export interface Config { * @visibility backend */ baseUrl?: string; + /** + * Provider-specific authentication parameters (IAM, session tokens, etc.) + * @visibility secret + */ + auth?: { [key: string]: string }; }>; /** * MCP (Model Context Protocol) servers configuration diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/dev/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/dev/index.ts index 088e4cda15a..707e99fdc78 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/dev/index.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/dev/index.ts @@ -41,5 +41,7 @@ backend.add( ); backend.add(import('../src')); - +backend.add( + import('@backstage-community/plugin-mcp-chat-backend-module-openai'), +); backend.start(); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json index cf21cbe0b42..3c5e89e91d8 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json @@ -28,9 +28,11 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-defaults": "^0.16.0", - "@backstage/backend-plugin-api": "^1.8.0", - "@backstage/config": "^1.3.6", + "@backstage-community/plugin-mcp-chat-common": "workspace:^", + "@backstage-community/plugin-mcp-chat-node": "workspace:^", + "@backstage/backend-defaults": "^0.11.0", + "@backstage/backend-plugin-api": "^1.4.0", + "@backstage/config": "^1.3.0", "@backstage/errors": "^1.2.7", "@backstage/plugin-catalog-node": "^2.1.0", "@google/genai": "^1.41.0", @@ -38,12 +40,12 @@ "express": "^4.22.0", "express-promise-router": "^4.1.0", "knex": "^3.1.0", - "ollama": "^0.6.0", - "uuid": "^11.0.0" + "uuid": "^9.0.0" }, "devDependencies": { - "@backstage/backend-test-utils": "^1.11.1", - "@backstage/cli": "^0.36.0", + "@backstage-community/plugin-mcp-chat-backend-module-openai": "workspace:^", + "@backstage/backend-test-utils": "^1.6.0", + "@backstage/cli": "^0.33.0", "@types/express": "^4.17.6", "@types/supertest": "^7.0.0", "@types/uuid": "^11.0.0", diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend/report.api.md index b80cb4b3f6b..376a0dfafec 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/report.api.md @@ -8,7 +8,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { Config } from '@backstage/config'; import { DatabaseService } from '@backstage/backend-plugin-api'; import express from 'express'; -import { GenerateContentResponse } from '@google/genai'; +import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { HttpAuthService } from '@backstage/backend-plugin-api'; import { LoggerService } from '@backstage/backend-plugin-api'; import { RootConfigService } from '@backstage/backend-plugin-api'; @@ -74,24 +74,6 @@ export interface ChatResponse { }; } -// @public -export class ClaudeProvider extends LLMProvider { - // (undocumented) - protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; - // (undocumented) - protected getHeaders(): Record; - // (undocumented) - protected parseResponse(response: any): ChatResponse; - // (undocumented) - sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; - // (undocumented) - testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; -} - // @public export interface ConversationRecord { createdAt: Date; @@ -117,53 +99,6 @@ export function executeToolCall( // @public export function findNpxPath(): Promise; -// @public -export class GeminiProvider extends LLMProvider { - constructor(config: ProviderConfig); - // (undocumented) - protected formatRequest(_messages: ChatMessage[], _tools?: Tool[]): any; - // (undocumented) - protected getHeaders(): Record; - // (undocumented) - protected parseResponse(result: GenerateContentResponse): ChatResponse; - // (undocumented) - sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; - // (undocumented) - testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; -} - -// @public -export function getProviderConfig(config: RootConfigService): ProviderConfig; - -// @public -export function getProviderInfo(config: RootConfigService): { - provider: string; - model: string; - baseURL: string; -}; - -// @public -export class LiteLLMProvider extends LLMProvider { - // (undocumented) - protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; - // (undocumented) - protected getHeaders(): Record; - // (undocumented) - protected parseResponse(response: any): ChatResponse; - // (undocumented) - sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; - // (undocumented) - testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; -} - // @public export abstract class LLMProvider { constructor(config: ProviderConfig); @@ -176,8 +111,12 @@ export abstract class LLMProvider { messages: ChatMessage[], tools?: Tool[], ): any; + getBaseUrl(): string; // (undocumented) protected abstract getHeaders(): Record; + getLastResponseOutput(): any; + getModel(): string; + getType(): string; // (undocumented) protected logger?: LoggerService; // (undocumented) @@ -191,6 +130,8 @@ export abstract class LLMProvider { messages: ChatMessage[], tools?: Tool[], ): Promise; + setMcpServerConfigs(_configs: MCPServerFullConfig[]): void; + supportsNativeMcp(): boolean; // (undocumented) abstract testConnection(): Promise<{ connected: boolean; @@ -203,6 +144,14 @@ export abstract class LLMProvider { protected type: string; } +// @public +export interface LlmProviderExtensionPoint { + registerProvider(type: string, provider: LLMProvider): void; +} + +// @public +export const llmProviderExtensionPoint: ExtensionPoint; + // @public export type LLMProviderType = | 'openai' @@ -255,6 +204,7 @@ export class MCPClientServiceImpl implements MCPClientService { export type MCPClientServiceOptions = { logger: LoggerService; config: RootConfigService; + provider: LLMProvider; }; // @public @@ -309,68 +259,10 @@ export interface MessageValidationResult { isValid: boolean; } -// @public -export class OllamaProvider extends LLMProvider { - constructor(config: any); - // (undocumented) - protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; - // (undocumented) - protected getHeaders(): Record; - // (undocumented) - protected parseResponse(response: any): ChatResponse; - // (undocumented) - sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; - // (undocumented) - testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; -} - -// @public -export class OpenAIProvider extends LLMProvider { - // (undocumented) - protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; - // (undocumented) - protected getHeaders(): Record; - // (undocumented) - protected parseResponse(response: any): ChatResponse; - // (undocumented) - sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; - // (undocumented) - testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; -} - -// @public -export class OpenAIResponsesProvider extends LLMProvider { - // (undocumented) - protected formatRequest(messages: ChatMessage[], _tools?: Tool[]): any; - // (undocumented) - protected getHeaders(): Record; - getLastResponseOutput(): ResponsesApiResponse['output'] | null; - // (undocumented) - protected makeRequest(endpoint: string, body: any): Promise; - // (undocumented) - protected parseResponse(response: ResponsesApiResponse): ChatResponse; - // (undocumented) - sendMessage(messages: ChatMessage[], _tools?: Tool[]): Promise; - setMcpServerConfigs(configs: MCPServerFullConfig[]): void; - // (undocumented) - testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; -} - // @public export interface ProviderConfig { apiKey?: string; + auth?: Record; baseUrl: string; logger?: LoggerService; model: string; @@ -384,14 +276,6 @@ export interface ProviderConnectionStatus { models?: string[]; } -// @public -export class ProviderFactory { - static createProvider( - config: ProviderConfig, - logger?: LoggerService, - ): LLMProvider; -} - // @public export interface ProviderInfo { baseUrl: string; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/extensions.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/extensions.ts new file mode 100644 index 00000000000..f01a9132f1c --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/extensions.ts @@ -0,0 +1,25 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Re-exports the LLM provider extension point from the node library package + * for backward compatibility. New consumers should import directly from + * `@backstage-community/plugin-mcp-chat-node`. + */ +export { + llmProviderExtensionPoint, + type LlmProviderExtensionPoint, +} from '@backstage-community/plugin-mcp-chat-node'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/index.ts index 0327d6ee6e2..95ebfd170fb 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/index.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/index.ts @@ -20,20 +20,17 @@ export { mcpChatPlugin as default } from './plugin'; // ============================================================================= -// LLM Providers +// Extension Point // ============================================================================= export { - LLMProvider, - ProviderFactory, - getProviderConfig, - getProviderInfo, - OpenAIProvider, - OpenAIResponsesProvider, - ClaudeProvider, - GeminiProvider, - OllamaProvider, - LiteLLMProvider, -} from './providers'; + llmProviderExtensionPoint, + type LlmProviderExtensionPoint, +} from './extensions'; + +// ============================================================================= +// LLM Providers +// ============================================================================= +export { LLMProvider } from './providers'; // ============================================================================= // Services diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.test.ts index 76373f043d7..27a6e54d394 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.test.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.test.ts @@ -15,9 +15,11 @@ */ import { startTestBackend, mockServices } from '@backstage/backend-test-utils'; import { mcpChatPlugin } from './plugin'; +import { llmProviderExtensionPoint } from './extensions'; import request from 'supertest'; import { TestBackend } from '@backstage/backend-test-utils'; import { MCPServerType } from './types'; +import { createBackendModule } from '@backstage/backend-plugin-api'; jest.mock('./services/MCPClientServiceImpl', () => ({ MCPClientServiceImpl: jest.fn().mockImplementation(() => ({ @@ -111,10 +113,36 @@ describe('mcpChatPlugin', () => { let backend: TestBackend; const { validateMessages } = require('./utils'); + // Create a test module that registers a mock provider via the extension point + const mockProviderModule = createBackendModule({ + pluginId: 'mcp-chat', + moduleId: 'test-openai', + register(reg) { + reg.registerInit({ + deps: { + llmProviders: llmProviderExtensionPoint, + }, + async init({ llmProviders }) { + llmProviders.registerProvider('openai', { + sendMessage: jest.fn(), + testConnection: jest.fn(), + getType: () => 'openai', + getModel: () => 'gpt-4o-mini', + getBaseUrl: () => 'https://api.openai.com/v1', + supportsNativeMcp: () => false, + setMcpServerConfigs: jest.fn(), + getLastResponseOutput: () => null, + } as any); + }, + }); + }, + }); + beforeEach(async () => { backend = await startTestBackend({ features: [ mcpChatPlugin, + mockProviderModule, mockServices.rootConfig.factory({ data: mockConfig, }), diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.ts index 46046393bbd..78c5dfa7a8d 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.ts @@ -24,6 +24,8 @@ import { SummarizationService, } from './services'; import { validateConfig } from './utils'; +import { llmProviderExtensionPoint } from './extensions'; +import { LLMProvider } from './providers/base-provider'; /** * mcpChatPlugin backend plugin @@ -33,6 +35,15 @@ import { validateConfig } from './utils'; export const mcpChatPlugin = createBackendPlugin({ pluginId: 'mcp-chat', register(env) { + const providers = new Map(); + + env.registerExtensionPoint(llmProviderExtensionPoint, { + registerProvider(type: string, provider: LLMProvider) { + // Last-write-wins on duplicate registration (Req 1.4) + providers.set(type, provider); + }, + }); + env.registerInit({ deps: { logger: coreServices.logger, @@ -44,10 +55,38 @@ export const mcpChatPlugin = createBackendPlugin({ async init({ logger, httpRouter, config, database, httpAuth }) { validateConfig(config); - // Initialize core services + // Resolve active provider from extension point registry (Req 6.3, 8.2) + const configuredProviders = + config.getOptionalConfigArray('mcpChat.providers') ?? []; + const activeId = configuredProviders[0]?.getString('id'); + + if (!activeId) { + throw new Error('No provider configured in mcpChat.providers[0].id'); + } + + const activeProvider = providers.get(activeId); + if (!activeProvider) { + const available = Array.from(providers.keys()).join(', '); + throw new Error( + `No provider module registered for type '${activeId}'. ` + + `Available registered types: [${available}]. ` + + `Install the corresponding module package.`, + ); + } + + if (providers.size > 0) { + for (const [type] of providers) { + if (type === activeId) { + logger.info(`Active LLM provider: '${type}'`); + } + } + } + + // Inject resolved provider into MCPClientServiceImpl (Req 8.2) const mcpClientService = new MCPClientServiceImpl({ logger, config, + provider: activeProvider, }); const conversationStore = await ChatConversationStore.create({ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/base-provider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/base-provider.ts index effdd22bbd5..2601e87125e 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/base-provider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/base-provider.ts @@ -13,94 +13,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { LoggerService } from '@backstage/backend-plugin-api'; -import { ResponseError } from '@backstage/errors'; -import { ChatMessage, Tool, ChatResponse, ProviderConfig } from '../types'; /** - * Abstract base class for all LLM providers. - * Extend this class to create custom LLM provider implementations. - * - * @public + * Re-exports LLMProvider from the common package for backward compatibility. + * New consumers should import directly from `@backstage-community/plugin-mcp-chat-common`. */ -export abstract class LLMProvider { - protected apiKey?: string; // Made optional - protected baseUrl: string; - protected model: string; - protected type: string; - protected logger?: LoggerService; - - constructor(config: ProviderConfig) { - this.apiKey = config.apiKey; - this.baseUrl = config.baseUrl; - this.model = config.model; - this.type = config.type; - this.logger = config.logger; - } - - abstract sendMessage( - messages: ChatMessage[], - tools?: Tool[], - ): Promise; - - abstract testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; - - protected abstract getHeaders(): Record; - protected abstract formatRequest( - messages: ChatMessage[], - tools?: Tool[], - ): any; - protected abstract parseResponse(response: any): ChatResponse; - - protected truncateForLogging(data: string, maxLength = 4096): string { - if (data.length <= maxLength) return data; - return `${data.substring(0, maxLength)}... [truncated ${ - data.length - maxLength - } chars]`; - } - - protected async makeRequest(endpoint: string, body: any): Promise { - const url = `${this.baseUrl}${endpoint}`; - - this.logger?.debug(`[${this.type}] Request to ${url}`, { - body: this.truncateForLogging(JSON.stringify(body)), - }); - const startTime = Date.now(); - const response = await fetch(url, { - method: 'POST', - headers: this.getHeaders(), - body: JSON.stringify(body), - }); - const duration = Date.now() - startTime; - - if (!response.ok) { - const errorText = await response.text(); - this.logger?.error( - `[${this.type}] Request failed (${response.status}) after ${duration}ms`, - { responseData: errorText }, - ); - throw await ResponseError.fromResponse(response); - } - - const responseData = await response.json(); - - this.logger?.debug(`[${this.type}] Response received in ${duration}ms`, { - data: this.truncateForLogging(JSON.stringify(responseData)), - }); - - // Warn if response was truncated due to token limits - const finishReason = responseData.choices?.[0]?.finish_reason; - if (finishReason === 'length' || finishReason === 'max_tokens') { - this.logger?.warn( - `[${this.type}] Response was truncated due to token limit (finish_reason: ${finishReason}). ` + - `Consider increasing max_tokens in your provider configuration.`, - ); - } - - return responseData; - } -} +export { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/gemini-provider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/gemini-provider.test.ts deleted file mode 100644 index 936506cc1be..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/gemini-provider.test.ts +++ /dev/null @@ -1,776 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { mockServices } from '@backstage/backend-test-utils'; -import { GoogleGenAI } from '@google/genai'; -import { GeminiProvider } from './gemini-provider'; -import { ChatMessage, ProviderConfig, Tool } from '../types'; - -jest.mock('@google/genai'); - -const MockGoogleGenAI = GoogleGenAI as jest.MockedClass; - -describe('GeminiProvider', () => { - let provider: GeminiProvider; - let mockGenerateContent: jest.Mock; - - const mockLogger = mockServices.logger.mock(); - - const config: ProviderConfig = { - type: 'gemini', - apiKey: 'test-api-key', - baseUrl: 'https://generativelanguage.googleapis.com', - model: 'gemini-pro', - logger: mockLogger, - }; - - beforeEach(() => { - jest.clearAllMocks(); - - mockGenerateContent = jest.fn(); - MockGoogleGenAI.mockImplementation( - () => - ({ - models: { - generateContent: mockGenerateContent, - }, - } as any), - ); - - provider = new GeminiProvider(config); - }); - - describe('constructor', () => { - it('should initialize with valid config', () => { - expect(MockGoogleGenAI).toHaveBeenCalledWith({ apiKey: 'test-api-key' }); - }); - - it('should throw error when API key is missing', () => { - const invalidConfig = { ...config, apiKey: undefined }; - - expect(() => new GeminiProvider(invalidConfig)).toThrow( - 'Gemini API key is required', - ); - }); - }); - - describe('sendMessage', () => { - it('should send simple message without tools', async () => { - const messages: ChatMessage[] = [ - { role: 'user', content: 'Hello, how are you?' }, - ]; - - mockGenerateContent.mockResolvedValue({ - candidates: [ - { - content: { - parts: [{ text: 'I am doing well, thank you!' }], - }, - }, - ], - usageMetadata: { - promptTokenCount: 10, - candidatesTokenCount: 15, - totalTokenCount: 25, - }, - }); - - const result = await provider.sendMessage(messages); - - expect(mockGenerateContent).toHaveBeenCalledWith({ - model: 'gemini-pro', - contents: [ - { - role: 'user', - parts: [{ text: 'Hello, how are you?' }], - }, - ], - config: expect.objectContaining({ - temperature: 0.7, - maxOutputTokens: 8192, - safetySettings: expect.any(Array), - }), - }); - - expect(result).toEqual({ - choices: [ - { - message: { - role: 'assistant', - content: 'I am doing well, thank you!', - tool_calls: undefined, - }, - }, - ], - usage: { - prompt_tokens: 10, - completion_tokens: 15, - total_tokens: 25, - }, - }); - }); - - it('should handle system message correctly', async () => { - const messages: ChatMessage[] = [ - { role: 'system', content: 'You are a helpful assistant.' }, - { role: 'user', content: 'Hello!' }, - ]; - - mockGenerateContent.mockResolvedValue({ - candidates: [ - { - content: { - parts: [{ text: 'Hello! How can I help you?' }], - }, - }, - ], - }); - - await provider.sendMessage(messages); - - expect(mockGenerateContent).toHaveBeenCalledWith({ - model: 'gemini-pro', - contents: [{ role: 'user', parts: [{ text: 'Hello!' }] }], - config: expect.objectContaining({ - temperature: 0.7, - maxOutputTokens: 8192, - safetySettings: expect.any(Array), - systemInstruction: 'You are a helpful assistant.', - }), - }); - }); - - it('should handle tools correctly', async () => { - const messages: ChatMessage[] = [ - { role: 'user', content: 'What is the weather like?' }, - ]; - - const tools: Tool[] = [ - { - type: 'function', - function: { - name: 'get_weather', - description: 'Get current weather information', - parameters: { - type: 'object', - properties: { - location: { - type: 'string', - description: 'The city and state', - }, - }, - required: ['location'], - }, - }, - }, - ]; - - mockGenerateContent.mockResolvedValue({ - candidates: [ - { - content: { - parts: [ - { text: 'I can help you get weather information.' }, - { - functionCall: { - name: 'get_weather', - args: { location: 'New York' }, - }, - }, - ], - }, - }, - ], - }); - - const result = await provider.sendMessage(messages, tools); - - expect(mockGenerateContent).toHaveBeenCalledWith({ - model: 'gemini-pro', - contents: [ - { - role: 'user', - parts: [{ text: 'What is the weather like?' }], - }, - ], - config: expect.objectContaining({ - temperature: 0.7, - maxOutputTokens: 8192, - safetySettings: expect.any(Array), - tools: [ - { - functionDeclarations: [ - { - name: 'get_weather', - description: 'Get current weather information', - parameters: { - type: 'object', - properties: { - location: { - type: 'string', - description: 'The city and state', - }, - }, - required: ['location'], - }, - }, - ], - }, - ], - }), - }); - - expect(result.choices[0].message.tool_calls).toHaveLength(1); - expect(result.choices[0].message.tool_calls![0]).toMatchObject({ - type: 'function', - function: { - name: 'get_weather', - arguments: '{"location":"New York"}', - }, - }); - }); - - it('should handle tool response messages', async () => { - const messages: ChatMessage[] = [ - { role: 'user', content: 'What is the weather?' }, - { - role: 'assistant', - content: 'Let me check the weather for you.', - tool_calls: [ - { - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"location":"New York"}', - }, - }, - ], - }, - { - role: 'tool', - content: '{"temperature":"72F","condition":"sunny"}', - tool_call_id: 'call_123', - }, - ]; - - mockGenerateContent.mockResolvedValue({ - candidates: [ - { - content: { - parts: [{ text: 'The weather in New York is 72F and sunny.' }], - }, - }, - ], - }); - - await provider.sendMessage(messages); - - expect(mockGenerateContent).toHaveBeenCalledWith({ - model: 'gemini-pro', - contents: [ - { role: 'user', parts: [{ text: 'What is the weather?' }] }, - { - role: 'model', - parts: [ - { text: 'Let me check the weather for you.' }, - { - functionCall: { - name: 'get_weather', - args: { location: 'New York' }, - }, - }, - ], - }, - { - role: 'function', - parts: [ - { - functionResponse: { - name: 'get_weather', - response: { temperature: '72F', condition: 'sunny' }, - }, - }, - ], - }, - ], - config: expect.objectContaining({ - temperature: 0.7, - maxOutputTokens: 8192, - safetySettings: expect.any(Array), - }), - }); - }); - - it('should handle tool response with invalid JSON', async () => { - const messages: ChatMessage[] = [ - { - role: 'assistant', - content: 'Let me check that for you.', - tool_calls: [ - { - id: 'call_123', - type: 'function', - function: { - name: 'test_function', - arguments: '{}', - }, - }, - ], - }, - { - role: 'tool', - content: 'Invalid JSON response', - tool_call_id: 'call_123', - }, - ]; - - mockGenerateContent.mockResolvedValue({ - candidates: [ - { - content: { - parts: [{ text: 'I understand.' }], - }, - }, - ], - }); - - await provider.sendMessage(messages); - - expect(mockGenerateContent).toHaveBeenCalledWith({ - model: 'gemini-pro', - contents: [ - { - role: 'model', - parts: [ - { text: 'Let me check that for you.' }, - { - functionCall: { - name: 'test_function', - args: {}, - }, - }, - ], - }, - { - role: 'function', - parts: [ - { - functionResponse: { - name: 'test_function', - response: { result: 'Invalid JSON response' }, - }, - }, - ], - }, - ], - config: expect.objectContaining({ - temperature: 0.7, - maxOutputTokens: 8192, - safetySettings: expect.any(Array), - }), - }); - }); - - it('should handle API errors', async () => { - const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; - - mockGenerateContent.mockRejectedValue(new Error('API Error')); - - await expect(provider.sendMessage(messages)).rejects.toThrow('API Error'); - }); - - it('should not leak tools or systemInstruction across calls', async () => { - const tools: Tool[] = [ - { - type: 'function', - function: { - name: 'get_weather', - description: 'Get weather', - parameters: { type: 'object', properties: {} }, - }, - }, - ]; - - mockGenerateContent.mockResolvedValue({ - candidates: [{ content: { parts: [{ text: 'response' }] } }], - }); - - await provider.sendMessage( - [ - { role: 'system', content: 'Be helpful' }, - { role: 'user', content: 'First call' }, - ], - tools, - ); - - const firstCallConfig = mockGenerateContent.mock.calls[0][0].config; - expect(firstCallConfig.tools).toBeDefined(); - expect(firstCallConfig.systemInstruction).toBe('Be helpful'); - - await provider.sendMessage([ - { role: 'user', content: 'Second call without tools or system' }, - ]); - - const secondCallConfig = mockGenerateContent.mock.calls[1][0].config; - expect(secondCallConfig.tools).toBeUndefined(); - expect(secondCallConfig.systemInstruction).toBeUndefined(); - }); - - it('should handle empty response', async () => { - const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; - - mockGenerateContent.mockResolvedValue({ - candidates: [], - }); - - const result = await provider.sendMessage(messages); - - expect(result).toEqual({ - choices: [ - { - message: { - role: 'assistant', - content: '', - tool_calls: undefined, - }, - }, - ], - usage: undefined, - }); - }); - }); - - describe('testConnection', () => { - it('should return connected when API is working', async () => { - mockGenerateContent.mockResolvedValue({ - candidates: [ - { - content: { - parts: [{ text: 'Hello' }], - }, - }, - ], - }); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: true, - models: ['gemini-pro'], - }); - - expect(mockGenerateContent).toHaveBeenCalledWith({ - model: 'gemini-pro', - contents: [{ role: 'user', parts: [{ text: 'Hello' }] }], - config: expect.objectContaining({ - maxOutputTokens: 1, - temperature: 0.7, - safetySettings: expect.any(Array), - }), - }); - }); - - it('should return not connected when API throws error', async () => { - mockGenerateContent.mockRejectedValue(new Error('API connection failed')); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: false, - error: 'API connection failed', - }); - }); - - it('should handle non-Error exceptions', async () => { - mockGenerateContent.mockRejectedValue('String error'); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: false, - error: 'Failed to connect to Gemini API', - }); - }); - - it('should return not connected when no response', async () => { - mockGenerateContent.mockResolvedValue(null as any); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: false, - error: 'No response received from Gemini API', - }); - }); - }); - - describe('cleanJsonSchemaForGemini', () => { - it('should remove unsupported schema properties', () => { - const schema = { - $schema: 'http://json-schema.org/draft-07/schema#', - type: 'object', - additionalProperties: false, - $id: 'test-schema', - $ref: '#/definitions/Test', - definitions: { Test: {} }, - $defs: { Test: {} }, - properties: { - name: { - type: 'string', - $schema: 'nested', - additionalProperties: true, - }, - }, - items: { - type: 'string', - additionalProperties: false, - }, - anyOf: [ - { type: 'string', additionalProperties: true }, - { type: 'number' }, - ], - oneOf: [{ type: 'string', $schema: 'test' }], - allOf: [{ type: 'object', definitions: {} }], - }; - - // Access the private method through type assertion - const cleanedSchema = (provider as any).cleanJsonSchemaForGemini(schema); - - expect(cleanedSchema).toEqual({ - type: 'object', - properties: { - name: { - type: 'string', - }, - }, - items: { - type: 'string', - }, - anyOf: [{ type: 'string' }, { type: 'number' }], - oneOf: [{ type: 'string' }], - allOf: [{ type: 'object' }], - }); - }); - - it('should handle non-object schemas', () => { - expect((provider as any).cleanJsonSchemaForGemini(null)).toBeNull(); - expect((provider as any).cleanJsonSchemaForGemini('string')).toBe( - 'string', - ); - expect((provider as any).cleanJsonSchemaForGemini(123)).toBe(123); - }); - - it('should handle empty schema', () => { - const result = (provider as any).cleanJsonSchemaForGemini({}); - expect(result).toEqual({}); - }); - }); - - describe('convertToGeminiFormat', () => { - it('should convert basic messages correctly', () => { - const messages: ChatMessage[] = [ - { role: 'user', content: 'Hello' }, - { role: 'assistant', content: 'Hi there!' }, - ]; - - const result = (provider as any).convertToGeminiFormat(messages); - - expect(result).toEqual([ - { role: 'user', parts: [{ text: 'Hello' }] }, - { role: 'model', parts: [{ text: 'Hi there!' }] }, - ]); - }); - - it('should handle messages with null content', () => { - const messages: ChatMessage[] = [ - { role: 'user', content: null }, - { role: 'assistant', content: null }, - ]; - - const result = (provider as any).convertToGeminiFormat(messages); - - expect(result).toEqual([ - { role: 'user', parts: [{ text: '' }] }, - { role: 'model', parts: [{ text: '' }] }, - ]); - }); - - it('should skip system messages in conversion', () => { - const messages: ChatMessage[] = [ - { role: 'system', content: 'You are helpful' }, - { role: 'user', content: 'Hello' }, - ]; - - const result = (provider as any).convertToGeminiFormat(messages); - - expect(result).toEqual([{ role: 'user', parts: [{ text: 'Hello' }] }]); - }); - }); - - describe('convertToGeminiTools', () => { - it('should convert tools to Gemini format', () => { - const tools: Tool[] = [ - { - type: 'function', - function: { - name: 'get_weather', - description: 'Get weather information', - parameters: { - type: 'object', - properties: { - location: { type: 'string' }, - }, - required: ['location'], - additionalProperties: false, - }, - }, - }, - ]; - - const result = (provider as any).convertToGeminiTools(tools); - - expect(result).toEqual([ - { - functionDeclarations: [ - { - name: 'get_weather', - description: 'Get weather information', - parameters: { - type: 'object', - properties: { - location: { type: 'string' }, - }, - required: ['location'], - }, - }, - ], - }, - ]); - }); - }); - - describe('parseResponse', () => { - it('should parse response with only text', () => { - const mockResult = { - candidates: [ - { - content: { - parts: [{ text: 'Hello world' }], - }, - }, - ], - } as any; - - const result = (provider as any).parseResponse(mockResult); - - expect(result).toEqual({ - choices: [ - { - message: { - role: 'assistant', - content: 'Hello world', - tool_calls: undefined, - }, - }, - ], - usage: undefined, - }); - }); - - it('should parse response with function calls', () => { - const mockResult = { - candidates: [ - { - content: { - parts: [ - { text: 'Let me check that for you.' }, - { - functionCall: { - name: 'get_weather', - args: { location: 'New York' }, - }, - }, - ], - }, - }, - ], - } as any; - - const result = (provider as any).parseResponse(mockResult); - - expect(result.choices[0].message.content).toBe( - 'Let me check that for you.', - ); - expect(result.choices[0].message.tool_calls).toHaveLength(1); - expect(result.choices[0].message.tool_calls![0]).toMatchObject({ - type: 'function', - function: { - name: 'get_weather', - arguments: '{"location":"New York"}', - }, - }); - }); - - it('should generate unique IDs for tool calls', () => { - const mockResult = { - candidates: [ - { - content: { - parts: [ - { - functionCall: { - name: 'function1', - args: {}, - }, - }, - { - functionCall: { - name: 'function2', - args: {}, - }, - }, - ], - }, - }, - ], - } as any; - - const result = (provider as any).parseResponse(mockResult); - - expect(result.choices[0].message.tool_calls).toHaveLength(2); - expect(result.choices[0].message.tool_calls![0].id).toBeDefined(); - expect(result.choices[0].message.tool_calls![1].id).toBeDefined(); - expect(result.choices[0].message.tool_calls![0].id).not.toBe( - result.choices[0].message.tool_calls![1].id, - ); - }); - }); - - describe('getHeaders', () => { - it('should return empty headers', () => { - const headers = (provider as any).getHeaders(); - expect(headers).toEqual({}); - }); - }); - - describe('formatRequest', () => { - it('should return empty object', () => { - const request = (provider as any).formatRequest([], []); - expect(request).toEqual({}); - }); - }); -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/index.ts index 87ab861c029..37f99351972 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/index.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/index.ts @@ -14,22 +14,4 @@ * limitations under the License. */ -// ============================================================================= -// Provider Base Class and Factory -// ============================================================================= export { LLMProvider } from './base-provider'; -export { - ProviderFactory, - getProviderConfig, - getProviderInfo, -} from './provider-factory'; - -// ============================================================================= -// Provider Implementations -// ============================================================================= -export { OpenAIProvider } from './openai-provider'; -export { OpenAIResponsesProvider } from './openai-responses-provider'; -export { ClaudeProvider } from './claude-provider'; -export { GeminiProvider } from './gemini-provider'; -export { OllamaProvider } from './ollama-provider'; -export { LiteLLMProvider } from './litellm-provider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.test.ts deleted file mode 100644 index d82a4d71927..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.test.ts +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { mockServices } from '@backstage/backend-test-utils'; -import { LiteLLMProvider } from './litellm-provider'; -import { ProviderConfig, ChatMessage, Tool } from '../types'; - -// Mock fetch globally -global.fetch = jest.fn(); - -describe('LiteLLMProvider', () => { - let provider: LiteLLMProvider; - - const mockLogger = mockServices.logger.mock(); - - const config: ProviderConfig = { - type: 'litellm', - apiKey: 'test-api-key', - baseUrl: 'http://localhost:4000', - model: 'gpt-4', - logger: mockLogger, - }; - - beforeEach(() => { - jest.clearAllMocks(); - (global.fetch as jest.Mock).mockReset(); - provider = new LiteLLMProvider(config); - }); - - describe('constructor', () => { - it('should initialize with provided config', () => { - expect(provider).toBeDefined(); - }); - - it('should work without API key', () => { - const configWithoutKey = { - ...config, - apiKey: undefined, - }; - const testProvider = new LiteLLMProvider(configWithoutKey); - expect(testProvider).toBeDefined(); - }); - }); - - describe('sendMessage', () => { - it('should send simple message without tools', async () => { - const messages: ChatMessage[] = [ - { role: 'user', content: 'Hello, how are you?' }, - ]; - - const mockResponse = { - choices: [ - { - message: { - role: 'assistant', - content: 'I am doing well, thank you!', - }, - }, - ], - usage: { - prompt_tokens: 10, - completion_tokens: 15, - total_tokens: 25, - }, - }; - - (global.fetch as jest.Mock).mockResolvedValueOnce({ - ok: true, - json: async () => mockResponse, - }); - - const response = await provider.sendMessage(messages); - - expect(global.fetch).toHaveBeenCalledWith( - 'http://localhost:4000/chat/completions', - expect.objectContaining({ - method: 'POST', - headers: expect.objectContaining({ - 'Content-Type': 'application/json', - Authorization: 'Bearer test-api-key', - }), - body: expect.stringContaining('"model":"gpt-4"'), - }), - ); - - expect(response).toEqual(mockResponse); - }); - - it('should send message with tools', async () => { - const messages: ChatMessage[] = [ - { role: 'user', content: 'What is the weather?' }, - ]; - - const tools: Tool[] = [ - { - type: 'function', - function: { - name: 'get_weather', - description: 'Get current weather', - parameters: { - type: 'object', - properties: { - location: { type: 'string' }, - }, - }, - }, - }, - ]; - - const mockResponse = { - choices: [ - { - message: { - role: 'assistant', - content: null, - tool_calls: [ - { - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"location":"San Francisco"}', - }, - }, - ], - }, - }, - ], - }; - - (global.fetch as jest.Mock).mockResolvedValueOnce({ - ok: true, - json: async () => mockResponse, - }); - - const response = await provider.sendMessage(messages, tools); - - expect(global.fetch).toHaveBeenCalledWith( - 'http://localhost:4000/chat/completions', - expect.objectContaining({ - method: 'POST', - body: expect.stringContaining('"tools"'), - }), - ); - - expect(response.choices[0].message.tool_calls).toHaveLength(1); - expect(response.choices[0].message.tool_calls?.[0].function.name).toBe( - 'get_weather', - ); - }); - - it('should handle API errors', async () => { - const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; - - (global.fetch as jest.Mock).mockResolvedValueOnce({ - ok: false, - status: 500, - text: async () => 'Internal Server Error', - }); - - await expect(provider.sendMessage(messages)).rejects.toThrow(); - }); - }); - - describe('testConnection', () => { - it('should successfully test connection with models endpoint', async () => { - const mockModelsResponse = { - data: [ - { id: 'gpt-4' }, - { id: 'gpt-3.5-turbo' }, - { id: 'claude-3-opus' }, - ], - }; - - (global.fetch as jest.Mock).mockResolvedValueOnce({ - ok: true, - json: async () => mockModelsResponse, - }); - - const result = await provider.testConnection(); - - expect(result.connected).toBe(true); - expect(result.models).toEqual([ - 'gpt-4', - 'gpt-3.5-turbo', - 'claude-3-opus', - ]); - expect(result.error).toBeUndefined(); - }); - - it('should fallback to health endpoint if models endpoint fails', async () => { - (global.fetch as jest.Mock) - .mockRejectedValueOnce(new Error('Models endpoint failed')) - .mockResolvedValueOnce({ - ok: true, - json: async () => ({ status: 'healthy' }), - }); - - const result = await provider.testConnection(); - - expect(result.connected).toBe(true); - expect(result.models).toEqual(['gpt-4']); - }); - - it('should handle 401 authentication error', async () => { - (global.fetch as jest.Mock) - .mockResolvedValueOnce({ - ok: false, - status: 401, - text: async () => - JSON.stringify({ error: { message: 'Unauthorized' } }), - }) - .mockRejectedValueOnce(new Error('Health check failed')); - - const result = await provider.testConnection(); - - expect(result.connected).toBe(false); - expect(result.error).toContain('Invalid API key'); - }); - - it('should handle 404 endpoint not found error', async () => { - (global.fetch as jest.Mock) - .mockResolvedValueOnce({ - ok: false, - status: 404, - text: async () => 'Not Found', - }) - .mockRejectedValueOnce(new Error('Connection refused')); - - const result = await provider.testConnection(); - - expect(result.connected).toBe(false); - expect(result.error).toBeDefined(); - }); - - it('should handle network errors', async () => { - (global.fetch as jest.Mock) - .mockRejectedValueOnce(new Error('Network error')) - .mockRejectedValueOnce(new Error('Network error')); // Health check also fails with same error - - const result = await provider.testConnection(); - - expect(result.connected).toBe(false); - expect(result.error).toBe('Network error'); - }); - }); - - describe('getHeaders', () => { - it('should include Authorization header when API key is provided', () => { - const headers = (provider as any).getHeaders(); - - expect(headers).toEqual({ - 'Content-Type': 'application/json', - Authorization: 'Bearer test-api-key', - }); - }); - - it('should not include Authorization header when API key is missing', () => { - const configWithoutKey = { - ...config, - apiKey: undefined, - }; - const testProvider = new LiteLLMProvider(configWithoutKey); - const headers = (testProvider as any).getHeaders(); - - expect(headers).toEqual({ - 'Content-Type': 'application/json', - }); - expect(headers.Authorization).toBeUndefined(); - }); - }); - - describe('formatRequest', () => { - it('should format request with default parameters', () => { - const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; - - const request = (provider as any).formatRequest(messages); - - expect(request).toEqual({ - model: 'gpt-4', - messages, - max_tokens: 1000, - temperature: 0.7, - }); - }); - - it('should include tools when provided', () => { - const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; - - const tools: Tool[] = [ - { - type: 'function', - function: { - name: 'test_tool', - description: 'A test tool', - parameters: {}, - }, - }, - ]; - - const request = (provider as any).formatRequest(messages, tools); - - expect(request.tools).toEqual(tools); - expect(request.parallel_tool_calls).toBe(true); - }); - }); - - describe('parseResponse', () => { - it('should return response as-is for OpenAI-compatible format', () => { - const mockResponse = { - choices: [ - { - message: { - role: 'assistant', - content: 'Test response', - }, - }, - ], - }; - - const parsed = (provider as any).parseResponse(mockResponse); - - expect(parsed).toEqual(mockResponse); - }); - }); -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.test.ts deleted file mode 100644 index 16b055bb933..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.test.ts +++ /dev/null @@ -1,709 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { mockServices } from '@backstage/backend-test-utils'; -import { OllamaProvider } from './ollama-provider'; -import { ProviderConfig, ChatMessage, Tool } from '../types'; -import { Ollama } from 'ollama'; - -// Mock the Ollama library -jest.mock('ollama'); - -const MockOllama = Ollama as jest.MockedClass; - -describe('OllamaProvider', () => { - let provider: OllamaProvider; - let mockOllama: jest.Mocked; - - const mockLogger = mockServices.logger.mock(); - - const config: ProviderConfig = { - type: 'ollama', - baseUrl: 'http://localhost:11434', - model: 'llama2', - logger: mockLogger, - }; - - beforeEach(() => { - jest.clearAllMocks(); - - mockOllama = { - chat: jest.fn(), - list: jest.fn(), - } as any; - - MockOllama.mockImplementation(() => mockOllama); - - provider = new OllamaProvider(config); - }); - - describe('constructor', () => { - it('should initialize with default baseUrl', () => { - expect(MockOllama).toHaveBeenCalledWith({ - host: 'http://localhost:11434', - }); - }); - - it('should remove /v1 suffix from baseUrl', () => { - const configWithV1 = { - ...config, - baseUrl: 'http://localhost:11434/v1', - }; - - const testProvider = new OllamaProvider(configWithV1); - expect(testProvider).toBeDefined(); - - expect(MockOllama).toHaveBeenCalledWith({ - host: 'http://localhost:11434', - }); - }); - - it('should handle custom baseUrl', () => { - const customConfig = { - ...config, - baseUrl: 'http://custom-ollama:8080', - }; - - const testProvider = new OllamaProvider(customConfig); - expect(testProvider).toBeDefined(); - - expect(MockOllama).toHaveBeenCalledWith({ - host: 'http://custom-ollama:8080', - }); - }); - }); - - describe('sendMessage', () => { - it('should send simple message without tools', async () => { - const messages: ChatMessage[] = [ - { role: 'user', content: 'Hello, how are you?' }, - ]; - - const mockResponse = { - message: { - role: 'assistant', - content: 'I am doing well, thank you!', - }, - usage: { - prompt_tokens: 10, - completion_tokens: 15, - total_tokens: 25, - }, - } as any; - - mockOllama.chat.mockResolvedValue(mockResponse); - - const result = await provider.sendMessage(messages); - - expect(mockOllama.chat).toHaveBeenCalledWith({ - model: 'llama2', - messages: [ - { - role: 'user', - content: 'Hello, how are you?', - tool_call_id: undefined, - }, - ], - tools: undefined, - }); - - expect(result).toEqual({ - choices: [ - { - message: { - role: 'assistant', - content: 'I am doing well, thank you!', - tool_calls: undefined, - }, - }, - ], - usage: { - prompt_tokens: 10, - completion_tokens: 15, - total_tokens: 25, - }, - }); - }); - - it('should handle null content by converting to empty string', async () => { - const messages: ChatMessage[] = [{ role: 'user', content: null }]; - - const mockResponse = { - message: { - role: 'assistant', - content: 'Hello!', - }, - } as any; - - mockOllama.chat.mockResolvedValue(mockResponse); - - await provider.sendMessage(messages); - - expect(mockOllama.chat).toHaveBeenCalledWith({ - model: 'llama2', - messages: [ - { - role: 'user', - content: '', - tool_call_id: undefined, - }, - ], - tools: undefined, - }); - }); - - it('should handle tools correctly', async () => { - const messages: ChatMessage[] = [ - { role: 'user', content: 'What is the weather like?' }, - ]; - - const tools: Tool[] = [ - { - type: 'function', - function: { - name: 'get_weather', - description: 'Get current weather information', - parameters: { - type: 'object', - properties: { - location: { - type: 'string', - description: 'The city and state', - }, - }, - required: ['location'], - }, - }, - }, - ]; - - const mockResponse = { - message: { - role: 'assistant', - content: 'I can help you get weather information.', - tool_calls: [ - { - id: 'call_123', - function: { - name: 'get_weather', - arguments: { location: 'New York' }, - }, - }, - ], - }, - } as any; - - mockOllama.chat.mockResolvedValue(mockResponse); - - const result = await provider.sendMessage(messages, tools); - - expect(mockOllama.chat).toHaveBeenCalledWith({ - model: 'llama2', - messages: [ - { - role: 'user', - content: 'What is the weather like?', - tool_call_id: undefined, - }, - ], - tools: tools, - }); - - expect(result.choices[0].message.tool_calls).toHaveLength(1); - expect(result.choices[0].message.tool_calls![0]).toEqual({ - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"location":"New York"}', - }, - }); - }); - - it('should convert string tool call arguments to objects', async () => { - const messages: ChatMessage[] = [ - { - role: 'assistant', - content: 'Let me check that for you.', - tool_calls: [ - { - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"location":"New York"}', // String arguments - }, - }, - ], - }, - ]; - - const mockResponse = { - message: { - role: 'assistant', - content: 'Done!', - }, - } as any; - - mockOllama.chat.mockResolvedValue(mockResponse); - - await provider.sendMessage(messages); - - expect(mockOllama.chat).toHaveBeenCalledWith({ - model: 'llama2', - messages: [ - { - role: 'assistant', - content: 'Let me check that for you.', - tool_call_id: undefined, - tool_calls: [ - { - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: { location: 'New York' }, // Converted to object - }, - }, - ], - }, - ], - tools: undefined, - }); - }); - - it('should handle tool call arguments that are already objects', async () => { - const messages: ChatMessage[] = [ - { - role: 'assistant', - content: 'Let me check that for you.', - tool_calls: [ - { - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: JSON.stringify({ location: 'New York' }), - }, - }, - ], - }, - ]; - - const mockResponse = { - message: { - role: 'assistant', - content: 'Done!', - }, - } as any; - - mockOllama.chat.mockResolvedValue(mockResponse); - - await provider.sendMessage(messages); - - expect(mockOllama.chat).toHaveBeenCalledWith({ - model: 'llama2', - messages: [ - { - role: 'assistant', - content: 'Let me check that for you.', - tool_call_id: undefined, - tool_calls: [ - { - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: { location: 'New York' }, - }, - }, - ], - }, - ], - tools: undefined, - }); - }); - - it('should handle tool messages', async () => { - const messages: ChatMessage[] = [ - { - role: 'tool', - content: '{"temperature": "72°F", "condition": "sunny"}', - tool_call_id: 'call_123', - }, - ]; - - const mockResponse = { - message: { - role: 'assistant', - content: 'The weather is sunny and 72°F.', - }, - } as any; - - mockOllama.chat.mockResolvedValue(mockResponse); - - await provider.sendMessage(messages); - - expect(mockOllama.chat).toHaveBeenCalledWith({ - model: 'llama2', - messages: [ - { - role: 'tool', - content: '{"temperature": "72°F", "condition": "sunny"}', - tool_call_id: 'call_123', - }, - ], - tools: undefined, - }); - }); - - it('should handle response with alternative tool call format', async () => { - const messages: ChatMessage[] = [ - { role: 'user', content: 'Test message' }, - ]; - - const mockResponse = { - message: { - role: 'assistant', - content: 'I can help with that.', - tool_calls: [ - { - // Alternative format without nested function - name: 'get_info', - arguments: { query: 'test' }, - }, - ], - }, - } as any; - - mockOllama.chat.mockResolvedValue(mockResponse); - - const result = await provider.sendMessage(messages); - - expect(result.choices[0].message.tool_calls).toHaveLength(1); - expect(result.choices[0].message.tool_calls![0]).toEqual({ - id: 'call_0', - type: 'function', - function: { - name: 'get_info', - arguments: '{"query":"test"}', - }, - }); - }); - - it('should handle response without usage metadata', async () => { - const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; - - const mockResponse = { - message: { - role: 'assistant', - content: 'Hi there!', - }, - // No usage field - prompt_eval_count: 5, - eval_count: 8, - } as any; - - mockOllama.chat.mockResolvedValue(mockResponse); - - const result = await provider.sendMessage(messages); - - expect(result.usage).toEqual({ - prompt_tokens: 5, - completion_tokens: 8, - total_tokens: 13, - }); - }); - - it('should handle response with null content', async () => { - const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; - - const mockResponse = { - message: { - role: 'assistant', - content: null, - }, - } as any; - - mockOllama.chat.mockResolvedValue(mockResponse); - - const result = await provider.sendMessage(messages); - - expect(result.choices[0].message.content).toBeNull(); - }); - }); - - describe('testConnection', () => { - it('should return connected when model is available', async () => { - const mockModelList = { - models: [ - { name: 'llama2' }, - { name: 'codellama' }, - { name: 'mistral' }, - ], - } as any; - - mockOllama.list.mockResolvedValue(mockModelList); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: true, - models: ['llama2', 'codellama', 'mistral'], - }); - - expect(mockOllama.list).toHaveBeenCalled(); - }); - - it('should return error when configured model is not available', async () => { - const mockModelList = { - models: [{ name: 'codellama' }, { name: 'mistral' }], - } as any; - - mockOllama.list.mockResolvedValue(mockModelList); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: false, - models: ['codellama', 'mistral'], - error: - "Model 'llama2' is not available on this Ollama server. Available models: codellama, mistral. Please ensure the model is installed by running 'ollama pull llama2' or update your configuration to use an available model.", - }); - }); - - it('should handle empty model list', async () => { - const mockModelList = { - models: [], - }; - - mockOllama.list.mockResolvedValue(mockModelList); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: false, - models: [], - error: - "Model 'llama2' is not available on this Ollama server. Available models: none. Please ensure the model is installed by running 'ollama pull llama2' or update your configuration to use an available model.", - }); - }); - - it('should handle undefined models array', async () => { - const mockModelList = { - models: undefined, - }; - - mockOllama.list.mockResolvedValue(mockModelList as any); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: false, - models: [], - error: - "Model 'llama2' is not available on this Ollama server. Available models: none. Please ensure the model is installed by running 'ollama pull llama2' or update your configuration to use an available model.", - }); - }); - - it('should return error when connection fails', async () => { - const error = new Error('Connection refused'); - mockOllama.list.mockRejectedValue(error); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: false, - error: 'Connection refused', - }); - }); - - it('should handle non-Error exceptions', async () => { - mockOllama.list.mockRejectedValue('String error'); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: false, - error: 'Failed to connect to Ollama server', - }); - }); - }); - - describe('getHeaders', () => { - it('should return correct headers', () => { - const headers = (provider as any).getHeaders(); - - expect(headers).toEqual({ - 'Content-Type': 'application/json', - }); - }); - }); - - describe('formatRequest', () => { - it('should format request correctly without tools', () => { - const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; - - const request = (provider as any).formatRequest(messages); - - expect(request).toEqual({ - model: 'llama2', - messages: messages, - max_tokens: 1000, - temperature: 0.7, - }); - }); - - it('should format request correctly with tools', () => { - const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; - - const tools: Tool[] = [ - { - type: 'function', - function: { - name: 'test_function', - description: 'A test function', - parameters: { type: 'object' }, - }, - }, - ]; - - const request = (provider as any).formatRequest(messages, tools); - - expect(request).toEqual({ - model: 'llama2', - messages: messages, - max_tokens: 1000, - temperature: 0.7, - tools: tools, - }); - }); - - it('should not include tools when empty array', () => { - const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; - - const request = (provider as any).formatRequest(messages, []); - - expect(request).toEqual({ - model: 'llama2', - messages: messages, - max_tokens: 1000, - temperature: 0.7, - }); - }); - }); - - describe('parseResponse', () => { - it('should parse response correctly', () => { - const response = { - message: { - role: 'assistant', - content: 'Hello world', - }, - usage: { - prompt_tokens: 10, - completion_tokens: 15, - total_tokens: 25, - }, - }; - - const result = (provider as any).parseResponse(response); - - expect(result).toEqual({ - choices: [ - { - message: { - role: 'assistant', - content: 'Hello world', - tool_calls: undefined, - }, - }, - ], - usage: { - prompt_tokens: 10, - completion_tokens: 15, - total_tokens: 25, - }, - }); - }); - - it('should handle response with eval counts when no usage', () => { - const response = { - message: { - role: 'assistant', - content: 'Hello world', - }, - prompt_eval_count: 10, - eval_count: 15, - }; - - const result = (provider as any).parseResponse(response); - - expect(result.usage).toEqual({ - prompt_tokens: 10, - completion_tokens: 15, - total_tokens: 25, - }); - }); - - it('should handle response with missing eval counts', () => { - const response = { - message: { - role: 'assistant', - content: 'Hello world', - }, - }; - - const result = (provider as any).parseResponse(response); - - expect(result.usage).toEqual({ - prompt_tokens: 0, - completion_tokens: 0, - total_tokens: 0, - }); - }); - - it('should generate IDs for tool calls without IDs', () => { - const response = { - message: { - role: 'assistant', - content: 'Let me help with that.', - tool_calls: [ - { - function: { - name: 'test_function', - arguments: { test: 'value' }, - }, - }, - { - id: 'existing_id', - function: { - name: 'another_function', - arguments: { test: 'value2' }, - }, - }, - ], - }, - }; - - const result = (provider as any).parseResponse(response); - - expect(result.choices[0].message.tool_calls).toHaveLength(2); - expect(result.choices[0].message.tool_calls![0].id).toBe('call_0'); - expect(result.choices[0].message.tool_calls![1].id).toBe('existing_id'); - }); - }); -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.test.ts deleted file mode 100644 index 28e55a87cc1..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.test.ts +++ /dev/null @@ -1,782 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { mockServices } from '@backstage/backend-test-utils'; -import { OpenAIResponsesProvider } from './openai-responses-provider'; -import { - ProviderConfig, - ChatMessage, - MCPServerFullConfig, - MCPServerType, - ResponsesApiResponse, -} from '../types'; - -// Mock fetch globally -global.fetch = jest.fn(); - -describe('OpenAIResponsesProvider', () => { - let provider: OpenAIResponsesProvider; - const mockFetch = global.fetch as jest.MockedFunction; - - const mockLogger = mockServices.logger.mock(); - - const config: ProviderConfig = { - type: 'openai-responses', - apiKey: 'test-api-key', - baseUrl: 'http://test-api.com/v1', - model: 'gemini/models/gemini-2.5-flash', - logger: mockLogger, - }; - - const mockMCPServerFullConfigs: MCPServerFullConfig[] = [ - { - id: 'k8s', - name: 'Kubernetes Server', - type: MCPServerType.STREAMABLE_HTTP, - url: 'https://kubernetes-mcp-server.example.com/mcp', - }, - { - id: 'brave-search', - name: 'Brave Search', - type: MCPServerType.STREAMABLE_HTTP, - url: 'https://brave-search-mcp.example.com/mcp', - }, - ]; - - beforeEach(() => { - jest.clearAllMocks(); - provider = new OpenAIResponsesProvider(config); - provider.setMcpServerConfigs(mockMCPServerFullConfigs); - }); - - describe('constructor', () => { - it('should initialize with valid config', () => { - expect(provider).toBeDefined(); - }); - }); - - describe('setMcpServerConfigs', () => { - it('should store MCP server configurations', () => { - const newConfigs: MCPServerFullConfig[] = [ - { - id: 'test-server', - name: 'Test Server', - type: MCPServerType.STREAMABLE_HTTP, - url: 'https://test.com/mcp', - }, - ]; - provider.setMcpServerConfigs(newConfigs); - // Configuration is stored internally for use in formatRequest - expect(provider).toBeDefined(); - }); - }); - - describe('sendMessage', () => { - it('should send message with MCP tools to Responses API', async () => { - const messages: ChatMessage[] = [ - { - role: 'user', - content: 'How many pods in the mcp-servers namespace?', - }, - ]; - - const mockResponse: ResponsesApiResponse = { - id: 'resp_test_123', - object: 'response', - created_at: Date.now(), - model: 'gemini/models/gemini-2.5-flash', - status: 'completed', - output: [ - { - id: 'mcp_list_1', - type: 'mcp_list_tools', - server_label: 'k8s', - tools: [ - { - name: 'pods_list_in_namespace', - description: 'List all pods in a namespace', - input_schema: {}, - }, - ], - }, - { - id: 'mcp_call_1', - type: 'mcp_call', - name: 'pods_list_in_namespace', - arguments: '{"namespace":"mcp-servers"}', - server_label: 'k8s', - error: null, - output: 'Found 12 pods in mcp-servers namespace', - }, - { - id: 'msg_1', - type: 'message', - role: 'assistant', - status: 'completed', - content: [ - { - type: 'output_text', - text: 'There are 12 pods in the mcp-servers namespace.', - }, - ], - }, - ], - usage: { - input_tokens: 100, - output_tokens: 50, - total_tokens: 150, - }, - }; - - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => mockResponse, - } as Response); - - const result = await provider.sendMessage(messages); - - expect(mockFetch).toHaveBeenCalledWith( - 'http://test-api.com/v1/responses', - expect.objectContaining({ - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Authorization: 'Bearer test-api-key', - }, - body: JSON.stringify({ - input: 'How many pods in the mcp-servers namespace?', - model: 'gemini/models/gemini-2.5-flash', - tools: [ - { - type: 'mcp', - server_url: 'https://kubernetes-mcp-server.example.com/mcp', - server_label: 'k8s', - require_approval: 'never', - }, - { - type: 'mcp', - server_url: 'https://brave-search-mcp.example.com/mcp', - server_label: 'brave-search', - require_approval: 'never', - }, - ], - }), - }), - ); - - expect(result).toEqual({ - choices: [ - { - message: { - role: 'assistant', - content: 'There are 12 pods in the mcp-servers namespace.', - tool_calls: [ - { - id: 'mcp_call_1', - type: 'function', - function: { - name: 'pods_list_in_namespace', - arguments: '{"namespace":"mcp-servers"}', - }, - }, - ], - }, - }, - ], - usage: { - prompt_tokens: 100, - completion_tokens: 50, - total_tokens: 150, - }, - }); - }); - - it('should handle response without tool calls', async () => { - const messages: ChatMessage[] = [ - { role: 'user', content: 'Hello, how are you?' }, - ]; - - const mockResponse: ResponsesApiResponse = { - id: 'resp_test_456', - object: 'response', - created_at: Date.now(), - model: 'gemini/models/gemini-2.5-flash', - status: 'completed', - output: [ - { - id: 'msg_1', - type: 'message', - role: 'assistant', - status: 'completed', - content: [ - { - type: 'output_text', - text: 'I am doing well, thank you for asking!', - }, - ], - }, - ], - }; - - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => mockResponse, - } as Response); - - const result = await provider.sendMessage(messages); - - expect(result).toEqual({ - choices: [ - { - message: { - role: 'assistant', - content: 'I am doing well, thank you for asking!', - tool_calls: undefined, - }, - }, - ], - usage: undefined, - }); - }); - - it('should include system prompt as instructions', async () => { - const messages: ChatMessage[] = [ - { role: 'system', content: 'You are a helpful assistant.' }, - { role: 'user', content: 'Help me' }, - ]; - - const mockResponse: ResponsesApiResponse = { - id: 'resp_test_789', - object: 'response', - created_at: Date.now(), - model: 'gemini/models/gemini-2.5-flash', - status: 'completed', - output: [ - { - id: 'msg_1', - type: 'message', - role: 'assistant', - status: 'completed', - content: [ - { - type: 'output_text', - text: 'How can I help you?', - }, - ], - }, - ], - }; - - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => mockResponse, - } as Response); - - await provider.sendMessage(messages); - - expect(mockFetch).toHaveBeenCalledWith( - 'http://test-api.com/v1/responses', - expect.objectContaining({ - body: expect.stringContaining( - '"instructions":"You are a helpful assistant."', - ), - }), - ); - }); - - it('should filter out non-URL servers', async () => { - const mixedConfigs: MCPServerFullConfig[] = [ - { - id: 'url-server', - name: 'URL Server', - type: MCPServerType.STREAMABLE_HTTP, - url: 'https://example.com/mcp', - }, - { - id: 'stdio-server', - name: 'STDIO Server', - type: MCPServerType.STDIO, - npxCommand: 'some-mcp-server', - }, - ]; - - provider.setMcpServerConfigs(mixedConfigs); - - const messages: ChatMessage[] = [{ role: 'user', content: 'Test' }]; - - const mockResponse: ResponsesApiResponse = { - id: 'resp_test', - object: 'response', - created_at: Date.now(), - model: 'gemini/models/gemini-2.5-flash', - status: 'completed', - output: [ - { - id: 'msg_1', - type: 'message', - role: 'assistant', - status: 'completed', - content: [{ type: 'output_text', text: 'Test response' }], - }, - ], - }; - - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => mockResponse, - } as Response); - - await provider.sendMessage(messages); - - const fetchCall = mockFetch.mock.calls[0]; - const requestBody = JSON.parse(fetchCall[1]?.body as string); - - // Should only include the URL server - expect(requestBody.tools).toHaveLength(1); - expect(requestBody.tools[0].server_label).toBe('url-server'); - }); - - it('should handle API errors', async () => { - const messages: ChatMessage[] = [{ role: 'user', content: 'Test' }]; - - mockFetch.mockResolvedValueOnce({ - ok: false, - status: 500, - text: async () => 'Internal Server Error', - } as Response); - - await expect(provider.sendMessage(messages)).rejects.toThrow( - 'HTTP 500: Internal Server Error', - ); - }); - - it('should handle multiple tool calls', async () => { - const messages: ChatMessage[] = [ - { role: 'user', content: 'Check pods and search' }, - ]; - - const mockResponse: ResponsesApiResponse = { - id: 'resp_multi', - object: 'response', - created_at: Date.now(), - model: 'gemini/models/gemini-2.5-flash', - status: 'completed', - output: [ - { - id: 'mcp_call_1', - type: 'mcp_call', - name: 'pods_list', - arguments: '{}', - server_label: 'k8s', - error: null, - output: 'Found 10 pods', - }, - { - id: 'mcp_call_2', - type: 'mcp_call', - name: 'search', - arguments: '{"query":"kubernetes"}', - server_label: 'brave-search', - error: null, - output: 'Search results...', - }, - { - id: 'msg_1', - type: 'message', - role: 'assistant', - status: 'completed', - content: [ - { - type: 'output_text', - text: 'Found 10 pods and search results.', - }, - ], - }, - ], - }; - - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => mockResponse, - } as Response); - - const result = await provider.sendMessage(messages); - - expect(result.choices[0].message.tool_calls).toHaveLength(2); - expect(result.choices[0].message.tool_calls![0].function.name).toBe( - 'pods_list', - ); - expect(result.choices[0].message.tool_calls![1].function.name).toBe( - 'search', - ); - }); - - it('should include headers in tools when server has headers', async () => { - const serverWithHeaders: MCPServerFullConfig[] = [ - { - id: 'github-server', - name: 'GitHub Server', - type: MCPServerType.STREAMABLE_HTTP, - url: 'https://api.githubcopilot.com/mcp', - headers: { - Authorization: 'Bearer ghp_test_token_123', - }, - }, - ]; - - provider.setMcpServerConfigs(serverWithHeaders); - - const messages: ChatMessage[] = [ - { role: 'user', content: 'Test with headers' }, - ]; - - const mockResponse: ResponsesApiResponse = { - id: 'resp_headers', - object: 'response', - created_at: Date.now(), - model: 'gemini/models/gemini-2.5-flash', - status: 'completed', - output: [ - { - id: 'msg_1', - type: 'message', - role: 'assistant', - status: 'completed', - content: [{ type: 'output_text', text: 'Response' }], - }, - ], - }; - - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => mockResponse, - } as Response); - - await provider.sendMessage(messages); - - expect(mockFetch).toHaveBeenCalledWith( - 'http://test-api.com/v1/responses', - expect.objectContaining({ - method: 'POST', - headers: expect.objectContaining({ - 'Content-Type': 'application/json', - }), - }), - ); - - const callArgs = mockFetch.mock.calls[0]; - const bodyStr = callArgs[1]?.body as string; - const bodyObj = JSON.parse(bodyStr); - - expect(bodyObj.tools).toHaveLength(1); - expect(bodyObj.tools[0]).toEqual({ - type: 'mcp', - server_url: 'https://api.githubcopilot.com/mcp', - server_label: 'github-server', - require_approval: 'never', - headers: { - Authorization: 'Bearer ghp_test_token_123', - }, - }); - }); - - it('should not include headers field when server has no headers', async () => { - const serverWithoutHeaders: MCPServerFullConfig[] = [ - { - id: 'k8s-server', - name: 'Kubernetes Server', - type: MCPServerType.STREAMABLE_HTTP, - url: 'https://k8s.example.com/mcp', - }, - ]; - - provider.setMcpServerConfigs(serverWithoutHeaders); - - const messages: ChatMessage[] = [ - { role: 'user', content: 'Test without headers' }, - ]; - - const mockResponse: ResponsesApiResponse = { - id: 'resp_no_headers', - object: 'response', - created_at: Date.now(), - model: 'gemini/models/gemini-2.5-flash', - status: 'completed', - output: [ - { - id: 'msg_1', - type: 'message', - role: 'assistant', - status: 'completed', - content: [{ type: 'output_text', text: 'Response' }], - }, - ], - }; - - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => mockResponse, - } as Response); - - await provider.sendMessage(messages); - - const callArgs = mockFetch.mock.calls[0]; - const bodyStr = callArgs[1]?.body as string; - const bodyObj = JSON.parse(bodyStr); - - expect(bodyObj.tools).toHaveLength(1); - expect(bodyObj.tools[0]).toEqual({ - type: 'mcp', - server_url: 'https://k8s.example.com/mcp', - server_label: 'k8s-server', - require_approval: 'never', - }); - expect(bodyObj.tools[0].headers).toBeUndefined(); - }); - - it('should handle multiple servers with mixed header configurations', async () => { - const mixedServers: MCPServerFullConfig[] = [ - { - id: 'github-server', - name: 'GitHub Server', - type: MCPServerType.STREAMABLE_HTTP, - url: 'https://api.githubcopilot.com/mcp', - headers: { - Authorization: 'Bearer ghp_token', - 'X-Custom-Header': 'custom-value', - }, - }, - { - id: 'k8s-server', - name: 'Kubernetes Server', - type: MCPServerType.STREAMABLE_HTTP, - url: 'https://k8s.example.com/mcp', - }, - { - id: 'backstage-server', - name: 'Backstage Server', - type: MCPServerType.STREAMABLE_HTTP, - url: 'http://localhost:7008/api/mcp', - headers: { - Authorization: 'Bearer backstage_token', - }, - }, - ]; - - provider.setMcpServerConfigs(mixedServers); - - const messages: ChatMessage[] = [ - { role: 'user', content: 'Test mixed servers' }, - ]; - - const mockResponse: ResponsesApiResponse = { - id: 'resp_mixed', - object: 'response', - created_at: Date.now(), - model: 'gemini/models/gemini-2.5-flash', - status: 'completed', - output: [ - { - id: 'msg_1', - type: 'message', - role: 'assistant', - status: 'completed', - content: [{ type: 'output_text', text: 'Response' }], - }, - ], - }; - - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => mockResponse, - } as Response); - - await provider.sendMessage(messages); - - const callArgs = mockFetch.mock.calls[0]; - const bodyStr = callArgs[1]?.body as string; - const bodyObj = JSON.parse(bodyStr); - - expect(bodyObj.tools).toHaveLength(3); - - // First server with headers - expect(bodyObj.tools[0]).toEqual({ - type: 'mcp', - server_url: 'https://api.githubcopilot.com/mcp', - server_label: 'github-server', - require_approval: 'never', - headers: { - Authorization: 'Bearer ghp_token', - 'X-Custom-Header': 'custom-value', - }, - }); - - // Second server without headers - expect(bodyObj.tools[1]).toEqual({ - type: 'mcp', - server_url: 'https://k8s.example.com/mcp', - server_label: 'k8s-server', - require_approval: 'never', - }); - expect(bodyObj.tools[1].headers).toBeUndefined(); - - // Third server with headers - expect(bodyObj.tools[2]).toEqual({ - type: 'mcp', - server_url: 'http://localhost:7008/api/mcp', - server_label: 'backstage-server', - require_approval: 'never', - headers: { - Authorization: 'Bearer backstage_token', - }, - }); - }); - }); - - describe('testConnection', () => { - it('should return connected when API is reachable', async () => { - const mockResponse: ResponsesApiResponse = { - id: 'resp_test', - object: 'response', - created_at: Date.now(), - model: 'gemini/models/gemini-2.5-flash', - status: 'completed', - output: [ - { - id: 'msg_1', - type: 'message', - role: 'assistant', - status: 'completed', - content: [{ type: 'output_text', text: 'test' }], - }, - ], - }; - - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => mockResponse, - } as Response); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: true, - models: ['gemini/models/gemini-2.5-flash'], - }); - }); - - it('should return not connected on 401 error', async () => { - mockFetch.mockResolvedValueOnce({ - ok: false, - status: 401, - text: async () => 'Unauthorized', - } as Response); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: false, - error: 'Invalid API key. Please check your API key configuration.', - }); - }); - - it('should return not connected on network error', async () => { - mockFetch.mockRejectedValueOnce(new Error('Network error')); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: false, - error: 'Network error', - }); - }); - - it('should handle 429 rate limit error', async () => { - mockFetch.mockResolvedValueOnce({ - ok: false, - status: 429, - text: async () => 'Too Many Requests', - } as Response); - - const result = await provider.testConnection(); - - expect(result).toEqual({ - connected: false, - error: 'Rate limit exceeded. Please try again later.', - }); - }); - }); - - describe('getLastResponseOutput', () => { - it('should return the last response output', async () => { - const messages: ChatMessage[] = [{ role: 'user', content: 'Test' }]; - - const mockResponse: ResponsesApiResponse = { - id: 'resp_test', - object: 'response', - created_at: Date.now(), - model: 'gemini/models/gemini-2.5-flash', - status: 'completed', - output: [ - { - id: 'msg_1', - type: 'message', - role: 'assistant', - status: 'completed', - content: [{ type: 'output_text', text: 'Test' }], - }, - ], - }; - - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => mockResponse, - } as Response); - - await provider.sendMessage(messages); - const output = provider.getLastResponseOutput(); - - expect(output).toEqual(mockResponse.output); - }); - - it('should return null before any message is sent', () => { - const output = provider.getLastResponseOutput(); - expect(output).toBeNull(); - }); - }); - - describe('getHeaders', () => { - it('should include authorization header when API key is provided', () => { - const headers = (provider as any).getHeaders(); - expect(headers).toEqual({ - 'Content-Type': 'application/json', - Authorization: 'Bearer test-api-key', - }); - }); - - it('should not include authorization header when API key is not provided', () => { - const configWithoutKey: ProviderConfig = { - ...config, - apiKey: undefined, - }; - const providerWithoutKey = new OpenAIResponsesProvider(configWithoutKey); - const headers = (providerWithoutKey as any).getHeaders(); - expect(headers).toEqual({ - 'Content-Type': 'application/json', - }); - }); - }); -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.test.ts deleted file mode 100644 index d3fc7f65f78..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.test.ts +++ /dev/null @@ -1,372 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { mockServices } from '@backstage/backend-test-utils'; -import { - ProviderFactory, - getProviderConfig, - getProviderInfo, -} from './provider-factory'; -import { OpenAIProvider } from './openai-provider'; -import { ClaudeProvider } from './claude-provider'; -import { GeminiProvider } from './gemini-provider'; -import { OllamaProvider } from './ollama-provider'; -import { LiteLLMProvider } from './litellm-provider'; -import { ProviderConfig } from '../types'; - -describe('ProviderFactory', () => { - describe('createProvider', () => { - it('should create correct provider instances for supported types', () => { - const testCases = [ - { type: 'openai', expectedClass: OpenAIProvider }, - { type: 'claude', expectedClass: ClaudeProvider }, - { type: 'gemini', expectedClass: GeminiProvider }, - { type: 'ollama', expectedClass: OllamaProvider }, - { type: 'litellm', expectedClass: LiteLLMProvider }, - ]; - - testCases.forEach(({ type, expectedClass }) => { - const config: ProviderConfig = { - type, - apiKey: 'test-key', - baseUrl: 'https://example.com', - model: 'test-model', - logger: mockServices.logger.mock(), - }; - - const provider = ProviderFactory.createProvider(config); - expect(provider).toBeInstanceOf(expectedClass); - }); - }); - - it('should throw error for unsupported provider type', () => { - const config: ProviderConfig = { - type: 'unsupported', - apiKey: 'test-key', - baseUrl: 'https://example.com', - model: 'test-model', - logger: mockServices.logger.mock(), - }; - - expect(() => ProviderFactory.createProvider(config)).toThrow( - 'Unsupported provider: unsupported', - ); - }); - }); -}); - -describe('getProviderConfig', () => { - let mockConfig: ReturnType; - - beforeEach(() => { - mockConfig = mockServices.rootConfig.mock(); - }); - - it('should throw error when no providers are configured', () => { - mockConfig.getOptionalConfigArray.mockReturnValue([]); - - expect(() => getProviderConfig(mockConfig)).toThrow(); - }); - - it('should throw error for unsupported provider id', () => { - const mockProviderConfig = { - getString: jest.fn().mockImplementation((key: string) => { - if (key === 'id') return 'unsupported'; - if (key === 'model') return 'test-model'; - throw new Error(`Unexpected key: ${key}`); - }), - getOptionalString: jest.fn().mockImplementation((key: string) => { - if (key === 'baseUrl') return undefined; - return 'test-key'; - }), - } as any; - - mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); - - expect(() => getProviderConfig(mockConfig)).toThrow( - 'Unsupported provider id: unsupported. Allowed values are: openai, openai-responses, claude, gemini, ollama, litellm', - ); - }); - - it('should configure providers with correct default base URLs', () => { - const testCases = [ - { id: 'openai', expectedBaseUrl: 'https://api.openai.com/v1' }, - { id: 'claude', expectedBaseUrl: 'https://api.anthropic.com/v1' }, - { - id: 'gemini', - expectedBaseUrl: 'https://generativelanguage.googleapis.com', - }, - ]; - - testCases.forEach(({ id, expectedBaseUrl }) => { - const mockProviderConfig = { - getString: jest.fn().mockImplementation((key: string) => { - if (key === 'id') return id; - if (key === 'model') return 'test-model'; - throw new Error(`Unexpected key: ${key}`); - }), - getOptionalString: jest.fn().mockImplementation((key: string) => { - if (key === 'baseUrl') return undefined; - return 'test-key'; - }), - } as any; - - mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); - - const result = getProviderConfig(mockConfig); - expect(result.baseUrl).toBe(expectedBaseUrl); - expect(result.type).toBe(id); - expect(result.apiKey).toBe('test-key'); - expect(result.model).toBe('test-model'); - }); - }); - - it('should configure OpenAI provider with default and custom base URLs', () => { - const testCases = [ - { - customBaseUrl: undefined, - expectedBaseUrl: 'https://api.openai.com/v1', - }, - { - customBaseUrl: 'https://custom-openai.com/v1', - expectedBaseUrl: 'https://custom-openai.com/v1', - }, - ]; - - testCases.forEach(({ customBaseUrl, expectedBaseUrl }) => { - const mockProviderConfig = { - getString: jest.fn().mockImplementation((key: string) => { - if (key === 'id') return 'openai'; - if (key === 'model') return 'test-model'; - throw new Error(`Unexpected key: ${key}`); - }), - getOptionalString: jest.fn().mockImplementation((key: string) => { - if (key === 'token') return 'test-token'; - if (key === 'baseUrl') return customBaseUrl; - return undefined; - }), - } as any; - - mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); - - const result = getProviderConfig(mockConfig); - expect(result.baseUrl).toBe(expectedBaseUrl); - expect(result.type).toBe('openai'); - expect(result.apiKey).toBe('test-token'); - }); - }); - - it('should configure Ollama provider with default and custom base URLs', () => { - const testCases = [ - { customBaseUrl: undefined, expectedBaseUrl: 'http://localhost:11434' }, - { - customBaseUrl: 'http://custom:11434', - expectedBaseUrl: 'http://custom:11434', - }, - ]; - - testCases.forEach(({ customBaseUrl, expectedBaseUrl }) => { - const mockProviderConfig = { - getString: jest.fn().mockImplementation((key: string) => { - if (key === 'id') return 'ollama'; - if (key === 'model') return 'llama2'; - throw new Error(`Unexpected key: ${key}`); - }), - getOptionalString: jest.fn().mockImplementation((key: string) => { - if (key === 'token') return undefined; - if (key === 'baseUrl') return customBaseUrl; - return undefined; - }), - } as any; - - mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); - - const result = getProviderConfig(mockConfig); - expect(result.baseUrl).toBe(expectedBaseUrl); - expect(result.type).toBe('ollama'); - expect(result.apiKey).toBeUndefined(); - }); - }); - - it('should configure LiteLLM provider with default and custom base URLs', () => { - const testCases = [ - { customBaseUrl: undefined, expectedBaseUrl: 'http://localhost:4000' }, - { - customBaseUrl: 'http://custom:4000', - expectedBaseUrl: 'http://custom:4000', - }, - ]; - - testCases.forEach(({ customBaseUrl, expectedBaseUrl }) => { - const mockProviderConfig = { - getString: jest.fn().mockImplementation((key: string) => { - if (key === 'id') return 'litellm'; - if (key === 'model') return 'gpt-4o-mini'; - throw new Error(`Unexpected key: ${key}`); - }), - getOptionalString: jest.fn().mockImplementation((key: string) => { - if (key === 'token') return 'test-key'; - if (key === 'baseUrl') return customBaseUrl; - return undefined; - }), - } as any; - - mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); - - const result = getProviderConfig(mockConfig); - expect(result.baseUrl).toBe(expectedBaseUrl); - expect(result.type).toBe('litellm'); - expect(result.apiKey).toBe('test-key'); - }); - }); - - it('should allow LiteLLM provider without API key', () => { - const mockProviderConfig = { - getString: jest.fn().mockImplementation((key: string) => { - if (key === 'id') return 'litellm'; - if (key === 'model') return 'gpt-4o-mini'; - throw new Error(`Unexpected key: ${key}`); - }), - getOptionalString: jest.fn().mockImplementation((key: string) => { - if (key === 'token') return undefined; - if (key === 'baseUrl') return 'http://localhost:4000'; - return undefined; - }), - } as any; - - mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); - - const result = getProviderConfig(mockConfig); - expect(result.baseUrl).toBe('http://localhost:4000'); - expect(result.type).toBe('litellm'); - expect(result.apiKey).toBeUndefined(); - }); - - it('should throw error when API key is missing for non-Ollama/LiteLLM providers', () => { - const mockProviderConfig = { - getString: jest.fn().mockImplementation((key: string) => { - if (key === 'id') return 'openai'; - if (key === 'model') return 'gpt-4'; - throw new Error(`Unexpected key: ${key}`); - }), - getOptionalString: jest.fn().mockReturnValue(undefined), - } as any; - - mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); - - expect(() => getProviderConfig(mockConfig)).toThrow( - 'API key is required for provider: openai', - ); - }); - - it('should use first provider when multiple are configured', () => { - const mockProviderConfig1 = { - getString: jest.fn().mockImplementation((key: string) => { - if (key === 'id') return 'openai'; - if (key === 'model') return 'gpt-4'; - throw new Error(`Unexpected key: ${key}`); - }), - getOptionalString: jest.fn().mockImplementation((key: string) => { - if (key === 'baseUrl') return undefined; - return 'first-key'; - }), - } as any; - - const mockProviderConfig2 = { - getString: jest.fn().mockImplementation((key: string) => { - if (key === 'id') return 'claude'; - if (key === 'model') return 'claude-3-sonnet-20240229'; - throw new Error(`Unexpected key: ${key}`); - }), - getOptionalString: jest.fn().mockImplementation((key: string) => { - if (key === 'baseUrl') return undefined; - return 'second-key'; - }), - } as any; - - mockConfig.getOptionalConfigArray.mockReturnValue([ - mockProviderConfig1, - mockProviderConfig2, - ]); - - const result = getProviderConfig(mockConfig); - - expect(result).toEqual({ - type: 'openai', - apiKey: 'first-key', - baseUrl: 'https://api.openai.com/v1', - model: 'gpt-4', - }); - }); - - it('should throw error when model is missing', () => { - const mockProviderConfig = { - getString: jest.fn().mockImplementation((key: string) => { - if (key === 'id') return 'openai'; - if (key === 'model') return ''; - throw new Error(`Unexpected key: ${key}`); - }), - getOptionalString: jest.fn().mockImplementation((key: string) => { - if (key === 'baseUrl') return undefined; - return 'test-key'; - }), - } as any; - - mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); - - expect(() => getProviderConfig(mockConfig)).toThrow( - 'Model is required for provider: openai', - ); - }); -}); - -describe('getProviderInfo', () => { - let mockConfig: ReturnType; - - beforeEach(() => { - mockConfig = mockServices.rootConfig.mock(); - }); - - it('should return provider info from config', () => { - const mockProviderConfig = { - getString: jest.fn().mockImplementation((key: string) => { - if (key === 'id') return 'openai'; - if (key === 'model') return 'gpt-4'; - throw new Error(`Unexpected key: ${key}`); - }), - getOptionalString: jest.fn().mockImplementation((key: string) => { - if (key === 'baseUrl') return 'https://api.openai.com/v1'; - return 'test-key'; - }), - } as any; - - mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); - - const result = getProviderInfo(mockConfig); - - expect(result).toEqual({ - provider: 'openai', - model: 'gpt-4', - baseURL: 'https://api.openai.com/v1', - }); - }); - - it('should propagate errors from getProviderConfig', () => { - mockConfig.getOptionalConfigArray.mockReturnValue([]); - - expect(() => getProviderInfo(mockConfig)).toThrow(); - }); -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.ts deleted file mode 100644 index 0e7165aa422..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.ts +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { LLMProvider } from './base-provider'; -import { ProviderConfig } from '../types'; -import { OpenAIProvider } from './openai-provider'; -import { OpenAIResponsesProvider } from './openai-responses-provider'; -import { ClaudeProvider } from './claude-provider'; -import { GeminiProvider } from './gemini-provider'; -import { OllamaProvider } from './ollama-provider'; -import { LiteLLMProvider } from './litellm-provider'; -import { - RootConfigService, - LoggerService, -} from '@backstage/backend-plugin-api'; - -/** - * Factory class for creating LLM provider instances. - * Supports OpenAI, Claude, Gemini, Ollama, LiteLLM, and OpenAI Responses API. - * - * @public - */ -export class ProviderFactory { - /** - * Creates an LLM provider instance based on the configuration. - * - * @param config - The provider configuration - * @param logger - Optional logger service for debug logging - * @returns An LLM provider instance - */ - static createProvider( - config: ProviderConfig, - logger?: LoggerService, - ): LLMProvider { - const configWithLogger = { ...config, logger }; - switch (config.type) { - case 'openai': - return new OpenAIProvider(configWithLogger); - - case 'openai-responses': - return new OpenAIResponsesProvider(configWithLogger); - - case 'claude': - return new ClaudeProvider(configWithLogger); - - case 'gemini': - return new GeminiProvider(configWithLogger); - - case 'ollama': - return new OllamaProvider(configWithLogger); - - case 'litellm': - return new LiteLLMProvider(configWithLogger); - - default: - throw new Error(`Unsupported provider: ${config.type}`); - } - } -} - -/** - * Parses and returns the LLM provider configuration from Backstage config. - * Reads from mcpChat.providers configuration section. - * - * @param config - The Backstage root config service - * @returns The provider configuration - * @public - */ -export function getProviderConfig(config: RootConfigService): ProviderConfig { - const providers = config.getOptionalConfigArray('mcpChat.providers') || []; - - // For now, use the first provider. In the future, you might want to support multiple providers - const providerConfig = providers[0]; - const providerId = providerConfig.getString('id'); - const token = providerConfig.getOptionalString('token'); - const model = providerConfig.getString('model'); - - const allowedProviders = [ - 'openai', - 'openai-responses', - 'claude', - 'gemini', - 'ollama', - 'litellm', - ]; - if (!allowedProviders.includes(providerId)) { - throw new Error( - `Unsupported provider id: ${providerId}. Allowed values are: ${allowedProviders.join( - ', ', - )}`, - ); - } - - const configs: Record> = { - openai: { - type: 'openai', - apiKey: token, - baseUrl: - providerConfig.getOptionalString('baseUrl') || - 'https://api.openai.com/v1', - model: model, - }, - - 'openai-responses': { - type: 'openai-responses', - apiKey: token, - baseUrl: providerConfig.getOptionalString('baseUrl') || '', - model: model, - }, - - claude: { - type: 'claude', - apiKey: token, - baseUrl: 'https://api.anthropic.com/v1', - model: model, - }, - - gemini: { - type: 'gemini', - apiKey: token, - baseUrl: 'https://generativelanguage.googleapis.com', - model: model, - }, - - ollama: { - type: 'ollama', - // No API key needed for Ollama - baseUrl: - providerConfig.getOptionalString('baseUrl') || 'http://localhost:11434', - model: model, - }, - - litellm: { - type: 'litellm', - apiKey: token, // Optional, depends on LiteLLM configuration - baseUrl: - providerConfig.getOptionalString('baseUrl') || 'http://localhost:4000', - model: model, - }, - }; - - const configTemplate = configs[providerId]; - if (!configTemplate) { - throw new Error(`Unknown provider: ${providerId}`); - } - - // Validate required fields - // Ollama, LiteLLM, and OpenAI Responses can work without API keys depending on configuration - const noApiKeyRequired = ['ollama', 'litellm', 'openai-responses']; - if (!noApiKeyRequired.includes(providerId) && !configTemplate.apiKey) { - throw new Error(`API key is required for provider: ${providerId}`); - } - if (!configTemplate.baseUrl) { - throw new Error(`Base URL is required for provider: ${providerId}`); - } - if (!configTemplate.model) { - throw new Error(`Model is required for provider: ${providerId}`); - } - - return configTemplate as ProviderConfig; -} - -/** - * Returns provider information for status display purposes. - * - * @param config - The Backstage root config service - * @returns Provider info including type, model, and base URL - * @public - */ -export function getProviderInfo(config: RootConfigService) { - const providerConfig = getProviderConfig(config); - return { - provider: providerConfig.type, - model: providerConfig.model, - baseURL: providerConfig.baseUrl, - }; -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.test.ts index 4a413d94ecc..3031c7a1656 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.test.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.test.ts @@ -22,7 +22,6 @@ jest.mock('@modelcontextprotocol/sdk/client/index.js'); jest.mock('@modelcontextprotocol/sdk/client/streamableHttp.js'); jest.mock('@modelcontextprotocol/sdk/client/stdio.js'); jest.mock('@modelcontextprotocol/sdk/client/sse.js'); -jest.mock('../providers/provider-factory'); jest.mock('../utils'); const { Client } = require('@modelcontextprotocol/sdk/client/index.js'); @@ -32,7 +31,6 @@ const { const { StdioClientTransport, } = require('@modelcontextprotocol/sdk/client/stdio.js'); -const providerFactory = require('../providers/provider-factory'); const utils = require('../utils'); describe('MCPClientServiceImpl', () => { @@ -51,6 +49,12 @@ describe('MCPClientServiceImpl', () => { mockLLMProvider = { sendMessage: jest.fn(), testConnection: jest.fn(), + getType: jest.fn().mockReturnValue('openai'), + getModel: jest.fn().mockReturnValue('gpt-4'), + getBaseUrl: jest.fn().mockReturnValue('https://api.openai.com/v1'), + supportsNativeMcp: jest.fn().mockReturnValue(false), + setMcpServerConfigs: jest.fn(), + getLastResponseOutput: jest.fn().mockReturnValue(null), }; mockClient = { @@ -59,23 +63,6 @@ describe('MCPClientServiceImpl', () => { callTool: jest.fn(), }; - providerFactory.getProviderConfig.mockReturnValue({ - type: 'openai', - apiKey: 'test-key', - baseUrl: 'https://api.openai.com/v1', - model: 'gpt-4', - }); - - providerFactory.ProviderFactory.createProvider.mockReturnValue( - mockLLMProvider, - ); - - providerFactory.getProviderInfo.mockReturnValue({ - provider: 'openai', - model: 'gpt-4', - baseURL: 'https://api.openai.com/v1', - }); - utils.loadServerConfigs.mockReturnValue([]); utils.findNpxPath.mockResolvedValue('/usr/local/bin/npx'); utils.executeToolCall.mockResolvedValue({ @@ -94,27 +81,10 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, + provider: mockLLMProvider, }); expect(service).toBeDefined(); - expect(providerFactory.getProviderConfig).toHaveBeenCalledWith( - mockConfig, - ); - expect(providerFactory.ProviderFactory.createProvider).toHaveBeenCalled(); - }); - - it('should throw error when LLM provider configuration is invalid', () => { - providerFactory.getProviderConfig.mockImplementation(() => { - throw new Error('Invalid provider configuration'); - }); - - expect( - () => - new MCPClientServiceImpl({ - logger: mockLogger, - config: mockConfig, - }), - ).toThrow('Invalid provider configuration'); }); }); @@ -123,6 +93,7 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, + provider: mockLLMProvider, }); }); @@ -268,6 +239,7 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, + provider: mockLLMProvider, }); }); @@ -294,15 +266,15 @@ describe('MCPClientServiceImpl', () => { }); it('should handle provider status errors', async () => { - providerFactory.getProviderInfo.mockImplementation(() => { - throw new Error('Provider info failed'); - }); + mockLLMProvider.testConnection.mockRejectedValue( + new Error('Provider connection failed'), + ); const status = await service.getProviderStatus(); expect(status.providers).toHaveLength(0); expect(status.summary.totalProviders).toBe(0); - expect(status.summary.error).toBe('Provider info failed'); + expect(status.summary.error).toBe('Provider connection failed'); expect(status.timestamp).toBeDefined(); }); @@ -341,6 +313,7 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, + provider: mockLLMProvider, }); const servers = await service.initializeMCPServers(); @@ -366,6 +339,7 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, + provider: mockLLMProvider, }); const servers = await service.initializeMCPServers(); @@ -397,6 +371,7 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, + provider: mockLLMProvider, }); await service.initializeMCPServers(); @@ -427,6 +402,7 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, + provider: mockLLMProvider, }); const servers = await service.initializeMCPServers(); @@ -442,6 +418,7 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, + provider: mockLLMProvider, }); const tools = service.getAvailableTools(); @@ -475,6 +452,7 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, + provider: mockLLMProvider, }); await service.processQuery([{ role: 'user', content: 'Hello' }], []); @@ -514,6 +492,7 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, + provider: mockLLMProvider, }); await service.processQuery([{ role: 'user', content: 'Hello' }], []); @@ -559,6 +538,7 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, + provider: mockLLMProvider, }); await service.processQuery( diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.ts index 975f9e2d22d..12344daff64 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.ts @@ -21,14 +21,8 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import * as path from 'path'; -import { - ProviderFactory, - getProviderConfig as getConfig, - getProviderInfo, -} from '../providers/provider-factory'; import { executeToolCall, findNpxPath, loadServerConfigs } from '../utils'; import { LLMProvider } from '../providers/base-provider'; -import { OpenAIResponsesProvider } from '../providers/openai-responses-provider'; import { MCPClientService } from './MCPClientService'; import { ChatMessage, @@ -51,6 +45,7 @@ import { export type Options = { logger: LoggerService; config: RootConfigService; + provider: LLMProvider; }; /** @@ -73,34 +68,13 @@ export class MCPClientServiceImpl implements MCPClientService { constructor(options: Options) { this.logger = options.logger; this.config = options.config; - this.llmProvider = this.initializeLLMProvider(); + this.llmProvider = options.provider; this.mcpServers = this.initializeMCPServers(); this.systemPrompt = this.config.getOptionalString('mcpChat.systemPrompt') || "You are a helpful assistant. When using tools, provide a clear, readable summary of the results rather than showing raw data. Focus on answering the user's question with the information gathered."; } - private initializeLLMProvider(): LLMProvider { - try { - const providerConfig = getConfig(this.config); - const llmProvider = ProviderFactory.createProvider( - providerConfig, - this.logger, - ); - this.logger.info( - `Using LLM Provider: ${providerConfig.type}, Model: ${providerConfig.model}`, - ); - return llmProvider; - } catch (error) { - this.logger.error( - `Failed to initialize LLM provider: ${ - error instanceof Error ? error.message : String(error) - }`, - ); - throw error; - } - } - async initializeMCPServers(): Promise { // If initialization is already in progress or completed, return the same promise if (this.mcpServers) { @@ -124,9 +98,8 @@ export class MCPClientServiceImpl implements MCPClientService { // Store server configs for Responses API provider this.serverConfigs = serverConfigs; - // Check if using Responses API provider - initialize local MCP for tool discovery - const providerConfig = getConfig(this.config); - if (providerConfig.type === 'openai-responses') { + // Check if using native MCP provider - initialize local MCP for tool discovery + if (this.llmProvider.supportsNativeMcp()) { this.logger.info( 'Using OpenAI Responses API - initializing local MCP for tool discovery', ); @@ -428,9 +401,8 @@ export class MCPClientServiceImpl implements MCPClientService { }); } - // Check if using Responses API provider - const providerConfig = getConfig(this.config); - if (providerConfig.type === 'openai-responses') { + // Check if using native MCP provider + if (this.llmProvider.supportsNativeMcp()) { return this.processQueryWithResponsesApi(messages, enabledTools); } @@ -544,9 +516,7 @@ export class MCPClientServiceImpl implements MCPClientService { : this.serverConfigs; // Set the filtered configs on the provider - if (this.llmProvider instanceof OpenAIResponsesProvider) { - this.llmProvider.setMcpServerConfigs(enabledServerConfigs); - } + this.llmProvider.setMcpServerConfigs(enabledServerConfigs); // Send message - the provider handles MCP tool configuration internally const response = await this.llmProvider.sendMessage(messages); @@ -557,22 +527,20 @@ export class MCPClientServiceImpl implements MCPClientService { const toolResponses: any[] = []; // Get the raw output from the provider to extract tool execution details - if (this.llmProvider instanceof OpenAIResponsesProvider) { - const output = this.llmProvider.getLastResponseOutput(); - if (output) { - for (const event of output) { - if (event.type === 'mcp_call') { - const mcpCall = event as ResponsesApiMcpCall; - // Build tool response in the format expected by the UI - toolResponses.push({ - id: mcpCall.id, - name: mcpCall.name, - arguments: JSON.parse(mcpCall.arguments || '{}'), - result: mcpCall.error || mcpCall.output, - serverId: mcpCall.server_label, - error: mcpCall.error, - }); - } + const output = this.llmProvider.getLastResponseOutput(); + if (output) { + for (const event of output) { + if (event.type === 'mcp_call') { + const mcpCall = event as ResponsesApiMcpCall; + // Build tool response in the format expected by the UI + toolResponses.push({ + id: mcpCall.id, + name: mcpCall.name, + arguments: JSON.parse(mcpCall.arguments || '{}'), + result: mcpCall.error || mcpCall.output, + serverId: mcpCall.server_label, + error: mcpCall.error, + }); } } } @@ -594,15 +562,14 @@ export class MCPClientServiceImpl implements MCPClientService { async getProviderStatus(): Promise { try { - const info = getProviderInfo(this.config); const status = await this.llmProvider.testConnection(); - // Structure for future multi-provider support + // Derive provider info from the injected provider instance const providers = [ { - id: info.provider, - model: info.model, - baseUrl: info.baseURL, + id: this.llmProvider.getType(), + model: this.llmProvider.getModel(), + baseUrl: this.llmProvider.getBaseUrl(), connection: { connected: status.connected, models: status.models || [], diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/types.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/types.ts index c894490bf18..bdbd7a2b8b6 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/types.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/types.ts @@ -14,691 +14,43 @@ * limitations under the License. */ -import { LoggerService } from '@backstage/backend-plugin-api'; - -// ============================================================================= -// Constants and Enums -// ============================================================================= - -/** - * Valid roles for chat messages. - * Use these values when constructing ChatMessage objects. - * - * @public - */ -export const VALID_ROLES = ['user', 'assistant', 'system', 'tool'] as const; - -/** - * MCP server connection types. - * - * - `STDIO`: Local process communication via stdin/stdout - * - `STREAMABLE_HTTP`: Streamable HTTP transport - * - * @public - */ -export enum MCPServerType { - STDIO = 'stdio', - STREAMABLE_HTTP = 'streamable-http', -} - -/** - * Supported LLM provider types. - * Use this type for type-safe provider selection. - * - * @public - */ -export type LLMProviderType = - | 'openai' - | 'openai-responses' - | 'claude' - | 'gemini' - | 'ollama' - | 'litellm'; - -// ============================================================================= -// MCP Server Configuration Types -// ============================================================================= - -/** - * Configuration for an MCP server. - * Supports multiple connection types: STDIO and Streamable HTTP. - * - * @example - * ```typescript - * // STDIO server using npx - * const stdioServer: MCPServerConfig = { - * id: 'filesystem', - * name: 'File System', - * type: MCPServerType.STDIO, - * npxCommand: '@modelcontextprotocol/server-filesystem', - * args: ['/path/to/directory'] - * }; - * - * // HTTP server - * const httpServer: MCPServerConfig = { - * id: 'remote-api', - * name: 'Remote API', - * type: MCPServerType.STREAMABLE_HTTP, - * url: 'https://api.example.com/mcp' - * }; - * ``` - * - * @public - */ -export interface MCPServerConfig { - /** Unique identifier for the server */ - id: string; - /** Human-readable name for display */ - name: string; - /** Connection type: stdio or streamable-http */ - type: MCPServerType; - /** Path to a local script (for STDIO servers) */ - scriptPath?: string; - /** NPX package command to run (for STDIO servers) */ - npxCommand?: string; - /** Command-line arguments to pass to the server */ - args?: string[]; - /** URL endpoint (for HTTP servers) */ - url?: string; -} - -/** - * Sensitive configuration for an MCP server. - * Contains environment variables and HTTP headers that may include secrets. - * - * @example - * ```typescript - * const secrets: MCPServerSecrets = { - * env: { - * API_KEY: 'your-secret-key', - * DATABASE_URL: 'postgres://...' - * }, - * headers: { - * 'Authorization': 'Bearer token123' - * } - * }; - * ``` - * - * @public - */ -export interface MCPServerSecrets { - /** Environment variables to pass to the server process */ - env?: Record; - /** HTTP headers to include in requests (for HTTP-based servers) */ - headers?: Record; -} - -/** - * Complete MCP server configuration combining base config and secrets. - * - * @public - */ -export type MCPServerFullConfig = MCPServerConfig & MCPServerSecrets; - -/** - * MCP server with runtime status information. - * Used to display server health in the UI. - * - * @public - */ -export type MCPServer = MCPServerConfig & { - /** Current connection and validation status */ - status: { - /** Whether the server configuration is valid */ - valid: boolean; - /** Whether the server is currently connected */ - connected: boolean; - /** Error message if connection failed */ - error?: string; - }; -}; - -/** - * Aggregated status data for all MCP servers. - * - * @public - */ -export interface MCPServerStatusData { - /** Total number of configured servers */ - total: number; - /** Number of servers with valid configuration */ - valid: number; - /** Number of currently connected servers */ - active: number; - /** List of all servers with their status */ - servers: MCPServer[]; - /** ISO timestamp of when this status was generated */ - timestamp: string; -} - -// ============================================================================= -// LLM Provider Configuration Types -// ============================================================================= - -/** - * Configuration for an LLM provider. - * - * @example - * ```typescript - * const openaiConfig: ProviderConfig = { - * type: 'openai', - * apiKey: 'sk-...', - * baseUrl: 'https://api.openai.com/v1', - * model: 'gpt-4' - * }; - * - * const ollamaConfig: ProviderConfig = { - * type: 'ollama', - * baseUrl: 'http://localhost:11434', - * model: 'llama2' - * }; - * ``` - * - * @public - */ -export interface ProviderConfig { - /** Provider type identifier */ - type: string; - /** API key for authentication (optional for local providers like Ollama) */ - apiKey?: string; - /** Base URL for the provider's API */ - baseUrl: string; - /** Model identifier to use */ - model: string; - /** Logger for debugging */ - logger?: LoggerService; -} - -/** - * Runtime information about an active LLM provider. - * Used for status display and monitoring. - * - * @public - */ -export interface ProviderInfo { - /** Provider type identifier (e.g., 'openai', 'claude') */ - id: string; - /** Currently configured model */ - model: string; - /** API base URL */ - baseUrl: string; - /** Current connection status */ - connection: ProviderConnectionStatus; -} - -/** - * Connection test result for an LLM provider. - * - * @public - */ -export interface ProviderConnectionStatus { - /** Whether the provider is reachable and authenticated */ - connected: boolean; - /** List of available models (if supported by the provider) */ - models?: string[]; - /** Error message if connection failed */ - error?: string; -} - -/** - * Aggregated status data for all LLM providers. - * - * @public - */ -export interface ProviderStatusData { - /** List of all configured providers with their status */ - providers: ProviderInfo[]; - /** Summary statistics */ - summary: { - /** Total number of configured providers */ - totalProviders: number; - /** Number of providers that passed connection test */ - healthyProviders: number; - /** Error message if status check failed */ - error?: string; - }; - /** ISO timestamp of when this status was generated */ - timestamp: string; -} - -// ============================================================================= -// Chat Message Types -// ============================================================================= - -/** - * A chat message in the conversation. - * Compatible with OpenAI's Chat Completions API message format. - * - * @example - * ```typescript - * // User message - * const userMsg: ChatMessage = { - * role: 'user', - * content: 'What files are in the current directory?' - * }; - * - * // Assistant message with tool call - * const assistantMsg: ChatMessage = { - * role: 'assistant', - * content: null, - * tool_calls: [{ - * id: 'call_123', - * type: 'function', - * function: { name: 'list_files', arguments: '{"path": "."}' } - * }] - * }; - * - * // Tool response - * const toolMsg: ChatMessage = { - * role: 'tool', - * content: '["file1.txt", "file2.txt"]', - * tool_call_id: 'call_123' - * }; - * ``` - * - * @public - */ -export interface ChatMessage { - /** The role of the message author */ - role: 'system' | 'user' | 'assistant' | 'tool'; - /** Message content. Can be null for assistant messages that only contain tool calls. */ - content: string | null; - /** Tool calls requested by the assistant. Only present when role is 'assistant'. */ - tool_calls?: ToolCall[]; - /** ID of the tool call this message responds to. Required when role is 'tool'. */ - tool_call_id?: string; -} - /** - * Response from an LLM provider. - * Follows OpenAI's Chat Completions API response format. - * - * @public - */ -export interface ChatResponse { - /** Array of response choices (typically contains one choice) */ - choices: [ - { - /** The generated message */ - message: { - /** Always 'assistant' for responses */ - role: 'assistant'; - /** Text content of the response. Null if only tool calls are present. */ - content: string | null; - /** Tool calls the model wants to make */ - tool_calls?: ToolCall[]; - }; - }, - ]; - /** Token usage statistics (if provided by the model) */ - usage?: { - /** Number of tokens in the input prompt */ - prompt_tokens: number; - /** Number of tokens in the generated response */ - completion_tokens: number; - /** Total tokens used */ - total_tokens: number; - }; -} - -/** - * Complete response from a chat query including tool execution results. - * - * @public - */ -export interface QueryResponse { - /** The final text reply from the assistant */ - reply: string; - /** Tool calls that were made during the conversation */ - toolCalls: ToolCall[]; - /** Results from executing the tool calls */ - toolResponses: ToolExecutionResult[]; -} - -// ============================================================================= -// Tool Types -// ============================================================================= - -/** - * Tool definition in OpenAI function calling format. - * Describes a tool that the LLM can invoke. - * - * @example - * ```typescript - * const tool: Tool = { - * type: 'function', - * function: { - * name: 'get_weather', - * description: 'Get the current weather for a location', - * parameters: { - * type: 'object', - * properties: { - * location: { type: 'string', description: 'City name' }, - * unit: { type: 'string', enum: ['celsius', 'fahrenheit'] } - * }, - * required: ['location'] - * } - * } - * }; - * ``` - * - * @public - */ -export interface Tool { - /** Always 'function' for function-calling tools */ - type: 'function'; - /** Function definition */ - function: { - /** Unique name of the function */ - name: string; - /** Description of what the function does (shown to the LLM) */ - description: string; - /** JSON Schema describing the function parameters (flexible to support various LLM providers) */ - parameters: Record; - }; -} - -/** - * A tool call made by the LLM. - * Represents the model's request to invoke a specific tool. - * - * @example - * ```typescript - * const toolCall: ToolCall = { - * id: 'call_abc123', - * type: 'function', - * function: { - * name: 'get_weather', - * arguments: '{"location": "San Francisco", "unit": "celsius"}' - * } - * }; - * - * // Parse the arguments - * const args = JSON.parse(toolCall.function.arguments); - * ``` - * - * @public - */ -export interface ToolCall { - /** Unique identifier for this tool call */ - id: string; - /** Always 'function' for function calls */ - type: 'function'; - /** Function invocation details */ - function: { - /** Name of the function to call */ - name: string; - /** JSON-encoded string of the function arguments */ - arguments: string; - }; -} - -/** - * Tool associated with a specific MCP server. - * Extends the base Tool with server identification for routing. - * - * @public - */ -export interface ServerTool extends Tool { - /** ID of the MCP server that provides this tool */ - serverId: string; -} - -/** - * Result of executing a tool call. - * - * @public - */ -export interface ToolExecutionResult { - /** ID of the original tool call */ - id: string; - /** Name of the tool that was executed */ - name: string; - /** Parsed arguments that were passed to the tool */ - arguments: Record; - /** String result returned by the tool */ - result: string; - /** ID of the MCP server that executed the tool */ - serverId: string; -} - -// ============================================================================= -// Validation Types -// ============================================================================= - -/** - * Result of validating chat messages. - * - * @example - * ```typescript - * const result = validateMessages(messages); - * if (!result.isValid) { - * console.error('Validation failed:', result.error); - * } - * ``` - * - * @public - */ -export interface MessageValidationResult { - /** Whether the messages passed validation */ - isValid: boolean; - /** Error message describing the validation failure */ - error?: string; -} - -// ============================================================================= -// OpenAI Responses API Types -// ============================================================================= - -/** - * MCP tool configuration for OpenAI Responses API. - * Used to configure native MCP support in the Responses API. - * - * @public - */ -export interface ResponsesApiMcpTool { - /** Tool type identifier */ - type: 'mcp'; - /** URL of the MCP server */ - server_url: string; - /** Human-readable label for the server */ - server_label: string; - /** When to require user approval for tool calls */ - require_approval: 'never' | 'always' | 'auto'; - /** List of allowed tool names (if not set, all tools are allowed) */ - allowed_tools?: string[]; - /** HTTP headers to send with requests */ - headers?: Record; -} - -/** - * MCP list tools output event from OpenAI Responses API. - * - * @public - */ -export interface ResponsesApiMcpListTools { - /** Event ID */ - id: string; - /** Event type identifier */ - type: 'mcp_list_tools'; - /** Label of the server that provided the tools */ - server_label: string; - /** List of available tools */ - tools: Array<{ - /** Tool name */ - name: string; - /** Tool description */ - description: string; - /** JSON Schema for tool input */ - input_schema: Record; - }>; -} - -/** - * MCP tool call output event from OpenAI Responses API. - * - * @public - */ -export interface ResponsesApiMcpCall { - /** Event ID */ - id: string; - /** Event type identifier */ - type: 'mcp_call'; - /** Name of the tool that was called */ - name: string; - /** JSON-encoded arguments passed to the tool */ - arguments: string; - /** Label of the server that handled the call */ - server_label: string; - /** Error message if the call failed */ - error: string | null; - /** Output from the tool call */ - output: string; -} - -/** - * Message output event from OpenAI Responses API. - * - * @public - */ -export interface ResponsesApiMessage { - /** Event ID */ - id: string; - /** Event type identifier */ - type: 'message'; - /** Message role */ - role: 'assistant'; - /** Completion status */ - status: 'completed' | 'failed'; - /** Message content blocks */ - content: Array<{ - /** Content type */ - type: 'output_text'; - /** Text content */ - text: string; - /** Optional annotations */ - annotations?: unknown[]; - }>; -} - -/** - * Union type for all possible output events from OpenAI Responses API. - * - * @public - */ -export type ResponsesApiOutputEvent = - | ResponsesApiMcpListTools - | ResponsesApiMcpCall - | ResponsesApiMessage; - -/** - * Complete response from OpenAI Responses API. - * - * @public - */ -export interface ResponsesApiResponse { - /** Response ID */ - id: string; - /** Object type */ - object: 'response'; - /** Unix timestamp of creation */ - created_at: number; - /** Model used for generation */ - model: string; - /** Response status */ - status: 'completed' | 'failed' | 'cancelled'; - /** Output events from the response */ - output: ResponsesApiOutputEvent[]; - /** Token usage statistics */ - usage?: { - /** Input tokens used */ - input_tokens: number; - /** Output tokens generated */ - output_tokens: number; - /** Total tokens */ - total_tokens: number; - /** Detailed input token breakdown */ - input_tokens_details?: { - /** Tokens served from cache */ - cached_tokens: number; - }; - /** Detailed output token breakdown */ - output_tokens_details?: unknown; - }; - /** Error message if failed */ - error?: string | null; - /** System instructions */ - instructions?: string | null; - /** Configured tools */ - tools?: ResponsesApiMcpTool[]; - /** Whether parallel tool calls are enabled */ - parallel_tool_calls?: boolean; - /** ID of the previous response in a conversation */ - previous_response_id?: string | null; - /** Temperature setting used */ - temperature?: number | null; - /** Top-p setting used */ - top_p?: number | null; - /** Text format configuration */ - text?: { - format: { - type: string; - }; - }; - /** Truncation settings */ - truncation?: unknown; -} - -// ============================================================================= -// Conversation Storage Types -// ============================================================================= - -/** - * A stored conversation record. - * Used for API responses and internal representation. - * - * @public - */ -export interface ConversationRecord { - /** Unique identifier for the conversation */ - id: string; - /** User entity ref who owns this conversation */ - userId: string; - /** Array of chat messages in the conversation */ - messages: ChatMessage[]; - /** Optional array of tool names used in the conversation */ - toolsUsed?: string[]; - /** AI-generated or user-edited conversation title */ - title?: string; - /** Whether the conversation is starred/favorited */ - isStarred: boolean; - /** Timestamp when the conversation was created */ - createdAt: Date; - /** Timestamp when the conversation was last updated */ - updatedAt: Date; -} - -/** - * Database row representation of a conversation. - * Used internally for database operations. - * - * @internal - */ -export interface ConversationRow { - /** UUID primary key */ - id: string; - /** User entity ref (snake_case for DB) */ - user_id: string; - /** JSON-serialized messages array */ - messages: string; - /** JSON-serialized tools array or null */ - tools_used: string | null; - /** AI-generated or user-edited conversation title */ - title: string | null; - /** Whether the conversation is starred/favorited */ - is_starred: boolean; - /** Creation timestamp */ - created_at: Date; - /** Last update timestamp */ - updated_at: Date; -} + * Re-exports all shared types from the common package for backward compatibility. + * New consumers should import directly from `@backstage-community/plugin-mcp-chat-common`. + */ +export { + // Constants and Enums + VALID_ROLES, + MCPServerType, + + // LLM Provider Base Class + LLMProvider, + + // Types + type LLMProviderType, + type MCPServerConfig, + type MCPServerSecrets, + type MCPServerFullConfig, + type MCPServer, + type MCPServerStatusData, + type ProviderConfig, + type ProviderInfo, + type ProviderConnectionStatus, + type ProviderStatusData, + type ChatMessage, + type ChatResponse, + type QueryResponse, + type Tool, + type ToolCall, + type ServerTool, + type ToolExecutionResult, + type MessageValidationResult, + type ResponsesApiMcpTool, + type ResponsesApiMcpListTools, + type ResponsesApiMcpCall, + type ResponsesApiMessage, + type ResponsesApiResponse, + type ResponsesApiOutputEvent, + type ConversationRecord, + type ConversationRow, +} from '@backstage-community/plugin-mcp-chat-common'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-common/.eslintrc.js new file mode 100644 index 00000000000..e2a53a6ad28 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/README.md b/workspaces/mcp-chat/plugins/mcp-chat-common/README.md new file mode 100644 index 00000000000..f26cea1d7aa --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/README.md @@ -0,0 +1,5 @@ +# @backstage-community/plugin-mcp-chat-common + +Welcome to the common package for the mcp-chat plugin! + +_This plugin was created through the Backstage CLI_ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/package.json b/workspaces/mcp-chat/plugins/mcp-chat-common/package.json new file mode 100644 index 00000000000..2814c8d7b3e --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/package.json @@ -0,0 +1,56 @@ +{ + "name": "@backstage-community/plugin-mcp-chat-common", + "version": "0.1.0", + "license": "Apache-2.0", + "private": true, + "description": "Common functionalities for the mcp-chat plugin", + "main": "src/index.ts", + "types": "src/index.ts", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "module": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "common-library", + "pluginId": "mcp-chat", + "pluginPackages": [ + "@backstage-community/plugin-mcp-chat-common", + "@backstage-community/plugin-mcp-chat-backend", + "@backstage-community/plugin-mcp-chat" + ] + }, + "sideEffects": false, + "scripts": { + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/errors": "^1.2.7" + }, + "devDependencies": { + "@backstage/cli": "^0.33.0" + }, + "files": [ + "dist" + ], + "repository": { + "type": "git", + "url": "https://github.com/backstage/community-plugins", + "directory": "workspaces/mcp-chat/plugins/mcp-chat-common" + }, + "keywords": [ + "backstage", + "backstage-plugin", + "mcp", + "mcp-chat", + "common" + ], + "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-common", + "bugs": "https://github.com/backstage/community-plugins/issues" +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/src/base-provider.ts b/workspaces/mcp-chat/plugins/mcp-chat-common/src/base-provider.ts new file mode 100644 index 00000000000..954996bf649 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/src/base-provider.ts @@ -0,0 +1,105 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ResponseError } from '@backstage/errors'; +import { + ChatMessage, + Tool, + ChatResponse, + ProviderConfig, + MCPServerFullConfig, +} from './types'; + +/** + * Abstract base class for all LLM providers. + * Extend this class to create custom LLM provider implementations. + * + * @public + */ +export abstract class LLMProvider { + protected apiKey?: string; // Made optional + protected baseUrl: string; + protected model: string; + protected type: string; + + constructor(config: ProviderConfig) { + this.apiKey = config.apiKey; + this.baseUrl = config.baseUrl; + this.model = config.model; + this.type = config.type; + } + + /** Returns the provider type identifier. */ + getType(): string { + return this.type; + } + + /** Returns the model identifier. */ + getModel(): string { + return this.model; + } + + /** Returns the base URL for the provider's API. */ + getBaseUrl(): string { + return this.baseUrl; + } + + abstract sendMessage( + messages: ChatMessage[], + tools?: Tool[], + ): Promise; + + abstract testConnection(): Promise<{ + connected: boolean; + models?: string[]; + error?: string; + }>; + + protected abstract getHeaders(): Record; + protected abstract formatRequest( + messages: ChatMessage[], + tools?: Tool[], + ): any; + protected abstract parseResponse(response: any): ChatResponse; + + /** Override to return `true` in providers that handle MCP natively. */ + supportsNativeMcp(): boolean { + return false; + } + + /** Set MCP server configs for native MCP providers. No-op by default. */ + setMcpServerConfigs(_configs: MCPServerFullConfig[]): void { + // no-op + } + + /** Get last response output for native MCP providers. Returns `null` by default. */ + getLastResponseOutput(): any { + return null; + } + + protected async makeRequest(endpoint: string, body: any): Promise { + const response = await fetch(`${this.baseUrl}${endpoint}`, { + method: 'POST', + headers: this.getHeaders(), + body: JSON.stringify(body), + }); + + if (!response.ok) { + throw await ResponseError.fromResponse(response); + } + + return response.json(); + } +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-common/src/index.ts new file mode 100644 index 00000000000..25cdd2fa5b8 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/src/index.ts @@ -0,0 +1,74 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Common types and base classes for the mcp-chat plugin ecosystem. + * + * @packageDocumentation + */ + +// ============================================================================= +// LLM Provider Base Class +// ============================================================================= +export { LLMProvider } from './base-provider'; + +// ============================================================================= +// Types +// ============================================================================= +export type { + // Provider types + ProviderConfig, + ProviderStatusData, + ProviderInfo, + ProviderConnectionStatus, + LLMProviderType, + + // MCP Server types + MCPServerConfig, + MCPServerSecrets, + MCPServerFullConfig, + MCPServer, + MCPServerStatusData, + + // Chat types + ChatMessage, + ChatResponse, + QueryResponse, + + // Tool types + Tool, + ToolCall, + ServerTool, + ToolExecutionResult, + + // Validation types + MessageValidationResult, + + // Conversation types + ConversationRecord, + ConversationRow, + + // OpenAI Responses API types + ResponsesApiMcpTool, + ResponsesApiMcpListTools, + ResponsesApiMcpCall, + ResponsesApiMessage, + ResponsesApiResponse, + ResponsesApiOutputEvent, +} from './types'; + +// Enums and Constants +export { MCPServerType, VALID_ROLES } from './types'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/src/setupTests.ts b/workspaces/mcp-chat/plugins/mcp-chat-common/src/setupTests.ts new file mode 100644 index 00000000000..f3a222d4e19 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts b/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts new file mode 100644 index 00000000000..b4cb4727076 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts @@ -0,0 +1,584 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ============================================================================= +// Constants and Enums +// ============================================================================= + +/** + * Valid roles for chat messages. + * Use these values when constructing ChatMessage objects. + * + * @public + */ +export const VALID_ROLES = ['user', 'assistant', 'system', 'tool'] as const; + +/** + * MCP server connection types. + * + * - `STDIO`: Local process communication via stdin/stdout + * - `STREAMABLE_HTTP`: Streamable HTTP transport + * + * @public + */ +export enum MCPServerType { + STDIO = 'stdio', + STREAMABLE_HTTP = 'streamable-http', +} + +/** + * Supported LLM provider types. + * Use this type for type-safe provider selection. + * + * @public + */ +export type LLMProviderType = + | 'openai' + | 'openai-responses' + | 'claude' + | 'gemini' + | 'ollama' + | 'litellm'; + +// ============================================================================= +// MCP Server Configuration Types +// ============================================================================= + +/** + * Configuration for an MCP server. + * Supports multiple connection types: STDIO and Streamable HTTP. + * + * @public + */ +export interface MCPServerConfig { + /** Unique identifier for the server */ + id: string; + /** Human-readable name for display */ + name: string; + /** Connection type: stdio or streamable-http */ + type: MCPServerType; + /** Path to a local script (for STDIO servers) */ + scriptPath?: string; + /** NPX package command to run (for STDIO servers) */ + npxCommand?: string; + /** Command-line arguments to pass to the server */ + args?: string[]; + /** URL endpoint (for HTTP servers) */ + url?: string; +} + +/** + * Sensitive configuration for an MCP server. + * Contains environment variables and HTTP headers that may include secrets. + * + * @public + */ +export interface MCPServerSecrets { + /** Environment variables to pass to the server process */ + env?: Record; + /** HTTP headers to include in requests (for HTTP-based servers) */ + headers?: Record; +} + +/** + * Complete MCP server configuration combining base config and secrets. + * + * @public + */ +export type MCPServerFullConfig = MCPServerConfig & MCPServerSecrets; + +/** + * MCP server with runtime status information. + * Used to display server health in the UI. + * + * @public + */ +export type MCPServer = MCPServerConfig & { + /** Current connection and validation status */ + status: { + /** Whether the server configuration is valid */ + valid: boolean; + /** Whether the server is currently connected */ + connected: boolean; + /** Error message if connection failed */ + error?: string; + }; +}; + +/** + * Aggregated status data for all MCP servers. + * + * @public + */ +export interface MCPServerStatusData { + /** Total number of configured servers */ + total: number; + /** Number of servers with valid configuration */ + valid: number; + /** Number of currently connected servers */ + active: number; + /** List of all servers with their status */ + servers: MCPServer[]; + /** ISO timestamp of when this status was generated */ + timestamp: string; +} + +// ============================================================================= +// LLM Provider Configuration Types +// ============================================================================= + +/** + * Configuration for an LLM provider. + * + * @public + */ +export interface ProviderConfig { + /** Provider type identifier */ + type: string; + /** API key for authentication (optional for local providers like Ollama) */ + apiKey?: string; + /** Base URL for the provider's API */ + baseUrl: string; + /** Model identifier to use */ + model: string; + /** Optional auth record for provider-specific authentication (IAM, session, etc.) */ + auth?: Record; +} + +/** + * Runtime information about an active LLM provider. + * Used for status display and monitoring. + * + * @public + */ +export interface ProviderInfo { + /** Provider type identifier (e.g., 'openai', 'claude') */ + id: string; + /** Currently configured model */ + model: string; + /** API base URL */ + baseUrl: string; + /** Current connection status */ + connection: ProviderConnectionStatus; +} + +/** + * Connection test result for an LLM provider. + * + * @public + */ +export interface ProviderConnectionStatus { + /** Whether the provider is reachable and authenticated */ + connected: boolean; + /** List of available models (if supported by the provider) */ + models?: string[]; + /** Error message if connection failed */ + error?: string; +} + +/** + * Aggregated status data for all LLM providers. + * + * @public + */ +export interface ProviderStatusData { + /** List of all configured providers with their status */ + providers: ProviderInfo[]; + /** Summary statistics */ + summary: { + /** Total number of configured providers */ + totalProviders: number; + /** Number of providers that passed connection test */ + healthyProviders: number; + /** Error message if status check failed */ + error?: string; + }; + /** ISO timestamp of when this status was generated */ + timestamp: string; +} + +// ============================================================================= +// Chat Message Types +// ============================================================================= + +/** + * A chat message in the conversation. + * Compatible with OpenAI's Chat Completions API message format. + * + * @public + */ +export interface ChatMessage { + /** The role of the message author */ + role: 'system' | 'user' | 'assistant' | 'tool'; + /** Message content. Can be null for assistant messages that only contain tool calls. */ + content: string | null; + /** Tool calls requested by the assistant. Only present when role is 'assistant'. */ + tool_calls?: ToolCall[]; + /** ID of the tool call this message responds to. Required when role is 'tool'. */ + tool_call_id?: string; +} + +/** + * Response from an LLM provider. + * Follows OpenAI's Chat Completions API response format. + * + * @public + */ +export interface ChatResponse { + /** Array of response choices (typically contains one choice) */ + choices: [ + { + /** The generated message */ + message: { + /** Always 'assistant' for responses */ + role: 'assistant'; + /** Text content of the response. Null if only tool calls are present. */ + content: string | null; + /** Tool calls the model wants to make */ + tool_calls?: ToolCall[]; + }; + }, + ]; + /** Token usage statistics (if provided by the model) */ + usage?: { + /** Number of tokens in the input prompt */ + prompt_tokens: number; + /** Number of tokens in the generated response */ + completion_tokens: number; + /** Total tokens used */ + total_tokens: number; + }; +} + +/** + * Complete response from a chat query including tool execution results. + * + * @public + */ +export interface QueryResponse { + /** The final text reply from the assistant */ + reply: string; + /** Tool calls that were made during the conversation */ + toolCalls: ToolCall[]; + /** Results from executing the tool calls */ + toolResponses: ToolExecutionResult[]; +} + +// ============================================================================= +// Tool Types +// ============================================================================= + +/** + * Tool definition in OpenAI function calling format. + * Describes a tool that the LLM can invoke. + * + * @public + */ +export interface Tool { + /** Always 'function' for function-calling tools */ + type: 'function'; + /** Function definition */ + function: { + /** Unique name of the function */ + name: string; + /** Description of what the function does (shown to the LLM) */ + description: string; + /** JSON Schema describing the function parameters (flexible to support various LLM providers) */ + parameters: Record; + }; +} + +/** + * A tool call made by the LLM. + * Represents the model's request to invoke a specific tool. + * + * @public + */ +export interface ToolCall { + /** Unique identifier for this tool call */ + id: string; + /** Always 'function' for function calls */ + type: 'function'; + /** Function invocation details */ + function: { + /** Name of the function to call */ + name: string; + /** JSON-encoded string of the function arguments */ + arguments: string; + }; +} + +/** + * Tool associated with a specific MCP server. + * Extends the base Tool with server identification for routing. + * + * @public + */ +export interface ServerTool extends Tool { + /** ID of the MCP server that provides this tool */ + serverId: string; +} + +/** + * Result of executing a tool call. + * + * @public + */ +export interface ToolExecutionResult { + /** ID of the original tool call */ + id: string; + /** Name of the tool that was executed */ + name: string; + /** Parsed arguments that were passed to the tool */ + arguments: Record; + /** String result returned by the tool */ + result: string; + /** ID of the MCP server that executed the tool */ + serverId: string; +} + +// ============================================================================= +// Validation Types +// ============================================================================= + +/** + * Result of validating chat messages. + * + * @public + */ +export interface MessageValidationResult { + /** Whether the messages passed validation */ + isValid: boolean; + /** Error message describing the validation failure */ + error?: string; +} + +// ============================================================================= +// OpenAI Responses API Types +// ============================================================================= + +/** + * MCP tool configuration for OpenAI Responses API. + * Used to configure native MCP support in the Responses API. + * + * @public + */ +export interface ResponsesApiMcpTool { + /** Tool type identifier */ + type: 'mcp'; + /** URL of the MCP server */ + server_url: string; + /** Human-readable label for the server */ + server_label: string; + /** When to require user approval for tool calls */ + require_approval: 'never' | 'always' | 'auto'; + /** List of allowed tool names (if not set, all tools are allowed) */ + allowed_tools?: string[]; + /** HTTP headers to send with requests */ + headers?: Record; +} + +/** + * MCP list tools output event from OpenAI Responses API. + * + * @public + */ +export interface ResponsesApiMcpListTools { + /** Event ID */ + id: string; + /** Event type identifier */ + type: 'mcp_list_tools'; + /** Label of the server that provided the tools */ + server_label: string; + /** List of available tools */ + tools: Array<{ + /** Tool name */ + name: string; + /** Tool description */ + description: string; + /** JSON Schema for tool input */ + input_schema: Record; + }>; +} + +/** + * MCP tool call output event from OpenAI Responses API. + * + * @public + */ +export interface ResponsesApiMcpCall { + /** Event ID */ + id: string; + /** Event type identifier */ + type: 'mcp_call'; + /** Name of the tool that was called */ + name: string; + /** JSON-encoded arguments passed to the tool */ + arguments: string; + /** Label of the server that handled the call */ + server_label: string; + /** Error message if the call failed */ + error: string | null; + /** Output from the tool call */ + output: string; +} + +/** + * Message output event from OpenAI Responses API. + * + * @public + */ +export interface ResponsesApiMessage { + /** Event ID */ + id: string; + /** Event type identifier */ + type: 'message'; + /** Message role */ + role: 'assistant'; + /** Completion status */ + status: 'completed' | 'failed'; + /** Message content blocks */ + content: Array<{ + /** Content type */ + type: 'output_text'; + /** Text content */ + text: string; + /** Optional annotations */ + annotations?: unknown[]; + }>; +} + +/** + * Union type for all possible output events from OpenAI Responses API. + * + * @public + */ +export type ResponsesApiOutputEvent = + | ResponsesApiMcpListTools + | ResponsesApiMcpCall + | ResponsesApiMessage; + +/** + * Complete response from OpenAI Responses API. + * + * @public + */ +export interface ResponsesApiResponse { + /** Response ID */ + id: string; + /** Object type */ + object: 'response'; + /** Unix timestamp of creation */ + created_at: number; + /** Model used for generation */ + model: string; + /** Response status */ + status: 'completed' | 'failed' | 'cancelled'; + /** Output events from the response */ + output: ResponsesApiOutputEvent[]; + /** Token usage statistics */ + usage?: { + /** Input tokens used */ + input_tokens: number; + /** Output tokens generated */ + output_tokens: number; + /** Total tokens */ + total_tokens: number; + /** Detailed input token breakdown */ + input_tokens_details?: { + /** Tokens served from cache */ + cached_tokens: number; + }; + /** Detailed output token breakdown */ + output_tokens_details?: unknown; + }; + /** Error message if failed */ + error?: string | null; + /** System instructions */ + instructions?: string | null; + /** Configured tools */ + tools?: ResponsesApiMcpTool[]; + /** Whether parallel tool calls are enabled */ + parallel_tool_calls?: boolean; + /** ID of the previous response in a conversation */ + previous_response_id?: string | null; + /** Temperature setting used */ + temperature?: number | null; + /** Top-p setting used */ + top_p?: number | null; + /** Text format configuration */ + text?: { + format: { + type: string; + }; + }; + /** Truncation settings */ + truncation?: unknown; +} + +// ============================================================================= +// Conversation Storage Types +// ============================================================================= + +/** + * A stored conversation record. + * Used for API responses and internal representation. + * + * @public + */ +export interface ConversationRecord { + /** Unique identifier for the conversation */ + id: string; + /** User entity ref who owns this conversation */ + userId: string; + /** Array of chat messages in the conversation */ + messages: ChatMessage[]; + /** Optional array of tool names used in the conversation */ + toolsUsed?: string[]; + /** AI-generated or user-edited conversation title */ + title?: string; + /** Whether the conversation is starred/favorited */ + isStarred: boolean; + /** Timestamp when the conversation was created */ + createdAt: Date; + /** Timestamp when the conversation was last updated */ + updatedAt: Date; +} + +/** + * Database row representation of a conversation. + * Used internally for database operations. + * + * @internal + */ +export interface ConversationRow { + /** UUID primary key */ + id: string; + /** User entity ref (snake_case for DB) */ + user_id: string; + /** JSON-serialized messages array */ + messages: string; + /** JSON-serialized tools array or null */ + tools_used: string | null; + /** AI-generated or user-edited conversation title */ + title: string | null; + /** Whether the conversation is starred/favorited */ + is_starred: boolean; + /** Creation timestamp */ + created_at: Date; + /** Last update timestamp */ + updated_at: Date; +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-node/.eslintrc.js new file mode 100644 index 00000000000..e2a53a6ad28 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/README.md b/workspaces/mcp-chat/plugins/mcp-chat-node/README.md new file mode 100644 index 00000000000..fb83ee8ac9f --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/README.md @@ -0,0 +1,5 @@ +# @@backstage-community/plugin-mcp-chat-node + +Welcome to the Node.js library package for the mcp-chat plugin! + +_This plugin was created through the Backstage CLI_ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/package.json b/workspaces/mcp-chat/plugins/mcp-chat-node/package.json new file mode 100644 index 00000000000..4617440a40d --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/package.json @@ -0,0 +1,55 @@ +{ + "name": "@backstage-community/plugin-mcp-chat-node", + "version": "0.1.0", + "license": "Apache-2.0", + "private": true, + "description": "Node.js library for the mcp-chat plugin", + "main": "src/index.ts", + "types": "src/index.ts", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "node-library", + "pluginId": "mcp-chat", + "pluginPackages": [ + "@backstage-community/plugin-mcp-chat-node", + "@backstage-community/plugin-mcp-chat-common", + "@backstage-community/plugin-mcp-chat-backend" + ] + }, + "scripts": { + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage-community/plugin-mcp-chat-common": "workspace:^", + "@backstage/backend-plugin-api": "^1.4.0" + }, + "devDependencies": { + "@backstage/cli": "^0.33.0" + }, + "files": [ + "dist" + ], + "repository": { + "type": "git", + "url": "https://github.com/backstage/community-plugins", + "directory": "workspaces/mcp-chat/plugins/mcp-chat-node" + }, + "keywords": [ + "backstage", + "backstage-plugin", + "mcp", + "mcp-chat", + "node-library" + ], + "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-node", + "bugs": "https://github.com/backstage/community-plugins/issues" +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/src/extensions.ts b/workspaces/mcp-chat/plugins/mcp-chat-node/src/extensions.ts new file mode 100644 index 00000000000..fd8890a670b --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/src/extensions.ts @@ -0,0 +1,44 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createExtensionPoint } from '@backstage/backend-plugin-api'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; + +/** + * Extension point for registering LLM provider implementations + * with the mcp-chat backend plugin. + * + * @public + */ +export interface LlmProviderExtensionPoint { + /** + * Register an LLM provider instance keyed by type string. + * If a provider with the same type is already registered, it is replaced + * and a warning is logged. + */ + registerProvider(type: string, provider: LLMProvider): void; +} + +/** + * Extension point that allows provider modules to register + * LLM provider implementations with the mcp-chat plugin. + * + * @public + */ +export const llmProviderExtensionPoint = + createExtensionPoint({ + id: 'mcp-chat.llm-provider', + }); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-node/src/index.ts new file mode 100644 index 00000000000..95786cfe4a2 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/src/index.ts @@ -0,0 +1,26 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Node.js library for the mcp-chat plugin. + * + * @packageDocumentation + */ + +export { + llmProviderExtensionPoint, + type LlmProviderExtensionPoint, +} from './extensions'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/src/setupTests.ts b/workspaces/mcp-chat/plugins/mcp-chat-node/src/setupTests.ts new file mode 100644 index 00000000000..f3a222d4e19 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/src/setupTests.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export {}; diff --git a/workspaces/mcp-chat/yarn.lock b/workspaces/mcp-chat/yarn.lock index 207b842958e..7793ef9e12e 100644 --- a/workspaces/mcp-chat/yarn.lock +++ b/workspaces/mcp-chat/yarn.lock @@ -1125,9 +1125,9 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.28.6, @babel/code-frame@npm:^7.29.0, @babel/code-frame@npm:^7.8.3": - version: 7.29.0 - resolution: "@babel/code-frame@npm:7.29.0" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.26.2, @babel/code-frame@npm:^7.27.1, @babel/code-frame@npm:^7.8.3": + version: 7.28.6 + resolution: "@babel/code-frame@npm:7.28.6" dependencies: "@babel/helper-validator-identifier": "npm:^7.28.5" js-tokens: "npm:^4.0.0" @@ -1136,33 +1136,26 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.29.0": - version: 7.29.1 - resolution: "@babel/generator@npm:7.29.1" +"@babel/generator@npm:^7.27.3": + version: 7.27.5 + resolution: "@babel/generator@npm:7.27.5" dependencies: - "@babel/parser": "npm:^7.29.0" - "@babel/types": "npm:^7.29.0" - "@jridgewell/gen-mapping": "npm:^0.3.12" - "@jridgewell/trace-mapping": "npm:^0.3.28" + "@babel/parser": "npm:^7.27.5" + "@babel/types": "npm:^7.27.3" + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" jsesc: "npm:^3.0.2" - checksum: 10/61fe4ddd6e817aa312a14963ccdbb5c9a8c57e8b97b98d19a8a99ccab2215fda1a5f52bc8dd8d2e3c064497ddeb3ab8ceb55c76fa0f58f8169c34679d2256fe0 - languageName: node - linkType: hard - -"@babel/helper-globals@npm:^7.28.0": - version: 7.28.0 - resolution: "@babel/helper-globals@npm:7.28.0" - checksum: 10/91445f7edfde9b65dcac47f4f858f68dc1661bf73332060ab67ad7cc7b313421099a2bfc4bda30c3db3842cfa1e86fffbb0d7b2c5205a177d91b22c8d7d9cb47 + checksum: 10/f5e6942670cb32156b3ac2d75ce09b373558823387f15dd1413c27fe9eb5756a7c6011fc7f956c7acc53efb530bfb28afffa24364d46c4e9ffccc4e5c8b3b094 languageName: node linkType: hard "@babel/helper-module-imports@npm:^7.16.7": - version: 7.28.6 - resolution: "@babel/helper-module-imports@npm:7.28.6" + version: 7.27.1 + resolution: "@babel/helper-module-imports@npm:7.27.1" dependencies: - "@babel/traverse": "npm:^7.28.6" - "@babel/types": "npm:^7.28.6" - checksum: 10/64b1380d74425566a3c288074d7ce4dea56d775d2d3325a3d4a6df1dca702916c1d268133b6f385de9ba5b822b3c6e2af5d3b11ac88e5453d5698d77264f0ec0 + "@babel/traverse": "npm:^7.27.1" + "@babel/types": "npm:^7.27.1" + checksum: 10/58e792ea5d4ae71676e0d03d9fef33e886a09602addc3bd01388a98d87df9fcfd192968feb40ac4aedb7e287ec3d0c17b33e3ecefe002592041a91d8a1998a8d languageName: node linkType: hard @@ -1180,6 +1173,34 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-option@npm:7.27.1" + checksum: 10/db73e6a308092531c629ee5de7f0d04390835b21a263be2644276cb27da2384b64676cab9f22cd8d8dbd854c92b1d7d56fc8517cf0070c35d1c14a8c828b0903 + languageName: node + linkType: hard + +"@babel/helper-wrap-function@npm:^7.27.1": + version: 7.28.6 + resolution: "@babel/helper-wrap-function@npm:7.28.6" + dependencies: + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + checksum: 10/d8a895a75399904746f4127db33593a20021fc55d1a5b5dfeb060b87cc13a8dceea91e70a4951bcd376ba9bd8232b0c04bff9a86c1dab83d691e01852c3b5bcd + languageName: node + linkType: hard + +"@babel/helpers@npm:^7.28.6": + version: 7.29.2 + resolution: "@babel/helpers@npm:7.29.2" + dependencies: + "@babel/template": "npm:^7.28.6" + "@babel/types": "npm:^7.29.0" + checksum: 10/ad77706f3f917bd224e037fd0fbc67c45b240d2a45981321b093f70b7c535bee9bbddb0a19e34c362cb000ae21cdd8638f8a87a5f305a5bd7547e93fdcc524fe + languageName: node + linkType: hard + "@babel/highlight@npm:^7.0.0": version: 7.25.9 resolution: "@babel/highlight@npm:7.25.9" @@ -1192,14 +1213,14 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.28.6, @babel/parser@npm:^7.29.0": - version: 7.29.2 - resolution: "@babel/parser@npm:7.29.2" +"@babel/parser@npm:^7.27.2, @babel/parser@npm:^7.27.4, @babel/parser@npm:^7.27.5": + version: 7.27.5 + resolution: "@babel/parser@npm:7.27.5" dependencies: "@babel/types": "npm:^7.29.0" bin: parser: ./bin/babel-parser.js - checksum: 10/45d050bf75aa5194b3255f156173e8553d615ff5a2434674cc4a10cdc7c261931befb8618c996a1c449b87f0ef32a3407879af2ac967d95dc7b4fdbae7037efa + checksum: 10/0ad671be7994dba7d31ec771bd70ea5090aa34faf73e93b1b072e3c0a704ab69f4a7a68ebfb9d6a7fa455e0aa03dfa65619c4df6bae1cf327cba925b1d233fc4 languageName: node linkType: hard @@ -1210,9 +1231,9 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.28.6": - version: 7.28.6 - resolution: "@babel/template@npm:7.28.6" +"@babel/template@npm:^7.27.2": + version: 7.27.2 + resolution: "@babel/template@npm:7.27.2" dependencies: "@babel/code-frame": "npm:^7.28.6" "@babel/parser": "npm:^7.28.6" @@ -1221,9 +1242,9 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.28.6": - version: 7.29.0 - resolution: "@babel/traverse@npm:7.29.0" +"@babel/traverse@npm:^7.27.1": + version: 7.27.4 + resolution: "@babel/traverse@npm:7.27.4" dependencies: "@babel/code-frame": "npm:^7.29.0" "@babel/generator": "npm:^7.29.0" @@ -1236,9 +1257,9 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.28.6, @babel/types@npm:^7.29.0": - version: 7.29.0 - resolution: "@babel/types@npm:7.29.0" +"@babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3": + version: 7.27.6 + resolution: "@babel/types@npm:7.27.6" dependencies: "@babel/helper-string-parser": "npm:^7.27.1" "@babel/helper-validator-identifier": "npm:^7.28.5" @@ -1246,18 +1267,95 @@ __metadata: languageName: node linkType: hard +"@backstage-community/plugin-mcp-chat-backend-module-anthropic@workspace:plugins/mcp-chat-backend-module-anthropic": + version: 0.0.0-use.local + resolution: "@backstage-community/plugin-mcp-chat-backend-module-anthropic@workspace:plugins/mcp-chat-backend-module-anthropic" + dependencies: + "@backstage-community/plugin-mcp-chat-common": "workspace:^" + "@backstage-community/plugin-mcp-chat-node": "workspace:^" + "@backstage/backend-plugin-api": "npm:^1.4.0" + "@backstage/cli": "npm:^0.33.0" + "@backstage/config": "npm:^1.3.0" + languageName: unknown + linkType: soft + +"@backstage-community/plugin-mcp-chat-backend-module-gemini@workspace:plugins/mcp-chat-backend-module-gemini": + version: 0.0.0-use.local + resolution: "@backstage-community/plugin-mcp-chat-backend-module-gemini@workspace:plugins/mcp-chat-backend-module-gemini" + dependencies: + "@backstage-community/plugin-mcp-chat-common": "workspace:^" + "@backstage-community/plugin-mcp-chat-node": "workspace:^" + "@backstage/backend-plugin-api": "npm:^1.4.0" + "@backstage/cli": "npm:^0.33.0" + "@backstage/config": "npm:^1.3.0" + "@google/generative-ai": "npm:^0.24.1" + languageName: unknown + linkType: soft + +"@backstage-community/plugin-mcp-chat-backend-module-litellm@workspace:plugins/mcp-chat-backend-module-litellm": + version: 0.0.0-use.local + resolution: "@backstage-community/plugin-mcp-chat-backend-module-litellm@workspace:plugins/mcp-chat-backend-module-litellm" + dependencies: + "@backstage-community/plugin-mcp-chat-common": "workspace:^" + "@backstage-community/plugin-mcp-chat-node": "workspace:^" + "@backstage/backend-plugin-api": "npm:^1.4.0" + "@backstage/cli": "npm:^0.33.0" + "@backstage/config": "npm:^1.3.0" + languageName: unknown + linkType: soft + +"@backstage-community/plugin-mcp-chat-backend-module-ollama@workspace:plugins/mcp-chat-backend-module-ollama": + version: 0.0.0-use.local + resolution: "@backstage-community/plugin-mcp-chat-backend-module-ollama@workspace:plugins/mcp-chat-backend-module-ollama" + dependencies: + "@backstage-community/plugin-mcp-chat-common": "workspace:^" + "@backstage-community/plugin-mcp-chat-node": "workspace:^" + "@backstage/backend-plugin-api": "npm:^1.4.0" + "@backstage/cli": "npm:^0.33.0" + "@backstage/config": "npm:^1.3.0" + ollama: "npm:^0.6.0" + languageName: unknown + linkType: soft + +"@backstage-community/plugin-mcp-chat-backend-module-openai-responses@workspace:plugins/mcp-chat-backend-module-openai-responses": + version: 0.0.0-use.local + resolution: "@backstage-community/plugin-mcp-chat-backend-module-openai-responses@workspace:plugins/mcp-chat-backend-module-openai-responses" + dependencies: + "@backstage-community/plugin-mcp-chat-common": "workspace:^" + "@backstage-community/plugin-mcp-chat-node": "workspace:^" + "@backstage/backend-plugin-api": "npm:^1.4.0" + "@backstage/cli": "npm:^0.33.0" + "@backstage/config": "npm:^1.3.0" + languageName: unknown + linkType: soft + +"@backstage-community/plugin-mcp-chat-backend-module-openai@workspace:^, @backstage-community/plugin-mcp-chat-backend-module-openai@workspace:plugins/mcp-chat-backend-module-openai": + version: 0.0.0-use.local + resolution: "@backstage-community/plugin-mcp-chat-backend-module-openai@workspace:plugins/mcp-chat-backend-module-openai" + dependencies: + "@backstage-community/plugin-mcp-chat-common": "workspace:^" + "@backstage-community/plugin-mcp-chat-node": "workspace:^" + "@backstage/backend-plugin-api": "npm:^1.4.0" + "@backstage/cli": "npm:^0.33.0" + "@backstage/config": "npm:^1.3.0" + languageName: unknown + linkType: soft + "@backstage-community/plugin-mcp-chat-backend@workspace:plugins/mcp-chat-backend": version: 0.0.0-use.local resolution: "@backstage-community/plugin-mcp-chat-backend@workspace:plugins/mcp-chat-backend" dependencies: - "@backstage/backend-defaults": "npm:^0.16.0" - "@backstage/backend-plugin-api": "npm:^1.8.0" - "@backstage/backend-test-utils": "npm:^1.11.1" - "@backstage/cli": "npm:^0.36.0" - "@backstage/config": "npm:^1.3.6" + "@backstage-community/plugin-mcp-chat-backend-module-openai": "workspace:^" + "@backstage-community/plugin-mcp-chat-common": "workspace:^" + "@backstage-community/plugin-mcp-chat-node": "workspace:^" + "@backstage/backend-defaults": "npm:^0.11.0" + "@backstage/backend-plugin-api": "npm:^1.4.0" + "@backstage/backend-test-utils": "npm:^1.6.0" + "@backstage/cli": "npm:^0.33.0" + "@backstage/config": "npm:^1.3.0" "@backstage/errors": "npm:^1.2.7" - "@backstage/plugin-catalog-node": "npm:^2.1.0" - "@google/genai": "npm:^1.41.0" + "@backstage/plugin-catalog-node": "npm:^2.0.0" + "@google/generative-ai": "npm:^0.24.1" "@modelcontextprotocol/sdk": "npm:^1.25.2" "@types/express": "npm:^4.17.6" "@types/supertest": "npm:^7.0.0" @@ -1265,9 +1363,27 @@ __metadata: express: "npm:^4.22.0" express-promise-router: "npm:^4.1.0" knex: "npm:^3.1.0" - ollama: "npm:^0.6.0" supertest: "npm:^7.0.0" - uuid: "npm:^11.0.0" + uuid: "npm:^9.0.0" + languageName: unknown + linkType: soft + +"@backstage-community/plugin-mcp-chat-common@workspace:^, @backstage-community/plugin-mcp-chat-common@workspace:plugins/mcp-chat-common": + version: 0.0.0-use.local + resolution: "@backstage-community/plugin-mcp-chat-common@workspace:plugins/mcp-chat-common" + dependencies: + "@backstage/cli": "npm:^0.33.0" + "@backstage/errors": "npm:^1.2.7" + languageName: unknown + linkType: soft + +"@backstage-community/plugin-mcp-chat-node@workspace:^, @backstage-community/plugin-mcp-chat-node@workspace:plugins/mcp-chat-node": + version: 0.0.0-use.local + resolution: "@backstage-community/plugin-mcp-chat-node@workspace:plugins/mcp-chat-node" + dependencies: + "@backstage-community/plugin-mcp-chat-common": "workspace:^" + "@backstage/backend-plugin-api": "npm:^1.4.0" + "@backstage/cli": "npm:^0.33.0" languageName: unknown linkType: soft @@ -1327,9 +1443,9 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-app-api@npm:^1.6.0": - version: 1.6.0 - resolution: "@backstage/backend-app-api@npm:1.6.0" +"@backstage/backend-app-api@npm:^1.5.0": + version: 1.5.0 + resolution: "@backstage/backend-app-api@npm:1.5.0" dependencies: "@backstage/backend-plugin-api": "npm:^1.8.0" "@backstage/config": "npm:^1.3.6" @@ -1338,6 +1454,89 @@ __metadata: languageName: node linkType: hard +"@backstage/backend-defaults@npm:^0.11.0": + version: 0.11.1 + resolution: "@backstage/backend-defaults@npm:0.11.1" + dependencies: + "@aws-sdk/abort-controller": "npm:^3.347.0" + "@aws-sdk/client-codecommit": "npm:^3.350.0" + "@aws-sdk/client-s3": "npm:^3.350.0" + "@aws-sdk/credential-providers": "npm:^3.350.0" + "@aws-sdk/types": "npm:^3.347.0" + "@azure/storage-blob": "npm:^12.5.0" + "@backstage/backend-app-api": "npm:^1.2.5" + "@backstage/backend-dev-utils": "npm:^0.1.5" + "@backstage/backend-plugin-api": "npm:^1.4.1" + "@backstage/cli-node": "npm:^0.2.13" + "@backstage/config": "npm:^1.3.3" + "@backstage/config-loader": "npm:^1.10.2" + "@backstage/errors": "npm:^1.2.7" + "@backstage/integration": "npm:^1.17.1" + "@backstage/integration-aws-node": "npm:^0.1.17" + "@backstage/plugin-auth-node": "npm:^0.6.5" + "@backstage/plugin-events-node": "npm:^0.4.13" + "@backstage/plugin-permission-node": "npm:^0.10.2" + "@backstage/types": "npm:^1.2.1" + "@google-cloud/storage": "npm:^7.0.0" + "@keyv/memcache": "npm:^2.0.1" + "@keyv/redis": "npm:^4.0.1" + "@keyv/valkey": "npm:^1.0.1" + "@manypkg/get-packages": "npm:^1.1.3" + "@octokit/rest": "npm:^19.0.3" + "@opentelemetry/api": "npm:^1.9.0" + "@types/cors": "npm:^2.8.6" + "@types/express": "npm:^4.17.6" + archiver: "npm:^7.0.0" + base64-stream: "npm:^1.0.0" + better-sqlite3: "npm:^11.0.0" + compression: "npm:^1.7.4" + concat-stream: "npm:^2.0.0" + cookie: "npm:^0.7.0" + cors: "npm:^2.8.5" + cron: "npm:^3.0.0" + express: "npm:^4.17.1" + express-promise-router: "npm:^4.1.0" + express-rate-limit: "npm:^7.5.0" + fs-extra: "npm:^11.2.0" + git-url-parse: "npm:^15.0.0" + helmet: "npm:^6.0.0" + is-glob: "npm:^4.0.3" + jose: "npm:^5.0.0" + keyv: "npm:^5.2.1" + knex: "npm:^3.0.0" + lodash: "npm:^4.17.21" + logform: "npm:^2.3.2" + luxon: "npm:^3.0.0" + minimatch: "npm:^9.0.0" + mysql2: "npm:^3.0.0" + node-fetch: "npm:^2.7.0" + node-forge: "npm:^1.3.1" + p-limit: "npm:^3.1.0" + path-to-regexp: "npm:^8.0.0" + pg: "npm:^8.11.3" + pg-connection-string: "npm:^2.3.0" + pg-format: "npm:^1.0.4" + rate-limit-redis: "npm:^4.2.0" + raw-body: "npm:^2.4.1" + selfsigned: "npm:^2.0.0" + tar: "npm:^6.1.12" + triple-beam: "npm:^1.4.1" + uuid: "npm:^11.0.0" + winston: "npm:^3.2.1" + winston-transport: "npm:^4.5.0" + yauzl: "npm:^3.0.0" + yn: "npm:^4.0.0" + zod: "npm:^3.22.4" + zod-to-json-schema: "npm:^3.20.4" + peerDependencies: + "@google-cloud/cloud-sql-connector": ^1.4.0 + peerDependenciesMeta: + "@google-cloud/cloud-sql-connector": + optional: true + checksum: 10/984df8217c5c84221437e528b780fecaf0a7cd73106a51924c169ed65f2f829e42ac8ced53ac37613a6d6534d41483ac28db6ef1de6b9f9f714c416c139539b7 + languageName: node + linkType: hard + "@backstage/backend-defaults@npm:^0.16.0": version: 0.16.0 resolution: "@backstage/backend-defaults@npm:0.16.0" @@ -1433,9 +1632,9 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-plugin-api@npm:^1.8.0": - version: 1.8.0 - resolution: "@backstage/backend-plugin-api@npm:1.8.0" +"@backstage/backend-plugin-api@npm:^1.7.0": + version: 1.7.0 + resolution: "@backstage/backend-plugin-api@npm:1.7.0" dependencies: "@backstage/cli-common": "npm:^0.2.0" "@backstage/config": "npm:^1.3.6" @@ -1455,9 +1654,9 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-test-utils@npm:^1.11.1": - version: 1.11.1 - resolution: "@backstage/backend-test-utils@npm:1.11.1" +"@backstage/backend-test-utils@npm:^1.11.0": + version: 1.11.0 + resolution: "@backstage/backend-test-utils@npm:1.11.0" dependencies: "@backstage/backend-app-api": "npm:^1.6.0" "@backstage/backend-defaults": "npm:^0.16.0" @@ -1500,9 +1699,9 @@ __metadata: languageName: node linkType: hard -"@backstage/catalog-client@npm:^1.14.0": - version: 1.14.0 - resolution: "@backstage/catalog-client@npm:1.14.0" +"@backstage/catalog-client@npm:^1.13.0": + version: 1.13.0 + resolution: "@backstage/catalog-client@npm:1.13.0" dependencies: "@backstage/catalog-model": "npm:^1.7.7" "@backstage/errors": "npm:^1.2.7" @@ -1514,9 +1713,9 @@ __metadata: languageName: node linkType: hard -"@backstage/catalog-model@npm:^1.7.6, @backstage/catalog-model@npm:^1.7.7": - version: 1.7.7 - resolution: "@backstage/catalog-model@npm:1.7.7" +"@backstage/catalog-model@npm:^1.7.6": + version: 1.7.6 + resolution: "@backstage/catalog-model@npm:1.7.6" dependencies: "@backstage/errors": "npm:^1.2.7" "@backstage/types": "npm:^1.2.2" @@ -1526,9 +1725,9 @@ __metadata: languageName: node linkType: hard -"@backstage/cli-common@npm:^0.2.0": - version: 0.2.0 - resolution: "@backstage/cli-common@npm:0.2.0" +"@backstage/cli-common@npm:^0.1.15, @backstage/cli-common@npm:^0.1.18": + version: 0.1.18 + resolution: "@backstage/cli-common@npm:0.1.18" dependencies: "@backstage/errors": "npm:^1.2.7" cross-spawn: "npm:^7.0.3" @@ -1538,43 +1737,9 @@ __metadata: languageName: node linkType: hard -"@backstage/cli-defaults@npm:^0.1.0": - version: 0.1.0 - resolution: "@backstage/cli-defaults@npm:0.1.0" - dependencies: - "@backstage/cli-module-actions": "npm:^0.0.1" - "@backstage/cli-module-auth": "npm:^0.1.0" - "@backstage/cli-module-build": "npm:^0.1.0" - "@backstage/cli-module-config": "npm:^0.1.0" - "@backstage/cli-module-github": "npm:^0.1.0" - "@backstage/cli-module-info": "npm:^0.1.0" - "@backstage/cli-module-lint": "npm:^0.1.0" - "@backstage/cli-module-maintenance": "npm:^0.1.0" - "@backstage/cli-module-migrate": "npm:^0.1.0" - "@backstage/cli-module-new": "npm:^0.1.0" - "@backstage/cli-module-test-jest": "npm:^0.1.0" - "@backstage/cli-module-translations": "npm:^0.1.0" - checksum: 10/e1db3b0e52485b5ddba43e070f79bb0a41eedc32475fdf59cff837df70324fe033043d699b0bf91c1224da10dcc043126fe9a0d57c556e63f8792822d5d9ddf4 - languageName: node - linkType: hard - -"@backstage/cli-module-actions@npm:^0.0.1": - version: 0.0.1 - resolution: "@backstage/cli-module-actions@npm:0.0.1" - dependencies: - "@backstage/cli-node": "npm:^0.3.0" - "@backstage/errors": "npm:^1.2.7" - cleye: "npm:^2.3.0" - zod: "npm:^3.25.76 || ^4.0.0" - bin: - cli-module-actions: bin/backstage-cli-module-actions - checksum: 10/d6fcf0d5aaadaf9f0314594851f2ce833f503035018947e3a30c5ae7d2b5378022f9e625a07e54d738e36dc359a809fa282f0aee332bd9a2266d216d7ab83ca1 - languageName: node - linkType: hard - -"@backstage/cli-module-auth@npm:^0.1.0": - version: 0.1.0 - resolution: "@backstage/cli-module-auth@npm:0.1.0" +"@backstage/cli-node@npm:^0.2.18": + version: 0.2.18 + resolution: "@backstage/cli-node@npm:0.2.18" dependencies: "@backstage/cli-node": "npm:^0.3.0" "@backstage/errors": "npm:^1.2.7" @@ -1850,40 +2015,9 @@ __metadata: languageName: node linkType: hard -"@backstage/cli-node@npm:^0.3.0": - version: 0.3.0 - resolution: "@backstage/cli-node@npm:0.3.0" - dependencies: - "@backstage/cli-common": "npm:^0.2.0" - "@backstage/errors": "npm:^1.2.7" - "@backstage/types": "npm:^1.2.2" - "@manypkg/get-packages": "npm:^1.1.3" - "@yarnpkg/lockfile": "npm:^1.1.0" - "@yarnpkg/parsers": "npm:^3.0.0" - chalk: "npm:^4.0.0" - commander: "npm:^12.0.0" - fs-extra: "npm:^11.2.0" - keytar: "npm:^7.9.0" - pirates: "npm:^4.0.6" - proper-lockfile: "npm:^4.1.2" - semver: "npm:^7.5.3" - yaml: "npm:^2.0.0" - zod: "npm:^3.25.76 || ^4.0.0" - peerDependencies: - "@swc/core": ^1.15.6 - dependenciesMeta: - keytar: - optional: true - peerDependenciesMeta: - "@swc/core": - optional: true - checksum: 10/dcbbe2b143489917ce017c5a3c6da0654fab1344ccced7bd33618b1540de2dafd8b4493fcec6402aa4ae8cd5971038eac547b709c67dba00180b6b813b399f79 - languageName: node - linkType: hard - -"@backstage/cli@npm:^0.36.0": - version: 0.36.0 - resolution: "@backstage/cli@npm:0.36.0" +"@backstage/cli@npm:^0.35.4": + version: 0.35.4 + resolution: "@backstage/cli@npm:0.35.4" dependencies: "@backstage/cli-common": "npm:^0.2.0" "@backstage/cli-defaults": "npm:^0.1.0" @@ -1938,9 +2072,9 @@ __metadata: languageName: node linkType: hard -"@backstage/config-loader@npm:^1.10.9": - version: 1.10.9 - resolution: "@backstage/config-loader@npm:1.10.9" +"@backstage/config-loader@npm:^1.10.8": + version: 1.10.8 + resolution: "@backstage/config-loader@npm:1.10.8" dependencies: "@backstage/cli-common": "npm:^0.2.0" "@backstage/config": "npm:^1.3.6" @@ -1961,7 +2095,7 @@ __metadata: languageName: node linkType: hard -"@backstage/config@npm:^1.3.6": +"@backstage/config@npm:^1.3.0, @backstage/config@npm:^1.3.3, @backstage/config@npm:^1.3.6": version: 1.3.6 resolution: "@backstage/config@npm:1.3.6" dependencies: @@ -2161,7 +2295,17 @@ __metadata: languageName: node linkType: hard -"@backstage/eslint-plugin@npm:^0.2.2": +"@backstage/eslint-plugin@npm:^0.1.11": + version: 0.1.12 + resolution: "@backstage/eslint-plugin@npm:0.1.12" + dependencies: + "@manypkg/get-packages": "npm:^1.1.3" + minimatch: "npm:^9.0.0" + checksum: 10/1656bc6e1862c55ee26ab909fd028d922a6097b32d89f39b55a3e7d9b5fff338f5ead4330323be7cb468e45c308359463bbf3c0048d53418f3a82c24a4ea789e + languageName: node + linkType: hard + +"@backstage/eslint-plugin@npm:^0.2.1": version: 0.2.2 resolution: "@backstage/eslint-plugin@npm:0.2.2" dependencies: @@ -2171,9 +2315,9 @@ __metadata: languageName: node linkType: hard -"@backstage/filter-predicates@npm:^0.1.1": - version: 0.1.1 - resolution: "@backstage/filter-predicates@npm:0.1.1" +"@backstage/filter-predicates@npm:^0.1.0": + version: 0.1.0 + resolution: "@backstage/filter-predicates@npm:0.1.0" dependencies: "@backstage/config": "npm:^1.3.6" "@backstage/errors": "npm:^1.2.7" @@ -2184,15 +2328,14 @@ __metadata: languageName: node linkType: hard -"@backstage/frontend-plugin-api@npm:^0.15.0, @backstage/frontend-plugin-api@npm:^0.15.1": - version: 0.15.1 - resolution: "@backstage/frontend-plugin-api@npm:0.15.1" +"@backstage/frontend-plugin-api@npm:^0.14.1": + version: 0.14.1 + resolution: "@backstage/frontend-plugin-api@npm:0.14.1" dependencies: "@backstage/errors": "npm:^1.2.7" - "@backstage/filter-predicates": "npm:^0.1.1" "@backstage/types": "npm:^1.2.2" "@backstage/version-bridge": "npm:^1.0.12" - zod: "npm:^3.25.76 || ^4.0.0" + zod: "npm:^3.25.76" zod-to-json-schema: "npm:^3.25.1" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -2202,7 +2345,7 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/e40d2bbd8eb2b55eaced37e8f855cece9ed74092a89949a474e38ed6f06c20d289fef4595ee6267375effc9983ae6dfb8fc91d8d2d2b7d7a1642ced248ec1f01 + checksum: 10/d54c3bee4c7f3708c1196aedec76a4edcc4d99e5856a2d7b404ad1f70ed6395ee32ac7de69290b37f3cc32c19507b8cdda566c04655c57e6ed364ee356434538 languageName: node linkType: hard @@ -2242,6 +2385,24 @@ __metadata: languageName: node linkType: hard +"@backstage/integration@npm:^1.17.1, @backstage/integration@npm:^1.20.0": + version: 1.20.1 + resolution: "@backstage/integration@npm:1.20.1" + dependencies: + "@azure/identity": "npm:^4.0.0" + "@azure/storage-blob": "npm:^12.5.0" + "@backstage/config": "npm:^1.3.6" + "@backstage/errors": "npm:^1.2.7" + "@octokit/auth-app": "npm:^4.0.0" + "@octokit/rest": "npm:^19.0.3" + cross-fetch: "npm:^4.0.0" + git-url-parse: "npm:^15.0.0" + lodash: "npm:^4.17.21" + luxon: "npm:^3.0.0" + checksum: 10/7089debe4190b39a35751438daa4fca79fcaa4c679889b983ba626f568aee6412f1180e58ff08111ee07b365a80712efc5abf5042af86cd3645a1cce66e63a72 + languageName: node + linkType: hard + "@backstage/integration@npm:^2.0.0": version: 2.0.0 resolution: "@backstage/integration@npm:2.0.0" @@ -2305,9 +2466,9 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-auth-node@npm:^0.6.14": - version: 0.6.14 - resolution: "@backstage/plugin-auth-node@npm:0.6.14" +"@backstage/plugin-auth-node@npm:^0.6.13": + version: 0.6.13 + resolution: "@backstage/plugin-auth-node@npm:0.6.13" dependencies: "@backstage/backend-plugin-api": "npm:^1.8.0" "@backstage/catalog-client": "npm:^1.14.0" @@ -2328,7 +2489,7 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-catalog-common@npm:^1.1.8": +"@backstage/plugin-catalog-common@npm:^1.1.7, @backstage/plugin-catalog-common@npm:^1.1.8": version: 1.1.8 resolution: "@backstage/plugin-catalog-common@npm:1.1.8" dependencies: @@ -2339,27 +2500,27 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-catalog-node@npm:^2.1.0": - version: 2.1.0 - resolution: "@backstage/plugin-catalog-node@npm:2.1.0" +"@backstage/plugin-catalog-node@npm:^2.0.0": + version: 2.0.0 + resolution: "@backstage/plugin-catalog-node@npm:2.0.0" dependencies: - "@backstage/backend-plugin-api": "npm:^1.8.0" - "@backstage/catalog-client": "npm:^1.14.0" - "@backstage/catalog-model": "npm:^1.7.7" + "@backstage/backend-plugin-api": "npm:^1.7.0" + "@backstage/catalog-client": "npm:^1.13.0" + "@backstage/catalog-model": "npm:^1.7.6" "@backstage/errors": "npm:^1.2.7" "@backstage/plugin-catalog-common": "npm:^1.1.8" - "@backstage/plugin-permission-common": "npm:^0.9.7" - "@backstage/plugin-permission-node": "npm:^0.10.11" + "@backstage/plugin-permission-common": "npm:^0.9.6" + "@backstage/plugin-permission-node": "npm:^0.10.10" "@backstage/types": "npm:^1.2.2" "@opentelemetry/api": "npm:^1.9.0" lodash: "npm:^4.17.21" yaml: "npm:^2.0.0" peerDependencies: - "@backstage/backend-test-utils": ^1.11.1 + "@backstage/backend-test-utils": ^1.11.0 peerDependenciesMeta: "@backstage/backend-test-utils": optional: true - checksum: 10/f47bdaf40de1f9b344f20ab8179557af845fef66b2a875f1c4427f4464bd06d453e21028ab1873c5da4e60bacd2dff13cace6cdd77c7fa6f8a166cd64e6060e2 + checksum: 10/fd7550a3f34b6b3a13159a21c4b3889f7f1a6af1164cb3e84b6b0d0cd6d678da83629c4e7f476f6bec8042b9186d5b47575d0333da9194d12b96ce71af603afa languageName: node linkType: hard @@ -2408,9 +2569,9 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-events-node@npm:^0.4.20": - version: 0.4.20 - resolution: "@backstage/plugin-events-node@npm:0.4.20" +"@backstage/plugin-events-node@npm:^0.4.19": + version: 0.4.19 + resolution: "@backstage/plugin-events-node@npm:0.4.19" dependencies: "@backstage/backend-plugin-api": "npm:^1.8.0" "@backstage/errors": "npm:^1.2.7" @@ -2425,9 +2586,9 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-permission-common@npm:^0.9.6, @backstage/plugin-permission-common@npm:^0.9.7": - version: 0.9.7 - resolution: "@backstage/plugin-permission-common@npm:0.9.7" +"@backstage/plugin-permission-common@npm:^0.9.6": + version: 0.9.6 + resolution: "@backstage/plugin-permission-common@npm:0.9.6" dependencies: "@backstage/config": "npm:^1.3.6" "@backstage/errors": "npm:^1.2.7" @@ -2440,9 +2601,9 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-permission-node@npm:^0.10.11": - version: 0.10.11 - resolution: "@backstage/plugin-permission-node@npm:0.10.11" +"@backstage/plugin-permission-node@npm:^0.10.10": + version: 0.10.10 + resolution: "@backstage/plugin-permission-node@npm:0.10.10" dependencies: "@backstage/backend-plugin-api": "npm:^1.8.0" "@backstage/config": "npm:^1.3.6" @@ -2666,16 +2827,9 @@ __metadata: languageName: node linkType: hard -"@borewit/text-codec@npm:^0.2.1": - version: 0.2.2 - resolution: "@borewit/text-codec@npm:0.2.2" - checksum: 10/c971790a72d9e766286db71f68613d1bac3b8bd9eaba52fbf18a8b17903c095968ed5369efdba378751926440aab93f3dd17c89242ef20525808ddced22d49b8 - languageName: node - linkType: hard - -"@changesets/apply-release-plan@npm:^7.1.0": - version: 7.1.0 - resolution: "@changesets/apply-release-plan@npm:7.1.0" +"@changesets/apply-release-plan@npm:^7.0.12": + version: 7.0.12 + resolution: "@changesets/apply-release-plan@npm:7.0.12" dependencies: "@changesets/config": "npm:^3.1.3" "@changesets/get-version-range-type": "npm:^0.4.0" @@ -3162,184 +3316,184 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/aix-ppc64@npm:0.27.4" +"@esbuild/aix-ppc64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/aix-ppc64@npm:0.27.3" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/android-arm64@npm:0.27.4" +"@esbuild/android-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/android-arm64@npm:0.27.3" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/android-arm@npm:0.27.4" +"@esbuild/android-arm@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/android-arm@npm:0.27.3" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/android-x64@npm:0.27.4" +"@esbuild/android-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/android-x64@npm:0.27.3" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/darwin-arm64@npm:0.27.4" +"@esbuild/darwin-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/darwin-arm64@npm:0.27.3" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/darwin-x64@npm:0.27.4" +"@esbuild/darwin-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/darwin-x64@npm:0.27.3" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/freebsd-arm64@npm:0.27.4" +"@esbuild/freebsd-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/freebsd-arm64@npm:0.27.3" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/freebsd-x64@npm:0.27.4" +"@esbuild/freebsd-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/freebsd-x64@npm:0.27.3" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/linux-arm64@npm:0.27.4" +"@esbuild/linux-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-arm64@npm:0.27.3" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/linux-arm@npm:0.27.4" +"@esbuild/linux-arm@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-arm@npm:0.27.3" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/linux-ia32@npm:0.27.4" +"@esbuild/linux-ia32@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-ia32@npm:0.27.3" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/linux-loong64@npm:0.27.4" +"@esbuild/linux-loong64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-loong64@npm:0.27.3" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/linux-mips64el@npm:0.27.4" +"@esbuild/linux-mips64el@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-mips64el@npm:0.27.3" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/linux-ppc64@npm:0.27.4" +"@esbuild/linux-ppc64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-ppc64@npm:0.27.3" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/linux-riscv64@npm:0.27.4" +"@esbuild/linux-riscv64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-riscv64@npm:0.27.3" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/linux-s390x@npm:0.27.4" +"@esbuild/linux-s390x@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-s390x@npm:0.27.3" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/linux-x64@npm:0.27.4" +"@esbuild/linux-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/linux-x64@npm:0.27.3" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-arm64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/netbsd-arm64@npm:0.27.4" +"@esbuild/netbsd-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/netbsd-arm64@npm:0.27.3" conditions: os=netbsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/netbsd-x64@npm:0.27.4" +"@esbuild/netbsd-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/netbsd-x64@npm:0.27.3" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/openbsd-arm64@npm:0.27.4" +"@esbuild/openbsd-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/openbsd-arm64@npm:0.27.3" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/openbsd-x64@npm:0.27.4" +"@esbuild/openbsd-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/openbsd-x64@npm:0.27.3" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openharmony-arm64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/openharmony-arm64@npm:0.27.4" +"@esbuild/openharmony-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/openharmony-arm64@npm:0.27.3" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/sunos-x64@npm:0.27.4" +"@esbuild/sunos-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/sunos-x64@npm:0.27.3" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/win32-arm64@npm:0.27.4" +"@esbuild/win32-arm64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/win32-arm64@npm:0.27.3" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/win32-ia32@npm:0.27.4" +"@esbuild/win32-ia32@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/win32-ia32@npm:0.27.3" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.27.4": - version: 0.27.4 - resolution: "@esbuild/win32-x64@npm:0.27.4" +"@esbuild/win32-x64@npm:0.27.3": + version: 0.27.3 + resolution: "@esbuild/win32-x64@npm:0.27.3" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -3729,28 +3883,197 @@ __metadata: languageName: node linkType: hard -"@jest/create-cache-key-function@npm:^30.0.0": - version: 30.3.0 - resolution: "@jest/create-cache-key-function@npm:30.3.0" +"@istanbuljs/load-nyc-config@npm:^1.0.0": + version: 1.1.0 + resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" dependencies: - "@jest/types": "npm:30.3.0" - checksum: 10/67ed57eda68e77e73e7ceb9cdd142a14d0fd028099762e3405d15ac530d0726eebb5d203f885b84436dc8d5582e4c3d290af7bbbe0445ffeae97de8e3604ea05 + camelcase: "npm:^5.3.1" + find-up: "npm:^4.1.0" + get-package-type: "npm:^0.1.0" + js-yaml: "npm:^3.13.1" + resolve-from: "npm:^5.0.0" + checksum: 10/b000a5acd8d4fe6e34e25c399c8bdbb5d3a202b4e10416e17bfc25e12bab90bb56d33db6089ae30569b52686f4b35ff28ef26e88e21e69821d2b85884bd055b8 languageName: node linkType: hard -"@jest/pattern@npm:30.0.1": - version: 30.0.1 - resolution: "@jest/pattern@npm:30.0.1" +"@istanbuljs/schema@npm:^0.1.2, @istanbuljs/schema@npm:^0.1.3": + version: 0.1.3 + resolution: "@istanbuljs/schema@npm:0.1.3" + checksum: 10/a9b1e49acdf5efc2f5b2359f2df7f90c5c725f2656f16099e8b2cd3a000619ecca9fc48cf693ba789cf0fd989f6e0df6a22bc05574be4223ecdbb7997d04384b + languageName: node + linkType: hard + +"@jest/console@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/console@npm:29.7.0" dependencies: + "@jest/types": "npm:^29.6.3" "@types/node": "npm:*" - jest-regex-util: "npm:30.0.1" - checksum: 10/afd03b4d3eadc9c9970cf924955dee47984a7e767901fe6fa463b17b246f0ddeec07b3e82c09715c54bde3c8abb92074160c0d79967bd23778724f184e7f5b7b + chalk: "npm:^4.0.0" + jest-message-util: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + slash: "npm:^3.0.0" + checksum: 10/4a80c750e8a31f344233cb9951dee9b77bf6b89377cb131f8b3cde07ff218f504370133a5963f6a786af4d2ce7f85642db206ff7a15f99fe58df4c38ac04899e languageName: node linkType: hard -"@jest/schemas@npm:30.0.5": - version: 30.0.5 - resolution: "@jest/schemas@npm:30.0.5" +"@jest/core@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/core@npm:29.7.0" + dependencies: + "@jest/console": "npm:^29.7.0" + "@jest/reporters": "npm:^29.7.0" + "@jest/test-result": "npm:^29.7.0" + "@jest/transform": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + "@types/node": "npm:*" + ansi-escapes: "npm:^4.2.1" + chalk: "npm:^4.0.0" + ci-info: "npm:^3.2.0" + exit: "npm:^0.1.2" + graceful-fs: "npm:^4.2.9" + jest-changed-files: "npm:^29.7.0" + jest-config: "npm:^29.7.0" + jest-haste-map: "npm:^29.7.0" + jest-message-util: "npm:^29.7.0" + jest-regex-util: "npm:^29.6.3" + jest-resolve: "npm:^29.7.0" + jest-resolve-dependencies: "npm:^29.7.0" + jest-runner: "npm:^29.7.0" + jest-runtime: "npm:^29.7.0" + jest-snapshot: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + jest-validate: "npm:^29.7.0" + jest-watcher: "npm:^29.7.0" + micromatch: "npm:^4.0.4" + pretty-format: "npm:^29.7.0" + slash: "npm:^3.0.0" + strip-ansi: "npm:^6.0.0" + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + checksum: 10/ab6ac2e562d083faac7d8152ec1cc4eccc80f62e9579b69ed40aedf7211a6b2d57024a6cd53c4e35fd051c39a236e86257d1d99ebdb122291969a0a04563b51e + languageName: node + linkType: hard + +"@jest/create-cache-key-function@npm:^30.0.0": + version: 30.3.0 + resolution: "@jest/create-cache-key-function@npm:30.3.0" + dependencies: + "@jest/types": "npm:30.3.0" + checksum: 10/67ed57eda68e77e73e7ceb9cdd142a14d0fd028099762e3405d15ac530d0726eebb5d203f885b84436dc8d5582e4c3d290af7bbbe0445ffeae97de8e3604ea05 + languageName: node + linkType: hard + +"@jest/environment@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/environment@npm:29.7.0" + dependencies: + "@jest/fake-timers": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + "@types/node": "npm:*" + jest-mock: "npm:^29.7.0" + checksum: 10/90b5844a9a9d8097f2cf107b1b5e57007c552f64315da8c1f51217eeb0a9664889d3f145cdf8acf23a84f4d8309a6675e27d5b059659a004db0ea9546d1c81a8 + languageName: node + linkType: hard + +"@jest/expect-utils@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/expect-utils@npm:29.7.0" + dependencies: + jest-get-type: "npm:^29.6.3" + checksum: 10/ef8d379778ef574a17bde2801a6f4469f8022a46a5f9e385191dc73bb1fc318996beaed4513fbd7055c2847227a1bed2469977821866534593a6e52a281499ee + languageName: node + linkType: hard + +"@jest/expect@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/expect@npm:29.7.0" + dependencies: + expect: "npm:^29.7.0" + jest-snapshot: "npm:^29.7.0" + checksum: 10/fea6c3317a8da5c840429d90bfe49d928e89c9e89fceee2149b93a11b7e9c73d2f6e4d7cdf647163da938fc4e2169e4490be6bae64952902bc7a701033fd4880 + languageName: node + linkType: hard + +"@jest/fake-timers@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/fake-timers@npm:29.7.0" + dependencies: + "@jest/types": "npm:^29.6.3" + "@sinonjs/fake-timers": "npm:^10.0.2" + "@types/node": "npm:*" + jest-message-util: "npm:^29.7.0" + jest-mock: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + checksum: 10/9b394e04ffc46f91725ecfdff34c4e043eb7a16e1d78964094c9db3fde0b1c8803e45943a980e8c740d0a3d45661906de1416ca5891a538b0660481a3a828c27 + languageName: node + linkType: hard + +"@jest/globals@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/globals@npm:29.7.0" + dependencies: + "@jest/environment": "npm:^29.7.0" + "@jest/expect": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + jest-mock: "npm:^29.7.0" + checksum: 10/97dbb9459135693ad3a422e65ca1c250f03d82b2a77f6207e7fa0edd2c9d2015fbe4346f3dc9ebff1678b9d8da74754d4d440b7837497f8927059c0642a22123 + languageName: node + linkType: hard + +"@jest/pattern@npm:30.0.1": + version: 30.0.1 + resolution: "@jest/pattern@npm:30.0.1" + dependencies: + "@types/node": "npm:*" + jest-regex-util: "npm:30.0.1" + checksum: 10/afd03b4d3eadc9c9970cf924955dee47984a7e767901fe6fa463b17b246f0ddeec07b3e82c09715c54bde3c8abb92074160c0d79967bd23778724f184e7f5b7b + languageName: node + linkType: hard + +"@jest/reporters@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/reporters@npm:29.7.0" + dependencies: + "@bcoe/v8-coverage": "npm:^0.2.3" + "@jest/console": "npm:^29.7.0" + "@jest/test-result": "npm:^29.7.0" + "@jest/transform": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + "@jridgewell/trace-mapping": "npm:^0.3.18" + "@types/node": "npm:*" + chalk: "npm:^4.0.0" + collect-v8-coverage: "npm:^1.0.0" + exit: "npm:^0.1.2" + glob: "npm:^7.1.3" + graceful-fs: "npm:^4.2.9" + istanbul-lib-coverage: "npm:^3.0.0" + istanbul-lib-instrument: "npm:^6.0.0" + istanbul-lib-report: "npm:^3.0.0" + istanbul-lib-source-maps: "npm:^4.0.0" + istanbul-reports: "npm:^3.1.3" + jest-message-util: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + jest-worker: "npm:^29.7.0" + slash: "npm:^3.0.0" + string-length: "npm:^4.0.1" + strip-ansi: "npm:^6.0.0" + v8-to-istanbul: "npm:^9.0.1" + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + checksum: 10/a17d1644b26dea14445cedd45567f4ba7834f980be2ef74447204e14238f121b50d8b858fde648083d2cd8f305f81ba434ba49e37a5f4237a6f2a61180cc73dc + languageName: node + linkType: hard + +"@jest/schemas@npm:30.0.5": + version: 30.0.5 + resolution: "@jest/schemas@npm:30.0.5" dependencies: "@sinclair/typebox": "npm:^0.34.0" checksum: 10/40df4db55d4aeed09d1c7e19caf23788309cea34490a1c5d584c913494195e698b9967e996afc27226cac6d76e7512fe73ae6b9584480695c60dd18a5459cdba @@ -3766,6 +4089,64 @@ __metadata: languageName: node linkType: hard +"@jest/source-map@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/source-map@npm:29.6.3" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.18" + callsites: "npm:^3.0.0" + graceful-fs: "npm:^4.2.9" + checksum: 10/bcc5a8697d471396c0003b0bfa09722c3cd879ad697eb9c431e6164e2ea7008238a01a07193dfe3cbb48b1d258eb7251f6efcea36f64e1ebc464ea3c03ae2deb + languageName: node + linkType: hard + +"@jest/test-result@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/test-result@npm:29.7.0" + dependencies: + "@jest/console": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + "@types/istanbul-lib-coverage": "npm:^2.0.0" + collect-v8-coverage: "npm:^1.0.0" + checksum: 10/c073ab7dfe3c562bff2b8fee6cc724ccc20aa96bcd8ab48ccb2aa309b4c0c1923a9e703cea386bd6ae9b71133e92810475bb9c7c22328fc63f797ad3324ed189 + languageName: node + linkType: hard + +"@jest/test-sequencer@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/test-sequencer@npm:29.7.0" + dependencies: + "@jest/test-result": "npm:^29.7.0" + graceful-fs: "npm:^4.2.9" + jest-haste-map: "npm:^29.7.0" + slash: "npm:^3.0.0" + checksum: 10/4420c26a0baa7035c5419b0892ff8ffe9a41b1583ec54a10db3037cd46a7e29dd3d7202f8aa9d376e9e53be5f8b1bc0d16e1de6880a6d319b033b01dc4c8f639 + languageName: node + linkType: hard + +"@jest/transform@npm:^29.7.0": + version: 29.7.0 + resolution: "@jest/transform@npm:29.7.0" + dependencies: + "@babel/core": "npm:^7.11.6" + "@jest/types": "npm:^29.6.3" + "@jridgewell/trace-mapping": "npm:^0.3.18" + babel-plugin-istanbul: "npm:^6.1.1" + chalk: "npm:^4.0.0" + convert-source-map: "npm:^2.0.0" + fast-json-stable-stringify: "npm:^2.1.0" + graceful-fs: "npm:^4.2.9" + jest-haste-map: "npm:^29.7.0" + jest-regex-util: "npm:^29.6.3" + jest-util: "npm:^29.7.0" + micromatch: "npm:^4.0.4" + pirates: "npm:^4.0.4" + slash: "npm:^3.0.0" + write-file-atomic: "npm:^4.0.2" + checksum: 10/30f42293545ab037d5799c81d3e12515790bb58513d37f788ce32d53326d0d72ebf5b40f989e6896739aa50a5f77be44686e510966370d58511d5ad2637c68c1 + languageName: node + linkType: hard + "@jest/types@npm:30.3.0": version: 30.3.0 resolution: "@jest/types@npm:30.3.0" @@ -3849,9 +4230,9 @@ __metadata: languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28": - version: 0.3.31 - resolution: "@jridgewell/trace-mapping@npm:0.3.31" +"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": + version: 0.3.25 + resolution: "@jridgewell/trace-mapping@npm:0.3.25" dependencies: "@jridgewell/resolve-uri": "npm:^3.1.0" "@jridgewell/sourcemap-codec": "npm:^1.4.14" @@ -4532,6 +4913,17 @@ __metadata: languageName: node linkType: hard +"@module-federation/bridge-react-webpack-plugin@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/bridge-react-webpack-plugin@npm:0.9.1" + dependencies: + "@module-federation/sdk": "npm:0.9.1" + "@types/semver": "npm:7.5.8" + semver: "npm:7.6.3" + checksum: 10/4ff197741b1bdccf8f9e2236781e5ce3ef434e4207c5462b4b95b044c4c57a3ab3dd4dce48490d9fde5bd06fb855b9918841c7d04306726ee224d3e288074091 + languageName: node + linkType: hard + "@module-federation/cli@npm:0.21.6": version: 0.21.6 resolution: "@module-federation/cli@npm:0.21.6" @@ -4561,6 +4953,20 @@ __metadata: languageName: node linkType: hard +"@module-federation/data-prefetch@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/data-prefetch@npm:0.9.1" + dependencies: + "@module-federation/runtime": "npm:0.9.1" + "@module-federation/sdk": "npm:0.9.1" + fs-extra: "npm:9.1.0" + peerDependencies: + react: ">=16.9.0" + react-dom: ">=16.9.0" + checksum: 10/a3c0e8d77f4d06e3851d041175ef3f55d47ff4069a526b9ac773c8aba71a520a0490653c87cdcf3761e96f9eb9ea16d45026f3aafdf0851c34ff4db6d71ec113 + languageName: node + linkType: hard + "@module-federation/dts-plugin@npm:0.21.6": version: 0.21.6 resolution: "@module-federation/dts-plugin@npm:0.21.6" @@ -4591,6 +4997,36 @@ __metadata: languageName: node linkType: hard +"@module-federation/dts-plugin@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/dts-plugin@npm:0.9.1" + dependencies: + "@module-federation/error-codes": "npm:0.9.1" + "@module-federation/managers": "npm:0.9.1" + "@module-federation/sdk": "npm:0.9.1" + "@module-federation/third-party-dts-extractor": "npm:0.9.1" + adm-zip: "npm:^0.5.10" + ansi-colors: "npm:^4.1.3" + axios: "npm:^1.7.4" + chalk: "npm:3.0.0" + fs-extra: "npm:9.1.0" + isomorphic-ws: "npm:5.0.0" + koa: "npm:2.15.4" + lodash.clonedeepwith: "npm:4.5.0" + log4js: "npm:6.9.1" + node-schedule: "npm:2.1.1" + rambda: "npm:^9.1.0" + ws: "npm:8.18.0" + peerDependencies: + typescript: ^4.9.0 || ^5.0.0 + vue-tsc: ">=1.0.24" + peerDependenciesMeta: + vue-tsc: + optional: true + checksum: 10/e9fd11b150456f2621636587d181f6456fe5cd60a0720843fe1310e350c3ff8ebef02ea87d1bf40dc04a4b4cd65cfb2e9007ca1c20e4e5664142b7c670c4a57d + languageName: node + linkType: hard + "@module-federation/enhanced@npm:^0.21.6": version: 0.21.6 resolution: "@module-federation/enhanced@npm:0.21.6" @@ -4626,6 +5062,37 @@ __metadata: languageName: node linkType: hard +"@module-federation/enhanced@npm:^0.9.0": + version: 0.9.1 + resolution: "@module-federation/enhanced@npm:0.9.1" + dependencies: + "@module-federation/bridge-react-webpack-plugin": "npm:0.9.1" + "@module-federation/data-prefetch": "npm:0.9.1" + "@module-federation/dts-plugin": "npm:0.9.1" + "@module-federation/error-codes": "npm:0.9.1" + "@module-federation/inject-external-runtime-core-plugin": "npm:0.9.1" + "@module-federation/managers": "npm:0.9.1" + "@module-federation/manifest": "npm:0.9.1" + "@module-federation/rspack": "npm:0.9.1" + "@module-federation/runtime-tools": "npm:0.9.1" + "@module-federation/sdk": "npm:0.9.1" + btoa: "npm:^1.2.1" + upath: "npm:2.0.1" + peerDependencies: + typescript: ^4.9.0 || ^5.0.0 + vue-tsc: ">=1.0.24" + webpack: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + vue-tsc: + optional: true + webpack: + optional: true + checksum: 10/a7955711f37ba02a18f3570289dfd8fbed30511b82fcf593e56808559cfd49d8852028aa67950db5e45617d0917536d067d85847892e62c20b68ba6ab40e17c4 + languageName: node + linkType: hard + "@module-federation/error-codes@npm:0.21.6": version: 0.21.6 resolution: "@module-federation/error-codes@npm:0.21.6" @@ -4640,6 +5107,13 @@ __metadata: languageName: node linkType: hard +"@module-federation/error-codes@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/error-codes@npm:0.9.1" + checksum: 10/545aecc606a506ee47f061835e0eaa41b8d1b02f6bf71b36ec9ae85a1b0370af1f7b7cf92a8f52c3c4b35da858653244316de5ab06bea5dac5b92995467631cc + languageName: node + linkType: hard + "@module-federation/inject-external-runtime-core-plugin@npm:0.21.6": version: 0.21.6 resolution: "@module-federation/inject-external-runtime-core-plugin@npm:0.21.6" @@ -4649,6 +5123,15 @@ __metadata: languageName: node linkType: hard +"@module-federation/inject-external-runtime-core-plugin@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/inject-external-runtime-core-plugin@npm:0.9.1" + peerDependencies: + "@module-federation/runtime-tools": 0.9.1 + checksum: 10/931eef6292c278450fc8cdb017073fa0b721796461eee12a254fc60a88a2f17e91395b12371f2c8b3b25b4056fc2dd2b76d1022e679be7353947c3d797e75ea5 + languageName: node + linkType: hard + "@module-federation/managers@npm:0.21.6": version: 0.21.6 resolution: "@module-federation/managers@npm:0.21.6" @@ -4660,6 +5143,17 @@ __metadata: languageName: node linkType: hard +"@module-federation/managers@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/managers@npm:0.9.1" + dependencies: + "@module-federation/sdk": "npm:0.9.1" + find-pkg: "npm:2.0.0" + fs-extra: "npm:9.1.0" + checksum: 10/32c1666244ba98644ab6eccdc844415d1aece1c105f6ba2ff17a3836866e7cdb2f61e556cb5a2b506b898ec709951f318d397f4d153efeff377067237968462f + languageName: node + linkType: hard + "@module-federation/manifest@npm:0.21.6": version: 0.21.6 resolution: "@module-federation/manifest@npm:0.21.6" @@ -4673,6 +5167,19 @@ __metadata: languageName: node linkType: hard +"@module-federation/manifest@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/manifest@npm:0.9.1" + dependencies: + "@module-federation/dts-plugin": "npm:0.9.1" + "@module-federation/managers": "npm:0.9.1" + "@module-federation/sdk": "npm:0.9.1" + chalk: "npm:3.0.0" + find-pkg: "npm:2.0.0" + checksum: 10/539b86bd5388296fb35a34c7b732b92788600ab6625d53f11588ad67c3a603ac3c1974541d9cf04db2d24635be1610414c29388e849d96bbb812cad3b1c79425 + languageName: node + linkType: hard + "@module-federation/rspack@npm:0.21.6": version: 0.21.6 resolution: "@module-federation/rspack@npm:0.21.6" @@ -4698,6 +5205,30 @@ __metadata: languageName: node linkType: hard +"@module-federation/rspack@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/rspack@npm:0.9.1" + dependencies: + "@module-federation/bridge-react-webpack-plugin": "npm:0.9.1" + "@module-federation/dts-plugin": "npm:0.9.1" + "@module-federation/inject-external-runtime-core-plugin": "npm:0.9.1" + "@module-federation/managers": "npm:0.9.1" + "@module-federation/manifest": "npm:0.9.1" + "@module-federation/runtime-tools": "npm:0.9.1" + "@module-federation/sdk": "npm:0.9.1" + peerDependencies: + "@rspack/core": ">=0.7" + typescript: ^4.9.0 || ^5.0.0 + vue-tsc: ">=1.0.24" + peerDependenciesMeta: + typescript: + optional: true + vue-tsc: + optional: true + checksum: 10/e6deb7236ccc66d7f0475a09916ec714c9855847bfd3d3ec6cdbee991016a222a22f6ae3fd14d71351d55e22e8949140f37ce9ce79dece5416731c6698726096 + languageName: node + linkType: hard + "@module-federation/runtime-core@npm:0.21.6": version: 0.21.6 resolution: "@module-federation/runtime-core@npm:0.21.6" @@ -4718,6 +5249,16 @@ __metadata: languageName: node linkType: hard +"@module-federation/runtime-core@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/runtime-core@npm:0.9.1" + dependencies: + "@module-federation/error-codes": "npm:0.9.1" + "@module-federation/sdk": "npm:0.9.1" + checksum: 10/6f9edbe23013395d7896fc2a24cb4055bc78df5a335f090e079df951835c1cf91c567228f19879eee3fddb0b34128abd0b50feaca1cf3fb2828c7b9bacc22169 + languageName: node + linkType: hard + "@module-federation/runtime-tools@npm:0.21.6": version: 0.21.6 resolution: "@module-federation/runtime-tools@npm:0.21.6" @@ -4738,6 +5279,16 @@ __metadata: languageName: node linkType: hard +"@module-federation/runtime-tools@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/runtime-tools@npm:0.9.1" + dependencies: + "@module-federation/runtime": "npm:0.9.1" + "@module-federation/webpack-bundler-runtime": "npm:0.9.1" + checksum: 10/9436e814a4ab72839b8aed1aa097f32cf7d4d49728dd863c9ce6dc4fb149fe49da6dc9cdeb97814f0023cc91489c9aca06cbfdf9fb4e43d20498ab6ee78c95dd + languageName: node + linkType: hard + "@module-federation/runtime@npm:0.21.6, @module-federation/runtime@npm:^0.21.6": version: 0.21.6 resolution: "@module-federation/runtime@npm:0.21.6" @@ -4760,6 +5311,17 @@ __metadata: languageName: node linkType: hard +"@module-federation/runtime@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/runtime@npm:0.9.1" + dependencies: + "@module-federation/error-codes": "npm:0.9.1" + "@module-federation/runtime-core": "npm:0.9.1" + "@module-federation/sdk": "npm:0.9.1" + checksum: 10/71eb1c3e81b307ebfe06c43ce70bfa56b217e9dfbed27f0b4235d3d0d05cc0fe2eb1dc57fffb3260ed9e0239257ef117ae13924c642b5ff97d9c65bdf48206fe + languageName: node + linkType: hard + "@module-federation/sdk@npm:0.21.6": version: 0.21.6 resolution: "@module-federation/sdk@npm:0.21.6" @@ -4774,6 +5336,13 @@ __metadata: languageName: node linkType: hard +"@module-federation/sdk@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/sdk@npm:0.9.1" + checksum: 10/ea0320feff328a05405e65503d1df28e46a9ad17ef99b77f1428db5c89efbadd2a76ec82d99a54ac1d21286cee6d9ddbba881a9c46748dfe8abdb11e9afef7da + languageName: node + linkType: hard + "@module-federation/third-party-dts-extractor@npm:0.21.6": version: 0.21.6 resolution: "@module-federation/third-party-dts-extractor@npm:0.21.6" @@ -4785,6 +5354,17 @@ __metadata: languageName: node linkType: hard +"@module-federation/third-party-dts-extractor@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/third-party-dts-extractor@npm:0.9.1" + dependencies: + find-pkg: "npm:2.0.0" + fs-extra: "npm:9.1.0" + resolve: "npm:1.22.8" + checksum: 10/68c70c79573cd927212d95879aa7b35490519d0ec9f58dd264c9d61e22fea8d452e45a52a94155128d8378e5cdcaecb229707b5b0f4e4c0d53ae96e2fbac366a + languageName: node + linkType: hard + "@module-federation/webpack-bundler-runtime@npm:0.21.6": version: 0.21.6 resolution: "@module-federation/webpack-bundler-runtime@npm:0.21.6" @@ -4805,10 +5385,10 @@ __metadata: languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.18.0": - version: 5.18.0 - resolution: "@mui/core-downloads-tracker@npm:5.18.0" - checksum: 10/065b46739d2bd84b880ad2f6a0a2062d60e3a296ce18ff380cad22ab5b2cb3de396755f322f4bea3a422ffffe1a9244536fc3c9623056ff3873c996e6664b1b9 +"@mui/core-downloads-tracker@npm:^5.17.1": + version: 5.17.1 + resolution: "@mui/core-downloads-tracker@npm:5.17.1" + checksum: 10/40a697aa031f089dde29812563320221efa1ec18840b0d0b744ba8846b558146d58910b5b4e67b7eb1942c6817ffc389b4b6b28456c762d39d250bc1e54423f7 languageName: node linkType: hard @@ -5052,6 +5632,13 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:1.4.0": + version: 1.4.0 + resolution: "@noble/hashes@npm:1.4.0" + checksum: 10/e156e65794c473794c52fa9d06baf1eb20903d0d96719530f523cc4450f6c721a957c544796e6efd0197b2296e7cd70efeb312f861465e17940a3e3c7e0febc6 + languageName: node + linkType: hard + "@noble/hashes@npm:^1.1.5": version: 1.8.0 resolution: "@noble/hashes@npm:1.8.0" @@ -5226,7 +5813,17 @@ __metadata: languageName: node linkType: hard -"@octokit/core@npm:^4.2.1": +"@octokit/auth-unauthenticated@npm:^3.0.0": + version: 3.0.5 + resolution: "@octokit/auth-unauthenticated@npm:3.0.5" + dependencies: + "@octokit/request-error": "npm:^3.0.0" + "@octokit/types": "npm:^9.0.0" + checksum: 10/30f327c66118b09f4c1698e404f2b41e2540925ba1e41d728a25172fa7dcd5f005b64062bbaa05c5b5423b896b3fe5de7078264c526dda9cacec4d792aacacf5 + languageName: node + linkType: hard + +"@octokit/core@npm:^4.0.0, @octokit/core@npm:^4.2.1": version: 4.2.4 resolution: "@octokit/core@npm:4.2.4" dependencies: @@ -5262,9 +5859,19 @@ __metadata: languageName: node linkType: hard -"@octokit/graphql@npm:^5.0.0": - version: 5.0.6 - resolution: "@octokit/graphql@npm:5.0.6" +"@octokit/graphql-schema@npm:^13.7.0": + version: 13.10.0 + resolution: "@octokit/graphql-schema@npm:13.10.0" + dependencies: + graphql: "npm:^16.0.0" + graphql-tag: "npm:^2.10.3" + checksum: 10/c8714a9dc8f36d01e3db125e570a95030faeaf6c815811be2190ce288691bfcc5e939d161b33ef91b4c9fbca21663bace53d3eea2115a443de27a51b5dbfe2a4 + languageName: node + linkType: hard + +"@octokit/graphql@npm:^5.0.0": + version: 5.0.6 + resolution: "@octokit/graphql@npm:5.0.6" dependencies: "@octokit/request": "npm:^6.0.0" "@octokit/types": "npm:^9.0.0" @@ -5273,6 +5880,23 @@ __metadata: languageName: node linkType: hard +"@octokit/oauth-app@npm:^4.2.0": + version: 4.2.4 + resolution: "@octokit/oauth-app@npm:4.2.4" + dependencies: + "@octokit/auth-oauth-app": "npm:^5.0.0" + "@octokit/auth-oauth-user": "npm:^2.0.0" + "@octokit/auth-unauthenticated": "npm:^3.0.0" + "@octokit/core": "npm:^4.0.0" + "@octokit/oauth-authorization-url": "npm:^5.0.0" + "@octokit/oauth-methods": "npm:^2.0.0" + "@types/aws-lambda": "npm:^8.10.83" + fromentries: "npm:^1.3.1" + universal-user-agent: "npm:^6.0.0" + checksum: 10/1c9e48b56fb4cf3428b8967335b46cedf7740d27932ea394530d07deffa8c3bff5ceef8d14bf145b3bfc64ad1088f4ddf46ceca2a4c052f267c3faa12188ef14 + languageName: node + linkType: hard + "@octokit/oauth-authorization-url@npm:^5.0.0": version: 5.0.0 resolution: "@octokit/oauth-authorization-url@npm:5.0.0" @@ -5763,6 +6387,151 @@ __metadata: languageName: node linkType: hard +"@peculiar/asn1-cms@npm:^2.6.0, @peculiar/asn1-cms@npm:^2.6.1": + version: 2.6.1 + resolution: "@peculiar/asn1-cms@npm:2.6.1" + dependencies: + "@peculiar/asn1-schema": "npm:^2.6.0" + "@peculiar/asn1-x509": "npm:^2.6.1" + "@peculiar/asn1-x509-attr": "npm:^2.6.1" + asn1js: "npm:^3.0.6" + tslib: "npm:^2.8.1" + checksum: 10/e431f6229b98c63a929538d266488e8c2dddc895936117da8f9ec775558e08c20ded6a4adcca4bb88bfea282e7204d4f6bba7a46da2cced162c174e1e6964f36 + languageName: node + linkType: hard + +"@peculiar/asn1-csr@npm:^2.6.0": + version: 2.6.1 + resolution: "@peculiar/asn1-csr@npm:2.6.1" + dependencies: + "@peculiar/asn1-schema": "npm:^2.6.0" + "@peculiar/asn1-x509": "npm:^2.6.1" + asn1js: "npm:^3.0.6" + tslib: "npm:^2.8.1" + checksum: 10/4ac2f1c3a2cb392fcdd5aa602140abe90f849af0a9e8296aab9aaf1712ee2e0c4f5fa86b0fe83975e771b0aba91fc848670f9c2008ea1e850c849fae6e181179 + languageName: node + linkType: hard + +"@peculiar/asn1-ecc@npm:^2.6.0": + version: 2.6.1 + resolution: "@peculiar/asn1-ecc@npm:2.6.1" + dependencies: + "@peculiar/asn1-schema": "npm:^2.6.0" + "@peculiar/asn1-x509": "npm:^2.6.1" + asn1js: "npm:^3.0.6" + tslib: "npm:^2.8.1" + checksum: 10/baa646c1c86283d5876230b1cfbd80cf42f97b3bb8d8b23cd5830f6f8d6466e6a06887c6838f3c4c61c87df9ffd2abe905f555472e8e70d722ce964a8074d838 + languageName: node + linkType: hard + +"@peculiar/asn1-pfx@npm:^2.6.1": + version: 2.6.1 + resolution: "@peculiar/asn1-pfx@npm:2.6.1" + dependencies: + "@peculiar/asn1-cms": "npm:^2.6.1" + "@peculiar/asn1-pkcs8": "npm:^2.6.1" + "@peculiar/asn1-rsa": "npm:^2.6.1" + "@peculiar/asn1-schema": "npm:^2.6.0" + asn1js: "npm:^3.0.6" + tslib: "npm:^2.8.1" + checksum: 10/50adc7db96928d98b85a1a2e6765ba1d4ec708f937b8172ea6a22e3b92137ea36d656aded64b3be661db39f924102c5a80da54ee647e2441af3bc19c55a183ef + languageName: node + linkType: hard + +"@peculiar/asn1-pkcs8@npm:^2.6.1": + version: 2.6.1 + resolution: "@peculiar/asn1-pkcs8@npm:2.6.1" + dependencies: + "@peculiar/asn1-schema": "npm:^2.6.0" + "@peculiar/asn1-x509": "npm:^2.6.1" + asn1js: "npm:^3.0.6" + tslib: "npm:^2.8.1" + checksum: 10/99c4326da30e7ef17bb8e92d8a9525b78c101e4d743493000e220f3da6bbc4755371f1dbcc2a36951fb15769c2efead20d90a08918fd268c21bebcac26e71053 + languageName: node + linkType: hard + +"@peculiar/asn1-pkcs9@npm:^2.6.0": + version: 2.6.1 + resolution: "@peculiar/asn1-pkcs9@npm:2.6.1" + dependencies: + "@peculiar/asn1-cms": "npm:^2.6.1" + "@peculiar/asn1-pfx": "npm:^2.6.1" + "@peculiar/asn1-pkcs8": "npm:^2.6.1" + "@peculiar/asn1-schema": "npm:^2.6.0" + "@peculiar/asn1-x509": "npm:^2.6.1" + "@peculiar/asn1-x509-attr": "npm:^2.6.1" + asn1js: "npm:^3.0.6" + tslib: "npm:^2.8.1" + checksum: 10/61759a50d6adf108a0376735b2e76cdfc9c41db39a7abed23ca332f7699d831aa6324534aa38153018a31e6ee5e8fef85534c92b68067f6afcb90787e953c449 + languageName: node + linkType: hard + +"@peculiar/asn1-rsa@npm:^2.6.0, @peculiar/asn1-rsa@npm:^2.6.1": + version: 2.6.1 + resolution: "@peculiar/asn1-rsa@npm:2.6.1" + dependencies: + "@peculiar/asn1-schema": "npm:^2.6.0" + "@peculiar/asn1-x509": "npm:^2.6.1" + asn1js: "npm:^3.0.6" + tslib: "npm:^2.8.1" + checksum: 10/e91efe57017feac71c69ee5950e9c323b45aaf10baa32153fe88f237948f9d906ba04c645d085c4293c90440cad95392a91b3760251cd0ebc8e4c1a383fc331a + languageName: node + linkType: hard + +"@peculiar/asn1-schema@npm:^2.6.0": + version: 2.6.0 + resolution: "@peculiar/asn1-schema@npm:2.6.0" + dependencies: + asn1js: "npm:^3.0.6" + pvtsutils: "npm:^1.3.6" + tslib: "npm:^2.8.1" + checksum: 10/af9b1094d0e020f0fd828777488578322d62a41f597ead7d80939dafcfe35b672fcb0ec7460ef66b2a155f9614d4340a98896d417a830aff1685cb4c21d5bbe4 + languageName: node + linkType: hard + +"@peculiar/asn1-x509-attr@npm:^2.6.1": + version: 2.6.1 + resolution: "@peculiar/asn1-x509-attr@npm:2.6.1" + dependencies: + "@peculiar/asn1-schema": "npm:^2.6.0" + "@peculiar/asn1-x509": "npm:^2.6.1" + asn1js: "npm:^3.0.6" + tslib: "npm:^2.8.1" + checksum: 10/86f7d5495459dee81daadd830ebb7d26ec15a98f6479c88b90a915ac9f28105b0d5003ba0c382b4aa8f7fa42e399f7cc37e4fe73c26cbaacd47e63a50b132e25 + languageName: node + linkType: hard + +"@peculiar/asn1-x509@npm:^2.6.0, @peculiar/asn1-x509@npm:^2.6.1": + version: 2.6.1 + resolution: "@peculiar/asn1-x509@npm:2.6.1" + dependencies: + "@peculiar/asn1-schema": "npm:^2.6.0" + asn1js: "npm:^3.0.6" + pvtsutils: "npm:^1.3.6" + tslib: "npm:^2.8.1" + checksum: 10/e3187ad04d397cdd6a946895a51202b67f57992dfef55e40acc7e7ea325e2854267ed2581c4b1ea729d7147e9e8e6f34af77f1ffb48e3e8b25b2216b213b4641 + languageName: node + linkType: hard + +"@peculiar/x509@npm:^1.14.2": + version: 1.14.3 + resolution: "@peculiar/x509@npm:1.14.3" + dependencies: + "@peculiar/asn1-cms": "npm:^2.6.0" + "@peculiar/asn1-csr": "npm:^2.6.0" + "@peculiar/asn1-ecc": "npm:^2.6.0" + "@peculiar/asn1-pkcs9": "npm:^2.6.0" + "@peculiar/asn1-rsa": "npm:^2.6.0" + "@peculiar/asn1-schema": "npm:^2.6.0" + "@peculiar/asn1-x509": "npm:^2.6.0" + pvtsutils: "npm:^1.3.6" + reflect-metadata: "npm:^0.2.2" + tslib: "npm:^2.8.1" + tsyringe: "npm:^4.10.0" + checksum: 10/d37c56fa5f2c644141948d85010e14f0e4963089e3b0b81edd0bfe85bdfea0eb3f38ab6ff20d322db2bd6977117824cc498a77b2d35af111983b4d58b5e2ccd1 + languageName: node + linkType: hard + "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -5770,25 +6539,26 @@ __metadata: languageName: node linkType: hard -"@pmmmwh/react-refresh-webpack-plugin@npm:^0.6.0": - version: 0.6.2 - resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.6.2" +"@pmmmwh/react-refresh-webpack-plugin@npm:^0.5.7": + version: 0.5.17 + resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.5.17" dependencies: - anser: "npm:^2.1.1" + ansi-html: "npm:^0.0.9" core-js-pure: "npm:^3.23.3" error-stack-parser: "npm:^2.0.6" html-entities: "npm:^2.1.0" + loader-utils: "npm:^2.0.4" schema-utils: "npm:^4.2.0" source-map: "npm:^0.7.3" peerDependencies: - "@types/webpack": 5.x + "@types/webpack": 4.x || 5.x react-refresh: ">=0.10.0 <1.0.0" sockjs-client: ^1.4.0 - type-fest: ">=0.17.0 <6.0.0" - webpack: ^5.0.0 - webpack-dev-server: ^4.8.0 || 5.x + type-fest: ">=0.17.0 <5.0.0" + webpack: ">=4.43.0 <6.0.0" + webpack-dev-server: 3.x || 4.x || 5.x webpack-hot-middleware: 2.x - webpack-plugin-serve: 1.x + webpack-plugin-serve: 0.x || 1.x peerDependenciesMeta: "@types/webpack": optional: true @@ -5802,7 +6572,7 @@ __metadata: optional: true webpack-plugin-serve: optional: true - checksum: 10/157a20464b0bdca39b31e09450f6ce1d91cbe32bcce882a02df797482b0226247d13e5a2c750a3fb2e2758bffc25d49a468b33b66d8364aa4e1ed785596453c8 + checksum: 10/3fbeb07dc6cfbbae9ba3e4e1d23e71b5783281830a5441c4c577a9c015c1b9e260917d3efc697c43d9981e4d3e3609abf48601fe855caf9931dfb8fc5ee3a948 languageName: node linkType: hard @@ -7704,6 +8474,16 @@ __metadata: languageName: node linkType: hard +"@rollup/pluginutils@npm:^4.2.1": + version: 4.2.1 + resolution: "@rollup/pluginutils@npm:4.2.1" + dependencies: + estree-walker: "npm:^2.0.1" + picomatch: "npm:^2.2.2" + checksum: 10/503a6f0a449e11a2873ac66cfdfb9a3a0b77ffa84c5cad631f5e4bc1063c850710e8d5cd5dab52477c0d66cda2ec719865726dbe753318cd640bab3fff7ca476 + languageName: node + linkType: hard + "@rollup/pluginutils@npm:^5.0.1, @rollup/pluginutils@npm:^5.1.0": version: 5.3.0 resolution: "@rollup/pluginutils@npm:5.3.0" @@ -8175,9 +8955,9 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^4.2.12": - version: 4.2.12 - resolution: "@smithy/abort-controller@npm:4.2.12" +"@smithy/abort-controller@npm:^4.0.4": + version: 4.0.4 + resolution: "@smithy/abort-controller@npm:4.0.4" dependencies: "@smithy/types": "npm:^4.13.1" tslib: "npm:^2.6.2" @@ -9096,9 +9876,9 @@ __metadata: languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.15.21": - version: 1.15.21 - resolution: "@swc/core-darwin-arm64@npm:1.15.21" +"@swc/core-darwin-arm64@npm:1.15.18": + version: 1.15.18 + resolution: "@swc/core-darwin-arm64@npm:1.15.18" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -9181,8 +9961,8 @@ __metadata: linkType: hard "@swc/core@npm:^1.15.6": - version: 1.15.21 - resolution: "@swc/core@npm:1.15.21" + version: 1.15.18 + resolution: "@swc/core@npm:1.15.18" dependencies: "@swc/core-darwin-arm64": "npm:1.15.21" "@swc/core-darwin-x64": "npm:1.15.21" @@ -9248,7 +10028,7 @@ __metadata: languageName: node linkType: hard -"@swc/jest@npm:^0.2.39": +"@swc/jest@npm:^0.2.22, @swc/jest@npm:^0.2.39": version: 0.2.39 resolution: "@swc/jest@npm:0.2.39" dependencies: @@ -9432,6 +10212,54 @@ __metadata: languageName: node linkType: hard +"@types/aws-lambda@npm:^8.10.83": + version: 8.10.161 + resolution: "@types/aws-lambda@npm:8.10.161" + checksum: 10/0ded8b107765dcf7f04a551d2ec174863c060d58194615cba2e85b2e0e1ba0a6e8fbdb1e2ebe33b27b42e973c5d2ae76751ac55cb61d4dead6444e6b27064c77 + languageName: node + linkType: hard + +"@types/babel__core@npm:^7.1.14": + version: 7.20.5 + resolution: "@types/babel__core@npm:7.20.5" + dependencies: + "@babel/parser": "npm:^7.20.7" + "@babel/types": "npm:^7.20.7" + "@types/babel__generator": "npm:*" + "@types/babel__template": "npm:*" + "@types/babel__traverse": "npm:*" + checksum: 10/c32838d280b5ab59d62557f9e331d3831f8e547ee10b4f85cb78753d97d521270cebfc73ce501e9fb27fe71884d1ba75e18658692c2f4117543f0fc4e3e118b3 + languageName: node + linkType: hard + +"@types/babel__generator@npm:*": + version: 7.27.0 + resolution: "@types/babel__generator@npm:7.27.0" + dependencies: + "@babel/types": "npm:^7.0.0" + checksum: 10/f572e67a9a39397664350a4437d8a7fbd34acc83ff4887a8cf08349e39f8aeb5ad2f70fb78a0a0a23a280affe3a5f4c25f50966abdce292bcf31237af1c27b1a + languageName: node + linkType: hard + +"@types/babel__template@npm:*": + version: 7.4.4 + resolution: "@types/babel__template@npm:7.4.4" + dependencies: + "@babel/parser": "npm:^7.1.0" + "@babel/types": "npm:^7.0.0" + checksum: 10/d7a02d2a9b67e822694d8e6a7ddb8f2b71a1d6962dfd266554d2513eefbb205b33ca71a0d163b1caea3981ccf849211f9964d8bd0727124d18ace45aa6c9ae29 + languageName: node + linkType: hard + +"@types/babel__traverse@npm:*, @types/babel__traverse@npm:^7.0.6": + version: 7.28.0 + resolution: "@types/babel__traverse@npm:7.28.0" + dependencies: + "@babel/types": "npm:^7.28.2" + checksum: 10/371c5e1b40399ef17570e630b2943617b84fafde2860a56f0ebc113d8edb1d0534ade0175af89eda1ae35160903c33057ed42457e165d4aa287fedab2c82abcf + languageName: node + linkType: hard + "@types/body-parser@npm:*": version: 1.19.6 resolution: "@types/body-parser@npm:1.19.6" @@ -9566,6 +10394,26 @@ __metadata: languageName: node linkType: hard +"@types/eslint-scope@npm:^3.7.7": + version: 3.7.7 + resolution: "@types/eslint-scope@npm:3.7.7" + dependencies: + "@types/eslint": "npm:*" + "@types/estree": "npm:*" + checksum: 10/e2889a124aaab0b89af1bab5959847c5bec09809209255de0e63b9f54c629a94781daa04adb66bffcdd742f5e25a17614fb933965093c0eea64aacda4309380e + languageName: node + linkType: hard + +"@types/eslint@npm:*": + version: 9.6.1 + resolution: "@types/eslint@npm:9.6.1" + dependencies: + "@types/estree": "npm:*" + "@types/json-schema": "npm:*" + checksum: 10/719fcd255760168a43d0e306ef87548e1e15bffe361d5f4022b0f266575637acc0ecb85604ac97879ee8ae83c6a6d0613b0ed31d0209ddf22a0fe6d608fc56fe + languageName: node + linkType: hard + "@types/eslint@npm:^8.56.10": version: 8.56.12 resolution: "@types/eslint@npm:8.56.12" @@ -9585,6 +10433,7 @@ __metadata: languageName: node linkType: hard +"@types/estree@npm:*, @types/estree@npm:1.0.8, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.8": "@types/estree@npm:*, @types/estree@npm:1.0.8, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.8": version: 1.0.8 resolution: "@types/estree@npm:1.0.8" @@ -9639,6 +10488,15 @@ __metadata: languageName: node linkType: hard +"@types/graceful-fs@npm:^4.1.3": + version: 4.1.9 + resolution: "@types/graceful-fs@npm:4.1.9" + dependencies: + "@types/node": "npm:*" + checksum: 10/79d746a8f053954bba36bd3d94a90c78de995d126289d656fb3271dd9f1229d33f678da04d10bce6be440494a5a73438e2e363e92802d16b8315b051036c5256 + languageName: node + linkType: hard + "@types/hast@npm:^2.0.0": version: 2.3.10 resolution: "@types/hast@npm:2.3.10" @@ -9691,7 +10549,7 @@ __metadata: languageName: node linkType: hard -"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.6": +"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.1, @types/istanbul-lib-coverage@npm:^2.0.6": version: 2.0.6 resolution: "@types/istanbul-lib-coverage@npm:2.0.6" checksum: 10/3feac423fd3e5449485afac999dcfcb3d44a37c830af898b689fadc65d26526460bedb889db278e0d4d815a670331796494d073a10ee6e3a6526301fe7415778 @@ -9716,6 +10574,16 @@ __metadata: languageName: node linkType: hard +"@types/jest@npm:^29.5.11": + version: 29.5.14 + resolution: "@types/jest@npm:29.5.14" + dependencies: + expect: "npm:^29.0.0" + pretty-format: "npm:^29.0.0" + checksum: 10/59ec7a9c4688aae8ee529316c43853468b6034f453d08a2e1064b281af9c81234cec986be796288f1bbb29efe943bc950e70c8fa8faae1e460d50e3cf9760f9b + languageName: node + linkType: hard + "@types/js-cookie@npm:^2.2.6": version: 2.2.7 resolution: "@types/js-cookie@npm:2.2.7" @@ -9723,6 +10591,17 @@ __metadata: languageName: node linkType: hard +"@types/jsdom@npm:^20.0.0": + version: 20.0.1 + resolution: "@types/jsdom@npm:20.0.1" + dependencies: + "@types/node": "npm:*" + "@types/tough-cookie": "npm:*" + parse5: "npm:^7.0.0" + checksum: 10/15fbb9a0bfb4a5845cf6e795f2fd12400aacfca53b8c7e5bca4a3e5e8fa8629f676327964d64258aefb127d2d8a2be86dad46359efbfca0e8c9c2b790e7f8a88 + languageName: node + linkType: hard + "@types/json-schema@npm:*, @types/json-schema@npm:^7.0.11, @types/json-schema@npm:^7.0.15, @types/json-schema@npm:^7.0.4, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.6, @types/json-schema@npm:^7.0.7, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" @@ -10094,6 +10973,13 @@ __metadata: languageName: node linkType: hard +"@types/stack-utils@npm:^2.0.0": + version: 2.0.3 + resolution: "@types/stack-utils@npm:2.0.3" + checksum: 10/72576cc1522090fe497337c2b99d9838e320659ac57fa5560fcbdcbafcf5d0216c6b3a0a8a4ee4fdb3b1f5e3420aa4f6223ab57b82fef3578bec3206425c6cf5 + languageName: node + linkType: hard + "@types/styled-jsx@npm:^2.2.8": version: 2.2.9 resolution: "@types/styled-jsx@npm:2.2.9" @@ -10607,22 +11493,187 @@ __metadata: languageName: node linkType: hard -"@xobotyi/scrollbar-width@npm:^1.9.5": - version: 1.9.5 - resolution: "@xobotyi/scrollbar-width@npm:1.9.5" - checksum: 10/026ccd174ec3ce032f42794c7e2ee9dab3cfee4f8f9d6ce4f2b4a2fe50cbf8be7406583fb2e203707c699690c5d40a13ee1611f1f67f6ceb01ac2a543acadc30 +"@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/ast@npm:1.14.1" + dependencies: + "@webassemblyjs/helper-numbers": "npm:1.13.2" + "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" + checksum: 10/f83e6abe38057f5d87c1fb356513a371a8b43c9b87657f2790741a66b1ef8ecf958d1391bc42f27c5fb33f58ab8286a38ea849fdd21f433cd4df1307424bab45 languageName: node linkType: hard -"@xtuc/ieee754@npm:^1.2.0": - version: 1.2.0 - resolution: "@xtuc/ieee754@npm:1.2.0" - checksum: 10/ab033b032927d77e2f9fa67accdf31b1ca7440974c21c9cfabc8349e10ca2817646171c4f23be98d0e31896d6c2c3462a074fe37752e523abc3e45c79254259c +"@webassemblyjs/floating-point-hex-parser@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.13.2" + checksum: 10/e866ec8433f4a70baa511df5e8f2ebcd6c24f4e2cc6274c7c5aabe2bcce3459ea4680e0f35d450e1f3602acf3913b6b8e4f15069c8cfd34ae8609fb9a7d01795 languageName: node linkType: hard -"@xtuc/long@npm:4.2.2": - version: 4.2.2 +"@webassemblyjs/helper-api-error@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/helper-api-error@npm:1.13.2" + checksum: 10/48b5df7fd3095bb252f59a139fe2cbd999a62ac9b488123e9a0da3906ad8a2f2da7b2eb21d328c01a90da987380928706395c2897d1f3ed9e2125b6d75a920d0 + languageName: node + linkType: hard + +"@webassemblyjs/helper-buffer@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/helper-buffer@npm:1.14.1" + checksum: 10/9690afeafa5e765a34620aa6216e9d40f9126d4e37e9726a2594bf60cab6b211ef20ab6670fd3c4449dd4a3497e69e49b2b725c8da0fb213208c7f45f15f5d5b + languageName: node + linkType: hard + +"@webassemblyjs/helper-numbers@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/helper-numbers@npm:1.13.2" + dependencies: + "@webassemblyjs/floating-point-hex-parser": "npm:1.13.2" + "@webassemblyjs/helper-api-error": "npm:1.13.2" + "@xtuc/long": "npm:4.2.2" + checksum: 10/e4c7d0b09811e1cda8eec644a022b560b28f4e974f50195375ccd007df5ee48a922a6dcff5ac40b6a8ec850d56d0ea6419318eee49fec7819ede14e90417a6a4 + languageName: node + linkType: hard + +"@webassemblyjs/helper-wasm-bytecode@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.13.2" + checksum: 10/3edd191fff7296df1ef3b023bdbe6cb5ea668f6386fd197ccfce46015c6f2a8cc9763cfb86503a0b94973ad27996645afff2252ee39a236513833259a47af6ed + languageName: node + linkType: hard + +"@webassemblyjs/helper-wasm-section@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/helper-wasm-section@npm:1.14.1" + dependencies: + "@webassemblyjs/ast": "npm:1.14.1" + "@webassemblyjs/helper-buffer": "npm:1.14.1" + "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" + "@webassemblyjs/wasm-gen": "npm:1.14.1" + checksum: 10/6b73874f906532512371181d7088460f767966f26309e836060c5a8e4e4bfe6d523fb5f4c034b34aa22ebb1192815f95f0e264298769485c1f0980fdd63ae0ce + languageName: node + linkType: hard + +"@webassemblyjs/ieee754@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/ieee754@npm:1.13.2" + dependencies: + "@xtuc/ieee754": "npm:^1.2.0" + checksum: 10/d7e3520baa37a7309fa7db4d73d69fb869878853b1ebd4b168821bd03fcc4c0e1669c06231315b0039035d9a7a462e53de3ad982da4a426a4b0743b5888e8673 + languageName: node + linkType: hard + +"@webassemblyjs/leb128@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/leb128@npm:1.13.2" + dependencies: + "@xtuc/long": "npm:4.2.2" + checksum: 10/3a10542c86807061ec3230bac8ee732289c852b6bceb4b88ebd521a12fbcecec7c432848284b298154f28619e2746efbed19d6904aef06c49ef20a0b85f650cf + languageName: node + linkType: hard + +"@webassemblyjs/utf8@npm:1.13.2": + version: 1.13.2 + resolution: "@webassemblyjs/utf8@npm:1.13.2" + checksum: 10/27885e5d19f339501feb210867d69613f281eda695ac508f04d69fa3398133d05b6870969c0242b054dc05420ed1cc49a64dea4fe0588c18d211cddb0117cc54 + languageName: node + linkType: hard + +"@webassemblyjs/wasm-edit@npm:^1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wasm-edit@npm:1.14.1" + dependencies: + "@webassemblyjs/ast": "npm:1.14.1" + "@webassemblyjs/helper-buffer": "npm:1.14.1" + "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" + "@webassemblyjs/helper-wasm-section": "npm:1.14.1" + "@webassemblyjs/wasm-gen": "npm:1.14.1" + "@webassemblyjs/wasm-opt": "npm:1.14.1" + "@webassemblyjs/wasm-parser": "npm:1.14.1" + "@webassemblyjs/wast-printer": "npm:1.14.1" + checksum: 10/c62c50eadcf80876713f8c9f24106b18cf208160ab842fcb92060fd78c37bf37e7fcf0b7cbf1afc05d230277c2ce0f3f728432082c472dd1293e184a95f9dbdd + languageName: node + linkType: hard + +"@webassemblyjs/wasm-gen@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wasm-gen@npm:1.14.1" + dependencies: + "@webassemblyjs/ast": "npm:1.14.1" + "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" + "@webassemblyjs/ieee754": "npm:1.13.2" + "@webassemblyjs/leb128": "npm:1.13.2" + "@webassemblyjs/utf8": "npm:1.13.2" + checksum: 10/6085166b0987d3031355fe17a4f9ef0f412e08098d95454059aced2bd72a4c3df2bc099fa4d32d640551fc3eca1ac1a997b44432e46dc9d84642688e42c17ed4 + languageName: node + linkType: hard + +"@webassemblyjs/wasm-opt@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wasm-opt@npm:1.14.1" + dependencies: + "@webassemblyjs/ast": "npm:1.14.1" + "@webassemblyjs/helper-buffer": "npm:1.14.1" + "@webassemblyjs/wasm-gen": "npm:1.14.1" + "@webassemblyjs/wasm-parser": "npm:1.14.1" + checksum: 10/fa5d1ef8d2156e7390927f938f513b7fb4440dd6804b3d6c8622b7b1cf25a3abf1a5809f615896d4918e04b27b52bc3cbcf18faf2d563cb563ae0a9204a492db + languageName: node + linkType: hard + +"@webassemblyjs/wasm-parser@npm:1.14.1, @webassemblyjs/wasm-parser@npm:^1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wasm-parser@npm:1.14.1" + dependencies: + "@webassemblyjs/ast": "npm:1.14.1" + "@webassemblyjs/helper-api-error": "npm:1.13.2" + "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" + "@webassemblyjs/ieee754": "npm:1.13.2" + "@webassemblyjs/leb128": "npm:1.13.2" + "@webassemblyjs/utf8": "npm:1.13.2" + checksum: 10/07d9805fda88a893c984ed93d5a772d20d671e9731358ab61c6c1af8e0e58d1c42fc230c18974dfddebc9d2dd7775d514ba4d445e70080b16478b4b16c39c7d9 + languageName: node + linkType: hard + +"@webassemblyjs/wast-printer@npm:1.14.1": + version: 1.14.1 + resolution: "@webassemblyjs/wast-printer@npm:1.14.1" + dependencies: + "@webassemblyjs/ast": "npm:1.14.1" + "@xtuc/long": "npm:4.2.2" + checksum: 10/cef09aad2fcd291bfcf9efdae2ea1e961a1ba0f925d1d9dcdd8c746d32fbaf431b6d26a0241699c0e39f82139018aa720b4ceb84ac6f4c78f13072747480db69 + languageName: node + linkType: hard + +"@xobotyi/scrollbar-width@npm:^1.9.5": + version: 1.9.5 + resolution: "@xobotyi/scrollbar-width@npm:1.9.5" + checksum: 10/026ccd174ec3ce032f42794c7e2ee9dab3cfee4f8f9d6ce4f2b4a2fe50cbf8be7406583fb2e203707c699690c5d40a13ee1611f1f67f6ceb01ac2a543acadc30 + languageName: node + linkType: hard + +"@xtuc/ieee754@npm:^1.2.0": + version: 1.2.0 + resolution: "@xtuc/ieee754@npm:1.2.0" + checksum: 10/ab033b032927d77e2f9fa67accdf31b1ca7440974c21c9cfabc8349e10ca2817646171c4f23be98d0e31896d6c2c3462a074fe37752e523abc3e45c79254259c + languageName: node + linkType: hard + +"@xtuc/long@npm:4.2.2": + version: 4.2.2 + resolution: "@xtuc/long@npm:4.2.2" + checksum: 10/7217bae9fe240e0d804969e7b2af11cb04ec608837c78b56ca88831991b287e232a0b7fce8d548beaff42aaf0197ffa471d81be6ac4c4e53b0148025a2c076ec + languageName: node + linkType: hard + +"@xtuc/ieee754@npm:^1.2.0": + version: 1.2.0 + resolution: "@xtuc/ieee754@npm:1.2.0" + checksum: 10/ab033b032927d77e2f9fa67accdf31b1ca7440974c21c9cfabc8349e10ca2817646171c4f23be98d0e31896d6c2c3462a074fe37752e523abc3e45c79254259c + languageName: node + linkType: hard + +"@xtuc/long@npm:4.2.2": + version: 4.2.2 resolution: "@xtuc/long@npm:4.2.2" checksum: 10/7217bae9fe240e0d804969e7b2af11cb04ec608837c78b56ca88831991b287e232a0b7fce8d548beaff42aaf0197ffa471d81be6ac4c4e53b0148025a2c076ec languageName: node @@ -10645,6 +11696,13 @@ __metadata: languageName: node linkType: hard +"abab@npm:^2.0.6": + version: 2.0.6 + resolution: "abab@npm:2.0.6" + checksum: 10/ebe95d7278999e605823fc515a3b05d689bc72e7f825536e73c95ebf621636874c6de1b749b3c4bf866b96ccd4b3a2802efa313d0e45ad51a413c8c73247db20 + languageName: node + linkType: hard + "abbrev@npm:^2.0.0": version: 2.0.0 resolution: "abbrev@npm:2.0.0" @@ -10668,7 +11726,7 @@ __metadata: languageName: node linkType: hard -"accepts@npm:^1.3.8, accepts@npm:~1.3.8": +"accepts@npm:^1.3.8, accepts@npm:~1.3.4, accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" dependencies: @@ -10688,6 +11746,16 @@ __metadata: languageName: node linkType: hard +"acorn-globals@npm:^7.0.0": + version: 7.0.1 + resolution: "acorn-globals@npm:7.0.1" + dependencies: + acorn: "npm:^8.1.0" + acorn-walk: "npm:^8.0.2" + checksum: 10/2a2998a547af6d0db5f0cdb90acaa7c3cbca6709010e02121fb8b8617c0fbd8bab0b869579903fde358ac78454356a14fadcc1a672ecb97b04b1c2ccba955ce8 + languageName: node + linkType: hard + "acorn-import-phases@npm:^1.0.3": version: 1.0.4 resolution: "acorn-import-phases@npm:1.0.4" @@ -10706,7 +11774,7 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.1.1, acorn-walk@npm:^8.3.4": +"acorn-walk@npm:^8.0.2, acorn-walk@npm:^8.1.1, acorn-walk@npm:^8.3.4": version: 8.3.5 resolution: "acorn-walk@npm:8.3.5" dependencies: @@ -10715,7 +11783,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.16.0, acorn@npm:^8.4.1, acorn@npm:^8.9.0": +"acorn@npm:^8.11.0, acorn@npm:^8.14.0, acorn@npm:^8.15.0, acorn@npm:^8.4.1, acorn@npm:^8.9.0": version: 8.16.0 resolution: "acorn@npm:8.16.0" bin: @@ -10889,6 +11957,15 @@ __metadata: languageName: node linkType: hard +"ansi-html@npm:^0.0.9": + version: 0.0.9 + resolution: "ansi-html@npm:0.0.9" + bin: + ansi-html: bin/ansi-html + checksum: 10/3e83fae364d323d9c453f74a21aa29da68ae152e996c66de45a49a445ea362c4e2e9abce0069558239ff23e3d6ae73b5d27993d631382aa83d85f44b687e0aa1 + languageName: node + linkType: hard + "ansi-regex@npm:^4.1.0": version: 4.1.1 resolution: "ansi-regex@npm:4.1.1" @@ -10949,7 +12026,7 @@ __metadata: languageName: node linkType: hard -"anymatch@npm:~3.1.2": +"anymatch@npm:^3.0.3, anymatch@npm:~3.1.2": version: 3.1.3 resolution: "anymatch@npm:3.1.3" dependencies: @@ -11194,6 +12271,17 @@ __metadata: languageName: node linkType: hard +"asn1js@npm:^3.0.6": + version: 3.0.7 + resolution: "asn1js@npm:3.0.7" + dependencies: + pvtsutils: "npm:^1.3.6" + pvutils: "npm:^1.1.3" + tslib: "npm:^2.8.1" + checksum: 10/1ae92cc6825ff002aed5b2a800e89db1fccd0775b42278431332fe3ee6839711e80e1ca504c72a35a03d94d417c3b315fb03bc6a6f4518c309b1dcb5385a1a93 + languageName: node + linkType: hard + "assert@npm:^2.0.0": version: 2.1.0 resolution: "assert@npm:2.1.0" @@ -11306,9 +12394,20 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.12.0, axios@npm:^1.13.6": - version: 1.14.0 - resolution: "axios@npm:1.14.0" +"axios@npm:1.9.0": + version: 1.9.0 + resolution: "axios@npm:1.9.0" + dependencies: + follow-redirects: "npm:^1.15.6" + form-data: "npm:^4.0.0" + proxy-from-env: "npm:^1.1.0" + checksum: 10/a2f90bba56820883879f32a237e2b9ff25c250365dcafd41cec41b3406a3df334a148f90010182dfdadb4b41dc59f6f0b3e8898ff41b666d1157b5f3f4523497 + languageName: node + linkType: hard + +"axios@npm:^1.12.0": + version: 1.13.6 + resolution: "axios@npm:1.13.6" dependencies: follow-redirects: "npm:^1.15.11" form-data: "npm:^4.0.5" @@ -11336,6 +12435,48 @@ __metadata: languageName: node linkType: hard +"babel-jest@npm:^29.7.0": + version: 29.7.0 + resolution: "babel-jest@npm:29.7.0" + dependencies: + "@jest/transform": "npm:^29.7.0" + "@types/babel__core": "npm:^7.1.14" + babel-plugin-istanbul: "npm:^6.1.1" + babel-preset-jest: "npm:^29.6.3" + chalk: "npm:^4.0.0" + graceful-fs: "npm:^4.2.9" + slash: "npm:^3.0.0" + peerDependencies: + "@babel/core": ^7.8.0 + checksum: 10/8a0953bd813b3a8926008f7351611055548869e9a53dd36d6e7e96679001f71e65fd7dbfe253265c3ba6a4e630dc7c845cf3e78b17d758ef1880313ce8fba258 + languageName: node + linkType: hard + +"babel-plugin-istanbul@npm:^6.1.1": + version: 6.1.1 + resolution: "babel-plugin-istanbul@npm:6.1.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.0.0" + "@istanbuljs/load-nyc-config": "npm:^1.0.0" + "@istanbuljs/schema": "npm:^0.1.2" + istanbul-lib-instrument: "npm:^5.0.4" + test-exclude: "npm:^6.0.0" + checksum: 10/ffd436bb2a77bbe1942a33245d770506ab2262d9c1b3c1f1da7f0592f78ee7445a95bc2efafe619dd9c1b6ee52c10033d6c7d29ddefe6f5383568e60f31dfe8d + languageName: node + linkType: hard + +"babel-plugin-jest-hoist@npm:^29.6.3": + version: 29.6.3 + resolution: "babel-plugin-jest-hoist@npm:29.6.3" + dependencies: + "@babel/template": "npm:^7.3.3" + "@babel/types": "npm:^7.3.3" + "@types/babel__core": "npm:^7.1.14" + "@types/babel__traverse": "npm:^7.0.6" + checksum: 10/9bfa86ec4170bd805ab8ca5001ae50d8afcb30554d236ba4a7ffc156c1a92452e220e4acbd98daefc12bf0216fccd092d0a2efed49e7e384ec59e0597a926d65 + languageName: node + linkType: hard + "babel-plugin-macros@npm:^3.1.0": version: 3.1.0 resolution: "babel-plugin-macros@npm:3.1.0" @@ -11347,6 +12488,79 @@ __metadata: languageName: node linkType: hard +"babel-plugin-polyfill-corejs2@npm:^0.4.15": + version: 0.4.17 + resolution: "babel-plugin-polyfill-corejs2@npm:0.4.17" + dependencies: + "@babel/compat-data": "npm:^7.28.6" + "@babel/helper-define-polyfill-provider": "npm:^0.6.8" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 10/35796b7f960d2e90ae78e9eb60491550976b839bbb4ce4c060df822cce191e4b5d93f13f0e64c2ba3ffc6ab3d32d3ced3f84ec567cc141088a11fa5a1628265d + languageName: node + linkType: hard + +"babel-plugin-polyfill-corejs3@npm:^0.14.0": + version: 0.14.2 + resolution: "babel-plugin-polyfill-corejs3@npm:0.14.2" + dependencies: + "@babel/helper-define-polyfill-provider": "npm:^0.6.8" + core-js-compat: "npm:^3.48.0" + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 10/bb500bfec712eb5e8c9058dc299677a5325af7e09ebd725c89719f2f555eca3f2b1a8644137c8e67d7fc83d7be48a7189a1a385b61ed2cf63dbb64e79461b9ee + languageName: node + linkType: hard + +"babel-plugin-polyfill-regenerator@npm:^0.6.6": + version: 0.6.8 + resolution: "babel-plugin-polyfill-regenerator@npm:0.6.8" + dependencies: + "@babel/helper-define-polyfill-provider": "npm:^0.6.8" + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 10/974464353d6f974e97673385aff616a913c0b76039eab8c5317a2d07c661e080f3dcc213e86f3eae40010172a27ab793cda7a290a8a899716f9a22df9b1d92d2 + languageName: node + linkType: hard + +"babel-preset-current-node-syntax@npm:^1.0.0": + version: 1.2.0 + resolution: "babel-preset-current-node-syntax@npm:1.2.0" + dependencies: + "@babel/plugin-syntax-async-generators": "npm:^7.8.4" + "@babel/plugin-syntax-bigint": "npm:^7.8.3" + "@babel/plugin-syntax-class-properties": "npm:^7.12.13" + "@babel/plugin-syntax-class-static-block": "npm:^7.14.5" + "@babel/plugin-syntax-import-attributes": "npm:^7.24.7" + "@babel/plugin-syntax-import-meta": "npm:^7.10.4" + "@babel/plugin-syntax-json-strings": "npm:^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" + "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4" + "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3" + "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3" + "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" + "@babel/plugin-syntax-top-level-await": "npm:^7.14.5" + peerDependencies: + "@babel/core": ^7.0.0 || ^8.0.0-0 + checksum: 10/3608fa671cfa46364ea6ec704b8fcdd7514b7b70e6ec09b1199e13ae73ed346c51d5ce2cb6d4d5b295f6a3f2cad1fdeec2308aa9e037002dd7c929194cc838ea + languageName: node + linkType: hard + +"babel-preset-jest@npm:^29.6.3": + version: 29.6.3 + resolution: "babel-preset-jest@npm:29.6.3" + dependencies: + babel-plugin-jest-hoist: "npm:^29.6.3" + babel-preset-current-node-syntax: "npm:^1.0.0" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/aa4ff2a8a728d9d698ed521e3461a109a1e66202b13d3494e41eea30729a5e7cc03b3a2d56c594423a135429c37bf63a9fa8b0b9ce275298be3095a88c69f6fb + languageName: node + linkType: hard + "bail@npm:^2.0.0": version: 2.0.2 resolution: "bail@npm:2.0.2" @@ -11458,15 +12672,6 @@ __metadata: languageName: node linkType: hard -"baseline-browser-mapping@npm:^2.9.0": - version: 2.10.12 - resolution: "baseline-browser-mapping@npm:2.10.12" - bin: - baseline-browser-mapping: dist/cli.cjs - checksum: 10/ec3ecf8885a8aaf0c8294ac7414aa6948d1a0d2bdc68be238f7403b5a8b9bc52bbbb0ba9e230b487128047154565552c98cdf5489d31cc8ae49607b4ff5e1064 - languageName: node - linkType: hard - "basic-ftp@npm:^5.0.2": version: 5.2.0 resolution: "basic-ftp@npm:5.2.0" @@ -11506,6 +12711,17 @@ __metadata: languageName: node linkType: hard +"better-sqlite3@npm:^11.0.0": + version: 11.10.0 + resolution: "better-sqlite3@npm:11.10.0" + dependencies: + bindings: "npm:^1.5.0" + node-gyp: "npm:latest" + prebuild-install: "npm:^7.1.1" + checksum: 10/5e4c7437c4fe6033335a79c82974d7ab29f33c51c36f48b73e87e087d21578468575de1c56a7badd4f76f17255e25abefddaeacf018e5eeb9e0cb8d6e3e4a5e1 + languageName: node + linkType: hard + "better-sqlite3@npm:^12.0.0": version: 12.8.0 resolution: "better-sqlite3@npm:12.8.0" @@ -11778,9 +12994,9 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.21.4, browserslist@npm:^4.28.1": - version: 4.28.1 - resolution: "browserslist@npm:4.28.1" +"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.21.4": + version: 4.25.0 + resolution: "browserslist@npm:4.25.0" dependencies: baseline-browser-mapping: "npm:^2.9.0" caniuse-lite: "npm:^1.0.30001759" @@ -11789,7 +13005,7 @@ __metadata: update-browserslist-db: "npm:^1.2.0" bin: browserslist: cli.js - checksum: 10/64f2a97de4bce8473c0e5ae0af8d76d1ead07a5b05fc6bc87b848678bb9c3a91ae787b27aa98cdd33fc00779607e6c156000bed58fefb9cf8e4c5a183b994cdb + checksum: 10/4a5442b1a0d09c4c64454f184b8fed17d8c3e202034bf39de28f74497d7bd28dddee121b2bab4e34825fe0ed4c166d84e32a39f576c76fce73c1f8f05e4b6ee6 languageName: node linkType: hard @@ -11917,6 +13133,13 @@ __metadata: languageName: node linkType: hard +"bytestreamjs@npm:^2.0.1": + version: 2.0.1 + resolution: "bytestreamjs@npm:2.0.1" + checksum: 10/523b1024e3f887cdc0b3db7c4fc14b8563aaeb75e6642a41991b3208277fd0ae9cd66003c73473fe706c42797bf0c3f1f498fb9880b431d75b332e5709d56a0c + languageName: node + linkType: hard + "cacache@npm:^18.0.0": version: 18.0.4 resolution: "cacache@npm:18.0.4" @@ -11955,6 +13178,16 @@ __metadata: languageName: node linkType: hard +"cache-content-type@npm:^1.0.0": + version: 1.0.1 + resolution: "cache-content-type@npm:1.0.1" + dependencies: + mime-types: "npm:^2.1.18" + ylru: "npm:^1.2.0" + checksum: 10/18db4d59452669ccbfd7146a1510a37eb28e9eccf18ca7a4eb603dff2edc5cccdca7498fc3042a2978f76f11151fba486eb9eb69d9afa3fb124957870aef4fd3 + languageName: node + linkType: hard + "call-bind-apply-helpers@npm:^1.0.0, call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2": version: 1.0.2 resolution: "call-bind-apply-helpers@npm:1.0.2" @@ -12011,6 +13244,20 @@ __metadata: languageName: node linkType: hard +"camelcase@npm:^5.3.1": + version: 5.3.1 + resolution: "camelcase@npm:5.3.1" + checksum: 10/e6effce26b9404e3c0f301498184f243811c30dfe6d0b9051863bd8e4034d09c8c2923794f280d6827e5aa055f6c434115ff97864a16a963366fb35fd673024b + languageName: node + linkType: hard + +"camelcase@npm:^6.2.0": + version: 6.3.0 + resolution: "camelcase@npm:6.3.0" + checksum: 10/8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d + languageName: node + linkType: hard + "caniuse-api@npm:^3.0.0": version: 3.0.0 resolution: "caniuse-api@npm:3.0.0" @@ -12068,6 +13315,13 @@ __metadata: languageName: node linkType: hard +"char-regex@npm:^1.0.2": + version: 1.0.2 + resolution: "char-regex@npm:1.0.2" + checksum: 10/1ec5c2906adb9f84e7f6732a40baef05d7c85401b82ffcbc44b85fbd0f7a2b0c2a96f2eb9cf55cae3235dc12d4023003b88f09bcae8be9ae894f52ed746f4d48 + languageName: node + linkType: hard + "character-entities-html4@npm:^2.0.0": version: 2.1.0 resolution: "character-entities-html4@npm:2.1.0" @@ -12159,6 +13413,15 @@ __metadata: languageName: node linkType: hard +"chokidar@npm:^4.0.1": + version: 4.0.3 + resolution: "chokidar@npm:4.0.3" + dependencies: + readdirp: "npm:^4.0.1" + checksum: 10/bf2a575ea5596000e88f5db95461a9d59ad2047e939d5a4aac59dd472d126be8f1c1ff3c7654b477cf532d18f42a97279ef80ee847972fd2a25410bf00b80b59 + languageName: node + linkType: hard + "chownr@npm:^1.1.1": version: 1.1.4 resolution: "chownr@npm:1.1.4" @@ -12180,14 +13443,7 @@ __metadata: languageName: node linkType: hard -"chrome-trace-event@npm:^1.0.2": - version: 1.0.4 - resolution: "chrome-trace-event@npm:1.0.4" - checksum: 10/1762bed739774903bf5915fe3045c3120fc3c7f7d929d88e566447ea38944937a6370ccb687278318c43c24f837ad22dac780bed67c066336815557b8cf558c6 - languageName: node - linkType: hard - -"ci-info@npm:^3.2.0": +"ci-info@npm:^3.2.0, ci-info@npm:^3.7.0": version: 3.9.0 resolution: "ci-info@npm:3.9.0" checksum: 10/75bc67902b4d1c7b435497adeb91598f6d52a3389398e44294f6601b20cfef32cf2176f7be0eb961d9e085bb333a8a5cae121cb22f81cf238ae7f58eb80e9397 @@ -12205,6 +13461,13 @@ __metadata: languageName: node linkType: hard +"cjs-module-lexer@npm:^1.0.0": + version: 1.4.3 + resolution: "cjs-module-lexer@npm:1.4.3" + checksum: 10/d2b92f919a2dedbfd61d016964fce8da0035f827182ed6839c97cac56e8a8077cfa6a59388adfe2bc588a19cef9bbe830d683a76a6e93c51f65852062cfe2591 + languageName: node + linkType: hard + "classnames@npm:^2.2.6": version: 2.5.1 resolution: "classnames@npm:2.5.1" @@ -12325,6 +13588,13 @@ __metadata: languageName: node linkType: hard +"co@npm:^4.6.0": + version: 4.6.0 + resolution: "co@npm:4.6.0" + checksum: 10/a5d9f37091c70398a269e625cedff5622f200ed0aa0cff22ee7b55ed74a123834b58711776eb0f1dc58eb6ebbc1185aa7567b57bd5979a948c6e4f85073e2c05 + languageName: node + linkType: hard + "code-block-writer@npm:^13.0.3": version: 13.0.3 resolution: "code-block-writer@npm:13.0.3" @@ -12344,7 +13614,7 @@ __metadata: languageName: node linkType: hard -"color-convert@npm:^1.9.0": +"color-convert@npm:^1.9.0, color-convert@npm:^1.9.3": version: 1.9.3 resolution: "color-convert@npm:1.9.3" dependencies: @@ -12695,7 +13965,7 @@ __metadata: languageName: node linkType: hard -"content-disposition@npm:~0.5.4": +"content-disposition@npm:~0.5.2, content-disposition@npm:~0.5.4": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" dependencies: @@ -12704,7 +13974,7 @@ __metadata: languageName: node linkType: hard -"content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": +"content-type@npm:^1.0.4, content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" checksum: 10/585847d98dc7fb8035c02ae2cb76c7a9bd7b25f84c447e5ed55c45c2175e83617c8813871b4ee22f368126af6b2b167df655829007b21aa10302873ea9c62662 @@ -12718,14 +13988,7 @@ __metadata: languageName: node linkType: hard -"convert-source-map@npm:^2.0.0": - version: 2.0.0 - resolution: "convert-source-map@npm:2.0.0" - checksum: 10/c987be3ec061348cdb3c2bfb924bec86dea1eacad10550a85ca23edb0fe3556c3a61c7399114f3331ccb3499d7fd0285ab24566e5745929412983494c3926e15 - languageName: node - linkType: hard - -"cookie-signature@npm:^1.2.1, cookie-signature@npm:^1.2.2": +"cookie-signature@npm:^1.2.1": version: 1.2.2 resolution: "cookie-signature@npm:1.2.2" checksum: 10/be44a3c9a56f3771aea3a8bd8ad8f0a8e2679bcb967478267f41a510b4eb5ec55085386ba79c706c4ac21605ca76f4251973444b90283e0eb3eeafe8a92c7708 @@ -12753,7 +14016,7 @@ __metadata: languageName: node linkType: hard -"cookies@npm:~0.9.1": +"cookies@npm:~0.9.0, cookies@npm:~0.9.1": version: 0.9.1 resolution: "cookies@npm:0.9.1" dependencies: @@ -12772,6 +14035,15 @@ __metadata: languageName: node linkType: hard +"core-js-compat@npm:^3.48.0": + version: 3.49.0 + resolution: "core-js-compat@npm:3.49.0" + dependencies: + browserslist: "npm:^4.28.1" + checksum: 10/eb35ad9b31a613092d32e5eb0c9fecb695e680bb29509fe04ae297ef790cea47d06864ef8939c8f5f189cce0bd2807fef8b2d6450f7eeb917ffaaf38a775dece + languageName: node + linkType: hard + "core-js-pure@npm:^3.23.3": version: 3.49.0 resolution: "core-js-pure@npm:3.49.0" @@ -12809,7 +14081,7 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^7.0.0": +"cosmiconfig@npm:^7.0.0, cosmiconfig@npm:^7.0.1": version: 7.1.0 resolution: "cosmiconfig@npm:7.1.0" dependencies: @@ -12839,6 +14111,23 @@ __metadata: languageName: node linkType: hard +"cosmiconfig@npm:^8.2.0": + version: 8.3.6 + resolution: "cosmiconfig@npm:8.3.6" + dependencies: + import-fresh: "npm:^3.3.0" + js-yaml: "npm:^4.1.0" + parse-json: "npm:^5.2.0" + path-type: "npm:^4.0.0" + peerDependencies: + typescript: ">=4.9.5" + peerDependenciesMeta: + typescript: + optional: true + checksum: 10/91d082baca0f33b1c085bf010f9ded4af43cbedacba8821da0fb5667184d0a848addc52c31fadd080007f904a555319c238cf5f4c03e6d58ece2e4876b2e73d6 + languageName: node + linkType: hard + "cpu-features@npm:~0.0.10": version: 0.0.10 resolution: "cpu-features@npm:0.0.10" @@ -12906,6 +14195,23 @@ __metadata: languageName: node linkType: hard +"create-jest@npm:^29.7.0": + version: 29.7.0 + resolution: "create-jest@npm:29.7.0" + dependencies: + "@jest/types": "npm:^29.6.3" + chalk: "npm:^4.0.0" + exit: "npm:^0.1.2" + graceful-fs: "npm:^4.2.9" + jest-config: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + prompts: "npm:^2.0.1" + bin: + create-jest: bin/create-jest.js + checksum: 10/847b4764451672b4174be4d5c6d7d63442ec3aa5f3de52af924e4d996d87d7801c18e125504f25232fc75840f6625b3ac85860fac6ce799b5efae7bdcaf4a2b7 + languageName: node + linkType: hard + "create-require@npm:^1.1.0, create-require@npm:^1.1.1": version: 1.1.1 resolution: "create-require@npm:1.1.1" @@ -13149,6 +14455,29 @@ __metadata: languageName: node linkType: hard +"cssom@npm:^0.5.0": + version: 0.5.0 + resolution: "cssom@npm:0.5.0" + checksum: 10/b502a315b1ce020a692036cc38cb36afa44157219b80deadfa040ab800aa9321fcfbecf02fd2e6ec87db169715e27978b4ab3701f916461e9cf7808899f23b54 + languageName: node + linkType: hard + +"cssom@npm:~0.3.6": + version: 0.3.8 + resolution: "cssom@npm:0.3.8" + checksum: 10/49eacc88077555e419646c0ea84ddc73c97e3a346ad7cb95e22f9413a9722d8964b91d781ce21d378bd5ae058af9a745402383fa4e35e9cdfd19654b63f892a9 + languageName: node + linkType: hard + +"cssstyle@npm:^2.3.0": + version: 2.3.0 + resolution: "cssstyle@npm:2.3.0" + dependencies: + cssom: "npm:~0.3.6" + checksum: 10/46f7f05a153446c4018b0454ee1464b50f606cb1803c90d203524834b7438eb52f3b173ba0891c618f380ced34ee12020675dc0052a7f1be755fe4ebc27ee977 + languageName: node + linkType: hard + "csstype@npm:^2.5.2": version: 2.6.21 resolution: "csstype@npm:2.6.21" @@ -13289,6 +14618,17 @@ __metadata: languageName: node linkType: hard +"data-urls@npm:^3.0.2": + version: 3.0.2 + resolution: "data-urls@npm:3.0.2" + dependencies: + abab: "npm:^2.0.6" + whatwg-mimetype: "npm:^3.0.0" + whatwg-url: "npm:^11.0.0" + checksum: 10/033fc3dd0fba6d24bc9a024ddcf9923691dd24f90a3d26f6545d6a2f71ec6956f93462f2cdf2183cc46f10dc01ed3bcb36731a8208456eb1a08147e571fe2a76 + languageName: node + linkType: hard + "data-view-buffer@npm:^1.0.2": version: 1.0.2 resolution: "data-view-buffer@npm:1.0.2" @@ -13394,7 +14734,7 @@ __metadata: languageName: node linkType: hard -"decimal.js@npm:^10.4.3": +"decimal.js@npm:^10.4.2, decimal.js@npm:^10.4.3": version: 10.6.0 resolution: "decimal.js@npm:10.6.0" checksum: 10/c0d45842d47c311d11b38ce7ccc911121953d4df3ebb1465d92b31970eb4f6738a065426a06094af59bee4b0d64e42e7c8984abd57b6767c64ea90cf90bb4a69 @@ -13419,6 +14759,18 @@ __metadata: languageName: node linkType: hard +"dedent@npm:^1.0.0": + version: 1.7.2 + resolution: "dedent@npm:1.7.2" + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + checksum: 10/30b9062290dca72b0f5a6cd3667633448cef8cd0dec602eab61015741269ad49df90cabf0521f9a32d134ceab4e21aa7f097258c55cc3baadef94874686d6480 + languageName: node + linkType: hard + "deep-equal@npm:~1.0.1": version: 1.0.1 resolution: "deep-equal@npm:1.0.1" @@ -13616,6 +14968,13 @@ __metadata: languageName: node linkType: hard +"detect-newline@npm:^3.0.0": + version: 3.1.0 + resolution: "detect-newline@npm:3.1.0" + checksum: 10/ae6cd429c41ad01b164c59ea36f264a2c479598e61cba7c99da24175a7ab80ddf066420f2bec9a1c57a6bead411b4655ff15ad7d281c000a89791f48cbe939e7 + languageName: node + linkType: hard + "detect-node@npm:^2.0.4": version: 2.1.0 resolution: "detect-node@npm:2.1.0" @@ -13655,6 +15014,13 @@ __metadata: languageName: node linkType: hard +"diff-sequences@npm:^29.6.3": + version: 29.6.3 + resolution: "diff-sequences@npm:29.6.3" + checksum: 10/179daf9d2f9af5c57ad66d97cb902a538bcf8ed64963fa7aa0c329b3de3665ce2eb6ffdc2f69f29d445fa4af2517e5e55e5b6e00c00a9ae4f43645f97f7078cb + languageName: node + linkType: hard + "diff@npm:^4.0.1": version: 4.0.4 resolution: "diff@npm:4.0.4" @@ -13824,6 +15190,15 @@ __metadata: languageName: node linkType: hard +"domexception@npm:^4.0.0": + version: 4.0.0 + resolution: "domexception@npm:4.0.0" + dependencies: + webidl-conversions: "npm:^7.0.0" + checksum: 10/4ed443227d2871d76c58d852b2e93c68e0443815b2741348f20881bedee8c1ad4f9bfc5d30c7dec433cd026b57da63407c010260b1682fef4c8847e7181ea43f + languageName: node + linkType: hard + "domhandler@npm:^4.0.0, domhandler@npm:^4.2.0, domhandler@npm:^4.3.1": version: 4.3.1 resolution: "domhandler@npm:4.3.1" @@ -13919,10 +15294,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.263": - version: 1.5.328 - resolution: "electron-to-chromium@npm:1.5.328" - checksum: 10/bec0f12759edb8ee10a8856c7f8343a69e92d7626c443dec66a7718a3e54b0114397238ecc8320cb8502cab050a890988550da126843d2216b1a3e745914c512 +"electron-to-chromium@npm:^1.5.160": + version: 1.5.171 + resolution: "electron-to-chromium@npm:1.5.171" + checksum: 10/6d58ff50407107d7e86e7beb8d0361358f90dbc10c7d92a2ff9cdfbaf27a65165c00ae05a345ab32fa6e371ff9c7d1fef1441d57adfa8f59701c56734745c0a1 languageName: node linkType: hard @@ -13941,6 +15316,13 @@ __metadata: languageName: node linkType: hard +"emittery@npm:^0.13.1": + version: 0.13.1 + resolution: "emittery@npm:0.13.1" + checksum: 10/fbe214171d878b924eedf1757badf58a5dce071cd1fa7f620fa841a0901a80d6da47ff05929d53163105e621ce11a71b9d8acb1148ffe1745e045145f6e69521 + languageName: node + linkType: hard + "emoji-regex@npm:^8.0.0": version: 8.0.0 resolution: "emoji-regex@npm:8.0.0" @@ -13969,6 +15351,13 @@ __metadata: languageName: node linkType: hard +"encodeurl@npm:^1.0.2": + version: 1.0.2 + resolution: "encodeurl@npm:1.0.2" + checksum: 10/e50e3d508cdd9c4565ba72d2012e65038e5d71bdc9198cb125beb6237b5b1ade6c0d343998da9e170fb2eae52c1bed37d4d6d98a46ea423a0cddbed5ac3f780c + languageName: node + linkType: hard + "encodeurl@npm:^2.0.0, encodeurl@npm:~2.0.0": version: 2.0.0 resolution: "encodeurl@npm:2.0.0" @@ -14004,6 +15393,16 @@ __metadata: languageName: node linkType: hard +"enhanced-resolve@npm:^5.20.0": + version: 5.20.1 + resolution: "enhanced-resolve@npm:5.20.1" + dependencies: + graceful-fs: "npm:^4.2.4" + tapable: "npm:^2.3.0" + checksum: 10/588afc56de97334e5742faebcf8177a504da08ea817d399f9901f35d8e9e5e6fa86b4c2ce95a99081f947764e09c9991cc0fc0ba5751bae455c329643a709187 + languageName: node + linkType: hard + "enquirer@npm:^2.4.1": version: 2.4.1 resolution: "enquirer@npm:2.4.1" @@ -14021,6 +15420,20 @@ __metadata: languageName: node linkType: hard +"entities@npm:^4.4.0": + version: 4.5.0 + resolution: "entities@npm:4.5.0" + checksum: 10/ede2a35c9bce1aeccd055a1b445d41c75a14a2bb1cd22e242f20cf04d236cdcd7f9c859eb83f76885327bfae0c25bf03303665ee1ce3d47c5927b98b0e3e3d48 + languageName: node + linkType: hard + +"entities@npm:^6.0.0": + version: 6.0.1 + resolution: "entities@npm:6.0.1" + checksum: 10/62af1307202884349d2867f0aac5c60d8b57102ea0b0e768b16246099512c28e239254ad772d6834e7e14cb1b6f153fc3d0c031934e3183b086c86d3838d874a + languageName: node + linkType: hard + "env-paths@npm:^2.2.0": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -14184,6 +15597,13 @@ __metadata: languageName: node linkType: hard +"es-module-lexer@npm:^2.0.0": + version: 2.0.0 + resolution: "es-module-lexer@npm:2.0.0" + checksum: 10/b075855289b5f40ee496f3d7525c5c501d029c3da15c22298a0030d625bf36d1da0768b26278f7f4bada2a602459b505888e20b77c414fba5da5619b0e84dbd1 + languageName: node + linkType: hard + "es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": version: 1.1.1 resolution: "es-object-atoms@npm:1.1.1" @@ -14232,50 +15652,36 @@ __metadata: languageName: node linkType: hard -"esbuild-loader@npm:^4.0.0": - version: 4.4.2 - resolution: "esbuild-loader@npm:4.4.2" - dependencies: - esbuild: "npm:^0.27.1" - get-tsconfig: "npm:^4.10.1" - loader-utils: "npm:^2.0.4" - webpack-sources: "npm:^1.4.3" - peerDependencies: - webpack: ^4.40.0 || ^5.0.0 - checksum: 10/d4c2f5a53f0e204bf9dc87f6767e59080fed016a3f54d8878a519a06fc82918bdb598f8eaab3bd47489566f4112f4737f1e00a5611f012e88d8d1f92eb8ccec6 - languageName: node - linkType: hard - -"esbuild@npm:^0.27.1": - version: 0.27.4 - resolution: "esbuild@npm:0.27.4" - dependencies: - "@esbuild/aix-ppc64": "npm:0.27.4" - "@esbuild/android-arm": "npm:0.27.4" - "@esbuild/android-arm64": "npm:0.27.4" - "@esbuild/android-x64": "npm:0.27.4" - "@esbuild/darwin-arm64": "npm:0.27.4" - "@esbuild/darwin-x64": "npm:0.27.4" - "@esbuild/freebsd-arm64": "npm:0.27.4" - "@esbuild/freebsd-x64": "npm:0.27.4" - "@esbuild/linux-arm": "npm:0.27.4" - "@esbuild/linux-arm64": "npm:0.27.4" - "@esbuild/linux-ia32": "npm:0.27.4" - "@esbuild/linux-loong64": "npm:0.27.4" - "@esbuild/linux-mips64el": "npm:0.27.4" - "@esbuild/linux-ppc64": "npm:0.27.4" - "@esbuild/linux-riscv64": "npm:0.27.4" - "@esbuild/linux-s390x": "npm:0.27.4" - "@esbuild/linux-x64": "npm:0.27.4" - "@esbuild/netbsd-arm64": "npm:0.27.4" - "@esbuild/netbsd-x64": "npm:0.27.4" - "@esbuild/openbsd-arm64": "npm:0.27.4" - "@esbuild/openbsd-x64": "npm:0.27.4" - "@esbuild/openharmony-arm64": "npm:0.27.4" - "@esbuild/sunos-x64": "npm:0.27.4" - "@esbuild/win32-arm64": "npm:0.27.4" - "@esbuild/win32-ia32": "npm:0.27.4" - "@esbuild/win32-x64": "npm:0.27.4" +"esbuild@npm:^0.27.0": + version: 0.27.3 + resolution: "esbuild@npm:0.27.3" + dependencies: + "@esbuild/aix-ppc64": "npm:0.27.3" + "@esbuild/android-arm": "npm:0.27.3" + "@esbuild/android-arm64": "npm:0.27.3" + "@esbuild/android-x64": "npm:0.27.3" + "@esbuild/darwin-arm64": "npm:0.27.3" + "@esbuild/darwin-x64": "npm:0.27.3" + "@esbuild/freebsd-arm64": "npm:0.27.3" + "@esbuild/freebsd-x64": "npm:0.27.3" + "@esbuild/linux-arm": "npm:0.27.3" + "@esbuild/linux-arm64": "npm:0.27.3" + "@esbuild/linux-ia32": "npm:0.27.3" + "@esbuild/linux-loong64": "npm:0.27.3" + "@esbuild/linux-mips64el": "npm:0.27.3" + "@esbuild/linux-ppc64": "npm:0.27.3" + "@esbuild/linux-riscv64": "npm:0.27.3" + "@esbuild/linux-s390x": "npm:0.27.3" + "@esbuild/linux-x64": "npm:0.27.3" + "@esbuild/netbsd-arm64": "npm:0.27.3" + "@esbuild/netbsd-x64": "npm:0.27.3" + "@esbuild/openbsd-arm64": "npm:0.27.3" + "@esbuild/openbsd-x64": "npm:0.27.3" + "@esbuild/openharmony-arm64": "npm:0.27.3" + "@esbuild/sunos-x64": "npm:0.27.3" + "@esbuild/win32-arm64": "npm:0.27.3" + "@esbuild/win32-ia32": "npm:0.27.3" + "@esbuild/win32-x64": "npm:0.27.3" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -14331,7 +15737,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10/32b46ec22ef78bae6cc141145022a4c0209852c07151f037fbefccc2033ca54e7f33705f8fca198eb7026f400142f64c2dbc9f0d0ce9c0a638ebc472a04abc4a + checksum: 10/aa74b8d8a3ed8e2eea4d8421737b322f4d21215244e8fa2156c6402d49b5bda01343c220196f1e3f830a7ce92b54ef653c6c723a8cc2e912bb4d17b7398b51ae languageName: node linkType: hard @@ -14356,6 +15762,13 @@ __metadata: languageName: node linkType: hard +"escape-string-regexp@npm:^2.0.0": + version: 2.0.0 + resolution: "escape-string-regexp@npm:2.0.0" + checksum: 10/9f8a2d5743677c16e85c810e3024d54f0c8dea6424fad3c79ef6666e81dd0846f7437f5e729dfcdac8981bc9e5294c39b4580814d114076b8d36318f46ae4395 + languageName: node + linkType: hard + "escape-string-regexp@npm:^4.0.0": version: 4.0.0 resolution: "escape-string-regexp@npm:4.0.0" @@ -14370,6 +15783,25 @@ __metadata: languageName: node linkType: hard +"escodegen@npm:^1.8.1": + version: 1.14.3 + resolution: "escodegen@npm:1.14.3" + dependencies: + esprima: "npm:^4.0.1" + estraverse: "npm:^4.2.0" + esutils: "npm:^2.0.2" + optionator: "npm:^0.8.1" + source-map: "npm:~0.6.1" + dependenciesMeta: + source-map: + optional: true + bin: + escodegen: bin/escodegen.js + esgenerate: bin/esgenerate.js + checksum: 10/70f095ca9393535f9f1c145ef99dc0b3ff14cca6bc4a79d90ff3352f90c3f2e07f75af6d6c05174ea67c45271f75e80dd440dd7d04ed2cf44c9452c3042fa84a + languageName: node + linkType: hard + "escodegen@npm:^2.1.0": version: 2.1.0 resolution: "escodegen@npm:2.1.0" @@ -14596,6 +16028,16 @@ __metadata: languageName: node linkType: hard +"eslint-scope@npm:5.1.1": + version: 5.1.1 + resolution: "eslint-scope@npm:5.1.1" + dependencies: + esrecurse: "npm:^4.3.0" + estraverse: "npm:^4.1.1" + checksum: 10/c541ef384c92eb5c999b7d3443d80195fcafb3da335500946f6db76539b87d5826c8f2e1d23bf6afc3154ba8cd7c8e566f8dc00f1eea25fdf3afc8fb9c87b238 + languageName: node + linkType: hard + "eslint-scope@npm:^7.2.2": version: 7.2.2 resolution: "eslint-scope@npm:7.2.2" @@ -14636,6 +16078,22 @@ __metadata: languageName: node linkType: hard +"eslint-webpack-plugin@npm:^4.2.0": + version: 4.2.0 + resolution: "eslint-webpack-plugin@npm:4.2.0" + dependencies: + "@types/eslint": "npm:^8.56.10" + jest-worker: "npm:^29.7.0" + micromatch: "npm:^4.0.5" + normalize-path: "npm:^3.0.0" + schema-utils: "npm:^4.2.0" + peerDependencies: + eslint: ^8.0.0 || ^9.0.0 + webpack: ^5.0.0 + checksum: 10/061d11a93832b82bd0362d6c546f51fe5e3a0eb811374b86536a2929ff46fea7e5ef30e32f0d3194b9da146a7c0ae43f13b2ec5ce0f65a9ca9c4d961d9e446b3 + languageName: node + linkType: hard + "eslint@npm:^8.6.0": version: 8.57.1 resolution: "eslint@npm:8.57.1" @@ -14730,7 +16188,7 @@ __metadata: languageName: node linkType: hard -"estraverse@npm:^4.1.1": +"estraverse@npm:^4.2.0": version: 4.3.0 resolution: "estraverse@npm:4.3.0" checksum: 10/3f67ad02b6dbfaddd9ea459cf2b6ef4ecff9a6082a7af9d22e445b9abc082ad9ca47e1825557b293fcdae477f4714e561123e30bb6a5b2f184fb2bad4a9497eb @@ -14758,7 +16216,7 @@ __metadata: languageName: node linkType: hard -"estree-walker@npm:^2.0.2": +"estree-walker@npm:^2.0.1, estree-walker@npm:^2.0.2": version: 2.0.2 resolution: "estree-walker@npm:2.0.2" checksum: 10/b02109c5d46bc2ed47de4990eef770f7457b1159a229f0999a09224d2b85ffeed2d7679cffcff90aeb4448e94b0168feb5265b209cdec29aad50a3d6e93d21e2 @@ -14793,16 +16251,7 @@ __metadata: languageName: node linkType: hard -"events-universal@npm:^1.0.0": - version: 1.0.1 - resolution: "events-universal@npm:1.0.1" - dependencies: - bare-events: "npm:^2.7.0" - checksum: 10/71b2e6079b4dc030c613ef73d99f1acb369dd3ddb6034f49fd98b3e2c6632cde9f61c15fb1351004339d7c79672252a4694ecc46a6124dc794b558be50a83867 - languageName: node - linkType: hard - -"events@npm:^3.0.0, events@npm:^3.2.0, events@npm:^3.3.0": +"events@npm:^3.0.0, events@npm:^3.3.0": version: 3.3.0 resolution: "events@npm:3.3.0" checksum: 10/a3d47e285e28d324d7180f1e493961a2bbb4cad6412090e4dec114f4db1f5b560c7696ee8e758f55e23913ede856e3689cd3aa9ae13c56b5d8314cd3b3ddd1be @@ -14836,6 +16285,30 @@ __metadata: languageName: node linkType: hard +"execa@npm:^5.0.0": + version: 5.1.1 + resolution: "execa@npm:5.1.1" + dependencies: + cross-spawn: "npm:^7.0.3" + get-stream: "npm:^6.0.0" + human-signals: "npm:^2.1.0" + is-stream: "npm:^2.0.0" + merge-stream: "npm:^2.0.0" + npm-run-path: "npm:^4.0.1" + onetime: "npm:^5.1.2" + signal-exit: "npm:^3.0.3" + strip-final-newline: "npm:^2.0.0" + checksum: 10/8ada91f2d70f7dff702c861c2c64f21dfdc1525628f3c0454fd6f02fce65f7b958616cbd2b99ca7fa4d474e461a3d363824e91b3eb881705231abbf387470597 + languageName: node + linkType: hard + +"exit@npm:^0.1.2": + version: 0.1.2 + resolution: "exit@npm:0.1.2" + checksum: 10/387555050c5b3c10e7a9e8df5f43194e95d7737c74532c409910e585d5554eaff34960c166643f5e23d042196529daad059c292dcf1fb61b8ca878d3677f4b87 + languageName: node + linkType: hard + "expand-template@npm:^2.0.3": version: 2.0.3 resolution: "expand-template@npm:2.0.3" @@ -14852,6 +16325,19 @@ __metadata: languageName: node linkType: hard +"expect@npm:^29.0.0, expect@npm:^29.7.0": + version: 29.7.0 + resolution: "expect@npm:29.7.0" + dependencies: + "@jest/expect-utils": "npm:^29.7.0" + jest-get-type: "npm:^29.6.3" + jest-matcher-utils: "npm:^29.7.0" + jest-message-util: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + checksum: 10/63f97bc51f56a491950fb525f9ad94f1916e8a014947f8d8445d3847a665b5471b768522d659f5e865db20b6c2033d2ac10f35fcbd881a4d26407a4f6f18451a + languageName: node + linkType: hard + "exponential-backoff@npm:^3.1.1": version: 3.1.3 resolution: "exponential-backoff@npm:3.1.3" @@ -14887,7 +16373,7 @@ __metadata: languageName: node linkType: hard -"express@npm:^4.22.0, express@npm:^4.22.1": +"express@npm:^4.17.1, express@npm:^4.22.0, express@npm:^4.22.1": version: 4.22.1 resolution: "express@npm:4.22.1" dependencies: @@ -15010,7 +16496,7 @@ __metadata: languageName: node linkType: hard -"fast-json-stable-stringify@npm:^2.0.0": +"fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" checksum: 10/2c20055c1fa43c922428f16ca8bb29f2807de63e5c851f665f7ac9790176c01c3b40335257736b299764a8d383388dabc73c8083b8e1bc3d99f0a941444ec60e @@ -15121,6 +16607,15 @@ __metadata: languageName: node linkType: hard +"fb-watchman@npm:^2.0.0": + version: 2.0.2 + resolution: "fb-watchman@npm:2.0.2" + dependencies: + bser: "npm:2.1.1" + checksum: 10/4f95d336fb805786759e383fd7fff342ceb7680f53efcc0ef82f502eb479ce35b98e8b207b6dfdfeea0eba845862107dc73813775fc6b56b3098c6e90a2dad77 + languageName: node + linkType: hard + "fd-package-json@npm:^2.0.0": version: 2.0.0 resolution: "fd-package-json@npm:2.0.0" @@ -15275,7 +16770,7 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^4.1.0": +"find-up@npm:^4.0.0, find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" dependencies: @@ -15403,6 +16898,29 @@ __metadata: languageName: node linkType: hard +"fork-ts-checker-webpack-plugin@npm:^9.0.0": + version: 9.1.0 + resolution: "fork-ts-checker-webpack-plugin@npm:9.1.0" + dependencies: + "@babel/code-frame": "npm:^7.16.7" + chalk: "npm:^4.1.2" + chokidar: "npm:^4.0.1" + cosmiconfig: "npm:^8.2.0" + deepmerge: "npm:^4.2.2" + fs-extra: "npm:^10.0.0" + memfs: "npm:^3.4.1" + minimatch: "npm:^3.0.4" + node-abort-controller: "npm:^3.0.1" + schema-utils: "npm:^3.1.1" + semver: "npm:^7.3.5" + tapable: "npm:^2.2.1" + peerDependencies: + typescript: ">3.6.0" + webpack: ^5.11.0 + checksum: 10/1d24387224f7d49a17f7e44c9150971172f34ae30c4b1f581b8af967e73e8f36a434ed56f78aa45fd8cf0833c73a1b020102cc61070d7dc630b70c21c9770a1b + languageName: node + linkType: hard + "form-data-encoder@npm:^1.7.2": version: 1.9.0 resolution: "form-data-encoder@npm:1.9.0" @@ -15518,6 +17036,13 @@ __metadata: languageName: node linkType: hard +"fromentries@npm:^1.3.1": + version: 1.3.2 + resolution: "fromentries@npm:1.3.2" + checksum: 10/10d6e07d289db102c0c1eaf5c3e3fa55ddd6b50033d7de16d99a7cd89f1e1a302dfadb26457031f9bb5d2ed95a179aaf0396092dde5abcae06e8a2f0476826be + languageName: node + linkType: hard + "fs-constants@npm:^1.0.0": version: 1.0.0 resolution: "fs-constants@npm:1.0.0" @@ -15620,7 +17145,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:~2.3.2": +"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2": version: 2.3.3 resolution: "fsevents@npm:2.3.3" dependencies: @@ -15630,7 +17155,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": +"fsevents@patch:fsevents@npm%3A^2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" dependencies: @@ -15745,6 +17270,13 @@ __metadata: languageName: node linkType: hard +"gensync@npm:^1.0.0-beta.2": + version: 1.0.0-beta.2 + resolution: "gensync@npm:1.0.0-beta.2" + checksum: 10/17d8333460204fbf1f9160d067e1e77f908a5447febb49424b8ab043026049835c9ef3974445c57dbd39161f4d2b04356d7de12b2eecaa27a7a7ea7d871cbedd + languageName: node + linkType: hard + "get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" @@ -15797,6 +17329,13 @@ __metadata: languageName: node linkType: hard +"get-stream@npm:^6.0.0": + version: 6.0.1 + resolution: "get-stream@npm:6.0.1" + checksum: 10/781266d29725f35c59f1d214aedc92b0ae855800a980800e2923b3fbc4e56b3cb6e462c42e09a1cf1a00c64e056a78fa407cbe06c7c92b7e5cd49b4b85c2a497 + languageName: node + linkType: hard + "get-symbol-description@npm:^1.1.0": version: 1.1.0 resolution: "get-symbol-description@npm:1.1.0" @@ -15808,9 +17347,9 @@ __metadata: languageName: node linkType: hard -"get-tsconfig@npm:^4.10.0, get-tsconfig@npm:^4.10.1": - version: 4.13.7 - resolution: "get-tsconfig@npm:4.13.7" +"get-tsconfig@npm:^4.10.0": + version: 4.10.1 + resolution: "get-tsconfig@npm:4.10.1" dependencies: resolve-pkg-maps: "npm:^1.0.0" checksum: 10/e23622bd3c5766a2fe43a28cb7a490ebb175eb7f429e4ec53688e3b7a40882fb0ec6f3b753f237757d63861ccd8033232d1d76f8960a683af8e09099e7c897fe @@ -15888,16 +17427,9 @@ __metadata: languageName: node linkType: hard -"glob-to-regexp@npm:^0.4.1": - version: 0.4.1 - resolution: "glob-to-regexp@npm:0.4.1" - checksum: 10/9009529195a955c40d7b9690794aeff5ba665cc38f1519e111c58bb54366fd0c106bde80acf97ba4e533208eb53422c83b136611a54c5fefb1edd8dc267cb62e - languageName: node - linkType: hard - -"glob@npm:13.0.6, glob@npm:^13.0.0": - version: 13.0.6 - resolution: "glob@npm:13.0.6" +"glob@npm:9.3.5": + version: 9.3.5 + resolution: "glob@npm:9.3.5" dependencies: minimatch: "npm:^10.2.2" minipass: "npm:^7.1.3" @@ -15922,7 +17454,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^7.1.3, glob@npm:^7.1.6, glob@npm:^7.1.7": +"glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.6, glob@npm:^7.1.7": version: 7.2.3 resolution: "glob@npm:7.2.3" dependencies: @@ -16089,6 +17621,7 @@ __metadata: languageName: node linkType: hard +"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.5, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": "graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.5, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" @@ -16103,6 +17636,24 @@ __metadata: languageName: node linkType: hard +"graphql-tag@npm:^2.10.3": + version: 2.12.6 + resolution: "graphql-tag@npm:2.12.6" + dependencies: + tslib: "npm:^2.1.0" + peerDependencies: + graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 10/23a2bc1d3fbeae86444204e0ac08522e09dc369559ba75768e47421a7321b59f352fb5b2c9a5c37d3cf6de890dca4e5ac47e740c7cc622e728572ecaa649089e + languageName: node + linkType: hard + +"graphql@npm:^16.0.0": + version: 16.13.1 + resolution: "graphql@npm:16.13.1" + checksum: 10/a42f857f60351e1f4665aa5bc5524796d3f45bf81793e6db932f902aff769b0488dafaa1d9c07bddda7122a1f6d0b0105fab12d38992f6b6fb81fc3d7ced1afc + languageName: node + linkType: hard + "gtoken@npm:^7.0.0": version: 7.1.0 resolution: "gtoken@npm:7.1.0" @@ -16489,6 +18040,15 @@ __metadata: languageName: node linkType: hard +"html-encoding-sniffer@npm:^3.0.0": + version: 3.0.0 + resolution: "html-encoding-sniffer@npm:3.0.0" + dependencies: + whatwg-encoding: "npm:^2.0.0" + checksum: 10/707a812ec2acaf8bb5614c8618dc81e2fb6b4399d03e95ff18b65679989a072f4e919b9bef472039301a1bbfba64063ba4c79ea6e851c653ac9db80dbefe8fe5 + languageName: node + linkType: hard + "html-entities@npm:^2.1.0, html-entities@npm:^2.5.2, html-entities@npm:^2.6.0": version: 2.6.0 resolution: "html-entities@npm:2.6.0" @@ -16496,6 +18056,13 @@ __metadata: languageName: node linkType: hard +"html-escaper@npm:^2.0.0": + version: 2.0.2 + resolution: "html-escaper@npm:2.0.2" + checksum: 10/034d74029dcca544a34fb6135e98d427acd73019796ffc17383eaa3ec2fe1c0471dcbbc8f8ed39e46e86d43ccd753a160631615e4048285e313569609b66d5b7 + languageName: node + linkType: hard + "html-minifier-terser@npm:^6.0.2": version: 6.1.0 resolution: "html-minifier-terser@npm:6.1.0" @@ -16560,7 +18127,7 @@ __metadata: languageName: node linkType: hard -"http-assert@npm:^1.5.0": +"http-assert@npm:^1.3.0, http-assert@npm:^1.5.0": version: 1.5.0 resolution: "http-assert@npm:1.5.0" dependencies: @@ -16584,7 +18151,7 @@ __metadata: languageName: node linkType: hard -"http-errors@npm:^2.0.0, http-errors@npm:^2.0.1, http-errors@npm:~2.0.0, http-errors@npm:~2.0.1": +"http-errors@npm:^2.0.0, http-errors@npm:~2.0.0, http-errors@npm:~2.0.1": version: 2.0.1 resolution: "http-errors@npm:2.0.1" dependencies: @@ -16597,6 +18164,18 @@ __metadata: languageName: node linkType: hard +"http-errors@npm:~1.6.2": + version: 1.6.3 + resolution: "http-errors@npm:1.6.3" + dependencies: + depd: "npm:~1.1.2" + inherits: "npm:2.0.3" + setprototypeof: "npm:1.1.0" + statuses: "npm:>= 1.4.0 < 2" + checksum: 10/e48732657ea0b4a09853d2696a584fa59fa2a8c1ba692af7af3137b5491a997d7f9723f824e7e08eb6a87098532c09ce066966ddf0f9f3dd30905e52301acadb + languageName: node + linkType: hard + "http-errors@npm:~1.8.0": version: 1.8.1 resolution: "http-errors@npm:1.8.1" @@ -16674,7 +18253,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^5.0.0": +"https-proxy-agent@npm:^5.0.0, https-proxy-agent@npm:^5.0.1": version: 5.0.1 resolution: "https-proxy-agent@npm:5.0.1" dependencies: @@ -16703,6 +18282,13 @@ __metadata: languageName: node linkType: hard +"human-signals@npm:^2.1.0": + version: 2.1.0 + resolution: "human-signals@npm:2.1.0" + checksum: 10/df59be9e0af479036798a881d1f136c4a29e0b518d4abb863afbd11bf30efa3eeb1d0425fc65942dcc05ab3bf40205ea436b0ff389f2cd20b75b8643d539bf86 + languageName: node + linkType: hard + "hyperdyperid@npm:^1.2.0": version: 1.2.0 resolution: "hyperdyperid@npm:1.2.0" @@ -16726,7 +18312,16 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:^0.6.2": +"iconv-lite@npm:^0.4.24, iconv-lite@npm:~0.4.24": + version: 0.4.24 + resolution: "iconv-lite@npm:0.4.24" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3" + checksum: 10/6d3a2dac6e5d1fb126d25645c25c3a1209f70cceecc68b8ef51ae0da3cdc078c151fade7524a30b12a3094926336831fca09c666ef55b37e2c69638b5d6bd2e3 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: @@ -16735,7 +18330,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:^0.7.0, iconv-lite@npm:^0.7.2, iconv-lite@npm:~0.7.0": +"iconv-lite@npm:^0.7.0, iconv-lite@npm:~0.7.0": version: 0.7.2 resolution: "iconv-lite@npm:0.7.2" dependencies: @@ -16824,6 +18419,7 @@ __metadata: languageName: node linkType: hard +"import-fresh@npm:^3.1.0, import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": "import-fresh@npm:^3.1.0, import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": version: 3.3.1 resolution: "import-fresh@npm:3.3.1" @@ -16850,6 +18446,18 @@ __metadata: languageName: node linkType: hard +"import-local@npm:^3.0.2": + version: 3.2.0 + resolution: "import-local@npm:3.2.0" + dependencies: + pkg-dir: "npm:^4.2.0" + resolve-cwd: "npm:^3.0.0" + bin: + import-local-fixture: fixtures/cli.js + checksum: 10/0b0b0b412b2521739fbb85eeed834a3c34de9bc67e670b3d0b86248fc460d990a7b116ad056c084b87a693ef73d1f17268d6a5be626bb43c998a8b1c8a230004 + languageName: node + linkType: hard + "imurmurhash@npm:^0.1.4": version: 0.1.4 resolution: "imurmurhash@npm:0.1.4" @@ -16994,10 +18602,20 @@ __metadata: languageName: node linkType: hard -"ip-address@npm:10.1.0, ip-address@npm:^10.0.1": - version: 10.1.0 - resolution: "ip-address@npm:10.1.0" - checksum: 10/a6979629d1ad9c1fb424bc25182203fad739b40225aebc55ec6243bbff5035faf7b9ed6efab3a097de6e713acbbfde944baacfa73e11852bb43989c45a68d79e +"ip-address@npm:10.0.1": + version: 10.0.1 + resolution: "ip-address@npm:10.0.1" + checksum: 10/09731acda32cd8e14c46830c137e7e5940f47b36d63ffb87c737331270287d631cf25aa95570907a67d3f919fdb25f4470c404eda21e62f22e0a55927f4dd0fb + languageName: node + linkType: hard + +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: "npm:1.1.0" + sprintf-js: "npm:^1.1.3" + checksum: 10/1ed81e06721af012306329b31f532b5e24e00cb537be18ddc905a84f19fe8f83a09a1699862bf3a1ec4b9dea93c55a3fa5faf8b5ea380431469df540f38b092c languageName: node linkType: hard @@ -17217,6 +18835,13 @@ __metadata: languageName: node linkType: hard +"is-generator-fn@npm:^2.0.0": + version: 2.1.0 + resolution: "is-generator-fn@npm:2.1.0" + checksum: 10/a6ad5492cf9d1746f73b6744e0c43c0020510b59d56ddcb78a91cbc173f09b5e6beff53d75c9c5a29feb618bfef2bf458e025ecf3a57ad2268e2fb2569f56215 + languageName: node + linkType: hard + "is-generator-function@npm:^1.0.10, is-generator-function@npm:^1.0.7": version: 1.1.2 resolution: "is-generator-function@npm:1.1.2" @@ -17368,6 +18993,13 @@ __metadata: languageName: node linkType: hard +"is-potential-custom-element-name@npm:^1.0.1": + version: 1.0.1 + resolution: "is-potential-custom-element-name@npm:1.0.1" + checksum: 10/ced7bbbb6433a5b684af581872afe0e1767e2d1146b2207ca0068a648fb5cab9d898495d1ac0583524faaf24ca98176a7d9876363097c2d14fee6dd324f3a1ab + languageName: node + linkType: hard + "is-promise@npm:^4.0.0": version: 4.0.0 resolution: "is-promise@npm:4.0.0" @@ -17567,83 +19199,533 @@ __metadata: languageName: node linkType: hard -"isexe@npm:^3.1.1": - version: 3.1.5 - resolution: "isexe@npm:3.1.5" - checksum: 10/ae479f6b0505507f1a73c1d57be6d0546e59fc9202bb0d5b31ba8ff5f3e79dd385bce57a2e60c5645aba567018cbbfc663519cd28367e9962242d97dd151d2ab +"isexe@npm:^3.1.1": + version: 3.1.5 + resolution: "isexe@npm:3.1.5" + checksum: 10/ae479f6b0505507f1a73c1d57be6d0546e59fc9202bb0d5b31ba8ff5f3e79dd385bce57a2e60c5645aba567018cbbfc663519cd28367e9962242d97dd151d2ab + languageName: node + linkType: hard + +"isexe@npm:^4.0.0": + version: 4.0.0 + resolution: "isexe@npm:4.0.0" + checksum: 10/2ead327ef596042ef9c9ec5f236b316acfaedb87f4bb61b3c3d574fb2e9c8a04b67305e04733bde52c24d9622fdebd3270aadb632adfbf9cadef88fe30f479e5 + languageName: node + linkType: hard + +"isomorphic-timers-promises@npm:^1.0.1": + version: 1.0.1 + resolution: "isomorphic-timers-promises@npm:1.0.1" + checksum: 10/2dabe397039081dbf30039f295333a7f9888b072dd0afa3aa7d8ba8f812a6db5efcbda0861a4be43ecfec207d56314ecf27150187b8d0f924a93103fa93eac73 + languageName: node + linkType: hard + +"isomorphic-ws@npm:5.0.0": + version: 5.0.0 + resolution: "isomorphic-ws@npm:5.0.0" + peerDependencies: + ws: "*" + checksum: 10/e20eb2aee09ba96247465fda40c6d22c1153394c0144fa34fe6609f341af4c8c564f60ea3ba762335a7a9c306809349f9b863c8beedf2beea09b299834ad5398 + languageName: node + linkType: hard + +"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": + version: 3.2.2 + resolution: "istanbul-lib-coverage@npm:3.2.2" + checksum: 10/40bbdd1e937dfd8c830fa286d0f665e81b7a78bdabcd4565f6d5667c99828bda3db7fb7ac6b96a3e2e8a2461ddbc5452d9f8bc7d00cb00075fa6a3e99f5b6a81 + languageName: node + linkType: hard + +"istanbul-lib-instrument@npm:^5.0.4": + version: 5.2.1 + resolution: "istanbul-lib-instrument@npm:5.2.1" + dependencies: + "@babel/core": "npm:^7.12.3" + "@babel/parser": "npm:^7.14.7" + "@istanbuljs/schema": "npm:^0.1.2" + istanbul-lib-coverage: "npm:^3.2.0" + semver: "npm:^6.3.0" + checksum: 10/bbc4496c2f304d799f8ec22202ab38c010ac265c441947f075c0f7d46bd440b45c00e46017cf9053453d42182d768b1d6ed0e70a142c95ab00df9843aa5ab80e + languageName: node + linkType: hard + +"istanbul-lib-instrument@npm:^6.0.0": + version: 6.0.3 + resolution: "istanbul-lib-instrument@npm:6.0.3" + dependencies: + "@babel/core": "npm:^7.23.9" + "@babel/parser": "npm:^7.23.9" + "@istanbuljs/schema": "npm:^0.1.3" + istanbul-lib-coverage: "npm:^3.2.0" + semver: "npm:^7.5.4" + checksum: 10/aa5271c0008dfa71b6ecc9ba1e801bf77b49dc05524e8c30d58aaf5b9505e0cd12f25f93165464d4266a518c5c75284ecb598fbd89fec081ae77d2c9d3327695 + languageName: node + linkType: hard + +"istanbul-lib-report@npm:^3.0.0": + version: 3.0.1 + resolution: "istanbul-lib-report@npm:3.0.1" + dependencies: + istanbul-lib-coverage: "npm:^3.0.0" + make-dir: "npm:^4.0.0" + supports-color: "npm:^7.1.0" + checksum: 10/86a83421ca1cf2109a9f6d193c06c31ef04a45e72a74579b11060b1e7bb9b6337a4e6f04abfb8857e2d569c271273c65e855ee429376a0d7c91ad91db42accd1 + languageName: node + linkType: hard + +"istanbul-lib-source-maps@npm:^4.0.0": + version: 4.0.1 + resolution: "istanbul-lib-source-maps@npm:4.0.1" + dependencies: + debug: "npm:^4.1.1" + istanbul-lib-coverage: "npm:^3.0.0" + source-map: "npm:^0.6.1" + checksum: 10/5526983462799aced011d776af166e350191b816821ea7bcf71cab3e5272657b062c47dc30697a22a43656e3ced78893a42de677f9ccf276a28c913190953b82 + languageName: node + linkType: hard + +"istanbul-reports@npm:^3.1.3": + version: 3.2.0 + resolution: "istanbul-reports@npm:3.2.0" + dependencies: + html-escaper: "npm:^2.0.0" + istanbul-lib-report: "npm:^3.0.0" + checksum: 10/6773a1d5c7d47eeec75b317144fe2a3b1da84a44b6282bebdc856e09667865e58c9b025b75b3d87f5bc62939126cbba4c871ee84254537d934ba5da5d4c4ec4e + languageName: node + linkType: hard + +"iterare@npm:1.2.1": + version: 1.2.1 + resolution: "iterare@npm:1.2.1" + checksum: 10/ee8322dd9d92e86d8653c899df501c58c5b8e90d6767cf2af0b6d6dc5a4b9b7ed8bce936976f4f4c3a55be110a300c8a7d71967d03f72e104e8db66befcfd874 + languageName: node + linkType: hard + +"iterator.prototype@npm:^1.1.5": + version: 1.1.5 + resolution: "iterator.prototype@npm:1.1.5" + dependencies: + define-data-property: "npm:^1.1.4" + es-object-atoms: "npm:^1.0.0" + get-intrinsic: "npm:^1.2.6" + get-proto: "npm:^1.0.0" + has-symbols: "npm:^1.1.0" + set-function-name: "npm:^2.0.2" + checksum: 10/352bcf333f42189e65cc8cb2dcb94a5c47cf0a9110ce12aba788d405a980b5f5f3a06c79bf915377e1d480647169babd842ded0d898bed181bf6686e8e6823f6 + languageName: node + linkType: hard + +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 10/96f8786eaab98e4bf5b2a5d6d9588ea46c4d06bbc4f2eb861fdd7b6b182b16f71d8a70e79820f335d52653b16d4843b29dd9cdcf38ae80406756db9199497cf3 + languageName: node + linkType: hard + +"jest-changed-files@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-changed-files@npm:29.7.0" + dependencies: + execa: "npm:^5.0.0" + jest-util: "npm:^29.7.0" + p-limit: "npm:^3.1.0" + checksum: 10/3d93742e56b1a73a145d55b66e96711fbf87ef89b96c2fab7cfdfba8ec06612591a982111ca2b712bb853dbc16831ec8b43585a2a96b83862d6767de59cbf83d + languageName: node + linkType: hard + +"jest-circus@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-circus@npm:29.7.0" + dependencies: + "@jest/environment": "npm:^29.7.0" + "@jest/expect": "npm:^29.7.0" + "@jest/test-result": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + "@types/node": "npm:*" + chalk: "npm:^4.0.0" + co: "npm:^4.6.0" + dedent: "npm:^1.0.0" + is-generator-fn: "npm:^2.0.0" + jest-each: "npm:^29.7.0" + jest-matcher-utils: "npm:^29.7.0" + jest-message-util: "npm:^29.7.0" + jest-runtime: "npm:^29.7.0" + jest-snapshot: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + p-limit: "npm:^3.1.0" + pretty-format: "npm:^29.7.0" + pure-rand: "npm:^6.0.0" + slash: "npm:^3.0.0" + stack-utils: "npm:^2.0.3" + checksum: 10/716a8e3f40572fd0213bcfc1da90274bf30d856e5133af58089a6ce45089b63f4d679bd44e6be9d320e8390483ebc3ae9921981993986d21639d9019b523123d + languageName: node + linkType: hard + +"jest-cli@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-cli@npm:29.7.0" + dependencies: + "@jest/core": "npm:^29.7.0" + "@jest/test-result": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + chalk: "npm:^4.0.0" + create-jest: "npm:^29.7.0" + exit: "npm:^0.1.2" + import-local: "npm:^3.0.2" + jest-config: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + jest-validate: "npm:^29.7.0" + yargs: "npm:^17.3.1" + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + bin: + jest: bin/jest.js + checksum: 10/6cc62b34d002c034203065a31e5e9a19e7c76d9e8ef447a6f70f759c0714cb212c6245f75e270ba458620f9c7b26063cd8cf6cd1f7e3afd659a7cc08add17307 + languageName: node + linkType: hard + +"jest-config@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-config@npm:29.7.0" + dependencies: + "@babel/core": "npm:^7.11.6" + "@jest/test-sequencer": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + babel-jest: "npm:^29.7.0" + chalk: "npm:^4.0.0" + ci-info: "npm:^3.2.0" + deepmerge: "npm:^4.2.2" + glob: "npm:^7.1.3" + graceful-fs: "npm:^4.2.9" + jest-circus: "npm:^29.7.0" + jest-environment-node: "npm:^29.7.0" + jest-get-type: "npm:^29.6.3" + jest-regex-util: "npm:^29.6.3" + jest-resolve: "npm:^29.7.0" + jest-runner: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + jest-validate: "npm:^29.7.0" + micromatch: "npm:^4.0.4" + parse-json: "npm:^5.2.0" + pretty-format: "npm:^29.7.0" + slash: "npm:^3.0.0" + strip-json-comments: "npm:^3.1.1" + peerDependencies: + "@types/node": "*" + ts-node: ">=9.0.0" + peerDependenciesMeta: + "@types/node": + optional: true + ts-node: + optional: true + checksum: 10/6bdf570e9592e7d7dd5124fc0e21f5fe92bd15033513632431b211797e3ab57eaa312f83cc6481b3094b72324e369e876f163579d60016677c117ec4853cf02b + languageName: node + linkType: hard + +"jest-css-modules@npm:^2.1.0": + version: 2.1.0 + resolution: "jest-css-modules@npm:2.1.0" + dependencies: + identity-obj-proxy: "npm:3.0.0" + checksum: 10/c7065e35e44aca2272eaa3c271e5f6af00c42768fd92dfe10344392dfc94ffc599f76d166412f55d917ef28405e32b28e80ece426c803eea2507f8bdea05ccb5 + languageName: node + linkType: hard + +"jest-diff@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-diff@npm:29.7.0" + dependencies: + chalk: "npm:^4.0.0" + diff-sequences: "npm:^29.6.3" + jest-get-type: "npm:^29.6.3" + pretty-format: "npm:^29.7.0" + checksum: 10/6f3a7eb9cd9de5ea9e5aa94aed535631fa6f80221832952839b3cb59dd419b91c20b73887deb0b62230d06d02d6b6cf34ebb810b88d904bb4fe1e2e4f0905c98 + languageName: node + linkType: hard + +"jest-docblock@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-docblock@npm:29.7.0" + dependencies: + detect-newline: "npm:^3.0.0" + checksum: 10/8d48818055bc96c9e4ec2e217a5a375623c0d0bfae8d22c26e011074940c202aa2534a3362294c81d981046885c05d304376afba9f2874143025981148f3e96d + languageName: node + linkType: hard + +"jest-each@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-each@npm:29.7.0" + dependencies: + "@jest/types": "npm:^29.6.3" + chalk: "npm:^4.0.0" + jest-get-type: "npm:^29.6.3" + jest-util: "npm:^29.7.0" + pretty-format: "npm:^29.7.0" + checksum: 10/bd1a077654bdaa013b590deb5f7e7ade68f2e3289180a8c8f53bc8a49f3b40740c0ec2d3a3c1aee906f682775be2bebbac37491d80b634d15276b0aa0f2e3fda + languageName: node + linkType: hard + +"jest-environment-jsdom@npm:^29.0.2": + version: 29.7.0 + resolution: "jest-environment-jsdom@npm:29.7.0" + dependencies: + "@jest/environment": "npm:^29.7.0" + "@jest/fake-timers": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + "@types/jsdom": "npm:^20.0.0" + "@types/node": "npm:*" + jest-mock: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + jsdom: "npm:^20.0.0" + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + checksum: 10/23bbfc9bca914baef4b654f7983175a4d49b0f515a5094ebcb8f819f28ec186f53c0ba06af1855eac04bab1457f4ea79dae05f70052cf899863e8096daa6e0f5 + languageName: node + linkType: hard + +"jest-environment-node@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-environment-node@npm:29.7.0" + dependencies: + "@jest/environment": "npm:^29.7.0" + "@jest/fake-timers": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + "@types/node": "npm:*" + jest-mock: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + checksum: 10/9cf7045adf2307cc93aed2f8488942e39388bff47ec1df149a997c6f714bfc66b2056768973770d3f8b1bf47396c19aa564877eb10ec978b952c6018ed1bd637 + languageName: node + linkType: hard + +"jest-get-type@npm:^29.6.3": + version: 29.6.3 + resolution: "jest-get-type@npm:29.6.3" + checksum: 10/88ac9102d4679d768accae29f1e75f592b760b44277df288ad76ce5bf038c3f5ce3719dea8aa0f035dac30e9eb034b848ce716b9183ad7cc222d029f03e92205 + languageName: node + linkType: hard + +"jest-haste-map@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-haste-map@npm:29.7.0" + dependencies: + "@jest/types": "npm:^29.6.3" + "@types/graceful-fs": "npm:^4.1.3" + "@types/node": "npm:*" + anymatch: "npm:^3.0.3" + fb-watchman: "npm:^2.0.0" + fsevents: "npm:^2.3.2" + graceful-fs: "npm:^4.2.9" + jest-regex-util: "npm:^29.6.3" + jest-util: "npm:^29.7.0" + jest-worker: "npm:^29.7.0" + micromatch: "npm:^4.0.4" + walker: "npm:^1.0.8" + dependenciesMeta: + fsevents: + optional: true + checksum: 10/8531b42003581cb18a69a2774e68c456fb5a5c3280b1b9b77475af9e346b6a457250f9d756bfeeae2fe6cbc9ef28434c205edab9390ee970a919baddfa08bb85 + languageName: node + linkType: hard + +"jest-leak-detector@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-leak-detector@npm:29.7.0" + dependencies: + jest-get-type: "npm:^29.6.3" + pretty-format: "npm:^29.7.0" + checksum: 10/e3950e3ddd71e1d0c22924c51a300a1c2db6cf69ec1e51f95ccf424bcc070f78664813bef7aed4b16b96dfbdeea53fe358f8aeaaea84346ae15c3735758f1605 + languageName: node + linkType: hard + +"jest-matcher-utils@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-matcher-utils@npm:29.7.0" + dependencies: + chalk: "npm:^4.0.0" + jest-diff: "npm:^29.7.0" + jest-get-type: "npm:^29.6.3" + pretty-format: "npm:^29.7.0" + checksum: 10/981904a494299cf1e3baed352f8a3bd8b50a8c13a662c509b6a53c31461f94ea3bfeffa9d5efcfeb248e384e318c87de7e3baa6af0f79674e987482aa189af40 + languageName: node + linkType: hard + +"jest-message-util@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-message-util@npm:29.7.0" + dependencies: + "@babel/code-frame": "npm:^7.12.13" + "@jest/types": "npm:^29.6.3" + "@types/stack-utils": "npm:^2.0.0" + chalk: "npm:^4.0.0" + graceful-fs: "npm:^4.2.9" + micromatch: "npm:^4.0.4" + pretty-format: "npm:^29.7.0" + slash: "npm:^3.0.0" + stack-utils: "npm:^2.0.3" + checksum: 10/31d53c6ed22095d86bab9d14c0fa70c4a92c749ea6ceece82cf30c22c9c0e26407acdfbdb0231435dc85a98d6d65ca0d9cbcd25cd1abb377fe945e843fb770b9 + languageName: node + linkType: hard + +"jest-mock@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-mock@npm:29.7.0" + dependencies: + "@jest/types": "npm:^29.6.3" + "@types/node": "npm:*" + jest-util: "npm:^29.7.0" + checksum: 10/ae51d1b4f898724be5e0e52b2268a68fcd876d9b20633c864a6dd6b1994cbc48d62402b0f40f3a1b669b30ebd648821f086c26c08ffde192ced951ff4670d51c languageName: node linkType: hard -"isexe@npm:^4.0.0": - version: 4.0.0 - resolution: "isexe@npm:4.0.0" - checksum: 10/2ead327ef596042ef9c9ec5f236b316acfaedb87f4bb61b3c3d574fb2e9c8a04b67305e04733bde52c24d9622fdebd3270aadb632adfbf9cadef88fe30f479e5 +"jest-pnp-resolver@npm:^1.2.2": + version: 1.2.3 + resolution: "jest-pnp-resolver@npm:1.2.3" + peerDependencies: + jest-resolve: "*" + peerDependenciesMeta: + jest-resolve: + optional: true + checksum: 10/db1a8ab2cb97ca19c01b1cfa9a9c8c69a143fde833c14df1fab0766f411b1148ff0df878adea09007ac6a2085ec116ba9a996a6ad104b1e58c20adbf88eed9b2 languageName: node linkType: hard -"isomorphic-timers-promises@npm:^1.0.1": - version: 1.0.1 - resolution: "isomorphic-timers-promises@npm:1.0.1" - checksum: 10/2dabe397039081dbf30039f295333a7f9888b072dd0afa3aa7d8ba8f812a6db5efcbda0861a4be43ecfec207d56314ecf27150187b8d0f924a93103fa93eac73 +"jest-regex-util@npm:30.0.1": + version: 30.0.1 + resolution: "jest-regex-util@npm:30.0.1" + checksum: 10/fa8dac80c3e94db20d5e1e51d1bdf101cf5ede8f4e0b8f395ba8b8ea81e71804ffd747452a6bb6413032865de98ac656ef8ae43eddd18d980b6442a2764ed562 languageName: node linkType: hard -"isomorphic-ws@npm:5.0.0": - version: 5.0.0 - resolution: "isomorphic-ws@npm:5.0.0" - peerDependencies: - ws: "*" - checksum: 10/e20eb2aee09ba96247465fda40c6d22c1153394c0144fa34fe6609f341af4c8c564f60ea3ba762335a7a9c306809349f9b863c8beedf2beea09b299834ad5398 +"jest-regex-util@npm:^29.6.3": + version: 29.6.3 + resolution: "jest-regex-util@npm:29.6.3" + checksum: 10/0518beeb9bf1228261695e54f0feaad3606df26a19764bc19541e0fc6e2a3737191904607fb72f3f2ce85d9c16b28df79b7b1ec9443aa08c3ef0e9efda6f8f2a languageName: node linkType: hard -"iterare@npm:1.2.1": - version: 1.2.1 - resolution: "iterare@npm:1.2.1" - checksum: 10/ee8322dd9d92e86d8653c899df501c58c5b8e90d6767cf2af0b6d6dc5a4b9b7ed8bce936976f4f4c3a55be110a300c8a7d71967d03f72e104e8db66befcfd874 +"jest-resolve-dependencies@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-resolve-dependencies@npm:29.7.0" + dependencies: + jest-regex-util: "npm:^29.6.3" + jest-snapshot: "npm:^29.7.0" + checksum: 10/1e206f94a660d81e977bcfb1baae6450cb4a81c92e06fad376cc5ea16b8e8c6ea78c383f39e95591a9eb7f925b6a1021086c38941aa7c1b8a6a813c2f6e93675 languageName: node linkType: hard -"iterator.prototype@npm:^1.1.5": - version: 1.1.5 - resolution: "iterator.prototype@npm:1.1.5" +"jest-resolve@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-resolve@npm:29.7.0" dependencies: - define-data-property: "npm:^1.1.4" - es-object-atoms: "npm:^1.0.0" - get-intrinsic: "npm:^1.2.6" - get-proto: "npm:^1.0.0" - has-symbols: "npm:^1.1.0" - set-function-name: "npm:^2.0.2" - checksum: 10/352bcf333f42189e65cc8cb2dcb94a5c47cf0a9110ce12aba788d405a980b5f5f3a06c79bf915377e1d480647169babd842ded0d898bed181bf6686e8e6823f6 + chalk: "npm:^4.0.0" + graceful-fs: "npm:^4.2.9" + jest-haste-map: "npm:^29.7.0" + jest-pnp-resolver: "npm:^1.2.2" + jest-util: "npm:^29.7.0" + jest-validate: "npm:^29.7.0" + resolve: "npm:^1.20.0" + resolve.exports: "npm:^2.0.0" + slash: "npm:^3.0.0" + checksum: 10/faa466fd9bc69ea6c37a545a7c6e808e073c66f46ab7d3d8a6ef084f8708f201b85d5fe1799789578b8b47fa1de47b9ee47b414d1863bc117a49e032ba77b7c7 languageName: node linkType: hard -"jackspeak@npm:^3.1.2": - version: 3.4.3 - resolution: "jackspeak@npm:3.4.3" +"jest-runner@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-runner@npm:29.7.0" dependencies: - "@isaacs/cliui": "npm:^8.0.2" - "@pkgjs/parseargs": "npm:^0.11.0" - dependenciesMeta: - "@pkgjs/parseargs": - optional: true - checksum: 10/96f8786eaab98e4bf5b2a5d6d9588ea46c4d06bbc4f2eb861fdd7b6b182b16f71d8a70e79820f335d52653b16d4843b29dd9cdcf38ae80406756db9199497cf3 + "@jest/console": "npm:^29.7.0" + "@jest/environment": "npm:^29.7.0" + "@jest/test-result": "npm:^29.7.0" + "@jest/transform": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + "@types/node": "npm:*" + chalk: "npm:^4.0.0" + emittery: "npm:^0.13.1" + graceful-fs: "npm:^4.2.9" + jest-docblock: "npm:^29.7.0" + jest-environment-node: "npm:^29.7.0" + jest-haste-map: "npm:^29.7.0" + jest-leak-detector: "npm:^29.7.0" + jest-message-util: "npm:^29.7.0" + jest-resolve: "npm:^29.7.0" + jest-runtime: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + jest-watcher: "npm:^29.7.0" + jest-worker: "npm:^29.7.0" + p-limit: "npm:^3.1.0" + source-map-support: "npm:0.5.13" + checksum: 10/9d8748a494bd90f5c82acea99be9e99f21358263ce6feae44d3f1b0cd90991b5df5d18d607e73c07be95861ee86d1cbab2a3fc6ca4b21805f07ac29d47c1da1e languageName: node linkType: hard -"jest-css-modules@npm:^2.1.0": - version: 2.1.0 - resolution: "jest-css-modules@npm:2.1.0" - dependencies: - identity-obj-proxy: "npm:3.0.0" - checksum: 10/c7065e35e44aca2272eaa3c271e5f6af00c42768fd92dfe10344392dfc94ffc599f76d166412f55d917ef28405e32b28e80ece426c803eea2507f8bdea05ccb5 +"jest-runtime@npm:^29.0.2, jest-runtime@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-runtime@npm:29.7.0" + dependencies: + "@jest/environment": "npm:^29.7.0" + "@jest/fake-timers": "npm:^29.7.0" + "@jest/globals": "npm:^29.7.0" + "@jest/source-map": "npm:^29.6.3" + "@jest/test-result": "npm:^29.7.0" + "@jest/transform": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + "@types/node": "npm:*" + chalk: "npm:^4.0.0" + cjs-module-lexer: "npm:^1.0.0" + collect-v8-coverage: "npm:^1.0.0" + glob: "npm:^7.1.3" + graceful-fs: "npm:^4.2.9" + jest-haste-map: "npm:^29.7.0" + jest-message-util: "npm:^29.7.0" + jest-mock: "npm:^29.7.0" + jest-regex-util: "npm:^29.6.3" + jest-resolve: "npm:^29.7.0" + jest-snapshot: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + slash: "npm:^3.0.0" + strip-bom: "npm:^4.0.0" + checksum: 10/59eb58eb7e150e0834a2d0c0d94f2a0b963ae7182cfa6c63f2b49b9c6ef794e5193ef1634e01db41420c36a94cefc512cdd67a055cd3e6fa2f41eaf0f82f5a20 languageName: node linkType: hard -"jest-regex-util@npm:30.0.1": - version: 30.0.1 - resolution: "jest-regex-util@npm:30.0.1" - checksum: 10/fa8dac80c3e94db20d5e1e51d1bdf101cf5ede8f4e0b8f395ba8b8ea81e71804ffd747452a6bb6413032865de98ac656ef8ae43eddd18d980b6442a2764ed562 +"jest-snapshot@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-snapshot@npm:29.7.0" + dependencies: + "@babel/core": "npm:^7.11.6" + "@babel/generator": "npm:^7.7.2" + "@babel/plugin-syntax-jsx": "npm:^7.7.2" + "@babel/plugin-syntax-typescript": "npm:^7.7.2" + "@babel/types": "npm:^7.3.3" + "@jest/expect-utils": "npm:^29.7.0" + "@jest/transform": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + babel-preset-current-node-syntax: "npm:^1.0.0" + chalk: "npm:^4.0.0" + expect: "npm:^29.7.0" + graceful-fs: "npm:^4.2.9" + jest-diff: "npm:^29.7.0" + jest-get-type: "npm:^29.6.3" + jest-matcher-utils: "npm:^29.7.0" + jest-message-util: "npm:^29.7.0" + jest-util: "npm:^29.7.0" + natural-compare: "npm:^1.4.0" + pretty-format: "npm:^29.7.0" + semver: "npm:^7.5.3" + checksum: 10/cb19a3948256de5f922d52f251821f99657339969bf86843bd26cf3332eae94883e8260e3d2fba46129a27c3971c1aa522490e460e16c7fad516e82d10bbf9f8 languageName: node linkType: hard @@ -17661,6 +19743,36 @@ __metadata: languageName: node linkType: hard +"jest-validate@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-validate@npm:29.7.0" + dependencies: + "@jest/types": "npm:^29.6.3" + camelcase: "npm:^6.2.0" + chalk: "npm:^4.0.0" + jest-get-type: "npm:^29.6.3" + leven: "npm:^3.1.0" + pretty-format: "npm:^29.7.0" + checksum: 10/8ee1163666d8eaa16d90a989edba2b4a3c8ab0ffaa95ad91b08ca42b015bfb70e164b247a5b17f9de32d096987cada63ed8491ab82761bfb9a28bc34b27ae161 + languageName: node + linkType: hard + +"jest-watcher@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-watcher@npm:29.7.0" + dependencies: + "@jest/test-result": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + "@types/node": "npm:*" + ansi-escapes: "npm:^4.2.1" + chalk: "npm:^4.0.0" + emittery: "npm:^0.13.1" + jest-util: "npm:^29.7.0" + string-length: "npm:^4.0.1" + checksum: 10/4f616e0345676631a7034b1d94971aaa719f0cd4a6041be2aa299be437ea047afd4fe05c48873b7963f5687a2f6c7cbf51244be8b14e313b97bfe32b1e127e55 + languageName: node + linkType: hard + "jest-worker@npm:^27.4.5": version: 27.5.1 resolution: "jest-worker@npm:27.5.1" @@ -17684,7 +19796,7 @@ __metadata: languageName: node linkType: hard -"jiti@npm:2.4.2": +"jiti@npm:2.4.2, jiti@npm:^2.4.2": version: 2.4.2 resolution: "jiti@npm:2.4.2" bin: @@ -17760,6 +19872,13 @@ __metadata: languageName: node linkType: hard +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: 10/bebe7ae829bbd586ce8cbe83501dd8cb8c282c8902a8aeeed0a073a89dc37e8103b1244f3c6acd60278bcbfe12d93a3f83c9ac396868a3b3bbc3c5e5e3b648ef + languageName: node + linkType: hard + "jsep@npm:^1.2.0, jsep@npm:^1.3.6, jsep@npm:^1.4.0": version: 1.4.0 resolution: "jsep@npm:1.4.0" @@ -17767,7 +19886,7 @@ __metadata: languageName: node linkType: hard -"jsesc@npm:^3.0.2": +"jsesc@npm:^3.0.2, jsesc@npm:~3.1.0": version: 3.1.0 resolution: "jsesc@npm:3.1.0" bin: @@ -17792,6 +19911,7 @@ __metadata: languageName: node linkType: hard +"json-parse-even-better-errors@npm:^2.3.0, json-parse-even-better-errors@npm:^2.3.1": "json-parse-even-better-errors@npm:^2.3.0, json-parse-even-better-errors@npm:^2.3.1": version: 2.3.1 resolution: "json-parse-even-better-errors@npm:2.3.1" @@ -17885,7 +20005,7 @@ __metadata: languageName: node linkType: hard -"json5@npm:^2.1.2": +"json5@npm:^2.1.2, json5@npm:^2.2.3": version: 2.2.3 resolution: "json5@npm:2.2.3" bin: @@ -18290,6 +20410,47 @@ __metadata: languageName: node linkType: hard +"koa-convert@npm:^2.0.0": + version: 2.0.0 + resolution: "koa-convert@npm:2.0.0" + dependencies: + co: "npm:^4.6.0" + koa-compose: "npm:^4.1.0" + checksum: 10/7385b3391995f59c1312142e110d5dff677f9850dbfbcf387cd36a7b0af03b5d26e82b811eb9bb008b4f3e661cdab1f8817596e46b1929da2cf6e97a2f7456ed + languageName: node + linkType: hard + +"koa@npm:2.15.4": + version: 2.15.4 + resolution: "koa@npm:2.15.4" + dependencies: + accepts: "npm:^1.3.5" + cache-content-type: "npm:^1.0.0" + content-disposition: "npm:~0.5.2" + content-type: "npm:^1.0.4" + cookies: "npm:~0.9.0" + debug: "npm:^4.3.2" + delegates: "npm:^1.0.0" + depd: "npm:^2.0.0" + destroy: "npm:^1.0.4" + encodeurl: "npm:^1.0.2" + escape-html: "npm:^1.0.3" + fresh: "npm:~0.5.2" + http-assert: "npm:^1.3.0" + http-errors: "npm:^1.6.3" + is-generator-function: "npm:^1.0.7" + koa-compose: "npm:^4.1.0" + koa-convert: "npm:^2.0.0" + on-finished: "npm:^2.3.0" + only: "npm:~0.0.2" + parseurl: "npm:^1.3.2" + statuses: "npm:^1.5.0" + type-is: "npm:^1.6.16" + vary: "npm:^1.1.2" + checksum: 10/98de77173822f0a28c0f5d1ebd261ab02f3f905d40602e51957a0c7202122647a60c5b6c59be03361dd24bf6a5685eac97af84b306914efd057751e71f93cb0f + languageName: node + linkType: hard + "koa@npm:3.0.3": version: 3.0.3 resolution: "koa@npm:3.0.3" @@ -18420,6 +20581,13 @@ __metadata: languageName: node linkType: hard +"loader-runner@npm:^4.3.1": + version: 4.3.1 + resolution: "loader-runner@npm:4.3.1" + checksum: 10/d77127497c3f91fdba351e3e91156034e6e590e9f050b40df6c38ac16c54b5c903f7e2e141e09fefd046ee96b26fb50773c695ebc0aa205a4918683b124b04ba + languageName: node + linkType: hard + "loader-utils@npm:^1.1.0": version: 1.4.2 resolution: "loader-utils@npm:1.4.2" @@ -18431,6 +20599,7 @@ __metadata: languageName: node linkType: hard +"loader-utils@npm:^2.0.0, loader-utils@npm:^2.0.4": "loader-utils@npm:^2.0.0, loader-utils@npm:^2.0.4": version: 2.0.4 resolution: "loader-utils@npm:2.0.4" @@ -18491,6 +20660,13 @@ __metadata: languageName: node linkType: hard +"lodash.debounce@npm:^4.0.8": + version: 4.0.8 + resolution: "lodash.debounce@npm:4.0.8" + checksum: 10/cd0b2819786e6e80cb9f5cda26b1a8fc073daaf04e48d4cb462fa4663ec9adb3a5387aa22d7129e48eed1afa05b482e2a6b79bfc99b86886364449500cbb00fd + languageName: node + linkType: hard + "lodash.defaults@npm:^4.2.0": version: 4.2.0 resolution: "lodash.defaults@npm:4.2.0" @@ -18719,13 +20895,6 @@ __metadata: languageName: node linkType: hard -"lru-cache@npm:^11.0.0, lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1": - version: 11.2.7 - resolution: "lru-cache@npm:11.2.7" - checksum: 10/fbff4b8dee8189dde9b52cdfb3ea89b4c9cec094c1538cd30d1f47299477ff312efdb35f7994477ec72328f8e754e232b26a143feda1bd1f79ff22da6664d2c5 - languageName: node - linkType: hard - "lru-cache@npm:^6.0.0": version: 6.0.0 resolution: "lru-cache@npm:6.0.0" @@ -18788,6 +20957,15 @@ __metadata: languageName: node linkType: hard +"make-dir@npm:^4.0.0": + version: 4.0.0 + resolution: "make-dir@npm:4.0.0" + dependencies: + semver: "npm:^7.5.3" + checksum: 10/bf0731a2dd3aab4db6f3de1585cea0b746bb73eb5a02e3d8d72757e376e64e6ada190b1eddcde5b2f24a81b688a9897efd5018737d05e02e2a671dda9cff8a8a + languageName: node + linkType: hard + "make-error@npm:^1.1.1": version: 1.3.6 resolution: "make-error@npm:1.3.6" @@ -18842,6 +21020,15 @@ __metadata: languageName: node linkType: hard +"makeerror@npm:1.0.12": + version: 1.0.12 + resolution: "makeerror@npm:1.0.12" + dependencies: + tmpl: "npm:1.0.5" + checksum: 10/4c66ddfc654537333da952c084f507fa4c30c707b1635344eb35be894d797ba44c901a9cebe914aa29a7f61357543ba09b09dddbd7f65b4aee756b450f169f40 + languageName: node + linkType: hard + "markdown-escape@npm:^2.0.0": version: 2.0.0 resolution: "markdown-escape@npm:2.0.0" @@ -19208,6 +21395,7 @@ __metadata: languageName: node linkType: hard +"memfs@npm:^3.1.2, memfs@npm:^3.4.1": "memfs@npm:^3.1.2, memfs@npm:^3.4.1": version: 3.5.3 resolution: "memfs@npm:3.5.3" @@ -19855,7 +22043,7 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:^4.0.2, micromatch@npm:^4.0.5, micromatch@npm:^4.0.8": +"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5, micromatch@npm:^4.0.8": version: 4.0.8 resolution: "micromatch@npm:4.0.8" dependencies: @@ -19891,7 +22079,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:^2.1.27, mime-types@npm:^2.1.35, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34, mime-types@npm:~2.1.35": +"mime-types@npm:^2.1.12, mime-types@npm:^2.1.31, mime-types@npm:^2.1.35, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -19969,6 +22157,18 @@ __metadata: languageName: node linkType: hard +"mini-css-extract-plugin@npm:^2.4.2": + version: 2.10.1 + resolution: "mini-css-extract-plugin@npm:2.10.1" + dependencies: + schema-utils: "npm:^4.0.0" + tapable: "npm:^2.2.1" + peerDependencies: + webpack: ^5.0.0 + checksum: 10/2d0cecc3bea85cd7f9b1ce0974f1672976d610a9267e2988ff19f5d03b017bff12b32151a412de0f519a70be7d3b050b499b20101445fb21728cc2d35dd4041a + languageName: node + linkType: hard + "minimalistic-assert@npm:^1.0.0, minimalistic-assert@npm:^1.0.1": version: 1.0.1 resolution: "minimalistic-assert@npm:1.0.1" @@ -20010,9 +22210,9 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^10.2.1, minimatch@npm:^10.2.2": - version: 10.2.4 - resolution: "minimatch@npm:10.2.4" +"minimatch@npm:^5.0.1, minimatch@npm:^5.1.0": + version: 5.1.6 + resolution: "minimatch@npm:5.1.6" dependencies: brace-expansion: "npm:^5.0.2" checksum: 10/aea4874e521c55bb60744685bbffe3d152e5460f84efac3ea936e6bbe2ceba7deb93345fec3f9bb17f7b6946776073a64d40ae32bf5f298ad690308121068a1f @@ -20411,23 +22611,7 @@ __metadata: languageName: node linkType: hard -"node-abort-controller@npm:^3.0.1": - version: 3.1.1 - resolution: "node-abort-controller@npm:3.1.1" - checksum: 10/0a2cdb7ec0aeaf3cb31e1ca0e192f5add48f1c5c9c9ed822129f9dddbd9432f69b7425982f94ce803c56a2104884530aa67cd57696e5774b2e5b8ec2f58de042 - languageName: node - linkType: hard - -"node-addon-api@npm:^4.3.0": - version: 4.3.0 - resolution: "node-addon-api@npm:4.3.0" - dependencies: - node-gyp: "npm:latest" - checksum: 10/d3b38d16cb9ad0714d965331d0e38cef1c27750c2c3343cd3464a9ed8158501a2910ccbf2fd9fdc476e806a19dbc9e0524ff9d66a7c779d42a9752a63ba30b80 - languageName: node - linkType: hard - -"node-domexception@npm:1.0.0, node-domexception@npm:^1.0.0": +"node-domexception@npm:1.0.0": version: 1.0.0 resolution: "node-domexception@npm:1.0.0" checksum: 10/e332522f242348c511640c25a6fc7da4f30e09e580c70c6b13cb0be83c78c3e71c8d4665af2527e869fc96848924a4316ae7ec9014c091e2156f41739d4fa233 @@ -20460,21 +22644,10 @@ __metadata: languageName: node linkType: hard -"node-fetch@npm:^3.3.2": - version: 3.3.2 - resolution: "node-fetch@npm:3.3.2" - dependencies: - data-uri-to-buffer: "npm:^4.0.0" - fetch-blob: "npm:^3.1.4" - formdata-polyfill: "npm:^4.0.10" - checksum: 10/24207ca8c81231c7c59151840e3fded461d67a31cf3e3b3968e12201a42f89ce4a0b5fb7079b1fa0a4655957b1ca9257553200f03a9f668b45ebad265ca5593d - languageName: node - linkType: hard - "node-forge@npm:^1, node-forge@npm:^1.3.2": - version: 1.4.0 - resolution: "node-forge@npm:1.4.0" - checksum: 10/d70fd769768e646eda73343d4d4105ccb6869315d975905a22117431c04ae5b6df6c488e34ed275b1a66b50195a09b84b5c8aeca3b8605c20605fcb8e9f109d9 + version: 1.3.3 + resolution: "node-forge@npm:1.3.3" + checksum: 10/f41c31b9296771a4b8c955d58417471712f54f324603a35f8e6cbac19d5e6eaaf5fd5fd14584dfedecbf46a05438ded6eee60a5f2f0822fc5061aaa073cfc75d languageName: node linkType: hard @@ -20525,6 +22698,13 @@ __metadata: languageName: node linkType: hard +"node-int64@npm:^0.4.0": + version: 0.4.0 + resolution: "node-int64@npm:0.4.0" + checksum: 10/b7afc2b65e56f7035b1a2eec57ae0fbdee7d742b1cdcd0f4387562b6527a011ab1cbe9f64cc8b3cca61e3297c9637c8bf61cec2e6b8d3a711d4b5267dfafbe02 + languageName: node + linkType: hard + "node-machine-id@npm:^1.1.12": version: 1.1.12 resolution: "node-machine-id@npm:1.1.12" @@ -20661,6 +22841,15 @@ __metadata: languageName: node linkType: hard +"npm-run-path@npm:^4.0.1": + version: 4.0.1 + resolution: "npm-run-path@npm:4.0.1" + dependencies: + path-key: "npm:^3.0.0" + checksum: 10/5374c0cea4b0bbfdfae62da7bbdf1e1558d338335f4cacf2515c282ff358ff27b2ecb91ffa5330a8b14390ac66a1e146e10700440c1ab868208430f56b5f4d23 + languageName: node + linkType: hard + "nth-check@npm:^2.0.1": version: 2.1.1 resolution: "nth-check@npm:2.1.1" @@ -20670,6 +22859,13 @@ __metadata: languageName: node linkType: hard +"nwsapi@npm:^2.2.2": + version: 2.2.23 + resolution: "nwsapi@npm:2.2.23" + checksum: 10/aa4a570039c33d70b51436d1bb533f3e2c33c488ccbe9b09285c46a6cee5ef266fd60103461085c6954ba52460786a8138f042958328c7c1b4763898eb3dadfa + languageName: node + linkType: hard + "object-assign@npm:^4, object-assign@npm:^4.0.1, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" @@ -20778,7 +22974,7 @@ __metadata: languageName: node linkType: hard -"on-finished@npm:^2.4.1, on-finished@npm:~2.4.1": +"on-finished@npm:^2.3.0, on-finished@npm:^2.4.1, on-finished@npm:~2.4.1": version: 2.4.1 resolution: "on-finished@npm:2.4.1" dependencies: @@ -20812,7 +23008,7 @@ __metadata: languageName: node linkType: hard -"onetime@npm:^5.1.0": +"onetime@npm:^5.1.0, onetime@npm:^5.1.2": version: 5.1.2 resolution: "onetime@npm:5.1.2" dependencies: @@ -20821,6 +23017,13 @@ __metadata: languageName: node linkType: hard +"only@npm:~0.0.2": + version: 0.0.2 + resolution: "only@npm:0.0.2" + checksum: 10/e2ad03e486534dc6bfb983393be83125a4669052b4a19a353eb00475b46971fb238a18223f2b609fe0d1bcb61ff8373964ccac64d05cbf970865299f655ed0ba + languageName: node + linkType: hard + "open@npm:^10.0.3, open@npm:^10.1.0": version: 10.2.0 resolution: "open@npm:10.2.0" @@ -21256,6 +23459,7 @@ __metadata: languageName: node linkType: hard +"parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": "parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" @@ -21300,7 +23504,7 @@ __metadata: languageName: node linkType: hard -"parseurl@npm:^1.3.3, parseurl@npm:~1.3.3": +"parseurl@npm:^1.3.3, parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" checksum: 10/407cee8e0a3a4c5cd472559bca8b6a45b82c124e9a4703302326e9ab60fc1081442ada4e02628efef1eb16197ddc7f8822f5a91fd7d7c86b51f530aedb17dfa2 @@ -21377,7 +23581,7 @@ __metadata: languageName: node linkType: hard -"path-key@npm:^3.1.0": +"path-key@npm:^3.0.0, path-key@npm:^3.1.0": version: 3.1.1 resolution: "path-key@npm:3.1.1" checksum: 10/55cd7a9dd4b343412a8386a743f9c746ef196e57c823d90ca3ab917f90ab9f13dd0ded27252ba49dbdfcab2b091d998bc446f6220cd3cea65db407502a740020 @@ -21593,9 +23797,9 @@ __metadata: linkType: hard "picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": - version: 2.3.2 - resolution: "picomatch@npm:2.3.2" - checksum: 10/b788ef8148a2415b9dec12f0bb350ae6a5830f8f1950e472abc2f5225494debf7d1b75eb031df0ceaea9e8ec3e7bad599e8dbf3c60d61b42be429ba41bff4426 + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 10/60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc languageName: node linkType: hard @@ -21627,7 +23831,7 @@ __metadata: languageName: node linkType: hard -"pirates@npm:^4.0.1, pirates@npm:^4.0.6": +"pirates@npm:^4.0.1, pirates@npm:^4.0.4, pirates@npm:^4.0.6": version: 4.0.7 resolution: "pirates@npm:4.0.7" checksum: 10/2427f371366081ae42feb58214f04805d6b41d6b84d74480ebcc9e0ddbd7105a139f7c653daeaf83ad8a1a77214cf07f64178e76de048128fec501eab3305a96 @@ -21641,6 +23845,15 @@ __metadata: languageName: node linkType: hard +"pkg-dir@npm:^4.2.0": + version: 4.2.0 + resolution: "pkg-dir@npm:4.2.0" + dependencies: + find-up: "npm:^4.0.0" + checksum: 10/9863e3f35132bf99ae1636d31ff1e1e3501251d480336edb1c211133c8d58906bed80f154a1d723652df1fda91e01c7442c2eeaf9dc83157c7ae89087e43c8d6 + languageName: node + linkType: hard + "pkg-dir@npm:^5.0.0": version: 5.0.0 resolution: "pkg-dir@npm:5.0.0" @@ -21673,6 +23886,20 @@ __metadata: languageName: node linkType: hard +"pkijs@npm:^3.3.3": + version: 3.4.0 + resolution: "pkijs@npm:3.4.0" + dependencies: + "@noble/hashes": "npm:1.4.0" + asn1js: "npm:^3.0.6" + bytestreamjs: "npm:^2.0.1" + pvtsutils: "npm:^1.3.6" + pvutils: "npm:^1.1.3" + tslib: "npm:^2.8.1" + checksum: 10/a937347584b27012919f69e4b3865b2fd09dced85a344f9a22bbf1376dd9e1534ccbe0bbdb997807b4990b07865c1ea028447d78b2c8a64436d4d393193a0777 + languageName: node + linkType: hard + "pluralize@npm:^8.0.0": version: 8.0.0 resolution: "pluralize@npm:8.0.0" @@ -22236,7 +24463,7 @@ __metadata: languageName: node linkType: hard -"prismjs@npm:^1.30.0": +"prismjs@npm:^1.27.0": version: 1.30.0 resolution: "prismjs@npm:1.30.0" checksum: 10/6b48a2439a82e5c6882f48ebc1564c3890e16463ba17ac10c3ad4f62d98dea5b5c915b172b63b83023a70ad4f5d7be3e8a60304420db34a161fae69dd4e3e2da @@ -22295,7 +24522,7 @@ __metadata: languageName: node linkType: hard -"prompts@npm:^2.4.2": +"prompts@npm:^2.0.1, prompts@npm:^2.4.2": version: 2.4.2 resolution: "prompts@npm:2.4.2" dependencies: @@ -22420,13 +24647,6 @@ __metadata: languageName: node linkType: hard -"proxy-from-env@npm:^2.1.0": - version: 2.1.0 - resolution: "proxy-from-env@npm:2.1.0" - checksum: 10/fbbaf4dab2a6231dc9e394903a5f66f20475e36b734335790b46feb9da07c37d6b32e2c02e3e2ea4d4b23774c53d8562e5b7cc73282cb43f4a597b7eacaee2ee - languageName: node - linkType: hard - "public-encrypt@npm:^4.0.3": version: 4.0.3 resolution: "public-encrypt@npm:4.0.3" @@ -22458,32 +24678,16 @@ __metadata: languageName: node linkType: hard -"punycode@npm:^2.1.0": +"punycode@npm:^2.1.0, punycode@npm:^2.1.1, punycode@npm:^2.3.1": version: 2.3.1 resolution: "punycode@npm:2.3.1" checksum: 10/febdc4362bead22f9e2608ff0171713230b57aff9dddc1c273aa2a651fbd366f94b7d6a71d78342a7c0819906750351ca7f2edd26ea41b626d87d6a13d1bd059 languageName: node linkType: hard -"pvtsutils@npm:^1.3.6": - version: 1.3.6 - resolution: "pvtsutils@npm:1.3.6" - dependencies: - tslib: "npm:^2.8.1" - checksum: 10/d45b12f8526e13ecf15fe09b30cde65501f3300fd2a07c11b28a966d434d1f767c8a61597ecba2e19c7eb19ca0c740341a6babc67a4f741e08b1ef1095c71663 - languageName: node - linkType: hard - -"pvutils@npm:^1.1.3": - version: 1.1.5 - resolution: "pvutils@npm:1.1.5" - checksum: 10/9a5a71603c72bf9ea3a4501e8251e3f7a56026ed059bf63a18bd9a30cac6c35cc8250b39eb6291c1cb204cdeb6660663ab9bb2c74e85a512919bb2d614e340ea - languageName: node - linkType: hard - -"qs@npm:^6.11.2, qs@npm:^6.12.3, qs@npm:^6.14.0, qs@npm:^6.14.1, qs@npm:^6.9.4": - version: 6.15.0 - resolution: "qs@npm:6.15.0" +"qs@npm:^6.11.2, qs@npm:^6.12.3, qs@npm:^6.14.0, qs@npm:^6.14.1, qs@npm:^6.9.4, qs@npm:~6.14.0": + version: 6.14.1 + resolution: "qs@npm:6.14.1" dependencies: side-channel: "npm:^1.1.0" checksum: 10/a3458f2f389285c3512e0ebc55522ee370ac7cb720ba9f0eff3e30fb2bb07631caf556c08e2a3d4481a371ac14faa9ceb7442a0610c5a7e55b23a5bdee7b701c @@ -22513,6 +24717,13 @@ __metadata: languageName: node linkType: hard +"querystringify@npm:^2.1.1": + version: 2.2.0 + resolution: "querystringify@npm:2.2.0" + checksum: 10/46ab16f252fd892fc29d6af60966d338cdfeea68a231e9457631ffd22d67cec1e00141e0a5236a2eb16c0d7d74175d9ec1d6f963660c6f2b1c2fc85b194c5680 + languageName: node + linkType: hard + "queue-microtask@npm:^1.2.2": version: 1.2.3 resolution: "queue-microtask@npm:1.2.3" @@ -23227,6 +25438,13 @@ __metadata: languageName: node linkType: hard +"readdirp@npm:^4.0.1": + version: 4.1.2 + resolution: "readdirp@npm:4.1.2" + checksum: 10/7b817c265940dba90bb9c94d82920d76c3a35ea2d67f9f9d8bd936adcfe02d50c802b14be3dd2e725e002dddbe2cc1c7a0edfb1bc3a365c9dfd5a61e612eea1e + languageName: node + linkType: hard + "readdirp@npm:~3.6.0": version: 3.6.0 resolution: "readdirp@npm:3.6.0" @@ -23289,6 +25507,7 @@ __metadata: languageName: node linkType: hard +"reflect-metadata@npm:0.2.2, reflect-metadata@npm:^0.2.2": "reflect-metadata@npm:0.2.2, reflect-metadata@npm:^0.2.2": version: 0.2.2 resolution: "reflect-metadata@npm:0.2.2" @@ -23323,6 +25542,22 @@ __metadata: languageName: node linkType: hard +"regenerate-unicode-properties@npm:^10.2.2": + version: 10.2.2 + resolution: "regenerate-unicode-properties@npm:10.2.2" + dependencies: + regenerate: "npm:^1.4.2" + checksum: 10/5041ee31185c4700de9dd76783fab9def51c412751190d523d621db5b8e35a6c2d91f1642c12247e7d94f84b8ae388d044baac1e88fc2ba0ac215ca8dc7bed38 + languageName: node + linkType: hard + +"regenerate@npm:^1.4.2": + version: 1.4.2 + resolution: "regenerate@npm:1.4.2" + checksum: 10/dc6c95ae4b3ba6adbd7687cafac260eee4640318c7a95239d5ce847d9b9263979758389e862fe9c93d633b5792ea4ada5708df75885dc5aa05a309fa18140a87 + languageName: node + linkType: hard + "regexp.prototype.flags@npm:^1.5.3, regexp.prototype.flags@npm:^1.5.4": version: 1.5.4 resolution: "regexp.prototype.flags@npm:1.5.4" @@ -23337,6 +25572,38 @@ __metadata: languageName: node linkType: hard +"regexpu-core@npm:^6.3.1": + version: 6.4.0 + resolution: "regexpu-core@npm:6.4.0" + dependencies: + regenerate: "npm:^1.4.2" + regenerate-unicode-properties: "npm:^10.2.2" + regjsgen: "npm:^0.8.0" + regjsparser: "npm:^0.13.0" + unicode-match-property-ecmascript: "npm:^2.0.0" + unicode-match-property-value-ecmascript: "npm:^2.2.1" + checksum: 10/bf5f85a502a17f127a1f922270e2ecc1f0dd071ff76a3ec9afcd6b1c2bf7eae1486d1e3b1a6d621aee8960c8b15139e6b5058a84a68e518e1a92b52e9322faf9 + languageName: node + linkType: hard + +"regjsgen@npm:^0.8.0": + version: 0.8.0 + resolution: "regjsgen@npm:0.8.0" + checksum: 10/b930f03347e4123c917d7b40436b4f87f625b8dd3e705b447ddd44804e4616c3addb7453f0902d6e914ab0446c30e816e445089bb641a4714237fe8141a0ef9d + languageName: node + linkType: hard + +"regjsparser@npm:^0.13.0": + version: 0.13.0 + resolution: "regjsparser@npm:0.13.0" + dependencies: + jsesc: "npm:~3.1.0" + bin: + regjsparser: bin/parser + checksum: 10/eeaabd3454f59394cbb3bfeb15fd789e638040f37d0bee9071a9b0b85524ddc52b5f7aaaaa4847304c36fa37429e53d109c4dbf6b878cb5ffa4f4198c1042fb7 + languageName: node + linkType: hard + "rehype-raw@npm:^6.0.0": version: 6.1.1 resolution: "rehype-raw@npm:6.1.1" @@ -23480,6 +25747,15 @@ __metadata: languageName: node linkType: hard +"resolve-cwd@npm:^3.0.0": + version: 3.0.0 + resolution: "resolve-cwd@npm:3.0.0" + dependencies: + resolve-from: "npm:^5.0.0" + checksum: 10/546e0816012d65778e580ad62b29e975a642989108d9a3c5beabfb2304192fa3c9f9146fbdfe213563c6ff51975ae41bac1d3c6e047dd9572c94863a057b4d81 + languageName: node + linkType: hard + "resolve-dir@npm:^1.0.0, resolve-dir@npm:^1.0.1": version: 1.0.1 resolution: "resolve-dir@npm:1.0.1" @@ -23511,6 +25787,13 @@ __metadata: languageName: node linkType: hard +"resolve.exports@npm:^2.0.0": + version: 2.0.3 + resolution: "resolve.exports@npm:2.0.3" + checksum: 10/536efee0f30a10fac8604e6cdc7844dbc3f4313568d09f06db4f7ed8a5b8aeb8585966fe975083d1f2dfbc87cf5f8bc7ab65a5c23385c14acbb535ca79f8398a + languageName: node + linkType: hard + "resolve@npm:1.22.8": version: 1.22.8 resolution: "resolve@npm:1.22.8" @@ -23524,7 +25807,7 @@ __metadata: languageName: node linkType: hard -"resolve@npm:^1.1.7, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.4, resolve@npm:~1.22.1, resolve@npm:~1.22.2": +"resolve@npm:^1.1.7, resolve@npm:^1.17.0, resolve@npm:^1.19.0, resolve@npm:^1.20.0, resolve@npm:^1.22.1, resolve@npm:^1.22.11, resolve@npm:^1.22.4, resolve@npm:~1.22.1, resolve@npm:~1.22.2": version: 1.22.11 resolution: "resolve@npm:1.22.11" dependencies: @@ -23566,7 +25849,7 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@npm%3A^1.1.7#optional!builtin, resolve@patch:resolve@npm%3A^1.17.0#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A~1.22.1#optional!builtin, resolve@patch:resolve@npm%3A~1.22.2#optional!builtin": +"resolve@patch:resolve@npm%3A^1.1.7#optional!builtin, resolve@patch:resolve@npm%3A^1.17.0#optional!builtin, resolve@patch:resolve@npm%3A^1.19.0#optional!builtin, resolve@patch:resolve@npm%3A^1.20.0#optional!builtin, resolve@patch:resolve@npm%3A^1.22.1#optional!builtin, resolve@patch:resolve@npm%3A^1.22.11#optional!builtin, resolve@patch:resolve@npm%3A^1.22.4#optional!builtin, resolve@patch:resolve@npm%3A~1.22.1#optional!builtin, resolve@patch:resolve@npm%3A~1.22.2#optional!builtin": version: 1.22.11 resolution: "resolve@patch:resolve@npm%3A1.22.11#optional!builtin::version=1.22.11&hash=c3c19d" dependencies: @@ -23992,13 +26275,6 @@ __metadata: languageName: node linkType: hard -"sax@npm:^1.5.0": - version: 1.6.0 - resolution: "sax@npm:1.6.0" - checksum: 10/0909cedcd9f011ceeac80c0240a92d64ef712cf6c04e0f6ee236a8d812f86a59f61bee6bb5da28d75306db050b99e0593051ea77351795822253b984af6cf044 - languageName: node - linkType: hard - "scheduler@npm:^0.23.2": version: 0.23.2 resolution: "scheduler@npm:0.23.2" @@ -24019,6 +26295,7 @@ __metadata: languageName: node linkType: hard +"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1": "schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1": version: 3.3.0 resolution: "schema-utils@npm:3.3.0" @@ -24030,9 +26307,9 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^4.0.0, schema-utils@npm:^4.2.0, schema-utils@npm:^4.3.0, schema-utils@npm:^4.3.3": - version: 4.3.3 - resolution: "schema-utils@npm:4.3.3" +"schema-utils@npm:^4.0.0, schema-utils@npm:^4.2.0, schema-utils@npm:^4.3.0": + version: 4.3.2 + resolution: "schema-utils@npm:4.3.2" dependencies: "@types/json-schema": "npm:^7.0.9" ajv: "npm:^8.9.0" @@ -24076,6 +26353,16 @@ __metadata: languageName: node linkType: hard +"selfsigned@npm:^5.5.0": + version: 5.5.0 + resolution: "selfsigned@npm:5.5.0" + dependencies: + "@peculiar/x509": "npm:^1.14.2" + pkijs: "npm:^3.3.3" + checksum: 10/fe9be2647507c3ee21dcaf5cab20e1ae4b8b84eac83d2fe4d82f9a3b6c70636f9aaeeba0089e3343dcb13fbb31ef70c2e72c41f2e2dcf38368040b49830c670e + languageName: node + linkType: hard + "semver-compare@npm:^1.0.0": version: 1.0.0 resolution: "semver-compare@npm:1.0.0" @@ -24101,7 +26388,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^6.3.1": +"semver@npm:^6.3.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" bin: @@ -24369,7 +26656,7 @@ __metadata: languageName: node linkType: hard -"signal-exit@npm:^3.0.2": +"signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" checksum: 10/a2f098f247adc367dffc27845853e9959b9e88b01cb301658cfe4194352d8d2bb32e18467c786a7fe15f1d44b233ea35633d076d5e737870b7139949d1ab6318 @@ -24484,6 +26771,13 @@ __metadata: languageName: node linkType: hard +"source-list-map@npm:^2.0.0": + version: 2.0.1 + resolution: "source-list-map@npm:2.0.1" + checksum: 10/3918ffba5fe8447bc816800026fe707aab233d9d05a3487225d880e23b7e37ed455b4e1b844e05644f6ecc7c9b837c0cc32da54dd37f77c993370ebcdb049246 + languageName: node + linkType: hard + "source-map-js@npm:^1.2.1": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" @@ -24491,6 +26785,16 @@ __metadata: languageName: node linkType: hard +"source-map-support@npm:0.5.13": + version: 0.5.13 + resolution: "source-map-support@npm:0.5.13" + dependencies: + buffer-from: "npm:^1.0.0" + source-map: "npm:^0.6.0" + checksum: 10/d1514a922ac9c7e4786037eeff6c3322f461cd25da34bb9fefb15387b3490531774e6e31d95ab6d5b84a3e139af9c3a570ccaee6b47bd7ea262691ed3a8bc34e + languageName: node + linkType: hard + "source-map-support@npm:~0.5.20": version: 0.5.21 resolution: "source-map-support@npm:0.5.21" @@ -24529,6 +26833,13 @@ __metadata: languageName: node linkType: hard +"source-map@npm:^0.7.3": + version: 0.7.6 + resolution: "source-map@npm:0.7.6" + checksum: 10/c8d2da7c57c14f3fd7568f764b39ad49bbf9dd7632b86df3542b31fed117d4af2fb74a4f886fc06baf7a510fee68e37998efc3080aacdac951c36211dc29a7a3 + languageName: node + linkType: hard + "space-separated-tokens@npm:^1.0.0": version: 1.1.5 resolution: "space-separated-tokens@npm:1.1.5" @@ -24683,6 +26994,15 @@ __metadata: languageName: node linkType: hard +"stack-utils@npm:^2.0.3": + version: 2.0.6 + resolution: "stack-utils@npm:2.0.6" + dependencies: + escape-string-regexp: "npm:^2.0.0" + checksum: 10/cdc988acbc99075b4b036ac6014e5f1e9afa7e564482b687da6384eee6a1909d7eaffde85b0a17ffbe186c5247faf6c2b7544e802109f63b72c7be69b13151bb + languageName: node + linkType: hard + "stackframe@npm:^1.3.4": version: 1.3.4 resolution: "stackframe@npm:1.3.4" @@ -24718,7 +27038,16 @@ __metadata: languageName: node linkType: hard -"statuses@npm:>= 1.5.0 < 2": +"static-eval@npm:2.1.1": + version: 2.1.1 + resolution: "static-eval@npm:2.1.1" + dependencies: + escodegen: "npm:^2.1.0" + checksum: 10/b47e8238014745ea457f2dc9e14130298ce5dbec142a5c93a943f338fe1b47d03086d1897114e15d8603a9a7a39fed95bb49ccd3fa95dfc1550952eca0688417 + languageName: node + linkType: hard + +"statuses@npm:>= 1.4.0 < 2, statuses@npm:>= 1.5.0 < 2": version: 1.5.0 resolution: "statuses@npm:1.5.0" checksum: 10/c469b9519de16a4bb19600205cffb39ee471a5f17b82589757ca7bd40a8d92ebb6ed9f98b5a540c5d302ccbc78f15dc03cc0280dd6e00df1335568a5d5758a5c @@ -24816,6 +27145,16 @@ __metadata: languageName: node linkType: hard +"string-length@npm:^4.0.1": + version: 4.0.2 + resolution: "string-length@npm:4.0.2" + dependencies: + char-regex: "npm:^1.0.2" + strip-ansi: "npm:^6.0.0" + checksum: 10/ce85533ef5113fcb7e522bcf9e62cb33871aa99b3729cec5595f4447f660b0cefd542ca6df4150c97a677d58b0cb727a3fe09ac1de94071d05526c73579bf505 + languageName: node + linkType: hard + "string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": version: 4.2.3 resolution: "string-width@npm:4.2.3" @@ -24980,6 +27319,20 @@ __metadata: languageName: node linkType: hard +"strip-bom@npm:^4.0.0": + version: 4.0.0 + resolution: "strip-bom@npm:4.0.0" + checksum: 10/9dbcfbaf503c57c06af15fe2c8176fb1bf3af5ff65003851a102749f875a6dbe0ab3b30115eccf6e805e9d756830d3e40ec508b62b3f1ddf3761a20ebe29d3f3 + languageName: node + linkType: hard + +"strip-final-newline@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-final-newline@npm:2.0.0" + checksum: 10/69412b5e25731e1938184b5d489c32e340605bb611d6140344abc3421b7f3c6f9984b21dff296dfcf056681b82caa3bb4cc996a965ce37bcfad663e92eae9c64 + languageName: node + linkType: hard + "strip-indent@npm:^3.0.0": version: 3.0.0 resolution: "strip-indent@npm:3.0.0" @@ -25183,8 +27536,8 @@ __metadata: linkType: hard "svgo@npm:^2.7.0": - version: 2.8.2 - resolution: "svgo@npm:2.8.2" + version: 2.8.0 + resolution: "svgo@npm:2.8.0" dependencies: commander: "npm:^7.2.0" css-select: "npm:^4.1.3" @@ -25223,6 +27576,13 @@ __metadata: languageName: node linkType: hard +"symbol-tree@npm:^3.2.4": + version: 3.2.4 + resolution: "symbol-tree@npm:3.2.4" + checksum: 10/c09a00aadf279d47d0c5c46ca3b6b2fbaeb45f0a184976d599637d412d3a70bbdc043ff33effe1206dea0e36e0ad226cb957112e7ce9a4bf2daedf7fa4f85c53 + languageName: node + linkType: hard + "tapable@npm:^1.0.0": version: 1.1.3 resolution: "tapable@npm:1.1.3" @@ -25230,10 +27590,10 @@ __metadata: languageName: node linkType: hard -"tapable@npm:^2.0.0, tapable@npm:^2.2.1, tapable@npm:^2.3.0": - version: 2.3.2 - resolution: "tapable@npm:2.3.2" - checksum: 10/fd3affe2e34efb3970883f934b1828f10b48dffb1eb71a52b7f955bfdd88bf80e94ec388704d95334f72ddf77e34d813b19e1f4bf56897d20252fa025d44bede +"tapable@npm:^2.0.0": + version: 2.2.2 + resolution: "tapable@npm:2.2.2" + checksum: 10/065a0dc44aba1b32020faa1c27c719e8f76e5345347515d8494bf158524f36e9f22ad9eaa5b5494f9d5d67bf0640afdd5698505948c46d720b6b7e69d19349a6 languageName: node linkType: hard @@ -25291,7 +27651,7 @@ __metadata: languageName: node linkType: hard -"tar@npm:^6.1.11, tar@npm:^6.2.1": +"tar@npm:^6.1.11, tar@npm:^6.1.12, tar@npm:^6.2.1": version: 6.2.1 resolution: "tar@npm:6.2.1" dependencies: @@ -25354,37 +27714,9 @@ __metadata: languageName: node linkType: hard -"terminal-columns@npm:^2.0.0": - version: 2.0.0 - resolution: "terminal-columns@npm:2.0.0" - checksum: 10/f958993886e09d7c0780f47833316532a0c7dd7db2fb43da9d34a88c821633408a6e7084af59f99c20b045776814748f14a8e33573886186be7a30174092964f - languageName: node - linkType: hard - -"terser-webpack-plugin@npm:^5.3.17": - version: 5.4.0 - resolution: "terser-webpack-plugin@npm:5.4.0" - dependencies: - "@jridgewell/trace-mapping": "npm:^0.3.25" - jest-worker: "npm:^27.4.5" - schema-utils: "npm:^4.3.0" - terser: "npm:^5.31.1" - peerDependencies: - webpack: ^5.1.0 - peerDependenciesMeta: - "@swc/core": - optional: true - esbuild: - optional: true - uglify-js: - optional: true - checksum: 10/f4618b18cec5dd41fca4a53f621ea06df04ff7bb2b09d3766559284e171a91df2884083e5c143aaacee2000870b046eb7157e39d1d2d8024577395165a070094 - languageName: node - linkType: hard - -"terser@npm:^5.10.0, terser@npm:^5.31.1": - version: 5.46.1 - resolution: "terser@npm:5.46.1" +"terser@npm:^5.10.0": + version: 5.43.1 + resolution: "terser@npm:5.43.1" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.15.0" @@ -25392,7 +27724,7 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/16d21179905e549dae2560e107d069ba0fdb801c637bf5f07c2f30431e53b1641151d5e35915ca6578ac1d9763984095723034bf1a26740b183093f200293f86 + checksum: 10/c0a0fd62319e0ce66e800f57ae12ef4ca45f12e9422dac160b866f0d890d01f8b547c96de2557b8443d96953db36be5d900e8006436ef9f628dbd38082e8fe5d languageName: node linkType: hard @@ -25544,9 +27876,9 @@ __metadata: languageName: node linkType: hard -"to-buffer@npm:^1.2.0, to-buffer@npm:^1.2.1, to-buffer@npm:^1.2.2": - version: 1.2.2 - resolution: "to-buffer@npm:1.2.2" +"to-buffer@npm:^1.2.0": + version: 1.2.1 + resolution: "to-buffer@npm:1.2.1" dependencies: isarray: "npm:^2.0.5" safe-buffer: "npm:^5.2.1" @@ -25596,6 +27928,27 @@ __metadata: languageName: node linkType: hard +"tough-cookie@npm:^4.1.2": + version: 4.1.4 + resolution: "tough-cookie@npm:4.1.4" + dependencies: + psl: "npm:^1.1.33" + punycode: "npm:^2.1.1" + universalify: "npm:^0.2.0" + url-parse: "npm:^1.5.3" + checksum: 10/75663f4e2cd085f16af0b217e4218772adf0617fb3227171102618a54ce0187a164e505d61f773ed7d65988f8ff8a8f935d381f87da981752c1171b076b4afac + languageName: node + linkType: hard + +"tr46@npm:^3.0.0": + version: 3.0.0 + resolution: "tr46@npm:3.0.0" + dependencies: + punycode: "npm:^2.1.1" + checksum: 10/b09a15886cbfaee419a3469081223489051ce9dca3374dd9500d2378adedbee84a3c73f83bfdd6bb13d53657753fc0d4e20a46bfcd3f1b9057ef528426ad7ce4 + languageName: node + linkType: hard + "tr46@npm:~0.0.3": version: 0.0.3 resolution: "tr46@npm:0.0.3" @@ -25775,7 +28128,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.14.1, tslib@npm:^1.9.3": +"tslib@npm:^1.14.1, tslib@npm:^1.9.0": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: 10/7dbf34e6f55c6492637adb81b555af5e3b4f9cc6b998fb440dac82d3b42bdc91560a35a5fb75e20e24a076c651438234da6743d139e4feabf0783f3cdfe1dddb @@ -25798,6 +28151,15 @@ __metadata: languageName: node linkType: hard +"tsyringe@npm:^4.10.0": + version: 4.10.0 + resolution: "tsyringe@npm:4.10.0" + dependencies: + tslib: "npm:^1.9.3" + checksum: 10/b42660dc112cee2db02b3d69f2ef6a6a9d185afd96b18d8f88e47c1e62be94b69a9f5a58fcfdb2a3fbb7c6c175b8162ea00f7db6499bf333ce945e570e31615c + languageName: node + linkType: hard + "tty-browserify@npm:0.0.1": version: 0.0.1 resolution: "tty-browserify@npm:0.0.1" @@ -25830,6 +28192,15 @@ __metadata: languageName: node linkType: hard +"type-check@npm:~0.3.2": + version: 0.3.2 + resolution: "type-check@npm:0.3.2" + dependencies: + prelude-ls: "npm:~1.1.2" + checksum: 10/11dec0b50d7c3fd2e630b4b074ba36918ed2b1efbc87dfbd40ba9429d49c58d12dad5c415ece69fcf358fa083f33466fc370f23ab91aa63295c45d38b3a60dda + languageName: node + linkType: hard + "type-fest@npm:^0.13.1": version: 0.13.1 resolution: "type-fest@npm:0.13.1" @@ -25858,10 +28229,13 @@ __metadata: languageName: node linkType: hard -"type-flag@npm:^4.1.0": - version: 4.1.0 - resolution: "type-flag@npm:4.1.0" - checksum: 10/d3af106dab651751426f778095b3963791d15482b2154f92f4f98e5d6b72d593ae9873120d2de24f34191ab42c0d71c0259743162e543aee8d55b528ed1c6e78 +"type-is@npm:^1.6.16, type-is@npm:~1.6.18": + version: 1.6.18 + resolution: "type-is@npm:1.6.18" + dependencies: + media-typer: "npm:0.3.0" + mime-types: "npm:~2.1.24" + checksum: 10/0bd9eeae5efd27d98fd63519f999908c009e148039d8e7179a074f105362d4fcc214c38b24f6cda79c87e563cbd12083a4691381ed28559220d4a10c2047bed4 languageName: node linkType: hard @@ -25876,16 +28250,6 @@ __metadata: languageName: node linkType: hard -"type-is@npm:~1.6.18": - version: 1.6.18 - resolution: "type-is@npm:1.6.18" - dependencies: - media-typer: "npm:0.3.0" - mime-types: "npm:~2.1.24" - checksum: 10/0bd9eeae5efd27d98fd63519f999908c009e148039d8e7179a074f105362d4fcc214c38b24f6cda79c87e563cbd12083a4691381ed28559220d4a10c2047bed4 - languageName: node - linkType: hard - "typed-array-buffer@npm:^1.0.3": version: 1.0.3 resolution: "typed-array-buffer@npm:1.0.3" @@ -26113,6 +28477,37 @@ __metadata: languageName: node linkType: hard +"unicode-canonical-property-names-ecmascript@npm:^2.0.0": + version: 2.0.1 + resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.1" + checksum: 10/3c3dabdb1d22aef4904399f9e810d0b71c0b12b3815169d96fac97e56d5642840c6071cf709adcace2252bc6bb80242396c2ec74b37224eb015c5f7aca40bad7 + languageName: node + linkType: hard + +"unicode-match-property-ecmascript@npm:^2.0.0": + version: 2.0.0 + resolution: "unicode-match-property-ecmascript@npm:2.0.0" + dependencies: + unicode-canonical-property-names-ecmascript: "npm:^2.0.0" + unicode-property-aliases-ecmascript: "npm:^2.0.0" + checksum: 10/1f34a7434a23df4885b5890ac36c5b2161a809887000be560f56ad4b11126d433c0c1c39baf1016bdabed4ec54829a6190ee37aa24919aa116dc1a5a8a62965a + languageName: node + linkType: hard + +"unicode-match-property-value-ecmascript@npm:^2.2.1": + version: 2.2.1 + resolution: "unicode-match-property-value-ecmascript@npm:2.2.1" + checksum: 10/a42bebebab4c82ea6d8363e487b1fb862f82d1b54af1b67eb3fef43672939b685780f092c4f235266b90225863afa1258d57e7be3578d8986a08d8fc309aabe1 + languageName: node + linkType: hard + +"unicode-property-aliases-ecmascript@npm:^2.0.0": + version: 2.2.0 + resolution: "unicode-property-aliases-ecmascript@npm:2.2.0" + checksum: 10/0dd0f6e70130c59b4a841bac206758f70227b113145e4afe238161e3e8540e8eb79963e7a228cd90ad13d499e96f7ef4ee8940835404b2181ad9bf9c174818e3 + languageName: node + linkType: hard + "unified@npm:^10.0.0": version: 10.1.2 resolution: "unified@npm:10.1.2" @@ -26288,6 +28683,13 @@ __metadata: languageName: node linkType: hard +"universalify@npm:^0.2.0": + version: 0.2.0 + resolution: "universalify@npm:0.2.0" + checksum: 10/e86134cb12919d177c2353196a4cc09981524ee87abf621f7bc8d249dbbbebaec5e7d1314b96061497981350df786e4c5128dbf442eba104d6e765bc260678b5 + languageName: node + linkType: hard + "universalify@npm:^2.0.0": version: 2.0.1 resolution: "universalify@npm:2.0.1" @@ -26365,6 +28767,16 @@ __metadata: languageName: node linkType: hard +"url-parse@npm:^1.5.3": + version: 1.5.10 + resolution: "url-parse@npm:1.5.10" + dependencies: + querystringify: "npm:^2.1.1" + requires-port: "npm:^1.0.0" + checksum: 10/c9e96bc8c5b34e9f05ddfeffc12f6aadecbb0d971b3cc26015b58d5b44676a99f50d5aeb1e5c9e61fa4d49961ae3ab1ae997369ed44da51b2f5ac010d188e6ad + languageName: node + linkType: hard + "url@npm:^0.11.4": version: 0.11.4 resolution: "url@npm:0.11.4" @@ -26528,6 +28940,17 @@ __metadata: languageName: node linkType: hard +"v8-to-istanbul@npm:^9.0.1": + version: 9.3.0 + resolution: "v8-to-istanbul@npm:9.3.0" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.12" + "@types/istanbul-lib-coverage": "npm:^2.0.1" + convert-source-map: "npm:^2.0.0" + checksum: 10/fb1d70f1176cb9dc46cabbb3fd5c52c8f3e8738b61877b6e7266029aed0870b04140e3f9f4550ac32aebcfe1d0f38b0bac57e1e8fb97d68fec82f2b416148166 + languageName: node + linkType: hard + "validate.io-array@npm:^1.0.3": version: 1.0.6 resolution: "validate.io-array@npm:1.0.6" @@ -26646,6 +29069,15 @@ __metadata: languageName: node linkType: hard +"w3c-xmlserializer@npm:^4.0.0": + version: 4.0.0 + resolution: "w3c-xmlserializer@npm:4.0.0" + dependencies: + xml-name-validator: "npm:^4.0.0" + checksum: 10/9a00c412b5496f4f040842c9520bc0aaec6e0c015d06412a91a723cd7d84ea605ab903965f546b4ecdb3eae267f5145ba08565222b1d6cb443ee488cda9a0aee + languageName: node + linkType: hard + "walk-up-path@npm:^4.0.0": version: 4.0.0 resolution: "walk-up-path@npm:4.0.0" @@ -26653,6 +29085,15 @@ __metadata: languageName: node linkType: hard +"walker@npm:^1.0.8": + version: 1.0.8 + resolution: "walker@npm:1.0.8" + dependencies: + makeerror: "npm:1.0.12" + checksum: 10/ad7a257ea1e662e57ef2e018f97b3c02a7240ad5093c392186ce0bcf1f1a60bbadd520d073b9beb921ed99f64f065efb63dfc8eec689a80e569f93c1c5d5e16c + languageName: node + linkType: hard + "watchpack@npm:^2.5.1": version: 2.5.1 resolution: "watchpack@npm:2.5.1" @@ -26709,6 +29150,13 @@ __metadata: languageName: node linkType: hard +"webidl-conversions@npm:^7.0.0": + version: 7.0.0 + resolution: "webidl-conversions@npm:7.0.0" + checksum: 10/4c4f65472c010eddbe648c11b977d048dd96956a625f7f8b9d64e1b30c3c1f23ea1acfd654648426ce5c743c2108a5a757c0592f02902cf7367adb7d14e67721 + languageName: node + linkType: hard + "webpack-dev-middleware@npm:^7.4.2": version: 7.4.5 resolution: "webpack-dev-middleware@npm:7.4.5" @@ -26790,7 +29238,7 @@ __metadata: languageName: node linkType: hard -"webpack@npm:~5.105.0": +"webpack@npm:^5.94.0": version: 5.105.4 resolution: "webpack@npm:5.105.4" dependencies: @@ -26846,6 +29294,15 @@ __metadata: languageName: node linkType: hard +"whatwg-encoding@npm:^2.0.0": + version: 2.0.0 + resolution: "whatwg-encoding@npm:2.0.0" + dependencies: + iconv-lite: "npm:0.6.3" + checksum: 10/162d712d88fd134a4fe587e53302da812eb4215a1baa4c394dfd86eff31d0a079ff932c05233857997de07481093358d6e7587997358f49b8a580a777be22089 + languageName: node + linkType: hard + "whatwg-fetch@npm:^3.6.20": version: 3.6.20 resolution: "whatwg-fetch@npm:3.6.20" @@ -26853,6 +29310,23 @@ __metadata: languageName: node linkType: hard +"whatwg-mimetype@npm:^3.0.0": + version: 3.0.0 + resolution: "whatwg-mimetype@npm:3.0.0" + checksum: 10/96f9f628c663c2ae05412c185ca81b3df54bcb921ab52fe9ebc0081c1720f25d770665401eb2338ab7f48c71568133845638e18a81ed52ab5d4dcef7d22b40ef + languageName: node + linkType: hard + +"whatwg-url@npm:^11.0.0": + version: 11.0.0 + resolution: "whatwg-url@npm:11.0.0" + dependencies: + tr46: "npm:^3.0.0" + webidl-conversions: "npm:^7.0.0" + checksum: 10/dfcd51c6f4bfb54685528fb10927f3fd3d7c809b5671beef4a8cdd7b1408a7abf3343a35bc71dab83a1424f1c1e92cc2700d7930d95d231df0fac361de0c7648 + languageName: node + linkType: hard + "whatwg-url@npm:^5.0.0": version: 5.0.0 resolution: "whatwg-url@npm:5.0.0" @@ -27061,6 +29535,16 @@ __metadata: languageName: node linkType: hard +"write-file-atomic@npm:^4.0.2": + version: 4.0.2 + resolution: "write-file-atomic@npm:4.0.2" + dependencies: + imurmurhash: "npm:^0.1.4" + signal-exit: "npm:^3.0.7" + checksum: 10/3be1f5508a46c190619d5386b1ac8f3af3dbe951ed0f7b0b4a0961eed6fc626bd84b50cf4be768dabc0a05b672f5d0c5ee7f42daa557b14415d18c3a13c7d246 + languageName: node + linkType: hard + "ws@npm:8.18.0": version: 8.18.0 resolution: "ws@npm:8.18.0" @@ -27077,8 +29561,8 @@ __metadata: linkType: hard "ws@npm:^8.18.0": - version: 8.20.0 - resolution: "ws@npm:8.20.0" + version: 8.18.2 + resolution: "ws@npm:8.18.2" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -27087,16 +29571,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 10/b7ab934b21ffdea9f25a5af5097e8c1ec7625db553bca026c5a23e35b7c236f3fb89782f2b57fab9da553864512f9aa7d245827ef998d26ffa1b2187a19a6d10 - languageName: node - linkType: hard - -"wsl-utils@npm:^0.1.0": - version: 0.1.0 - resolution: "wsl-utils@npm:0.1.0" - dependencies: - is-wsl: "npm:^3.1.0" - checksum: 10/de4c92187e04c3c27b4478f410a02e81c351dc85efa3447bf1666f34fc80baacd890a6698ec91995631714086992036013286aea3d77e6974020d40a08e00aec + checksum: 10/018e04ec95561d88248d53a2eaf094b4ae131e9b062f2679e6e8a62f04649bc543448f1e038125225ac6bbb25f54c1e65d7a2cc9dbc1e28b43e5e6b7162ad88e languageName: node linkType: hard @@ -27121,6 +29596,13 @@ __metadata: languageName: node linkType: hard +"yallist@npm:^3.0.2": + version: 3.1.1 + resolution: "yallist@npm:3.1.1" + checksum: 10/9af0a4329c3c6b779ac4736c69fae4190ac03029fa27c1aef4e6bcc92119b73dea6fe5db5fe881fb0ce2a0e9539a42cdf60c7c21eda04d1a0b8c082e38509efb + languageName: node + linkType: hard + "yallist@npm:^5.0.0": version: 5.0.0 resolution: "yallist@npm:5.0.0" @@ -27195,9 +29677,9 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^16.2.0": - version: 16.2.0 - resolution: "yargs@npm:16.2.0" +"yargs@npm:^17.1.1, yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" dependencies: cliui: "npm:^7.0.2" escalade: "npm:^3.1.1" @@ -27220,7 +29702,7 @@ __metadata: languageName: node linkType: hard -"ylru@npm:^1.3.2": +"ylru@npm:^1.2.0, ylru@npm:^1.3.2": version: 1.4.0 resolution: "ylru@npm:1.4.0" checksum: 10/5437f8eb2fb5dd515845c657dde3cecaa9f6bd4c6386d2a5212d3fafe02189c7d8ebfdfc84940a7811607cb3524eb362ce95d3180d355cd5deb610aa8c82c9bc @@ -27277,11 +29759,20 @@ __metadata: linkType: hard "zod-to-json-schema@npm:^3.25.1": - version: 3.25.2 - resolution: "zod-to-json-schema@npm:3.25.2" + version: 3.25.1 + resolution: "zod-to-json-schema@npm:3.25.1" + peerDependencies: + zod: ^3.25 || ^4 + checksum: 10/744dd370f4452c8db120de1475ea4d484a11df884c4636111d630e5e1351b8a7590d99cf14a2b9f21e7906f8b78721d958663a7973a40994e7d28770876674cc + languageName: node + linkType: hard + +"zod-validation-error@npm:^3.0.3": + version: 3.5.2 + resolution: "zod-validation-error@npm:3.5.2" peerDependencies: - zod: ^3.25.28 || ^4 - checksum: 10/7035328654113f1a0b8e4c2d34a06f918c93650ef8a50d4fb30ad8f22e47d5762c163af9c82494756b34776bae3c41c26cfc6945105b0eee7dceb528cc07e665 + zod: ^3.25.0 + checksum: 10/ca084429d32b6e084088a2d384fd12c2839929fbf0f31e383ae1606c60a85ac0a0cf7a9c1a61f8053690c50a39e9d6ee4d1286edc19305532f20de1b369109e6 languageName: node linkType: hard @@ -27308,6 +29799,13 @@ __metadata: languageName: node linkType: hard +"zod@npm:^3.25 || ^4.0": + version: 4.2.1 + resolution: "zod@npm:4.2.1" + checksum: 10/f21d106ce31e0f24040aa13b13fdd1300fcc8119622b28ca1b1b726ff70b75190dbcfeb927d34f19174683afa298e5df4d806f622abe9b037a0aadb9cdef6443 + languageName: node + linkType: hard + "zwitch@npm:^2.0.0": version: 2.0.4 resolution: "zwitch@npm:2.0.4" diff --git a/workspaces/tech-insights/.changeset/cyan-ducks-mate.md b/workspaces/tech-insights/.changeset/cyan-ducks-mate.md deleted file mode 100644 index c1b7b828a4f..00000000000 --- a/workspaces/tech-insights/.changeset/cyan-ducks-mate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage-community/plugin-tech-insights-maturity': patch ---- - -Fixed entity page integration instructions From 0e239bba8e100abb3563b4ab83f45014f233b549 Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Mon, 23 Mar 2026 21:26:49 -0400 Subject: [PATCH 03/17] feat(mcp-chat): added support for amazon bedrock Signed-off-by: Florian JUDITH --- .../mcp-chat/.changeset/silly-jars-happen.md | 2 + .../.eslintrc.js | 1 + .../README.md | 5 + .../config.d.ts | 52 ++ .../knip-report.md | 2 + .../package.json | 63 ++ .../src/BedrockProvider.ts | 285 +++++++ .../src/index.ts | 24 + .../src/module.ts | 79 ++ .../tsconfig.json | 9 + .../tsconfig.tsbuildinfo | 1 + .../knip-report.md | 1 + .../knip-report.md | 1 + .../report.api.md | 10 +- .../knip-report.md | 1 + .../report.api.md | 8 +- .../knip-report.md | 1 + .../report.api.md | 10 +- .../knip-report.md | 2 + .../report.api.md | 12 +- .../knip-report.md | 1 + .../report.api.md | 8 +- .../plugins/mcp-chat-backend/dev/index.ts | 3 + .../plugins/mcp-chat-backend/package.json | 1 + .../plugins/mcp-chat-common/knip-report.md | 2 + .../plugins/mcp-chat-common/package.json | 4 +- .../plugins/mcp-chat-node/knip-report.md | 2 + .../plugins/mcp-chat-node/package.json | 4 +- .../plugins/mcp-chat-node/report.api.md | 16 + .../mcp-chat/plugins/mcp-chat/package.json | 4 +- workspaces/mcp-chat/yarn.lock | 707 +++++++++++++++--- 31 files changed, 1190 insertions(+), 131 deletions(-) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/.eslintrc.js create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/README.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/config.d.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/knip-report.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/package.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/index.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/module.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.json create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.tsbuildinfo create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/knip-report.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-common/knip-report.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-node/knip-report.md create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-node/report.api.md diff --git a/workspaces/mcp-chat/.changeset/silly-jars-happen.md b/workspaces/mcp-chat/.changeset/silly-jars-happen.md index d8578848796..02fd6db37cc 100644 --- a/workspaces/mcp-chat/.changeset/silly-jars-happen.md +++ b/workspaces/mcp-chat/.changeset/silly-jars-happen.md @@ -1,5 +1,7 @@ --- +'@backstage-community/plugin-mcp-chat': patch '@backstage-community/plugin-mcp-chat-backend': major +'@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock': patch '@backstage-community/plugin-mcp-chat-backend-module-openai-responses': patch '@backstage-community/plugin-mcp-chat-backend-module-anthropic': patch '@backstage-community/plugin-mcp-chat-backend-module-litellm': patch diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/.eslintrc.js new file mode 100644 index 00000000000..e2a53a6ad28 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/README.md new file mode 100644 index 00000000000..57ce018d439 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/README.md @@ -0,0 +1,5 @@ +# @backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock + +The Amazon Bedrock backend module for the mcp-chat plugin. + +_This plugin was created through the Backstage CLI_ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/config.d.ts new file mode 100644 index 00000000000..65d61e8b043 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/config.d.ts @@ -0,0 +1,52 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface Config { + /** Configuration options for the MCP Chat plugin */ + mcpChat?: { + /** + * AI/LLM providers configuration + * @visibility backend + */ + providers?: Array<{ + /** + * Unique identifier for the provider + * @visibility backend + */ + id: string; + /** + * API token for the provider + * @visibility secret + */ + token?: string; + /** + * Model name to use for this provider + * @visibility backend + */ + model: string; + /** + * Base URL for the provider's API + * @visibility backend + */ + baseUrl?: string; + /** + * Provider-specific authentication parameters (IAM, session tokens, etc.) + * @visibility secret + */ + auth?: { [key: string]: string }; + }>; + }; +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/knip-report.md new file mode 100644 index 00000000000..2661c353270 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/knip-report.md @@ -0,0 +1,2 @@ +# Knip report + diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/package.json new file mode 100644 index 00000000000..8f63ee9bb18 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/package.json @@ -0,0 +1,63 @@ +{ + "name": "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock", + "version": "0.1.0", + "license": "Apache-2.0", + "main": "src/index.ts", + "types": "src/index.ts", + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module", + "pluginId": "mcp-chat", + "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", + "pluginPackages": [ + "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock", + "@backstage-community/plugin-mcp-chat-backend" + ] + }, + "dependencies": { + "@aws-sdk/client-bedrock-runtime": "^3.0.0", + "@backstage-community/plugin-mcp-chat-common": "workspace:^", + "@backstage-community/plugin-mcp-chat-node": "workspace:^", + "@backstage/backend-plugin-api": "^1.4.0", + "@backstage/config": "^1.3.0" + }, + "devDependencies": { + "@backstage/cli": "^0.33.0" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "files": [ + "dist", + "config.d.ts" + ], + "configSchema": "config.d.ts", + "repository": { + "type": "git", + "url": "https://github.com/backstage/community-plugins", + "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock" + }, + "keywords": [ + "backstage", + "backstage-plugin", + "backstage-backend-module", + "amazon-bedrock", + "aws", + "bedrock", + "llm", + "mcp", + "mcp-chat" + ], + "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock", + "bugs": "https://github.com/backstage/community-plugins/issues" +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.ts new file mode 100644 index 00000000000..d6bd5ec16c9 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.ts @@ -0,0 +1,285 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + BedrockRuntimeClient, + ConverseCommand, + type ConverseCommandInput, + type Message, + type ContentBlock, +} from '@aws-sdk/client-bedrock-runtime'; +import { + LLMProvider, + type ChatMessage, + type Tool, + type ChatResponse, + type ProviderConfig, + type ToolCall, +} from '@backstage-community/plugin-mcp-chat-common'; + +/** + * Amazon Bedrock Converse API provider. + * + * Uses the AWS SDK Bedrock Runtime client with the Converse API, + * which provides a unified interface across all Bedrock foundation models. + * + * Authentication is handled via the standard AWS credential chain + * (environment variables, IAM roles, SSO, etc.). Explicit credentials + * can be supplied through the `auth` config record with `accessKeyId`, + * `secretAccessKey`, and optionally `sessionToken`. + * + * @public + */ +export class BedrockProvider extends LLMProvider { + private client: BedrockRuntimeClient; + private lastTools?: Tool[]; + + constructor(config: ProviderConfig) { + super(config); + + const region = config.auth?.region || 'us-east-1'; + + const clientConfig: Record = { region }; + + if (config.auth?.accessKeyId && config.auth?.secretAccessKey) { + clientConfig.credentials = { + accessKeyId: config.auth.accessKeyId, + secretAccessKey: config.auth.secretAccessKey, + ...(config.auth.sessionToken && { + sessionToken: config.auth.sessionToken, + }), + }; + } + + if (config.baseUrl) { + clientConfig.endpoint = config.baseUrl; + } + + this.client = new BedrockRuntimeClient(clientConfig); + } + + async sendMessage( + messages: ChatMessage[], + tools?: Tool[], + ): Promise { + const bedrockMessages = this.convertToBedrockFormat(messages); + const systemPrompts = this.extractSystemPrompts(messages); + + const input: ConverseCommandInput = { + modelId: this.model, + messages: bedrockMessages, + }; + + if (systemPrompts.length > 0) { + input.system = systemPrompts; + } + + if (tools && tools.length > 0) { + // Store tools so we can re-attach toolConfig on follow-up calls + this.lastTools = tools; + input.toolConfig = this.convertToBedrockTools(tools); + } else if (this.hasToolBlocks(messages) && this.lastTools?.length) { + // Bedrock requires toolConfig whenever the conversation contains + // toolUse / toolResult blocks (e.g. the follow-up call after tool + // execution in processQuery which doesn't pass tools). + input.toolConfig = this.convertToBedrockTools(this.lastTools); + } + + const command = new ConverseCommand(input); + const response = await this.client.send(command); + + return this.parseConverseResponse(response); + } + + async testConnection(): Promise<{ + connected: boolean; + models?: string[]; + error?: string; + }> { + try { + const command = new ConverseCommand({ + modelId: this.model, + messages: [ + { + role: 'user', + content: [{ text: 'Hello' }], + }, + ], + inferenceConfig: { maxTokens: 1 }, + }); + + await this.client.send(command); + + return { + connected: true, + models: [this.model], + }; + } catch (error: unknown) { + const message = error instanceof Error ? error.message : 'Unknown error'; + return { + connected: false, + error: message, + }; + } + } + + protected getHeaders(): Record { + // Not used — Bedrock auth is handled by the AWS SDK + return {}; + } + + protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any { + // Not used — sendMessage calls the SDK directly + return { messages, tools }; + } + + protected parseResponse(response: any): ChatResponse { + return this.parseConverseResponse(response); + } + + private hasToolBlocks(messages: ChatMessage[]): boolean { + return messages.some( + msg => + msg.role === 'tool' || + (msg.role === 'assistant' && msg.tool_calls?.length), + ); + } + + private extractSystemPrompts( + messages: ChatMessage[], + ): Array<{ text: string }> { + return messages + .filter(msg => msg.role === 'system' && msg.content) + .map(msg => ({ text: msg.content as string })); + } + + private convertToBedrockFormat(messages: ChatMessage[]): Message[] { + return messages + .filter(msg => msg.role !== 'system') + .map(msg => { + if (msg.role === 'tool') { + return { + role: 'user' as const, + content: [ + { + toolResult: { + toolUseId: msg.tool_call_id || 'unknown', + content: [{ text: msg.content || '' }], + }, + }, + ] as ContentBlock[], + }; + } + + if (msg.role === 'assistant' && msg.tool_calls?.length) { + const blocks: ContentBlock[] = []; + + if (msg.content) { + blocks.push({ text: msg.content }); + } + + for (const tc of msg.tool_calls) { + let input: Record = {}; + try { + input = JSON.parse(tc.function.arguments); + } catch { + // keep empty input if parsing fails + } + blocks.push({ + toolUse: { + toolUseId: tc.id, + name: tc.function.name, + input, + }, + } as ContentBlock); + } + + return { + role: 'assistant' as const, + content: blocks, + }; + } + + return { + role: + msg.role === 'assistant' + ? ('assistant' as const) + : ('user' as const), + content: [{ text: msg.content || ' ' }] as ContentBlock[], + }; + }); + } + + private convertToBedrockTools( + tools: Tool[], + ): ConverseCommandInput['toolConfig'] { + return { + tools: tools.map(tool => ({ + toolSpec: { + name: tool.function.name, + description: tool.function.description, + inputSchema: { + json: tool.function.parameters as Record, + }, + }, + })) as ConverseCommandInput['toolConfig'] extends { tools?: infer T } + ? T + : never, + }; + } + + private parseConverseResponse(response: any): ChatResponse { + const output = response.output; + const content: ContentBlock[] = output?.message?.content || []; + + const textParts = content + .filter((block: any) => block.text) + .map((block: any) => block.text); + const textContent = textParts.join(''); + + const toolCalls: ToolCall[] = content + .filter((block: any) => block.toolUse) + .map((block: any) => ({ + id: block.toolUse.toolUseId, + type: 'function' as const, + function: { + name: block.toolUse.name, + arguments: JSON.stringify(block.toolUse.input), + }, + })); + + return { + choices: [ + { + message: { + role: 'assistant', + content: textContent, + tool_calls: toolCalls.length > 0 ? toolCalls : undefined, + }, + }, + ], + usage: response.usage + ? { + prompt_tokens: response.usage.inputTokens || 0, + completion_tokens: response.usage.outputTokens || 0, + total_tokens: + (response.usage.inputTokens || 0) + + (response.usage.outputTokens || 0), + } + : undefined, + }; + } +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/index.ts new file mode 100644 index 00000000000..15a2822168e --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Backend module for the mcp-chat plugin that provides the Amazon Bedrock LLM provider. + * + * @packageDocumentation + */ + +export { default } from './module'; +export { BedrockProvider } from './BedrockProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/module.ts new file mode 100644 index 00000000000..de3136ffa7f --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/module.ts @@ -0,0 +1,79 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createBackendModule, + coreServices, +} from '@backstage/backend-plugin-api'; +import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; +import type { Config } from '@backstage/config'; +import { BedrockProvider } from './BedrockProvider'; + +/** + * Reads the optional `auth` record from a provider config entry. + * @param entry - The config entry to read auth from + * @returns A record of string key-value pairs, or undefined if no auth config + */ +function readAuthRecord(entry: Config): Record | undefined { + const authConfig = entry.getOptionalConfig('auth'); + if (!authConfig) return undefined; + const result: Record = {}; + for (const key of authConfig.keys()) { + result[key] = authConfig.getString(key); + } + return result; +} + +/** + * Backend module that registers the Amazon Bedrock LLM provider + * with the mcp-chat backend plugin. + * + * @public + */ +export default createBackendModule({ + pluginId: 'mcp-chat', + moduleId: 'amazon-bedrock', + register(reg) { + reg.registerInit({ + deps: { + config: coreServices.rootConfig, + llmProviders: llmProviderExtensionPoint, + }, + async init({ config, llmProviders }) { + const providers = + config.getOptionalConfigArray('mcpChat.providers') || []; + const entry = providers.find( + p => p.getString('id') === 'amazon-bedrock', + ); + + if (!entry) return; // Skip registration if not configured + + const providerConfig = { + type: 'amazon-bedrock', + apiKey: entry.getOptionalString('token'), + baseUrl: entry.getOptionalString('baseUrl') || '', + model: entry.getString('model'), + auth: readAuthRecord(entry), + }; + + llmProviders.registerProvider( + 'amazon-bedrock', + new BedrockProvider(providerConfig), + ); + }, + }); + }, +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.json new file mode 100644 index 00000000000..6364965a1a3 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "@backstage/cli/config/tsconfig.json", + "include": ["src"], + "exclude": ["node_modules"], + "compilerOptions": { + "outDir": "dist", + "rootDir": "src" + } +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.tsbuildinfo b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.tsbuildinfo new file mode 100644 index 00000000000..379c50b25c2 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.tsbuildinfo @@ -0,0 +1 @@ +{"program":{"fileNames":["../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/typescript/lib/lib.scripthost.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/typescript/lib/lib.es2022.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/abort-handler.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/abort.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/auth.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/HttpApiKeyAuth.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/identity/identity.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/response.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/command.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoint.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/feature-ids.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/logger.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/uri.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/http.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/util.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/middleware.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/HttpSigner.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/IdentityProviderConfig.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/HttpAuthScheme.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/HttpAuthSchemeProvider.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/index.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transform/exact.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/externals-check/browser-externals-check.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/blob/blob-payload-input-types.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/crypto.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/checksum.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/client.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/connection/config.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transfer.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/connection/manager.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/connection/pool.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/connection/index.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/eventStream.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/encode.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoints/shared.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoints/EndpointRuleObject.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoints/ErrorRuleObject.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoints/TreeRuleObject.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoints/RuleSetObject.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoints/index.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/extensions/checksum.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/extensions/defaultClientConfiguration.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/shapes.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/retry.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/extensions/retry.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/extensions/defaultExtensionConfiguration.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/extensions/index.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/http/httpHandlerInitialization.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/identity/apiKeyIdentity.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/identity/awsCredentialIdentity.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/identity/tokenIdentity.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/identity/index.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/pagination.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/profile.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/serde.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/schema/sentinels.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/schema/static-schemas.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/schema/traits.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/schema/schema.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/schema/schema-deprecated.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/signature.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/stream.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/streaming-payload/streaming-blob-common-types.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/streaming-payload/streaming-blob-payload-input-types.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/streaming-payload/streaming-blob-payload-output-types.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transform/type-transform.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transform/client-method-transforms.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transform/client-payload-blob-type-narrow.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transform/mutable.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transform/no-undefined.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/waiter.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/index.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/dist-types/eventStreamConfiguration.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/dist-types/eventStreamHandlingMiddleware.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/dist-types/eventStreamHeaderMiddleware.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/dist-types/getEventStreamPlugin.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/types/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/middleware-host-header/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/middleware-user-agent/dist-types/configurations.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/abort.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/auth.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/blob/blob-types.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/checksum.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/client.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/command.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/connection.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/identity/Identity.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/identity/AnonymousIdentity.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/feature-ids.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/identity/AwsCredentialIdentity.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/identity/LoginIdentity.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/identity/TokenIdentity.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/identity/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/util.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/credentials.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/crypto.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/dns.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/encode.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/endpoint.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/eventStream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/extensions/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/function.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/http.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/logger.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/middleware.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/pagination.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/profile.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/request.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/response.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/retry.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/serde.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/shapes.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/signature.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/stream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/token.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/transfer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/uri.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/waiter.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/middleware-user-agent/dist-types/user-agent-middleware.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/middleware-user-agent/dist-types/index.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/types/dist-types/index.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/httpRequest.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/httpResponse.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/httpHandler.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/extensions/httpExtensionConfiguration.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/extensions/index.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/Field.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/Fields.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/isValidHostname.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/types.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/index.d.ts","../../node_modules/@aws-sdk/middleware-websocket/dist-types/WebSocketFetchHandler.d.ts","../../node_modules/@aws-sdk/middleware-websocket/dist-types/getWebSocketPlugin.d.ts","../../node_modules/@aws-sdk/middleware-websocket/dist-types/resolveWebSocketConfig.d.ts","../../node_modules/@aws-sdk/middleware-websocket/dist-types/ws-eventstream/eventStreamPayloadHandlerProvider.d.ts","../../node_modules/@aws-sdk/middleware-websocket/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/node-config-provider/dist-types/fromEnv.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/getHomeDir.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/getProfileName.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/getSSOTokenFilepath.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/getSSOTokenFromFile.d.ts","../../node_modules/@smithy/shared-ini-file-loader/node_modules/@smithy/types/dist-types/index.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/constants.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/loadSharedConfigFiles.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/loadSsoSessionData.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/parseKnownFiles.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/externalDataInterceptor.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/types.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/readFile.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/node-config-provider/dist-types/fromSharedConfigFiles.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/node-config-provider/dist-types/fromStatic.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/node-config-provider/dist-types/configLoader.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/node-config-provider/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/endpointsConfig/NodeUseDualstackEndpointConfigOptions.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/endpointsConfig/NodeUseFipsEndpointConfigOptions.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/endpointsConfig/resolveEndpointsConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/endpointsConfig/resolveCustomEndpointsConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/endpointsConfig/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionConfig/config.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionConfig/resolveRegionConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionConfig/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionInfo/EndpointVariantTag.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionInfo/EndpointVariant.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionInfo/PartitionHash.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionInfo/RegionHash.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionInfo/getRegionInfo.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionInfo/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/eventstream-serde-config-resolver/dist-types/EventStreamSerdeConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/eventstream-serde-config-resolver/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/resolveEndpointConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/types.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/adaptors/getEndpointFromInstructions.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/adaptors/toEndpointV1.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/adaptors/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/endpointMiddleware.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/getEndpointPlugin.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/resolveEndpointRequiredConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/types.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/AdaptiveRetryStrategy.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/StandardRetryStrategy.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/ConfiguredRetryStrategy.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/DefaultRateLimiter.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/config.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/constants.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/types.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/StandardRetryStrategy.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/AdaptiveRetryStrategy.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/configurations.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/delayDecider.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/omitRetryHeadersMiddleware.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/retryDecider.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/retryMiddleware.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/protocol-http/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/client.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/blob/Uint8ArrayBlobAdapter.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/checksum/ChecksumStream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/checksum/ChecksumStream.browser.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/checksum/createChecksumStream.browser.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/checksum/createChecksumStream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/createBufferedReadable.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/getAwsChunkedEncodingStream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/headStream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/sdk-stream-mixin.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/splitStream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/stream-type-check.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/collect-stream-body.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/extended-encode-uri-component.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/deref.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/middleware/schema-middleware-types.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/middleware/getSchemaSerdePlugin.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/Schema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/ListSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/MapSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/OperationSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/operation.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/StructureSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/ErrorSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/NormalizedSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/SimpleSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/sentinels.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/translateTraits.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/TypeRegistry.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/schema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/event-streams/EventStreamSerde.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/event-streams/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/event-streams.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/SerdeContext.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/HttpProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/HttpBindingProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/RpcProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/requestBuilder.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/resolve-path.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/serde/FromStringShapeDeserializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/serde/HttpInterceptingShapeDeserializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/serde/ToStringShapeSerializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/serde/HttpInterceptingShapeSerializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/serde/determineTimestampFormat.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/protocols.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/collect-stream-body.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/command.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/constants.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/create-aggregated-client.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/default-error-handler.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/defaults-mode.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/emitWarningIfUnsupportedVersion.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/exceptions.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/extended-encode-uri-component.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/extensions/checksum.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/extensions/retry.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/extensions/defaultExtensionConfiguration.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/extensions/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/get-array-if-single-item.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/get-value-from-text-node.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/is-serializable-header-value.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/NoOpLogger.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/object-mapping.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/resolve-path.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/ser-utils.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/serde-json.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/copyDocumentWithTransform.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/date-utils.d.ts","../../node_modules/@smithy/uuid/dist-types/v4.d.ts","../../node_modules/@smithy/uuid/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/generateIdempotencyToken.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/lazy-json.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/parse-utils.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/quote-header.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/schema-serde-lib/schema-date-utils.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/split-every.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/split-header.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/value/NumericValue.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/serde.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/client/emitWarningIfUnsupportedVersion.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/client/setCredentialFeature.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/client/setFeature.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/client/setTokenFeature.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/client/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/aws_sdk/resolveAwsSdkSigV4AConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/aws_sdk/AwsSdkSigV4Signer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/aws_sdk/AwsSdkSigV4ASigner.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/aws_sdk/NODE_AUTH_SCHEME_PREFERENCE_OPTIONS.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/SignatureV4Base.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/SignatureV4.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/constants.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/getCanonicalHeaders.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/getCanonicalQuery.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/getPayloadHash.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/moveHeadersToQuery.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/prepareRequest.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/credentialDerivation.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/headerUtil.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/signature-v4a-container.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/aws_sdk/resolveAwsSdkSigV4Config.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/aws_sdk/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/utils/getBearerTokenEnvKey.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/cbor/cbor.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/cbor/cbor-types.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/cbor/parseCborBody.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/cbor/CborCodec.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/cbor/SmithyRpcV2CborProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/cbor/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/cbor.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/cbor/AwsSmithyRpcV2CborProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/coercing-serializers.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/ConfigurableSerdeContext.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/JsonShapeDeserializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/JsonShapeSerializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/JsonCodec.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/AwsJsonRpcProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/AwsJson1_0Protocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/AwsJson1_1Protocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/AwsRestJsonProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/awsExpectUnion.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/parseJsonBody.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/XmlShapeSerializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/XmlCodec.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/XmlShapeDeserializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/QuerySerializerSettings.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/QueryShapeSerializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/AwsQueryProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/AwsEc2QueryProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/AwsRestXmlProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/parseXmlBody.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/auth/httpAuthSchemeProvider.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/models/enums.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/models/BedrockRuntimeServiceException.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/models/errors.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/models/models_0.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/ApplyGuardrailCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/ConverseCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/ConverseStreamCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/CountTokensCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/GetAsyncInvokeCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/InvokeModelCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/InvokeModelWithBidirectionalStreamCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/InvokeModelWithResponseStreamCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/ListAsyncInvokesCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/StartAsyncInvokeCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/endpoint/EndpointParameters.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/auth/httpAuthExtensionConfiguration.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/extensionConfiguration.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/runtimeExtensions.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/BedrockRuntimeClient.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/BedrockRuntime.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/schemas/schemas_0.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/pagination/Interfaces.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/pagination/ListAsyncInvokesPaginator.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/pagination/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/index.d.ts","../../node_modules/@backstage/types/dist/index.d.ts","../../node_modules/@backstage/errors/dist/index.d.ts","../mcp-chat-common/src/types.ts","../mcp-chat-common/src/base-provider.ts","../mcp-chat-common/src/index.ts","./src/BedrockProvider.ts","../../node_modules/@types/node/ts5.6/compatibility/float16array.d.ts","../../node_modules/@types/node/compatibility/iterators.d.ts","../../node_modules/@types/node/ts5.6/globals.typedarray.d.ts","../../node_modules/@types/node/ts5.6/buffer.buffer.d.ts","../../node_modules/buffer/index.d.ts","../../node_modules/@types/node/node_modules/undici-types/utility.d.ts","../../node_modules/@types/node/node_modules/undici-types/header.d.ts","../../node_modules/@types/node/node_modules/undici-types/readable.d.ts","../../node_modules/@types/node/node_modules/undici-types/fetch.d.ts","../../node_modules/@types/node/node_modules/undici-types/formdata.d.ts","../../node_modules/@types/node/node_modules/undici-types/connector.d.ts","../../node_modules/@types/node/node_modules/undici-types/client.d.ts","../../node_modules/@types/node/node_modules/undici-types/errors.d.ts","../../node_modules/@types/node/node_modules/undici-types/dispatcher.d.ts","../../node_modules/@types/node/node_modules/undici-types/global-dispatcher.d.ts","../../node_modules/@types/node/node_modules/undici-types/global-origin.d.ts","../../node_modules/@types/node/node_modules/undici-types/pool-stats.d.ts","../../node_modules/@types/node/node_modules/undici-types/pool.d.ts","../../node_modules/@types/node/node_modules/undici-types/handlers.d.ts","../../node_modules/@types/node/node_modules/undici-types/balanced-pool.d.ts","../../node_modules/@types/node/node_modules/undici-types/h2c-client.d.ts","../../node_modules/@types/node/node_modules/undici-types/agent.d.ts","../../node_modules/@types/node/node_modules/undici-types/mock-interceptor.d.ts","../../node_modules/@types/node/node_modules/undici-types/mock-call-history.d.ts","../../node_modules/@types/node/node_modules/undici-types/mock-agent.d.ts","../../node_modules/@types/node/node_modules/undici-types/mock-client.d.ts","../../node_modules/@types/node/node_modules/undici-types/mock-pool.d.ts","../../node_modules/@types/node/node_modules/undici-types/mock-errors.d.ts","../../node_modules/@types/node/node_modules/undici-types/proxy-agent.d.ts","../../node_modules/@types/node/node_modules/undici-types/env-http-proxy-agent.d.ts","../../node_modules/@types/node/node_modules/undici-types/retry-handler.d.ts","../../node_modules/@types/node/node_modules/undici-types/retry-agent.d.ts","../../node_modules/@types/node/node_modules/undici-types/api.d.ts","../../node_modules/@types/node/node_modules/undici-types/cache-interceptor.d.ts","../../node_modules/@types/node/node_modules/undici-types/interceptors.d.ts","../../node_modules/@types/node/node_modules/undici-types/util.d.ts","../../node_modules/@types/node/node_modules/undici-types/cookies.d.ts","../../node_modules/@types/node/node_modules/undici-types/patch.d.ts","../../node_modules/@types/node/node_modules/undici-types/websocket.d.ts","../../node_modules/@types/node/node_modules/undici-types/eventsource.d.ts","../../node_modules/@types/node/node_modules/undici-types/diagnostics-channel.d.ts","../../node_modules/@types/node/node_modules/undici-types/content-type.d.ts","../../node_modules/@types/node/node_modules/undici-types/cache.d.ts","../../node_modules/@types/node/node_modules/undici-types/index.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/assert/strict.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/dns/promises.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/dom-events.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/readline/promises.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/sea.d.ts","../../node_modules/@types/node/sqlite.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/stream/promises.d.ts","../../node_modules/@types/node/stream/consumers.d.ts","../../node_modules/@types/node/stream/web.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/test.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/timers/promises.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/ts5.6/index.d.ts","../../node_modules/@types/mime/index.d.ts","../../node_modules/@types/send/index.d.ts","../../node_modules/@types/qs/index.d.ts","../../node_modules/@types/range-parser/index.d.ts","../../node_modules/@types/express-serve-static-core/index.d.ts","../../node_modules/@types/http-errors/index.d.ts","../../node_modules/@types/serve-static/index.d.ts","../../node_modules/@types/connect/index.d.ts","../../node_modules/@types/body-parser/index.d.ts","../../node_modules/@types/express/index.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/helpers/typeAliases.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/helpers/util.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/ZodError.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/locales/en.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/errors.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/helpers/parseUtil.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/helpers/enumUtil.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/helpers/errorUtil.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/helpers/partialUtil.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/standard-schema.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/types.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/external.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/index.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/any.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/errorMessages.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/array.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/bigint.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/boolean.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/number.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/date.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/enum.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/intersection.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/literal.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/string.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/record.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/map.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/nativeEnum.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/never.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/null.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/nullable.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/object.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/set.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/tuple.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/undefined.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/union.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/unknown.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parseTypes.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/Refs.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/Options.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/getRelativePath.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parseDef.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/branded.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/catch.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/default.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/effects.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/optional.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/pipeline.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/promise.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/readonly.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/selectParser.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/zodToJsonSchema.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/index.d.ts","../../node_modules/@backstage/config/dist/index.d.ts","../../node_modules/@backstage/plugin-permission-common/dist/index.d.ts","../../node_modules/tarn/dist/PromiseInspection.d.ts","../../node_modules/tarn/dist/utils.d.ts","../../node_modules/tarn/dist/PendingOperation.d.ts","../../node_modules/tarn/dist/Resource.d.ts","../../node_modules/tarn/dist/Pool.d.ts","../../node_modules/tarn/dist/TimeoutError.d.ts","../../node_modules/tarn/dist/tarn.d.ts","../../node_modules/knex/types/result.d.ts","../../node_modules/knex/types/tables.d.ts","../../node_modules/knex/types/index.d.ts","../../node_modules/@backstage/plugin-permission-node/node_modules/zod/v3/external.d.cts","../../node_modules/@backstage/plugin-permission-node/node_modules/zod/v3/index.d.cts","../../node_modules/@backstage/catalog-model/dist/index.d.ts","../../node_modules/@backstage/plugin-search-common/dist/index.d.ts","../../node_modules/@backstage/plugin-catalog-common/dist/index.d.ts","../../node_modules/@backstage/filter-predicates/node_modules/zod/v3/external.d.cts","../../node_modules/@backstage/filter-predicates/node_modules/zod/v3/index.d.cts","../../node_modules/@backstage/filter-predicates/dist/index.d.ts","../../node_modules/@backstage/catalog-client/dist/index.d.ts","../../node_modules/@types/passport/node_modules/@types/express-serve-static-core/index.d.ts","../../node_modules/@types/passport/node_modules/@types/express/index.d.ts","../../node_modules/@types/passport/index.d.ts","../../node_modules/@backstage/plugin-auth-node/node_modules/zod/v3/external.d.cts","../../node_modules/@backstage/plugin-auth-node/node_modules/zod/v3/index.d.cts","../../node_modules/@backstage/plugin-auth-node/dist/index.d.ts","../../node_modules/@backstage/plugin-permission-node/dist/index.d.ts","../../node_modules/@types/luxon/src/zone.d.ts","../../node_modules/@types/luxon/src/settings.d.ts","../../node_modules/@types/luxon/src/_util.d.ts","../../node_modules/@types/luxon/src/misc.d.ts","../../node_modules/@types/luxon/src/duration.d.ts","../../node_modules/@types/luxon/src/interval.d.ts","../../node_modules/@types/luxon/src/datetime.d.ts","../../node_modules/@types/luxon/src/info.d.ts","../../node_modules/@types/luxon/src/luxon.d.ts","../../node_modules/@types/luxon/index.d.ts","../../node_modules/@backstage/backend-plugin-api/node_modules/@backstage/cli-common/dist/index.d.ts","../../node_modules/@backstage/backend-plugin-api/dist/index.d.ts","../mcp-chat-node/src/extensions.ts","../mcp-chat-node/src/index.ts","./src/module.ts","./src/index.ts","../../node_modules/@jest/expect-utils/build/index.d.ts","../../node_modules/chalk/index.d.ts","../../node_modules/@jest/schemas/node_modules/@sinclair/typebox/typebox.d.ts","../../node_modules/@jest/schemas/build/index.d.ts","../../node_modules/pretty-format/build/index.d.ts","../../node_modules/jest-diff/build/index.d.ts","../../node_modules/jest-matcher-utils/build/index.d.ts","../../node_modules/expect/build/index.d.ts","../../node_modules/@types/jest/index.d.ts","../../node_modules/@types/webpack-env/index.d.ts"],"fileInfos":[{"version":"824cb491a40f7e8fdeb56f1df5edf91b23f3e3ee6b4cde84d4a99be32338faee","affectsGlobalScope":true},"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","9a68c0c07ae2fa71b44384a839b7b8d81662a236d4b9ac30916718f7510b1b2d","5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","5514e54f17d6d74ecefedc73c504eadffdeda79c7ea205cf9febead32d45c4bc",{"version":"87d693a4920d794a73384b3c779cadcb8548ac6945aa7a925832fe2418c9527a","affectsGlobalScope":true},{"version":"76f838d5d49b65de83bc345c04aa54c62a3cfdb72a477dc0c0fce89a30596c30","affectsGlobalScope":true},{"version":"cd034f499c6cdca722b60c04b5b1b78e058487a7085a8e0d6fb50809947ee573","affectsGlobalScope":true},{"version":"138fb588d26538783b78d1e3b2c2cc12d55840b97bf5e08bca7f7a174fbe2f17","affectsGlobalScope":true},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true},{"version":"4443e68b35f3332f753eacc66a04ac1d2053b8b035a0e0ac1d455392b5e243b3","affectsGlobalScope":true},{"version":"bc47685641087c015972a3f072480889f0d6c65515f12bd85222f49a98952ed7","affectsGlobalScope":true},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true},{"version":"93495ff27b8746f55d19fcbcdbaccc99fd95f19d057aed1bd2c0cafe1335fbf0","affectsGlobalScope":true},{"version":"6fc23bb8c3965964be8c597310a2878b53a0306edb71d4b5a4dfe760186bcc01","affectsGlobalScope":true},{"version":"ea011c76963fb15ef1cdd7ce6a6808b46322c527de2077b6cfdf23ae6f5f9ec7","affectsGlobalScope":true},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true},{"version":"bb42a7797d996412ecdc5b2787720de477103a0b2e53058569069a0e2bae6c7e","affectsGlobalScope":true},{"version":"4738f2420687fd85629c9efb470793bb753709c2379e5f85bc1815d875ceadcd","affectsGlobalScope":true},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true},{"version":"9fc46429fbe091ac5ad2608c657201eb68b6f1b8341bd6d670047d32ed0a88fa","affectsGlobalScope":true},{"version":"61c37c1de663cf4171e1192466e52c7a382afa58da01b1dc75058f032ddf0839","affectsGlobalScope":true},{"version":"b541a838a13f9234aba650a825393ffc2292dc0fc87681a5d81ef0c96d281e7a","affectsGlobalScope":true},{"version":"b20fe0eca9a4e405f1a5ae24a2b3290b37cf7f21eba6cbe4fc3fab979237d4f3","affectsGlobalScope":true},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true},{"version":"49ed889be54031e1044af0ad2c603d627b8bda8b50c1a68435fe85583901d072","affectsGlobalScope":true},{"version":"e93d098658ce4f0c8a0779e6cab91d0259efb88a318137f686ad76f8410ca270","affectsGlobalScope":true},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true},{"version":"bf14a426dbbf1022d11bd08d6b8e709a2e9d246f0c6c1032f3b2edb9a902adbe","affectsGlobalScope":true},{"version":"5e07ed3809d48205d5b985642a59f2eba47c402374a7cf8006b686f79efadcbd","affectsGlobalScope":true},{"version":"2b72d528b2e2fe3c57889ca7baef5e13a56c957b946906d03767c642f386bbc3","affectsGlobalScope":true},{"version":"8073890e29d2f46fdbc19b8d6d2eb9ea58db9a2052f8640af20baff9afbc8640","affectsGlobalScope":true},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true},{"version":"51e547984877a62227042850456de71a5c45e7fe86b7c975c6e68896c86fa23b","affectsGlobalScope":true},{"version":"956d27abdea9652e8368ce029bb1e0b9174e9678a273529f426df4b3d90abd60","affectsGlobalScope":true},{"version":"4fa6ed14e98aa80b91f61b9805c653ee82af3502dc21c9da5268d3857772ca05","affectsGlobalScope":true},{"version":"e6633e05da3ff36e6da2ec170d0d03ccf33de50ca4dc6f5aeecb572cedd162fb","affectsGlobalScope":true},{"version":"d8670852241d4c6e03f2b89d67497a4bbefe29ecaa5a444e2c11a9b05e6fccc6","affectsGlobalScope":true},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true},{"version":"caccc56c72713969e1cfe5c3d44e5bab151544d9d2b373d7dbe5a1e4166652be","affectsGlobalScope":true},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true},{"version":"50d53ccd31f6667aff66e3d62adf948879a3a16f05d89882d1188084ee415bbc","affectsGlobalScope":true},{"version":"15b98a533864d324e5f57cd3cfc0579b231df58c1c0f6063ea0fcb13c3c74ff9","affectsGlobalScope":true},{"version":"33358442698bb565130f52ba79bfd3d4d484ac85fe33f3cb1759c54d18201393","affectsGlobalScope":true},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true},"b40885a4e39fb67eb251fb009bf990f3571ccf7279dccad26c2261b4e5c8ebcd","2d0e63718a9ab15554cca1ef458a269ff938aea2ad379990a018a49e27aadf40","530e5c7e4f74267b7800f1702cf0c576282296a960acbdb2960389b2b1d0875b","1c483cc60a58a0d4c9a068bdaa8d95933263e6017fbea33c9f99790cf870f0a8","07863eea4f350458f803714350e43947f7f73d1d67a9ddf747017065d36b073a","396c2c14fa408707235d761a965bd84ce3d4fc3117c3b9f1404d6987d98a30d6","0c46e15efeb2ff6db7c6830c801204e1048ccf0c8cc9ab1556b0b95832c9d1c9","c475aa6e8f0a20c76b5684658e0adaf7e1ba275a088ee6a5641e1f7fe9130b8a","a42db31dacd0fa00d7b13608396ca4c9a5494ae794ad142e9fb4aa6597e5ca54","4d2b263907b8c03c5b2df90e6c1f166e9da85bd87bf439683f150afc91fce7e7","db6eec0bf471520d5de8037e42a77349c920061fb0eb82d7dc8917262cbf0f17","13c83c04f3cbd2da8276c6290b75f295edf309b4f907f667f1b775d5f048f47e","ca70001e8ea975754a3994379faca469a99f81d00e1ff5b95cabac5e993359aa","b70bd59e0e52447f0c0afe7935145ef53de813368f9dd02832fa01bb872c1846","3bdc578841f58bfd1087e14f81394ece5efd56b953362ef100bdd5bd179cd625","2bc15addade46dc6480df2817c6761d84794c67819b81e9880ab5ce82afb1289","247d6e003639b4106281694e58aa359613b4a102b02906c277e650269eaecede","fe37c7dc4acc6be457da7c271485fcd531f619d1e0bfb7df6a47d00fca76f19c","159af954f2633a12fdee68605009e7e5b150dbeb6d70c46672fd41059c154d53","a1b36a1f91a54daf2e89e12b834fa41fb7338bc044d1f08a80817efc93c99ee5","8bb4a5b632dd5a868f3271750895cb61b0e20cff82032d87e89288faee8dd6e2","2a3e6dfb299953d5c8ba2aca69d61021bd6da24acea3d301c5fa1d6492fcb0ec","017de6fdabea79015d493bf71e56cbbff092525253c1d76003b3d58280cd82a0","cf94e5027dd533d4ee448b6076be91bc4186d70f9dc27fac3f3db58f1285d0be","74293f7ca4a5ddf3dab767560f1ac03f500d43352b62953964bf73ee8e235d3d","6745b52ab638aaf33756400375208300271d69a4db9d811007016e60a084830f","90ee466f5028251945ee737787ee5e920ee447122792ad3c68243f15efa08414","34c17533b08bd962570d7bdb838fcaf5bcf7b913c903bc9241b0696a635b8115","1d567a058fe33c75604d2f973f5f10010131ab2b46cf5dddd2f7f5ee64928f07","5af5ebe8c9b84f667cd047cfcf1942d53e3b369dbd63fbea2a189bbf381146c6","5e126f7796301203e1d1048c1e5709ff9251f872a19f5ac0ee1f375d8128ef9b","147734cfd0973548fb6ef75d1e7d2c0b56bb59aad72b280784e811d914dc47d6","d2594d95d465026ebbee361f4819dc7b3146f4a8b42091ffb5dd90f9ceb345ab","e399d54c1b272a400ed446ca35d5e43d6b820723c2e5727b188ebea261e7cc2e","123568587c36c9f2a75091d8cdf8f287193855ba5aa10797b4fc320c80920b7f","6deffa531bdb8817b363505e88d957653d0c454f42c69e31588d00102cd1a076","973551068756351486afe706b240eb4dc83678ab2d829a1c6b1a19871394fd5f","e647d13de80e1b6b4e1d94363ea6f5f8f77dfb95d562748b488a7248af25aabf","9b7b0209a8841f5ffa60ccdfae26f7dc70ea4e7e446a603ef4732e84f1bb1b4f","5edc4b81a61ea5e0319b32d8f581d9643cb747cf44477b16af048f62d358c433","d47c9f84b00def208cbfdd820f8d10425ead9dbf36350d77fb55d5ef6857dabc","7629bedb475a5f5d04cdf8c69f29f2cf52a1d92dd13c39661c3e865ad997bd7e","20cf19c8028a7b958e9c2000281d0f4c4cd12502fef7d63b088d44647cdd607b","799780c3726407eaa2e09e709c376ec459582f6f9c41d9643f863580cecf7ff8","37280465f8f9b2ea21d490979952b18b7f4d1f0d8fab2d627618fb2cfa1828e3",{"version":"52e29afa525973fc7cff28c4b6b359d91ad030d4aa198f060f813d4abcadb099","affectsGlobalScope":true},"a890cccdc380629c6cd9e9d92fff4ca69b9adddde84cc503296ada99429b5a3b","168b6da36cf7b832173d7832e017bc6c6c7b4023bf6b2de293efb991b96bca44","05b39d7219bb2f55f865bca39a3772e1c0a396ea562967929d6b666560c85617","bcae62618c23047e36d373f0feac5b13f09689e4cd08e788af13271dbe73a139","2c49c6d7da43f6d21e2ca035721c31b642ebf12a1e5e64cbf25f9e2d54723c36","5ae003688265a1547bbcb344bf0e26cb994149ac2c032756718e9039302dfac8","e1744dbace6ba2051a32da3c6b40e0fc690810a87b9ad4a1925b59f8f7157a34","ba8a615335e3dfdf0773558357f15edfff0461db9aa0aef99c6b60ebd7c40344","6921769648e4b83bb10e8fcf7011ea2d8f7de5d056daacf661648935a407376e","dd21167f276d648aa8a6d0aacd796e205d822406a51420b7d7f5aa18a6d9d6d9","3dea56c1745af2c31af0c84ecc6082044dc14cfa4d7366251e5bf91693eecd8b","eb6360635bc14b96a243bd5134e471f3ad26b0ecaf52d9d28621e443edb56e5c","e6f25eb7de8d9854badecb42caec553fb50c7ec37926473e3fb7f6df45bc945f","62a64260ea1dada7d643377c1a0ef3495363f4cca36adf7345e8566e7d7f419b","8b15e8af2fc862870418d0a082a9da2c2511b962844874cf3c2bad6b2763ca10","3d399835c3b3626e8e00fefc37868efe23dbb660cce8742486347ad29d334edd","b262699ba3cc0cae81dae0d9ff1262accf9832b2b7ee6548c626d74076bff8fe","057cac07c7bc5abdcfba44325fcea4906dff7919a3d7d82d4ec40f8b4c90cf2f","d94034601782f828aa556791279c86c37f09f7034a2ab873eefe136f77a6046b","fd25b101370ee175be080544387c4f29c137d4e23cad4de6c40c044bed6ecf99","8175f51ec284200f7bd403cb353d578e49a719e80416c18e9a12ebf2c4021b2b","e3acb4eb63b7fc659d7c2ac476140f7c85842a516b98d0e8698ba81650a1abd4","04d4c47854061cc5cefc3089f38e006375ae283c559ab2ce00763bca2e49516b","6a2146116c2fa9ca4fefa5c1d3de821462fc22e5330cda1196be15d439728c51","f4f1499db1953093d2fa6b5a4bb8852f0b8b353ff7df6aac12dc09dbb4f99176","db183df77deb66843c904baf2fc00ebb70d271466a1cb92dd1a5cb861bb612c5","809dcd114fb92a5190bb0cbc2b60774d3dbead29c3474be9dd1044409ddfa0a1","a69aa0011f1c8862b9d417aebd4b8c9e8e5945d1ac53dc1fceb53af8312009fe","093ae9227ee6102da600c1f50f4053f7179fba242815f69ba56728a6c60ee93a","6a2146116c2fa9ca4fefa5c1d3de821462fc22e5330cda1196be15d439728c51","b30cc18b84468d3fa20ac04ca5ba9bed5a03431fc8a22bcf2c266c132baa1d3f","a9452e81c28c642c2f095844c3473d979eba5ae89726ad52b15ea86b3e112ee2","a54f60678f44415d01a810ca27244e04b4dde3d9b6d9492874262f1a95e56c7d","84058607d19ac1fdef225a04832d7480478808c094cbaedbceda150fa87c7e25","27abd2f2ed5aaac951b12b8332aac7970c9cf0cfd88c458f0f016228180b4293","901c640dced9243875645e850705362cb0a9a7f2eea1a82bb95ed53d162f38dd","ebb0d92294fe20f62a07925ce590a93012d6323a6c77ddce92b7743fa1e9dd20","b499f398b4405b9f073b99ad853e47a6394ae6e1b7397c5d2f19c23a4081f213","ef2cbb05dee40c0167de4e459b9da523844707ab4b3b32e40090c649ad5616e9","068a22b89ecc0bed7182e79724a3d4d3d05daacfe3b6e6d3fd2fa3d063d94f44","e70d18d1352550a028f48d74e126a919c830267b38c76ddae4dc1571476a462a","5624b09ca38ea604954f0422a9354e79ada3100305362a0da79555b3dd86f578","24830e279f5773a4108e0cbde02bdcb6c20b1d347ff1509f63eed031bf8b3190","8899fd9f8ab5ce2b3af7ba0e1a47eede6a2a30a269283cc4a934ab755d0aadaa","f10759ece76e17645f840c7136b99cf9a2159b3eabf58e3eac9904cadc22eee5","363dd28f6a218239fbd45bbcc37202ad6a9a40b533b3e208e030137fa8037b03","c6986e90cf95cf639f7f55d8ca49c7aaf0d561d47e6d70ab6879e40f73518c8d","224d293a02b7d22edb77b4ab89c0d4f63b95ecd7c0698776719f33863a77ffdc","1518707348d7bd6154e30d49487ba92d47b6bd9a32d320cd8e602b59700b5317","ede55f9bac348427d5b32a45ad7a24cc6297354289076d50c68f1692add61bce","d53a7e00791305f0bd04ea6e4d7ea9850ccc3538877f070f55308b3222f0a793","4ea5b45c6693288bb66b2007041a950a9d2fe765e376738377ba445950e927f6","7f25e826bfabe77a159a5fec52af069c13378d0a09d2712c6373ff904ba55d4b","7ffef1ed1c2bc7d9cf2fc134a7e8c68b10416cdbe8e70da8a4bd7ad5c8698d9c","63c0926fcd1c3d6d9456f73ab17a6affcdfc41f7a0fa5971428a57e9ea5cf9e0","eb524eabfa1809d54dd289374c0ce0ed4f145abb878687e4fd5e67f91d7d08a6","4ef0a17c5bcae3d68227136b562a4d54a4db18cfa058354e52a9ac167d275bbb","b748dd4ccc072a2b7194b898dc8996a2cb56bfa15ccdb60ac0d2f9eaa8e28e9d","64269ed536e2647e12239481e8287509f9ee029cbb11169793796519cc37ecd4","c06fd8688dd064796b41170733bba3dcacfaf7e711045859364f4f778263fc7b","b0a8bf71fea54a788588c181c0bffbdd2c49904075a7c9cb8c98a3106ad6aa6d","434c5a40f2d5defeede46ae03fb07ed8b8c1d65e10412abd700291b24953c578","c5a6184688526f9cf53e3c9f216beb2123165bfa1ffcbfc7b1c3a925d031abf7",{"version":"cd548f9fcd3cebe99b5ba91ae0ec61c3eae50bed9bc3cfd29d42dcfc201b68b5","affectsGlobalScope":true},"14a8ec10f9faf6e0baff58391578250a51e19d2e14abcc6fc239edb0fb4df7c5","81b0cf8cd66ae6736fd5496c5bbb9e19759713e29c9ed414b00350bd13d89d70","4992afbc8b2cb81e0053d989514a87d1e6c68cc7dedfe71f4b6e1ba35e29b77a","1810b0b14614e53075d4d1b3e6be512bde19b1ed3a287925c0d24bae8585fa1b","1c390420d6e444195fd814cb9dc2d9ca65e86eb2df9c1e14ff328098e1dc48ae","ec8b45e83323be47c740f3b573760a6f444964d19bbe20d34e3bca4b0304b3ad","ab8b86168ceb965a16e6fc39989b601c0857e1fd3fd63ff8289230163b114171","62d2f0134c9b53d00823c0731128d446defe4f2434fb84557f4697de70a62789","dc4a2cf12254395c8ae3fb4c61e6fd9f7c16110be66483599f9641941416988f","82b4045609dc0918319f835de4f6cb6a931fd729602292921c443a732a6bb811","6a2146116c2fa9ca4fefa5c1d3de821462fc22e5330cda1196be15d439728c51","654bcc87bc095d6a2248a5889ec057b38cae6052744b48f4d2922a7efac4554f","cad0f26943006174f5e7508c0542873c87ef77fa71d265968e5aa1239ad4459c","0be66c79867b62eabb489870ba9661c60c32a5b7295cce269e07e88e7bee5bf3","eed82e8db4b66b1ea1746a64cd8699a7779138b8e45d495306016ce918b28440","3a19286bcc9303c9352c03d68bb4b63cecbf5c9b7848465847bb6c9ceafa1484","6cdf8f9ca64918a2f3c2679bc146d55f07490f7f5e91310b642bc1a587f2e17e","3b55c93b5d7a44834d9d0060ca8bad7166cf83e13ef0ed0e736da4c3dbe490a2","d1f8a829c5e90734bb47a1d1941b8819aeee6e81a2a772c3c0f70b30e3693fa9","3517c54fba6f0623919137ab4bdb3b3c16e64b8578f025b0372b99be48227ad7","19b3d0c212d241c237f79009b4cd0051e54971747fd89dc70a74f874d1192534","50ee70672a1889b61ceaed0fae5d5fae75cf470f0c126a750d8f6fe279b4d3a1","7ef6623abd38e20a54000fa123a2c0ad3b9975f3576b043e66fc0fd7f06f1dde","e6d4f862924429ccb8e8eb4849f7ce7dd69f6d9bb7ec928f183deca371a80ca4","431f831d369b17f10d0034f9925cc23eac6fd285a8d60ff9ab00a7dcb515d2fc","6f35f273680e256b2702a1a230b032be883a6d82ecd2dbe5a6a4f49f1eb95e06","3b10140aae26eca9f0619c299921e202351c891b34e7245762e0641469864ffd","c0c0b22cefd1896b92d805556fcabda18720d24981b8cb74e08ffea1f73f96c2","ceec94a0cd2b3a121166b6bfe968a069f33974b48d9c3b45f6158e342396e6b2","49e35a90f8bd2aa4533286d7013d9c9ff4f1d9f2547188752c4a88c040e42885","3261b6d56270a3d8535f34c2fdad217cfba860d0f74f154f0a6a2031d0c8daf9","6a2146116c2fa9ca4fefa5c1d3de821462fc22e5330cda1196be15d439728c51","7eca5b6e1cd1c28637103d2b6c44e8b89035a53e515ff31ae3babc82e6c8e1f9","49c9c8316d59f6175e6e0439b1d5ef1218f02ce622d1a599449de30645559eed","e4c48be0ffac936fb60b19394739847145674582cbc7e24000d9fd35ab037365","215de2c70639abaf351b8ff69041e44a767ecffc5e8d2ac13ca3f201853fa1fb","d228c7773484140fac7286c9ca4f0e04db4a62acb792a606a2dda24bef70dc21","8e464886b1ff36711539ffa15ec2482472220271100768c1d98acfdf355a23ba","fb0135c4906ff44d3064feebd84bae323ebb7b59b8ce7053d34e7283d27c9076","178c8707a575baddc8f529a6dbd5d574a090e3498b2d525753db7938c74227c3","ae81e464a7db70637d07b93582b051487c7d119ac7e1bab1b1582a96e631b3f7","148634fcee440c7bd8c1339b97455aaadc196b0229ffc8dc8b85965a7d65b380","d3c60c4cf88594f84f7f5ca5f87d59090787bfcf032e86d4f03d58394b826910","f3c3f17825c6a78681186da04c2f3a0f1c60cfa95f3d4b82bbbd6ebd57214a6a","8a2c67c55dfab4ea1f6e378cfa4b5cb60d8e8931316500f5b59c201674f6105c","b7b45ff1345f8e6bd6109a5b6ef0394c2e3bcbe48830516d9e78e20592ce468a","e5eb4863b7fc8515078dc09cd2f98fd179ff1a55216ecdc57d2dec7ce13e36c1","81785a3ea03d6db981ddfcf8fb1bd1377f985564def845c55e49e16f171deec4","537a2b61594512c5e75fad7e29d25c23922e27e5a1506eb4fce74fe858472a6e","8f9a2a6ddbd11ecbbc430ae8ce25528e696206f799ef1f22528569caf6ce580c","e05e03e1687d7f80f1569fdae117bb7b97feef1e839a61e1b3c61ffca8cc67c9","b311d973a0028d6bc19dfbaae891ad3f7c5057684eb105cfbeec992ab71fbc13","8a49e533b98d5c18a8d515cd3ae3bab9d02b6d4a9ac916e1dba9092ca0ebff15","fcb26ad5a6c39ce71dfac5dc16b3ed0e1a06a6dc8b9ac69112c935ad95fcad69","6acdef608420511aa0c9e3290b37d671bab4f719ffc2a2992c2e63a24605a657","291df5da0d84d1452cd68abfbcca08a3f96af610bf0e748528ba8d25784ce2b1","176cda558a7f76813f463a46af4607a81f10de5330c0f7a43d55982163aa0493","6621af294bd4af8f3f9dd9bd99bd83ed8d2facd16faa6690a5b02d305abd98ab","5eada4495ab95470990b51f467c78d47aecfccc42365df4b1e7e88a2952af1a3","6b08ada439e3c7fba3e6d18c19f934e7bbea3f34979f2490074f0623b849e8e4","40e9c2028b34c6c1e3281818d062f7008705254ee992d9857d051c603391e0f4","07a9aa7f3facdfac577ed4aa0c166295d54637508942a2154566d87804a33ae2","4a34de405e3017bf9e153850386aacdf6d26bbcd623073d13ab3c42c2ae7314c","993bcd7e2dd9479781f33daab41ec297b8d6e6ccc4c8f9b629a60cc41e07e5c8","714a7869be4ff21fa7be0dc183569db5e6818ca22882a79d2bb3a7801f5bfab4","dfa99386b9a1c1803eb20df3f6d3adc9e44effc84fa7c2ab6537ed1cb5cc8cfb","4cb85ba4cf75f1b950bd228949ae508f229296de60cf999593e4dd776f7e84e8","e39730c031200579280cae4ea331ec4e0aa42f8f7ad19c3ec4b0b90414e40113","e90bd7922cb6d591efd7330d0ba8247ec3edf4c511b81346fd49fff5184e6935","1b581d7fcfacd6bbdabb2ceae32af31e59bf7ef61a2c78de1a69ca879b104168","4720efe0341867600b139bca9a8fa7858b56b3a13a4a665bd98c77052ca64ea4","a0f62f1335e4c627a04eed453d4fa709f19ef60fd11c65e1fdfc96de9df374a5","37446d15751f05bb3ecde3ad5346b2ccfa7f4578411e9e699b38a867327ffbf9","11792ab82e35e82f93690040fd634689cad71e98ab56e0e31c3758662fc85736","8551ca11a261b2384e0db64bbd09ee78a2043a908251746db3a522b6a646e960","6c53c05df974ece61aca769df915345dc6d5b7649a01dc715b7da1809ce00a77","18c505381728b8cc6ea6986728403c1969f0d81216ed04163a867780af89f839","d121a48de03095d7dd5cd09d39e1a1c4892b520dad4c1d9c339c5d5008cfb536","3a6ce66cd39bc030697a52508cfda7c248167467848964cc40bd992bd9ce71e0","b4ec75c8a71c180e886ffccb4b5391a5217d7e7077038de966e2b79553850412","f8117362c4a91da9e2a29466d682334fe522d4e5d6cc652d95c38797b41f4546","ecf85664c5bbbb0db1190cd1a57ebdedf7ecbc0dbbbfd548106f069e0c38666c","b43a0693d7162abf3a5b3b9e78acfafd0d4713af4d54d1778900e30c11bc4f83","efb3cb71ed3e03cee59cd95bffa5c7eb365b0c637dd4d8efc358d8a34b396052","aed88228359e87a1b1a4d3d45f5b6555724c01ac81ecd34aa56d4a0a01ba6910","6365e9d7645838ef3e98c0a9f52c03ce6b00962a67f1e3e945f155a6b12e0578","f4dc28fbbba727722cb1fd82f51a7b9540fbe410ed04ddf35cab191d6aa2ba10","19b3d0c212d241c237f79009b4cd0051e54971747fd89dc70a74f874d1192534","4adc1491e1338de6745d009222786747f50d67ac34d901420fbaefbf1b51b58c","4cfbd2a7a4afee212bfb0c9c3cb6e4c7d48366e0565bf5b43a4cd96c91cf14bf","37c175e28375e157933b40ca98eeb608e05f2583821a0fae564dc04614d2d95e","3f20a041a051abfb2b47a66611cf4bcbf263605f5469ed7e8b51b3977892d83f","7de33f94f482eee2f6d1d8f24427b737e2c4006792ec4c2b87da0a426e741c4d","79134a050ccec1692c31f1dacccd05ce4fcdacdf98f0fa56546b98eb8bdefead","24f1b6865be734484de2baf99146122137654c5f5f28086c5cee97b998bfcd5c","398feb1537ae0409646b0489bac99a9f0d757a2048f0009255f8e35e9c0f9828","3da4432a9c24123f98f6f1ddc5cda9c9eedf0a8853d06321803dbc5a116e5270","afc60e07200c5eae65b702f95d83096de54d99fa6eb2e0154e83b5e11c520bda","f4651affee2900f19746d1bf0fb1c45e77f57576197561ddc90b7272835c3f37","19527fc5a08c68414a234b02ae9b9619cdb4b811435d12c0af528e5640236f6b","20a629bc3f82d238f596230637365b8aec8284c963d13dafdd4c8e2746be5e64","01c48e5bf524d3fc2a3fa5c08a2e18d113ad1985bc3caea0503a4ea3a9eee64a","68969a0efd9030866f60c027aedbd600f66ea09e1c9290853cc24c2dcc92000f","4dbfad496657abd078dc75749cd7853cdc0d58f5be6dfb39f3e28be4fe7e7af5","348d2fe7d7b187f09ea6488ead5eae9bfbdb86742a2bad53b03dff593a7d40d1","becdfb07610e16293af2937e5f315a760f90a40fec4ffd76eb46ebcb0b3d6e16","710926665f4ada6c854b47da86b727005cc0e0831097d43f8c30727a7499788c","3888f0e43cd987a0dfa4fc16dd2096459deea150be49a2d30d6cf29d47801c92","f4300c38f9809cf811d5a9196893e91639a9e2bb6edf9a4f7e640c3c4ce765ec","676c3327721e3410b7387b13af857f4be96f2be91b3813a724eedc06b9ce52d7","10716e50bcd2a25cecf2dd993f0aadf76f12a390d2f7e91dc2cac794831e865e","81a8f1f6218d0acc8cd2cf8b5089d21b45cf812bb5820affe3bab058b46cba7b","fa69921924cf112fa523a18215a3bfb352ac3f498b46e66b879e50ca46cc9203","9b82a268ba0a85015cb04cd558582c7949a1b91b6761292b9360d093c18e1dd1","ccfb77fcac04c34442ffca82ae90c8dd2a0ec1689ace547fab9a0ae337dd4752","7b464488950d74ca5037da375308fc0c94a539378fd0e9554556df45483aad02","beebde754323e430b4ecf5b9f837a05b1667b3df86bd924b52c4f80f20b3d660","2d97de1377bad99c7b9df395330201195ef1d7f861a07087f2d42aa0d4daccbd","c790db6044ce1bbafc46f13bde46b9f0065de155b26a199f442fe064f6b05d63","05a618d1e5019598f7d2256ce7a51d4bf70b682cbb8604d847c186e1df619a65","f405e934163ed30905b4682eb542bb2d446e59c477871be9d29f92ab474d522a","8294ddd1c6ea4ed9ec190a2d41500539c1623e274d5a67786d6b09849cb98d45","aab16135be8081c563dcbb33c25bb4bbf2065c7026d7228e6f1cd8153d8587e7","666d6d6d9f2298f8d8d17ac7a34ac9ca9a59e09fc97b1ae505df6ab4934e2dbe","f3941ac359b8377c0ccce596a2bd3cde8986279f42d75290b0272f3ab1aa604d","de3d39262355af808ff74b3df62aaad0ad3cbde76c13fb4fa6fb6e4cc817e78e","a5042497dfcd9aa8864af2db95b386bd345559edac65c3d8910684ce68e551fc","757f7967151a9b1f043aba090f09c1bdb0abe54f229efd3b7a656eb6da616bf4","786691c952fe3feac79aca8f0e7e580d95c19afc8a4c6f8765e99fb756d8d9d7","734614c9c05d178ceb1acf2808e1ca7c092cf39d435efc47417d8f744f3e4c0b","d65a7ea85e27f032d99e183e664a92f5be67c7bc7b31940957af6beaaf696844","5c26ad04f6048b6433f87556619fd2e50ba6601dcdf3276c826c65681197f79d","9c752e91fe237ce4857fbbef141bee357821e1e50c2f33a72c6df845703c87d5","f926160895757a498af7715653e2aedb952c2579a7cb5cc79d7b13538f9090bd","255be579a134ab321af2fefb52ace369a11ffb4df09d1fbfc1ed1a43c1e5eec5","7abc0a41bf6ba89ea19345f74e1b02795e8fda80ddcfe058d0a043b8870e1e23","ab0926fedbd1f97ec02ed906cf4b1cf74093ab7458a835c3617dba60f1950ba3","f1a661906cd0e7fa5b049b15bdef4b20a99abca08faac457eeb2b6407f30d12f","7f5a6eac3d3d334e2f2eba41f659e9618c06361958762869055e22219f341554","626291e7b45a4b6871649c908fbbc5ac98009a5182e2594fbfe80b860f513c77","4093c47f69ea7acf0931095d5e01bfe1a0fa78586dbf13f4ae1142f190d82cc4","4fc9939c86a7d80ab6a361264e5666336d37e080a00d831d9358ad83575267da","f4ba385eedea4d7be1feeeac05aaa05d6741d931251a85ab48e0610271d001ce","348d5347f700d1e6000cbdd1198730979e65bfb7d6c12cc1adedf19f0c7f7fca","6fa6ceb04be38c932343d6435eb6a4054c3170829993934b013b110273fe40af","396e7b817fc4f5461b92f9a03325c2ebb09711aebcee5c41c5fd3e738eb78526","4116c4d61baab4676b52f2558f26fe9c9b5ca02c2792f9c36a577e7813029551","a294d0b1a9b16f85768553fdbf1d47f360dbff03649a84015c83fd3a582ba527","8f2644578a3273f43fd700803b89b842d2cd09c1fba2421db45737357e50f5b1","639f94fe145a72ce520d3d7b9b3b6c9049624d90cbf85cff46fb47fb28d1d8fe","8327a51d574987a2b0f61ea40df4adddf959f67bc48c303d4b33d47ba3be114a","00e1da5fce4ae9975f7b3ca994dcb188cf4c21aee48643e1d6d4b44e72df21ee","b991d92a0c3a48764edd073a5d28b6b4591ec9b7d4b2381067a57f36293637d0","51b4ab145645785c8ced29238192f870dbb98f1968a7c7ef2580cd40663b2940","100802c3378b835a3ce31f5d108de149bd152b45b555f22f50c2cafb3a962ead","fd4fef81d1930b60c464872e311f4f2da3586a2a398a1bdf346ffc7b8863150f","354f47aa8d895d523ebc47aea561b5fedb44590ac2f0eae94b56839a0f08056a","b152c7b474d7e084e78fa5eb610261a0bfe0810e4fd7290e848fdc88812f4504","67f2cd6e208e68fdfa366967d1949575df6ccf90c104fc9747b3f1bdb69ad55a","603395070ec53375882d53b585430e8f2dc6f77f4b381b22680d26c0a9595edc","cef16d87ff9aed3c5b96b47e0ac4277916c1c530f10eedfce4acaeacefddd3bb","fab33f402019d670257c8c833ffd78a7c9a99b4f7c23271e656cdbea1e89571f","976d20bb5533077a2135f456a2b48b7adb7149e78832b182066930bad94f053a","589713fefe7282fd008a2672c5fbacc4a94f31138bae6a03db2c7b5453dc8788","26f7f55345682291a8280c99bb672e386722961063c890c77120aaca462ac2f9","bdc2312da906d4129217238545d7e01e1d00b191beea1a9529b660de8b78834f","62b753ed351fba7e0f6b57103529ce90f2e11b949b8fc69c39464fe958535c25","514321f6616d04f0c879ac9f06374ed9cb8eac63e57147ac954e8c0e7440ce00","3c583256798adf31ef79fd5e51cd28a6fc764db87c105b0270214642cf1988aa","abdb70e24d3b39bf89aa07e769b33667c2d6f4ddcb4724735d72a941de6d4631","ff4aeeeaf4f7f3dc3e099c2e2b2bb4ec80edda30b88466c4ddf1dd169c73bf26","151aa7caace0a8e58772bff6e3505d06191508692d8638cd93e7ca5ecfa8cd1b","3d59b606bca764ce06d7dd69130c48322d4a93a3acb26bb2968d4e79e1461c3c","0231f8c8413370642c1c061e66b5a03f075084edebf22af88e30f5ce8dbf69f4","474d9ca594140dffc0585ce4d4acdcfba9d691f30ae2cafacc86c97981101f5c","8e1884a47d3cfddccf98bc921d13042988da5ebfd94664127fa02384d5267fc3","ea7d883df1c6b48eb839eb9b17c39d9cecf2e967a5214a410920a328e0edd14e","82f75b2de1456b0be46945c6c68547f032f11238d07db45bbc9c93fca6abfe41","812e55580eb591f3c04245345be8c9dce378b26238fb59d704e54a61e6e37c83","1de7ee494c7ac185e6abf94428afe270e98a59f1bb4768e4bea7804645a0d57d","2c12f912bab4b1eb797b2fded3f295fee98736f8053a08d0032becbecb4b34b1","5776c61de0f11da1c3cf8aafc3df524e8445201c96a7c5065a36dc74c2dc0ef6","c110c6e2b6a8494ff722db0c32ff143bcf0ed04ecdb993a58b8d4c1ef5d8e1d3","7f0f90d0ffdd54875c464b940afaa0f711396f65392f20e9ffafc0af12ccbf14","483255952a9b6240575a67f7beb4768bd850999a32d44d2c6d0ae6dfcdafe35c","a1957cc53ce2402d4dc5c51b7ccc76b30581ab67bea12a030a76300be67c51d8","8149e534c91fc2bcb3bf59f7c1fab7584382abfc5348055e7f84d2552c3de987","c280ec77789efcf60ea1f6fd7159774422f588104dae9dfa438c9c921f5ab168","2826b3526af4f0e2c8f303e7a9a9a6bb8632e4a96fece2c787f2df286a696cea","77ced89806322a43991a88a9bd267d6dc9e03fd207a65e879804fa760292a03b","c8ff3a75cd1c990cbe56080b1d254695c989136c9521cb1252c739788fe55c83","485f7d76af9e2b5af78aac874b0ac5563c2ae8c0a7833f62b24d837df8561fb9","8bdf41d41ff195838a5f9e92e5cb3dfcdc4665bcca9882b8d2f82a370a52384e","2b234fce994b272403881b675d6ae2e2afb2a8be8bdec71002ff8ff2d5b59bd0","97ba9ccb439e5269a46562c6201063fbf6310922012fd58172304670958c21f6","50edac457bdc21b0c2f56e539b62b768f81b36c6199a87fbb63a89865b2348f0","d090654a3a57a76b5988f15b7bb7edc2cdc9c056a00985c7edd1c47a13881680","12a6a37d9676938a3a443a6bd9e8321d7221b6ad67b4485753322dc82a91e2a1","6c4833182ba7a753200bf30986d254653c1ac58855d784edd8dfe82f5db98954","69eeee4818209fdb59544d6f74bd6ff024944bdd4050a33577f62376d5cada8e","fa05a4a765755e92c1dcab306ef3648fa4aa108494b6e10d2329db8b89e89908","ea385ec05b32ad43bbd1002a7c553bbc6935754504d60dc38ee64cc8b3c21768","d61821435a95c7a660d5850ce6fe9c4400787595009853d982343b8089724319","c8ccc40088528bb10294d097da7440b9fa8f310b6f55de33412451183ca3a46d","3e56d3093cd84dac94761258d6d98226671481d43e93321f9825692940fcc0c2","25091d25f74760301f1e094456e2e6af52ceb6ef1ece48910463528e499992d8","ed79978235b685e7e9d2ac149c6ddaf602ce7e3a30725c20023e57f011760593","3345fc785abb65f2263f91ba092bb77470d949eddb41fc208256b964c2ccd5cb","dacdfa1d138a592734377df139ae70f203669bc3f9ac45e931aa0e6f2e567c8a","8a49075f007383f24df5b52376e41198e341a7b715da34a90b2c54b8fc8d4bcc","83f5494ed714e7898414a220e56886e00ffb58c80cbf745ecc45d6aae55f051a","28a019a0ebc44efd6b9148bbaf688bed1778d6977950da3d277f09e17687a46a","a67eff604aaeeae1c93f410dd9f176ab75a3fac2d2761e0bd9d83f933ec3e657","76a0210cd218dd17365ac0b7a99936804ede147c0a899d6bd2a9ac29cc8d4fea","853d02f4f46ca9700fefd0d45062f5b82c9335ba2224ca4d7bd34d6ae4fc4a7f","5f9ab7ba179f92fa3c5dddafec778a621fe9f64e2ba8c264ddf76fe5cf9eaf93","a0bce0fb40b88d17305f113ed02c4014329be52e8168b01fe825c049e9a37028","364e53fe15122e9d37aa8ee2c8eb037cde59bf5890b46a8205f4516b529501c0","1a577fdc45901cf461d4edc7697860c63a60526f60b7b2ba8ff7c89a9e7a1932","a6da29e6495bf303eb5f0b65dca3f92711b9cd6729eb1bed3e29dbc8b0fc2604","c35bd33a53356146889d87a05b34fc5a130ba93bc1bb36d021c0a7c817c4cc8d","f6067be38e8661d7e68287db5a602501897e2fbb385dfa2ecd170dd9f4524e8a","506b96750c75c5e5af820ac8356f27b2bcd0b077a02d33d90e87be9f0604f59d","d9c87237f57a1ca503eebb89514f65c48800b10b5574f7cda978addab1474dfb","b3cc1bb7311f35569b531e781d4a42d2b91f8dfd8bc194cc310c8b61011d6e43","33cff836b608822d3b4a52f523d964472c5437d08d81dbd1171ccf743276a223","8ca2d01f5f3d4d4067aadea230570afa4c91e24e485fbe2e9d53ead3b33f80d0","f43f73148ca38e22ee1afbf538fe9e8bcee6d86afc2b9d57daadfe6245e6ad4c","57aa6a9a1c79c2c73dfdf23b26019e6f91a3fe9e08b0bd7832c724dd7d0fe7a2","110996aad86ee528a4a46527cd47aaf767de0cb8cca8fdb0b7b87da749c68052","6cca39f12cd8b42e48c6203fedfdd0a9f9c96134eb465a8be68df76a089f9959","cde88efad8081aedb4e9968b4aa443cb6088f5113d8678003f5f177722d905e2","abc2ab38b312bbc76ff52e8d8ef90598eb19ce1c6f1c5ebb38685f93dba470ca","ccbecdcc8a5e9516ec17a9258e80a168c62a76c544ce55888feb6c22664eae8d","cc0a058997c09abe1ed57e0372cd7657d877be64d0b4b9fbe20ff247d61d6612","d26904f264c521b8dd44a2b9ea1ba5bd64a2d871c8fc059f0fa1a3e4a269fd0b","27e453271f5ad1d46c71457eb5132f7144e23eb11c72b73c3a4c8e8b0149d453","c72bebdcfcfb7f2daa857b9d403cb1b8e0696c0a860b74f970e4ca48f4d406ab","ca0a18352359b0d495c1b95717de28af03f861c01e3dec8105a2397a841f484f","60fceb1c8cd74f7363b22f08b63f3dcea558041573c738334e2756aee7d6fa65","0eafef0d23b57d331a9607682598ce1aae265c3b94f731cbc7ed7338fee7f41b","a2dec58c87acdef8e1212b95be760571c3d0cbd7b21a0bcd2f553c4943f1b4ba","db382b318bc333eb7548cc1f0dcd149794d7e1d4969d54f9586f2533b287b5ac","9761bf5d22d558d20d9010370ae7ac73d49c02cfc931babd7a010b0f3d56727c","48b794b2e593bf76f2f2f7f7a391ac40644ac623426e566674c2cf01cfe0a8d5","2be3cf1dfff9359a87e80c98015a393ed253ed9fd5bb8a8d6489a65bac681343","e57080da20379bbc001330a90d1ac46359001666976231d2be34c81564be9a2b","c12f6c5202b036760f8610d32fc7d4f1d69d694b8440d19ee5479b6a46df1e15","c36a4fc691d1480d4d1651a50a0c5c3b19a792c5aff0b87f4fcab3530772ecc8","da7939bdd11118ecfd4e0391375c466a7f8c99f03abf68c361e0c4d978dcf080","9b9493208641585c4ec62fb629e9b7d5564d126ca22a5f36fe8eeb97d6bf2be4","99115d3526d38a41eb206e970e85a2ba41408e12a0d432c33675d20869e1080c","47f564c90fc3dc3f12b24eb8fd25235105a69a6aba8f8f2e4e8615ab3091f705","78b8a5461c34d953f0a2c863d564b5e749202b54d4a151341e1b11bd0543619c",{"version":"52e5443b5f27e0ad643e58ff690c138e4d251ff1a0811f0f28b14b99f8411234","affectsGlobalScope":true},"101c69a3ac1b79f607792ef1c77d5809b25e482683d9bbd3921b462c2f336f9a","30c5e6a4b2e08989544b546a9ac44a575cff576aaa3741f10652263c72d7d622","d01a18b75a98f3bf36f27935b989d16067b606253de50abafec56866da3e9aba","6dd35f934b9f3b3ae2a14fc8204de1f5a59f8b5334479303c4829780d44e845e",{"version":"c39e8eb7e18b15427e691321a9a45d9561435f0f43ac0c5d02f667d1f013dfbf","signature":"308abf4ff004fdd297cab7acc64e00a87751ced6ba22cfebfb14d2b3bf634300"},{"version":"394fda71d5d6bd00a372437dff510feab37b92f345861e592f956d6995e9c1ce","affectsGlobalScope":true},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true},{"version":"c564fc7c6f57b43ebe0b69bc6719d38ff753f6afe55dadf2dba36fb3558f39b6","affectsGlobalScope":true},{"version":"109b9c280e8848c08bf4a78fff1fed0750a6ca1735671b5cf08b71bae5448c03","affectsGlobalScope":true},"4967529644e391115ca5592184d4b63980569adf60ee685f968fd59ab1557188","cdcf9ea426ad970f96ac930cd176d5c69c6c24eebd9fc580e1572d6c6a88f62c","23cd712e2ce083d68afe69224587438e5914b457b8acf87073c22494d706a3d0","487b694c3de27ddf4ad107d4007ad304d29effccf9800c8ae23c2093638d906a","e525f9e67f5ddba7b5548430211cae2479070b70ef1fd93550c96c10529457bd","ccf4552357ce3c159ef75f0f0114e80401702228f1898bdc9402214c9499e8c0","c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","17fe9131bec653b07b0a1a8b99a830216e3e43fe0ea2605be318dc31777c8bbf","3c8e93af4d6ce21eb4c8d005ad6dc02e7b5e6781f429d52a35290210f495a674","2c9875466123715464539bfd69bcaccb8ff6f3e217809428e0d7bd6323416d01","ea6bc8de8b59f90a7a3960005fd01988f98fd0784e14bc6922dde2e93305ec7d","36107995674b29284a115e21a0618c4c2751b32a8766dd4cb3ba740308b16d59","914a0ae30d96d71915fc519ccb4efbf2b62c0ddfb3a3fc6129151076bc01dc60","2472ef4c28971272a897fdb85d4155df022e1f5d9a474a526b8fc2ef598af94e","6c8e442ba33b07892169a14f7757321e49ab0f1032d676d321a1fdab8a67d40c","b41767d372275c154c7ea6c9d5449d9a741b8ce080f640155cc88ba1763e35b3","1cd673d367293fc5cb31cd7bf03d598eb368e4f31f39cf2b908abbaf120ab85a","19851a6596401ca52d42117108d35e87230fc21593df5c4d3da7108526b6111c","3825bf209f1662dfd039010a27747b73d0ef379f79970b1d05601ec8e8a4249f","0b6e25234b4eec6ed96ab138d96eb70b135690d7dd01f3dd8a8ab291c35a683a","40bfc70953be2617dc71979c14e9e99c5e65c940a4f1c9759ddb90b0f8ff6b1a","da52342062e70c77213e45107921100ba9f9b3a30dd019444cf349e5fb3470c4","e9ace91946385d29192766bf783b8460c7dbcbfc63284aa3c9cae6de5155c8bc","40b463c6766ca1b689bfcc46d26b5e295954f32ad43e37ee6953c0a677e4ae2b","561c60d8bfe0fec2c08827d09ff039eca0c1f9b50ef231025e5a549655ed0298","1e30c045732e7db8f7a82cf90b516ebe693d2f499ce2250a977ec0d12e44a529","84b736594d8760f43400202859cda55607663090a43445a078963031d47e25e7","499e5b055a5aba1e1998f7311a6c441a369831c70905cc565ceac93c28083d53","54c3e2371e3d016469ad959697fd257e5621e16296fa67082c2575d0bf8eced0","beb8233b2c220cfa0feea31fbe9218d89fa02faa81ef744be8dce5acb89bb1fd","78b29846349d4dfdd88bd6650cc5d2baaa67f2e89dc8a80c8e26ef7995386583","5d0375ca7310efb77e3ef18d068d53784faf62705e0ad04569597ae0e755c401","59af37caec41ecf7b2e76059c9672a49e682c1a2aa6f9d7dc78878f53aa284d6","addf417b9eb3f938fddf8d81e96393a165e4be0d4a8b6402292f9c634b1cb00d","e38d4fdf79e1eadd92ed7844c331dbaa40f29f21541cfee4e1acff4db09cda33","8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","7c10a32ae6f3962672e6869ee2c794e8055d8225ef35c91c0228e354b4e5d2d3","2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","99f569b42ea7e7c5fe404b2848c0893f3e1a56e0547c1cd0f74d5dbb9a9de27e",{"version":"f4b4faedc57701ae727d78ba4a83e466a6e3bdcbe40efbf913b17e860642897c","affectsGlobalScope":true},"bbcfd9cd76d92c3ee70475270156755346c9086391e1b9cb643d072e0cf576b8","7394959e5a741b185456e1ef5d64599c36c60a323207450991e7a42e08911419","72c1f5e0a28e473026074817561d1bc9647909cf253c8d56c41d1df8d95b85f7",{"version":"59c893bb05d8d6da5c6b85b6670f459a66f93215246a92b6345e78796b86a9a7","affectsGlobalScope":true},"938f94db8400d0b479626b9006245a833d50ce8337f391085fad4af540279567","c4e8e8031808b158cfb5ac5c4b38d4a26659aec4b57b6a7e2ba0a141439c208c",{"version":"2c91d8366ff2506296191c26fd97cc1990bab3ee22576275d28b654a21261a44","affectsGlobalScope":true},"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a",{"version":"12fb9c13f24845000d7bd9660d11587e27ef967cbd64bd9df19ae3e6aa9b52d4","affectsGlobalScope":true},"289e9894a4668c61b5ffed09e196c1f0c2f87ca81efcaebdf6357cfb198dac14","25a1105595236f09f5bce42398be9f9ededc8d538c258579ab662d509aa3b98e","9de8df30f620738193bd68ee503dc76e5f47fc426fe971cfbd89c109fd90b32e","e009777bef4b023a999b2e5b9a136ff2cde37dc3f77c744a02840f05b18be8ff","ad1cc0ed328f3f708771272021be61ab146b32ecf2b78f3224959ff1e2cd2a5c",{"version":"71450bbc2d82821d24ca05699a533e72758964e9852062c53b30f31c36978ab8","affectsGlobalScope":true},{"version":"62f572306e0b173cc5dfc4c583471151f16ef3779cf27ab96922c92ec82a3bc8","affectsGlobalScope":true},"2f32444438ecb1fa4519f6ec3977d69ce0e3acfa18b803e5cd725c204501f350","0ab3c844f1eb5a1d94c90edc346a25eb9d3943af7a7812f061bf2d627d8afac0","ecfb45485e692f3eb3d0aef6e460adeabf670cef2d07e361b2be20cecfd0046b","161f09445a8b4ba07f62ae54b27054e4234e7957062e34c6362300726dabd315","77fced47f495f4ff29bb49c52c605c5e73cd9b47d50080133783032769a9d8a6","e6057f9e7b0c64d4527afeeada89f313f96a53291705f069a9193c18880578cb",{"version":"3cdbad1bb6929fd0220715d7da689c0b69df42c8239036ff75afe4f2232222ea","affectsGlobalScope":true},"0f5cda0282e1d18198e2887387eb2f026372ebc4e11c4e4516fef8a19ee4d514","e99b0e71f07128fc32583e88ccd509a1aaa9524c290efb2f48c22f9bf8ba83b1","76957a6d92b94b9e2852cf527fea32ad2dc0ef50f67fe2b14bd027c9ceef2d86",{"version":"237581f5ec4620a17e791d3bb79bad3af01e27a274dbee875ac9b0721a4fe97d","affectsGlobalScope":true},{"version":"a8a99a5e6ed33c4a951b67cc1fd5b64fd6ad719f5747845c165ca12f6c21ba16","affectsGlobalScope":true},"a58a15da4c5ba3df60c910a043281256fa52d36a0fcdef9b9100c646282e88dd","b36beffbf8acdc3ebc58c8bb4b75574b31a2169869c70fc03f82895b93950a12","de263f0089aefbfd73c89562fb7254a7468b1f33b61839aafc3f035d60766cb4","70b57b5529051497e9f6482b76d91c0dcbb103d9ead8a0549f5bab8f65e5d031","e6d81b1f7ab11dc1b1ad7ad29fcfad6904419b36baf55ed5e80df48d56ac3aff","1013eb2e2547ad8c100aca52ef9df8c3f209edee32bb387121bb3227f7c00088","b6b8e3736383a1d27e2592c484a940eeb37ec4808ba9e74dd57679b2453b5865","d6f36b683c59ac0d68a1d5ee906e578e2f5e9a285bca80ff95ce61cdc9ddcdeb","37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","125d792ec6c0c0f657d758055c494301cc5fdb327d9d9d5960b3f129aff76093",{"version":"27e4532aaaa1665d0dd19023321e4dc12a35a741d6b8e1ca3517fcc2544e0efe","affectsGlobalScope":true},"ea713aa14a670b1ea0fbaaca4fd204e645f71ca7653a834a8ec07ee889c45de6",{"version":"cd9c0ecbe36a3be0775bfc16ae30b95af2a4a1f10e7949ceab284c98750bcebd","affectsGlobalScope":true},{"version":"2918b7c516051c30186a1055ebcdb3580522be7190f8a2fff4100ea714c7c366","affectsGlobalScope":true},"ae86f30d5d10e4f75ce8dcb6e1bd3a12ecec3d071a21e8f462c5c85c678efb41","982efeb2573605d4e6d5df4dc7e40846bda8b9e678e058fc99522ab6165c479e","e03460fe72b259f6d25ad029f085e4bedc3f90477da4401d8fbc1efa9793230e","4286a3a6619514fca656089aee160bb6f2e77f4dd53dc5a96b26a0b4fc778055",{"version":"d67fc92a91171632fc74f413ce42ff1aa7fbcc5a85b127101f7ec446d2039a1f","affectsGlobalScope":true},{"version":"d40e4631100dbc067268bce96b07d7aff7f28a541b1bfb7ef791c64a696b3d33","affectsGlobalScope":true},"64bc5859f99559a3587c031ec6862c671f6fdd54e61d43d8ffd02a9422092677","42180b657831d1b8fead051698618b31da623fb71ff37f002cb9d932cfa775f1","4f98d6fb4fe7cbeaa04635c6eaa119d966285d4d39f0eb55b2654187b0b27446",{"version":"e4c653466d0497d87fa9ffd00e59a95f33bc1c1722c3f5c84dab2e950c18da70","affectsGlobalScope":true},"e6dcc3b933e864e91d4bea94274ad69854d5d2a1311a4b0e20408a57af19e95d","525882f5d67944cd6fa0ef70b8e7ade7757cb10d94b80968eb777d1a8ace4a52","d3f2d715f57df3f04bf7b16dde01dec10366f64fce44503c92b8f78f614c1769","cb90077223cc1365fa21ef0911a1f9b8f2f878943523d97350dc557973ca3823","baac9896d29bcc55391d769e408ff400d61273d832dd500f21de766205255acb","2f5747b1508ccf83fad0c251ba1e5da2f5a30b78b09ffa1cfaf633045160afed",{"version":"a45c25e77c911c1f2a04cade78f6f42b4d7d896a3882d4e226efd3a3fcd5f2c4","affectsGlobalScope":true},"b71c603a539078a5e3a039b20f2b0a0d1708967530cf97dec8850a9ca45baa2b","18f1541b81b80d806120a3489af683edfb811deb91aeca19735d9bb2613e6311","104c67f0da1bdf0d94865419247e20eded83ce7f9911a1aa75fc675c077ca66e","cc0d0b339f31ce0ab3b7a5b714d8e578ce698f1e13d7f8c60bfb766baeb1d35c","232f118ae64ab84dcd26ddb60eaed5a6e44302d36249abf05e9e3fc2cbb701a2","d3cfde44f8089768ebb08098c96d01ca260b88bccf238d55eee93f1c620ff5a5","293eadad9dead44c6fd1db6de552663c33f215c55a1bfa2802a1bceed88ff0ec","36eb5babc665b890786550d4a8cb20ef7105673a6d5551fbdd7012877bb26942","fec412ded391a7239ef58f455278154b62939370309c1fed322293d98c8796a6","e3498cf5e428e6c6b9e97bd88736f26d6cf147dedbfa5a8ad3ed8e05e059af8a","dba3f34531fd9b1b6e072928b6f885aa4d28dd6789cbd0e93563d43f4b62da53","f672c876c1a04a223cf2023b3d91e8a52bb1544c576b81bf64a8fec82be9969c","e4b03ddcf8563b1c0aee782a185286ed85a255ce8a30df8453aade2188bbc904","2329d90062487e1eaca87b5e06abcbbeeecf80a82f65f949fd332cfcf824b87b","25b3f581e12ede11e5739f57a86e8668fbc0124f6649506def306cad2c59d262","93c3e73824ad57f98fd23b39335dbdae2db0bd98199b0dc0b9ccc60bf3c5134a","a9ebb67d6bbead6044b43714b50dcb77b8f7541ffe803046fdec1714c1eba206","833e92c058d033cde3f29a6c7603f517001d1ddd8020bc94d2067a3bc69b2a8e","ef38456e22b0bffcd9ff28dc1a7138e84918a212e6960dd620cc3000341c0ebe","07a1cea63a067c0845029ea6e1933af842783efa3006510f504b1f09bd2ebff0","814187370f99638f6bb69c838d19dcdb20a41cb65627cfc16a04d9cc4522fc82","7df3ea6fcd7e74ab59724700357df41a12d8f57e22f3e5da36dc645f20753152","0e8edbe744dfc3ce65e9fa2283f1f0eb2c0aaaec4df19765f51c346e45452cda","a7559733f2f5f9ae4d071cef99c505870e167ee830c75faf121f34408b99afbe","9b6e899f6fa0cf536eead034fcae436ab6ecd9442153ee06a0fb5b01475bff85","1b399336f32abd1c83610e5c95337fdcf2dd5414cf4b44c1ff4927d2cd8f1cf2","55ddb00c1810d07a092af6a816f89a6e63c3c4ef04c9c27d36a7dd59bf59b5ae","5ecb3df85ac1c4a7e7a1e9761a5bfb52a65eef8e94e1280e1bff6389cd453099","9af342002e6b793ca8a69b322cf8347250c129b45dbca8731baaa66ec553561b","e01ab496375025f3e54f832d43f840c589e57eb2e5986421f791f51bbcbc494e","539cc98696e783f3fe32422a89f8a34479ce056adb211dd60b6a89550d3b9b7f","11d5d9c9b11fbd1537ecec72ec38f993d0358c42f7c98569998a04bbbf57d07c","c26c383b08e47dfbd741193ef1e7f8f002ac3b0d2f6bf3d4b6b9a99ee2d9378e","75473b178a514d8768d6ead4a4da267aa6bedeeb792cd9437e45b46fa2dcf608","e82a6fc9b90adc5270daa1e467feb3a2ae5393180839d7a347acd1d9ebe04493","3d877e9f51aabdb77efeea746c0c09464274dcaf7364e6e64880e9c2eaa8c990","9830d91d01b457b113b36b56d4534ba8fc42bc3c195a2108dc3431e9f77340c7","1e7d16304d31f287ec09753214b755eb78e1122432d06dc771f5c123199273b1","acca4486b08bf5dc91c23d65f47181bd13f82571969c85e8df474fa6bc5c2a88","296dcaf11fa0122dfe78a1d97bea96aa9bccb73098bc739ab253281ad192dffb","971dc452ac09307ee049acb21bbd30a82d1c163377465d6b33fd4d677ed2385d","226b58896f4f01f4c669d908f32c657bcab1a83f3aebb2f3d711a4fe7ba2a2d6","8a818c9cf372e5c5818d846d761ff59c531caa3b0aa62c5686be1df31dc08296","f01c60b06afe23316efccaaa8b6ccb5f507b8e6eadf5e2a84c6fe350aebaa1bd","9a447607a90667c6db7737f30d2429f6f06efde55a47a2a3eeebc52e866d153e","ecc6f977713316ef4339f32631ecb619a40a3061fa86ff3776591920d9977e24","0aea84fed0ab80d54f32a40aaf5f4d58c8a5259dd5f9fe39dbcd584575dbb100","a1769100f50f3e190c2ea2ed2a711e6798c70f9ad806b54c597a5b64488007b0","8105a77b1ce063fd0f60080d8985e01cb92516237cb4a254547ce7548e8916e5","dc6b3b3383218cc2c556687fd7ac7b6b1d9ad3abaf50da7f04a2d7a01abaee19","879443705ef53b56d8f5b944ea2c24bd5b37a1341eb0142789c2e2567d6bb6e1","44c18ff24c5c5b7883ca2e1b1d4236db715ca5cfd9b87705e1a7e4591b4b445e","3cceb8a1fe59bc1d233764bfef78e6c72a468e2af1e06a92e282b1848c78bc31","ed96d25fa3170958d1d376e653ade8e653638d3fb819a4792a503a5505eea849","a005dc547fff460703595b4c0faccb7ec68a5870a4d0e5a2932dc1fd59cc9856","dccbbf8ce85ea99cdbdc2269d55f75bc1fbad77d96c40fd82bd73af3fb8f39e4","449babe88138e129aef94c1696b527898f9e13ab62bce129daee0e85266e48a7","17a8d5ef1c541cd5382df1542ed21cd90a1f08aea0d5fea080c5b6e1f82c3233","a27859c0e69512ee3fd878dfa0182ad9caec5bab32b7d0a0a2ff2f93964600e2","7c54c4b7f7752b0315f14b9ae63f00d7a3f39308e598c670d8a96afdcb8e0a4e","9f559e612c27cce4bc181decc88ba90b00e5be42b6ed7fe9316d6c61476d7439","03dfcf3d00c60a769e705eb5b080c3674cd59ae830ee7ad82aed8f1883f60f06","ca8cec5a09c4323e1fcd9e0f0f84727c9b0818802fabae4ecf7f42a380483037","92d06124389a259ec6f17fa490dd2da4a8aff8fd9055047036e63211793a556b","aa8c0e10f176c156cfea40f5acdbc08cb44a43ba5411c743be645743ed3b1c02","b1bf7de0413303c8bd9424cf4955b433606e90eb31339202c8bffdb1dec982e9","979a151b6741901c83c365c97b7e55dcaccd92402fe6095dedd7be206bb23bae","ec982ebee52d26bdc7a7520612216c9c55e7a44e6fe0f654fb26e6ee41bc16c4","706132295c6d7639a0de0deaca13aa2ed5b823495dfebb5fc6a6c396ae324a7f","a9ebb67d6bbead6044b43714b50dcb77b8f7541ffe803046fdec1714c1eba206","833e92c058d033cde3f29a6c7603f517001d1ddd8020bc94d2067a3bc69b2a8e","78758d13c4ec1c04593c7920ac588579e54635549c1492b36dcf6ad09d9bef31","231f38789bfa215aaac440b83a816ab08a9d01d29d93ab657f95d0f629accd79","4cdf9eb4d324d141478333ee72b68eedb4e9f40bc3503a4d747606ba3f278113","a9ebb67d6bbead6044b43714b50dcb77b8f7541ffe803046fdec1714c1eba206","833e92c058d033cde3f29a6c7603f517001d1ddd8020bc94d2067a3bc69b2a8e","3bc5d8f6d191265ba9369b9607ad2d3803fb3527e03a5113cff68d9681f478a2","a54a900fb766fb34ee5ffc442a00f20db741bb9b376c8c18d62acbb77cb48d61",{"version":"86ea91bfa7fef1eeb958056f30f1db4e0680bc9b5132e5e9d6e9cfd773c0c4fd","affectsGlobalScope":true},"d26a79f97f25eb1c5fc36a8552e4decc7ad11104a016d31b1307c3afaf48feb1",{"version":"ff155930718467b27e379e4a195e4607ce277f805cad9d2fa5f4fd5dec224df6","affectsGlobalScope":true},"a9ebb67d6bbead6044b43714b50dcb77b8f7541ffe803046fdec1714c1eba206","833e92c058d033cde3f29a6c7603f517001d1ddd8020bc94d2067a3bc69b2a8e","56972217f61c7e5321c132a32423bf892fc39847b112019905b3478d77117ad1","ded701a77c87375fda31920102ed40995704c26c9844dd546d1861f24297d3e0","5339f84dfcb7b04aa1c2b4d7713d6128039381447f07abc2e48d36685e2eef44","fb35a61a39c933d31b5b2549d906b2c932a1486622958586f662dbd4b2fe72e6","24e2728268be1ad2407bab004549d2753a49b2acb0f117a04c4e28ffb3ecdd4f","aff159b14eba59afe98a88fe6f57881ba02895fb9763512dda9083497bdcd0e6","b6bc775d112a7761a50594fc589aeaa8893c139ffe3db2b4999756e17f367a8d","79f8edca4c97e2fa77473df1d8fda43daf4501a4c721af66d389ab771dcff207","7ca4605ebe31b24536fbcda17567275c6355c64ef4ac8ed9ff9b19b59adeb2f2","26080058b725ac0b480241751255b4391f722263778e84e66a62068705aafd3c","46afbf46c3d62eac2afead3a2011d506637bf4f2c05e1fd64bbf7e2bb2947b7c","02f634f868780eaaff5e2d3fb4570dac8e7f018a8650bb9a0ac1deb4915df8d1","302e3cfe08d08266460fa3c9884a8fb60261d100e75298eb14370b378f8e861a","74a5090f489072850111e8fdc8534f35a093c83e7796c0c434b17482abf8c99c","9c02420a1f4be45dcbef3f7ce90ebe600dc52ae66ca66e554162cb3b06ab3ebb","9522ce17a83f1f005313beb9c8647070094ce3585f2534530c71d596068ce02b",{"version":"5456f5a4488477d9118f2a40e7a5a9fe0e955b5c72ff661ff15ce86e323c2a8e","signature":"293b3ab21f016ad8dd17adbe7ec0a6d0f90f982b752e7764e50752cac480dce7"},{"version":"64c398bd7f55a96ec1ceeceb39c460b7b525b34b9e33756908dad5680a4b9d2d","signature":"36673e5d8139cc19499fda8cf6b76c2771863dbbbecdba99238badf9bd593e47"},"cdcc132f207d097d7d3aa75615ab9a2e71d6a478162dde8b67f88ea19f3e54de","0d14fa22c41fdc7277e6f71473b20ebc07f40f00e38875142335d5b63cdfc9d2","c085e9aa62d1ae1375794c1fb927a445fa105fed891a7e24edbb1c3300f7384a","f315e1e65a1f80992f0509e84e4ae2df15ecd9ef73df975f7c98813b71e4c8da","5b9586e9b0b6322e5bfbd2c29bd3b8e21ab9d871f82346cb71020e3d84bae73e","3e70a7e67c2cb16f8cd49097360c0309fe9d1e3210ff9222e9dac1f8df9d4fb6","ab68d2a3e3e8767c3fba8f80de099a1cfc18c0de79e42cb02ae66e22dfe14a66","d96cc6598148bf1a98fb2e8dcf01c63a4b3558bdaec6ef35e087fd0562eb40ec",{"version":"f8db4fea512ab759b2223b90ecbbe7dae919c02f8ce95ec03f7fb1cf757cfbeb","affectsGlobalScope":true},{"version":"ebf3ec92378d6eae07f236180ac6caba814464947ee2c90b347202e9f35c6379","affectsGlobalScope":true}],"root":[431,635,636],"options":{"allowImportingTsExtensions":true,"allowJs":true,"declaration":true,"declarationMap":false,"emitDeclarationOnly":true,"esModuleInterop":true,"experimentalDecorators":false,"importHelpers":false,"jsx":2,"module":99,"noFallthroughCasesInSwitch":true,"noImplicitAny":true,"noImplicitReturns":true,"noImplicitThis":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./dist","removeComments":false,"rootDir":"./src","skipLibCheck":true,"sourceMap":false,"strict":true,"strictBindCallApply":true,"strictFunctionTypes":true,"strictNullChecks":true,"strictPropertyInitialization":true,"stripInternal":true,"target":9,"useDefineForClassFields":true},"fileIdsList":[[131,404,405,406,407,408,409,410,411,412,413,418,435,480],[131,136,138,179,181,192,197,230,232,241,258,343,399,404,405,406,407,408,409,410,411,412,413,414,417,435,480],[131,399,435,480],[131,398,418,435,480],[131,241,343,403,418,435,480],[131,241,272,343,403,418,435,480],[404,405,406,407,408,409,410,411,412,413,435,480],[131,435,480],[131,179,192,415,435,480],[400,401,402,403,414,416,417,418,419,420,421,424,435,480],[343,435,480],[435,480],[343,401,435,480],[131,400,402,435,480],[131,418,435,480],[131,412,422,435,480],[422,423,435,480],[416,435,480],[131,291,435,480],[348,368,397,435,480],[344,345,346,347,435,480],[179,435,480],[131,350,435,480],[131,349,435,480],[215,435,480],[349,350,351,352,365,435,480],[131,215,435,480],[131,179,364,435,480],[366,367,435,480],[131,291,375,435,480],[376,377,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,435,480],[291,381,382,435,480],[131,291,307,381,435,480],[131,378,379,380,435,480],[131,378,381,435,480],[131,291,378,381,435,480],[291,393,435,480],[131,291,307,390,392,435,480],[131,378,391,435,480],[131,291,307,389,435,480],[131,378,388,390,435,480],[131,378,389,435,480],[139,180,435,480],[131,139,179,435,480],[131,153,154,435,480],[147,435,480],[131,149,435,480],[147,148,150,151,152,435,480],[140,141,142,143,144,145,146,149,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,435,480],[153,154,435,480],[216,217,218,219,435,480],[131,218,435,480],[220,223,229,435,480],[221,222,435,480],[224,435,480],[225,435,480],[131,226,227,435,480],[226,227,228,435,480],[374,435,480],[131,307,435,480],[131,291,307,372,435,480],[369,370,371,372,373,435,480],[131,192,370,435,480],[292,435,480],[131,192,291,296,435,480],[131,291,294,295,435,480],[131,291,296,435,480],[131,272,435,480],[273,274,295,296,297,298,299,300,301,302,303,304,305,435,480],[131,192,435,480],[131,295,435,480],[131,303,435,480],[131,284,435,480],[275,277,278,279,280,281,282,283,284,285,286,287,288,289,435,480],[131,276,435,480],[131,283,435,480],[131,278,435,480],[332,435,480],[329,330,333,334,335,336,337,338,339,340,435,480],[293,435,480],[306,435,480],[290,435,480],[341,435,480],[231,435,480],[131,233,234,435,480],[235,236,435,480],[233,234,237,238,239,240,435,480],[131,249,251,435,480],[131,250,435,480],[251,252,253,254,255,256,257,435,480],[131,253,435,480],[131,198,212,213,435,480],[131,211,435,480],[198,212,213,214,435,480],[183,184,185,187,188,189,190,191,435,480],[131,353,435,480],[353,354,355,356,357,358,359,360,361,362,363,435,480],[307,435,480],[131,241,435,480],[260,435,480],[131,317,318,435,480],[319,435,480],[131,260,308,309,310,311,312,313,314,315,316,320,321,322,323,324,325,326,327,328,342,435,480],[63,67,68,69,70,71,72,73,74,75,80,83,84,85,86,88,91,92,93,99,102,103,106,107,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,127,128,129,130,435,480],[131,242,435,480],[131,244,435,480],[242,435,480],[242,243,244,245,246,247,248,435,480],[131,435,480,512],[263,435,480],[262,264,435,480,512],[435,480,512],[261,262,265,266,267,268,269,270,271,435,480],[131,132,435,480],[132,133,134,135,435,480],[63,435,480],[62,435,480],[66,75,76,77,435,480],[75,78,435,480],[66,73,435,480],[66,78,435,480],[64,65,76,77,78,79,435,480],[82,435,480,512],[84,435,480],[67,68,74,75,435,480],[67,75,435,480],[87,89,90,435,480],[87,88,435,480],[92,435,480],[64,435,480],[69,94,435,480],[94,435,480],[97,435,480],[94,95,96,435,480],[94,95,96,97,98,435,480],[71,435,480],[67,73,75,435,480],[84,85,435,480],[100,435,480],[100,104,435,480],[100,101,104,105,435,480],[74,103,435,480],[81,435,480],[63,72,435,480],[71,73,435,480,495,497],[66,435,480],[66,108,109,110,435,480],[64,68,69,70,71,74,78,435,480],[68,86,435,480],[102,435,480],[67,69,75,114,116,118,435,480],[67,69,75,114,115,116,117,435,480],[118,435,480],[73,74,88,118,435,480],[67,73,435,480],[73,92,435,480],[74,84,85,435,480],[82,114,435,480,495,512],[67,68,124,125,435,480],[68,73,86,114,123,124,125,126,435,480,495,496],[68,86,102,435,480],[73,435,480],[193,194,195,196,435,480],[131,188,435,480],[185,435,480],[186,435,480],[131,183,184,435,480],[426,435,480,512,540,593,594,604,620,630,631],[427,435,480,481],[427,435,480,607,609,612],[426,435,480],[426,435,480,593,611],[435,480,541,542,543,545,546,551],[435,480,552],[426,435,480,540,593,607,613,616,618,632],[435,480,607,608],[426,435,480,592,593],[435,480,553,577,578],[435,480,553,577,579],[435,480,577,578],[435,480,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591],[435,480,554,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576],[435,480,578],[435,480,553,555,577,578],[435,480,553,555,578],[435,480,553,555,559,578,579],[435,480,553],[435,480,553,578],[435,480,553,565,577,578],[435,480,554,578],[435,480,553,569,577,578],[435,480,553,562,577,578],[435,480,553,561,564,577,578],[435,480,541,542,553],[435,480,543,544],[435,480,542,543],[435,480,551],[435,480,543],[435,480,541,542,543,546,547,548,549,550],[435,480,540,593,594,606,619,632],[426,435,480,512,594],[435,480,639],[199,200,201,202,205,206,207,208,209,210,435,480],[131,204,435,480],[131,205,435,480],[331,435,480],[435,480,495,530,538],[435,480,495,530],[435,480,492,495,530,532,533,534],[435,480,533,535,537,539],[435,480,641,644],[435,480,629],[435,480,622],[435,480,621,623,625,626,630],[435,480,623,624,627],[435,480,621,624,627],[435,480,623,625,627],[435,480,621,622,624,625,626,627,628],[435,480,621,627],[435,480,623],[435,477,480],[435,479,480],[435,480,485,515],[435,480,481,486,492,493,500,512,523],[435,480,481,482,492,500],[435,480,483,524],[435,480,484,485,493,501],[435,480,485,512,520],[435,480,486,488,492,500],[435,479,480,487],[435,480,488,489],[435,480,490,492],[435,479,480,492],[435,480,492,493,494,512,523],[435,480,492,493,494,507,512,515],[435,475,480],[435,475,480,488,492,495,500,512,523],[435,480,492,493,495,496,500,512,520,523],[435,480,495,497,512,520,523],[435,480,492,498],[435,480,499,523],[435,480,488,492,500,512],[435,445,449,480,523],[435,445,480,512,523],[435,440,480],[435,442,445,480,523],[435,480,500,520],[435,480,530],[435,440,480,530],[435,442,445,480,500,523],[435,437,438,439,441,444,480,492,512,523],[435,445,453,480],[435,438,443,480],[435,445,469,470,480],[435,438,441,445,480,515,523,530],[435,445,480],[435,437,480],[435,440,441,442,443,444,445,446,447,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,470,471,472,473,474,480],[435,445,462,465,480,488],[435,445,453,454,455,480],[435,443,445,454,456,480],[435,444,480],[435,438,440,445,480],[435,445,449,454,456,480],[435,449,480],[435,443,445,448,480,523],[435,438,442,445,453,480],[435,445,462,480],[435,440,445,469,480,515,528,530],[435,480,501],[435,480,502],[435,479,480,503],[435,477,478,479,480,481,482,483,484,485,486,487,488,489,490,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529],[435,480,505],[435,480,506],[435,480,492,507,508],[435,480,507,509,524,526],[435,480,492,512,513,515],[435,480,514,515],[435,480,512,513],[435,480,515],[435,480,516],[435,477,480,512],[435,480,492,518,519],[435,480,518,519],[435,480,485,500,512,520],[435,480,521],[480],[432,433,434,435,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529],[435,480,500,522],[435,480,495,506,523],[435,480,485,524],[435,480,512,525],[435,480,499,526],[435,480,527],[435,480,492,494,503,512,515,523,525,526,528],[435,480,512,529],[435,480,495,615],[435,480,535,537,539,614],[435,480,493,512,530,531],[435,480,495,530,532,536],[435,480,637,643],[435,480,641],[435,480,638,642],[435,480,492,512,520,601,602,603],[435,480,640],[435,480,596],[435,480,492,530,595,597,598],[435,480,599,600],[435,480,595],[425,430,435,480],[431,435,480,635],[431,435,480,593,632,634],[427,428,435,480],[428,429,435,480],[430,435,480,632],[435,480,633],[131,290,435,480],[131,290,374,435,480],[290,381,382,435,480],[131,290,306,381,435,480],[131,290,378,381,435,480],[290,393,435,480],[131,290,306,390,392,435,480],[131,290,306,389,435,480],[131,306,435,480],[131,290,306,372,435,480],[131,192,290,296,435,480],[131,290,293,295,435,480],[131,290,296,435,480],[131,260,308,309,310,311,312,313,314,315,316,320,321,322,323,324,325,326,327,328,341,435,480],[426,435,480,553,593],[426,435,480,540,553,593,607,613,616,632],[435,480,540,553,593,594,619,632],[430],[431,635],[632]],"referencedMap":[[419,1],[418,2],[415,3],[399,4],[404,5],[405,5],[406,5],[407,5],[408,5],[409,6],[410,5],[411,5],[412,5],[413,5],[420,7],[414,8],[416,9],[425,10],[401,11],[400,12],[402,13],[403,14],[422,15],[423,16],[424,17],[417,18],[421,19],[398,20],[344,12],[348,21],[345,22],[346,22],[347,22],[351,23],[350,24],[352,25],[366,26],[349,27],[365,28],[368,29],[367,12],[378,8],[376,30],[377,12],[397,31],[383,32],[384,32],[382,33],[385,33],[381,34],[379,35],[380,36],[386,12],[387,8],[394,37],[393,38],[391,8],[392,39],[395,40],[389,41],[390,42],[388,42],[396,8],[138,8],[139,8],[181,43],[180,44],[140,8],[141,8],[142,8],[143,8],[144,8],[145,8],[146,8],[155,45],[156,8],[157,12],[158,8],[159,8],[160,8],[161,8],[149,12],[162,12],[163,8],[148,46],[150,47],[147,8],[151,46],[152,47],[153,48],[179,49],[164,8],[165,47],[166,8],[167,8],[168,12],[169,8],[170,8],[171,8],[172,8],[173,8],[174,8],[175,50],[176,8],[177,8],[154,8],[178,8],[216,25],[217,25],[220,51],[219,52],[218,8],[230,53],[221,25],[223,54],[222,8],[225,55],[224,12],[226,56],[227,56],[228,57],[229,58],[375,59],[372,60],[373,61],[370,12],[369,12],[374,62],[371,63],[292,19],[293,64],[297,65],[296,66],[298,67],[295,8],[273,68],[274,12],[306,69],[299,70],[300,12],[301,71],[302,71],[304,72],[303,71],[305,19],[289,73],[275,8],[290,74],[277,75],[276,8],[284,76],[279,77],[280,77],[285,8],[281,77],[278,8],[286,77],[283,77],[282,8],[287,8],[288,8],[329,8],[330,12],[333,78],[341,79],[334,12],[335,12],[336,12],[337,12],[338,12],[339,12],[340,12],[294,80],[307,81],[291,82],[342,83],[231,8],[232,84],[235,85],[237,86],[236,8],[238,85],[239,85],[241,87],[233,8],[240,8],[234,12],[252,88],[251,89],[253,27],[254,12],[258,90],[255,8],[256,8],[257,91],[250,8],[214,92],[198,8],[212,93],[213,8],[215,94],[259,95],[354,96],[353,8],[355,12],[361,8],[356,8],[357,8],[358,8],[362,8],[364,97],[359,8],[360,8],[363,8],[324,8],[260,8],[308,98],[309,99],[310,12],[311,100],[312,12],[313,12],[314,12],[315,8],[316,98],[317,8],[319,101],[320,102],[318,8],[321,12],[322,12],[343,103],[323,12],[325,12],[326,98],[327,12],[328,12],[137,104],[243,105],[245,106],[246,107],[244,8],[247,12],[248,12],[249,108],[242,12],[261,12],[263,8],[262,109],[264,110],[265,111],[266,109],[267,109],[268,112],[272,113],[269,109],[270,112],[271,12],[132,8],[133,114],[134,8],[135,114],[136,115],[62,116],[63,117],[65,12],[78,118],[79,119],[76,120],[77,121],[64,12],[80,122],[83,123],[85,124],[86,125],[68,126],[87,12],[91,127],[89,128],[90,12],[84,12],[93,129],[69,130],[95,131],[96,132],[98,133],[97,134],[99,135],[94,136],[92,137],[100,138],[101,139],[105,140],[106,141],[104,142],[82,143],[70,12],[73,144],[107,145],[108,146],[109,146],[66,12],[111,147],[110,146],[131,104],[71,12],[75,148],[112,149],[113,12],[67,12],[103,150],[119,151],[118,152],[115,12],[116,153],[117,12],[114,154],[102,155],[120,156],[121,157],[122,123],[123,123],[124,158],[88,12],[126,159],[127,160],[81,12],[128,12],[129,161],[125,12],[72,162],[74,137],[130,116],[193,70],[194,8],[197,163],[195,8],[196,8],[188,8],[189,164],[186,165],[187,166],[185,167],[183,8],[184,8],[192,95],[190,12],[191,8],[182,104],[632,168],[631,169],[613,170],[607,171],[593,171],[427,171],[612,172],[610,173],[611,174],[619,175],[617,173],[618,174],[609,176],[594,177],[579,178],[578,179],[555,180],[580,12],[592,181],[581,178],[577,182],[554,183],[556,184],[557,185],[558,12],[582,178],[583,178],[560,186],[584,178],[585,178],[561,187],[562,178],[563,188],[566,189],[567,187],[568,190],[569,183],[570,191],[559,185],[571,178],[586,178],[587,192],[588,178],[589,178],[565,193],[572,184],[564,185],[573,178],[574,190],[575,178],[576,190],[590,178],[591,179],[543,194],[545,195],[552,173],[547,12],[548,12],[546,196],[549,197],[541,12],[542,12],[553,174],[544,198],[550,12],[551,199],[620,200],[605,173],[606,174],[608,201],[426,12],[637,12],[640,202],[639,12],[204,12],[208,12],[199,12],[200,12],[201,12],[202,12],[211,203],[205,204],[206,8],[207,205],[210,12],[209,8],[203,104],[332,206],[331,12],[539,207],[538,208],[535,209],[540,210],[536,12],[645,211],[630,212],[623,213],[627,214],[625,215],[628,216],[626,217],[629,218],[624,12],[622,219],[621,220],[531,12],[477,221],[478,221],[479,222],[480,223],[481,224],[482,225],[433,12],[483,226],[484,227],[485,228],[486,229],[487,230],[488,231],[489,231],[491,12],[490,232],[492,233],[493,234],[494,235],[476,236],[495,237],[496,238],[497,239],[498,240],[499,241],[500,242],[453,243],[464,244],[451,243],[465,112],[474,245],[443,246],[442,247],[473,248],[468,249],[472,250],[445,251],[461,252],[444,253],[471,254],[440,255],[441,249],[446,256],[447,12],[452,246],[450,256],[438,257],[475,258],[466,259],[456,260],[455,256],[457,261],[459,262],[454,263],[458,264],[469,248],[448,265],[449,266],[460,267],[439,112],[463,268],[462,256],[467,12],[437,12],[470,269],[501,270],[502,271],[503,272],[504,273],[505,274],[506,275],[507,276],[508,276],[509,277],[510,12],[511,12],[512,278],[514,279],[513,280],[515,281],[516,282],[517,283],[518,284],[519,285],[520,286],[521,287],[435,288],[432,12],[434,12],[530,289],[522,290],[523,291],[524,292],[525,293],[526,294],[527,295],[528,296],[529,297],[616,298],[614,209],[615,299],[533,12],[534,12],[532,300],[537,301],[646,12],[436,12],[638,12],[644,302],[642,303],[643,304],[604,305],[602,12],[603,12],[641,306],[597,307],[599,308],[595,12],[598,307],[600,12],[601,309],[596,310],[60,12],[61,12],[10,12],[11,12],[14,12],[13,12],[2,12],[15,12],[16,12],[17,12],[18,12],[19,12],[20,12],[21,12],[22,12],[3,12],[23,12],[4,12],[24,12],[28,12],[25,12],[26,12],[27,12],[29,12],[30,12],[31,12],[5,12],[32,12],[33,12],[34,12],[35,12],[6,12],[39,12],[36,12],[37,12],[38,12],[40,12],[7,12],[41,12],[46,12],[47,12],[42,12],[43,12],[44,12],[45,12],[8,12],[51,12],[48,12],[49,12],[50,12],[52,12],[9,12],[53,12],[54,12],[55,12],[58,12],[56,12],[57,12],[1,12],[59,12],[12,12],[431,311],[636,312],[635,313],[429,314],[430,315],[428,12],[633,316],[634,317]],"exportedModulesMap":[[419,1],[418,2],[415,3],[399,4],[404,5],[405,5],[406,5],[407,5],[408,5],[409,6],[410,5],[411,5],[412,5],[413,5],[420,7],[414,8],[416,9],[425,10],[401,11],[400,12],[402,13],[403,14],[422,15],[423,16],[424,17],[417,18],[421,318],[398,20],[344,12],[348,21],[345,22],[346,22],[347,22],[351,23],[350,24],[352,25],[366,26],[349,27],[365,28],[368,29],[367,12],[378,8],[376,319],[377,12],[397,31],[383,320],[384,320],[382,321],[385,321],[381,34],[379,35],[380,322],[386,12],[387,8],[394,323],[393,324],[391,8],[392,39],[395,325],[389,41],[390,42],[388,42],[396,8],[138,8],[139,8],[181,43],[180,44],[140,8],[141,8],[142,8],[143,8],[144,8],[145,8],[146,8],[155,45],[156,8],[157,12],[158,8],[159,8],[160,8],[161,8],[149,12],[162,12],[163,8],[148,46],[150,47],[147,8],[151,46],[152,47],[153,48],[179,49],[164,8],[165,47],[166,8],[167,8],[168,12],[169,8],[170,8],[171,8],[172,8],[173,8],[174,8],[175,50],[176,8],[177,8],[154,8],[178,8],[216,25],[217,25],[220,51],[219,52],[218,8],[230,53],[221,25],[223,54],[222,8],[225,55],[224,12],[226,56],[227,56],[228,57],[229,58],[375,59],[372,326],[373,327],[370,12],[369,12],[374,62],[371,63],[292,318],[293,64],[297,328],[296,329],[298,330],[295,8],[273,68],[274,12],[306,69],[299,70],[300,12],[301,71],[302,71],[304,72],[303,71],[305,318],[289,73],[275,8],[290,74],[277,75],[276,8],[284,76],[279,77],[280,77],[285,8],[281,77],[278,8],[286,77],[283,77],[282,8],[287,8],[288,8],[329,8],[330,12],[333,78],[341,79],[334,12],[335,12],[336,12],[337,12],[338,12],[339,12],[340,12],[294,80],[307,81],[291,82],[342,83],[231,8],[232,84],[235,85],[237,86],[236,8],[238,85],[239,85],[241,87],[233,8],[240,8],[234,12],[252,88],[251,89],[253,27],[254,12],[258,90],[255,8],[256,8],[257,91],[250,8],[214,92],[198,8],[212,93],[213,8],[215,94],[259,95],[354,96],[353,8],[355,12],[361,8],[356,8],[357,8],[358,8],[362,8],[364,97],[359,8],[360,8],[363,8],[324,8],[260,8],[308,81],[309,99],[310,12],[311,100],[312,12],[313,12],[314,12],[315,8],[316,81],[317,8],[319,101],[320,102],[318,8],[321,12],[322,12],[343,331],[323,12],[325,12],[326,81],[327,12],[328,12],[137,104],[243,105],[245,106],[246,107],[244,8],[247,12],[248,12],[249,108],[242,12],[261,12],[263,8],[262,109],[264,110],[265,111],[266,109],[267,109],[268,112],[272,113],[269,109],[270,112],[271,12],[132,8],[133,114],[134,8],[135,114],[136,115],[62,116],[63,117],[65,12],[78,118],[79,119],[76,120],[77,121],[64,12],[80,122],[83,123],[85,124],[86,125],[68,126],[87,12],[91,127],[89,128],[90,12],[84,12],[93,129],[69,130],[95,131],[96,132],[98,133],[97,134],[99,135],[94,136],[92,137],[100,138],[101,139],[105,140],[106,141],[104,142],[82,143],[70,12],[73,144],[107,145],[108,146],[109,146],[66,12],[111,147],[110,146],[131,104],[71,12],[75,148],[112,149],[113,12],[67,12],[103,150],[119,151],[118,152],[115,12],[116,153],[117,12],[114,154],[102,155],[120,156],[121,157],[122,123],[123,123],[124,158],[88,12],[126,159],[127,160],[81,12],[128,12],[129,161],[125,12],[72,162],[74,137],[130,116],[193,70],[194,8],[197,163],[195,8],[196,8],[188,8],[189,164],[186,165],[187,166],[185,167],[183,8],[184,8],[192,95],[190,12],[191,8],[182,104],[632,168],[631,169],[613,170],[607,171],[593,171],[427,171],[612,332],[610,173],[611,174],[619,333],[617,173],[618,174],[609,176],[594,177],[579,178],[578,179],[555,180],[580,12],[592,181],[581,178],[577,182],[554,183],[556,184],[557,185],[558,12],[582,178],[583,178],[560,186],[584,178],[585,178],[561,187],[562,178],[563,188],[566,189],[567,187],[568,190],[569,183],[570,191],[559,185],[571,178],[586,178],[587,192],[588,178],[589,178],[565,193],[572,184],[564,185],[573,178],[574,190],[575,178],[576,190],[590,178],[591,179],[543,194],[545,195],[552,173],[547,12],[548,12],[546,196],[549,197],[541,12],[542,12],[553,174],[544,198],[550,12],[551,199],[620,334],[605,173],[606,174],[608,201],[426,12],[637,12],[640,202],[639,12],[204,12],[208,12],[199,12],[200,12],[201,12],[202,12],[211,203],[205,204],[206,8],[207,205],[210,12],[209,8],[203,104],[332,206],[331,12],[539,207],[538,208],[535,209],[540,210],[536,12],[645,211],[630,212],[623,213],[627,214],[625,215],[628,216],[626,217],[629,218],[624,12],[622,219],[621,220],[531,12],[477,221],[478,221],[479,222],[480,223],[481,224],[482,225],[433,12],[483,226],[484,227],[485,228],[486,229],[487,230],[488,231],[489,231],[491,12],[490,232],[492,233],[493,234],[494,235],[476,236],[495,237],[496,238],[497,239],[498,240],[499,241],[500,242],[453,243],[464,244],[451,243],[465,112],[474,245],[443,246],[442,247],[473,248],[468,249],[472,250],[445,251],[461,252],[444,253],[471,254],[440,255],[441,249],[446,256],[447,12],[452,246],[450,256],[438,257],[475,258],[466,259],[456,260],[455,256],[457,261],[459,262],[454,263],[458,264],[469,248],[448,265],[449,266],[460,267],[439,112],[463,268],[462,256],[467,12],[437,12],[470,269],[501,270],[502,271],[503,272],[504,273],[505,274],[506,275],[507,276],[508,276],[509,277],[510,12],[511,12],[512,278],[514,279],[513,280],[515,281],[516,282],[517,283],[518,284],[519,285],[520,286],[521,287],[435,288],[432,12],[434,12],[530,289],[522,290],[523,291],[524,292],[525,293],[526,294],[527,295],[528,296],[529,297],[616,298],[614,209],[615,299],[533,12],[534,12],[532,300],[537,301],[646,12],[436,12],[638,12],[644,302],[642,303],[643,304],[604,305],[602,12],[603,12],[641,306],[597,307],[599,308],[595,12],[598,307],[600,12],[601,309],[596,310],[60,12],[61,12],[10,12],[11,12],[14,12],[13,12],[2,12],[15,12],[16,12],[17,12],[18,12],[19,12],[20,12],[21,12],[22,12],[3,12],[23,12],[4,12],[24,12],[28,12],[25,12],[26,12],[27,12],[29,12],[30,12],[31,12],[5,12],[32,12],[33,12],[34,12],[35,12],[6,12],[39,12],[36,12],[37,12],[38,12],[40,12],[7,12],[41,12],[46,12],[47,12],[42,12],[43,12],[44,12],[45,12],[8,12],[51,12],[48,12],[49,12],[50,12],[52,12],[9,12],[53,12],[54,12],[55,12],[58,12],[56,12],[57,12],[1,12],[59,12],[12,12],[431,335],[636,336],[635,337],[429,314],[430,315],[428,12],[633,316],[634,317]],"semanticDiagnosticsPerFile":[419,418,415,399,404,405,406,407,408,409,410,411,412,413,420,414,416,425,401,400,402,403,422,423,424,417,421,398,344,348,345,346,347,351,350,352,366,349,365,368,367,378,376,377,397,383,384,382,385,381,379,380,386,387,394,393,391,392,395,389,390,388,396,138,139,181,180,140,141,142,143,144,145,146,155,156,157,158,159,160,161,149,162,163,148,150,147,151,152,153,179,164,165,166,167,168,169,170,171,172,173,174,175,176,177,154,178,216,217,220,219,218,230,221,223,222,225,224,226,227,228,229,375,372,373,370,369,374,371,292,293,297,296,298,295,273,274,306,299,300,301,302,304,303,305,289,275,290,277,276,284,279,280,285,281,278,286,283,282,287,288,329,330,333,341,334,335,336,337,338,339,340,294,307,291,342,231,232,235,237,236,238,239,241,233,240,234,252,251,253,254,258,255,256,257,250,214,198,212,213,215,259,354,353,355,361,356,357,358,362,364,359,360,363,324,260,308,309,310,311,312,313,314,315,316,317,319,320,318,321,322,343,323,325,326,327,328,137,243,245,246,244,247,248,249,242,261,263,262,264,265,266,267,268,272,269,270,271,132,133,134,135,136,62,63,65,78,79,76,77,64,80,83,85,86,68,87,91,89,90,84,93,69,95,96,98,97,99,94,92,100,101,105,106,104,82,70,73,107,108,109,66,111,110,131,71,75,112,113,67,103,119,118,115,116,117,114,102,120,121,122,123,124,88,126,127,81,128,129,125,72,74,130,193,194,197,195,196,188,189,186,187,185,183,184,192,190,191,182,632,631,613,607,593,427,612,610,611,619,617,618,609,594,579,578,555,580,592,581,577,554,556,557,558,582,583,560,584,585,561,562,563,566,567,568,569,570,559,571,586,587,588,589,565,572,564,573,574,575,576,590,591,543,545,552,547,548,546,549,541,542,553,544,550,551,620,605,606,608,426,637,640,639,204,208,199,200,201,202,211,205,206,207,210,209,203,332,331,539,538,535,540,536,645,630,623,627,625,628,626,629,624,622,621,531,477,478,479,480,481,482,433,483,484,485,486,487,488,489,491,490,492,493,494,476,495,496,497,498,499,500,453,464,451,465,474,443,442,473,468,472,445,461,444,471,440,441,446,447,452,450,438,475,466,456,455,457,459,454,458,469,448,449,460,439,463,462,467,437,470,501,502,503,504,505,506,507,508,509,510,511,512,514,513,515,516,517,518,519,520,521,435,432,434,530,522,523,524,525,526,527,528,529,616,614,615,533,534,532,537,646,436,638,644,642,643,604,602,603,641,597,599,595,598,600,601,596,60,61,10,11,14,13,2,15,16,17,18,19,20,21,22,3,23,4,24,28,25,26,27,29,30,31,5,32,33,34,35,6,39,36,37,38,40,7,41,46,47,42,43,44,45,8,51,48,49,50,52,9,53,54,55,58,56,57,1,59,12,431,636,635,429,430,428,633,634]},"version":"5.4.5"} \ No newline at end of file diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/knip-report.md index 28921c328dd..2661c353270 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/knip-report.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/knip-report.md @@ -1 +1,2 @@ # Knip report + diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/knip-report.md index 28921c328dd..2661c353270 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/knip-report.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/knip-report.md @@ -1 +1,2 @@ # Knip report + diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/report.api.md index a9379a50f7c..d72a8acab0d 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/report.api.md @@ -4,12 +4,12 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; -import { ChatMessage } from '@backstage-community/plugin-mcp-chat-backend'; -import { ChatResponse } from '@backstage-community/plugin-mcp-chat-backend'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; import { GenerateContentResult } from '@google/generative-ai'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-backend'; -import { ProviderConfig } from '@backstage-community/plugin-mcp-chat-backend'; -import { Tool } from '@backstage-community/plugin-mcp-chat-backend'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; +import { ProviderConfig } from '@backstage-community/plugin-mcp-chat-common'; +import { Tool } from '@backstage-community/plugin-mcp-chat-common'; // @public const _default: BackendFeature; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/knip-report.md index 28921c328dd..2661c353270 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/knip-report.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/knip-report.md @@ -1 +1,2 @@ # Knip report + diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/report.api.md index 034d07aba20..7c09a3b7ef9 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/report.api.md @@ -4,10 +4,10 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; -import { ChatMessage } from '@backstage-community/plugin-mcp-chat-backend'; -import { ChatResponse } from '@backstage-community/plugin-mcp-chat-backend'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-backend'; -import { Tool } from '@backstage-community/plugin-mcp-chat-backend'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; +import { Tool } from '@backstage-community/plugin-mcp-chat-common'; // @public const _default: BackendFeature; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/knip-report.md index 28921c328dd..2661c353270 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/knip-report.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/knip-report.md @@ -1 +1,2 @@ # Knip report + diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/report.api.md index 230d517badf..c395304b52b 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/report.api.md @@ -4,11 +4,11 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; -import { ChatMessage } from '@backstage-community/plugin-mcp-chat-backend'; -import { ChatResponse } from '@backstage-community/plugin-mcp-chat-backend'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-backend'; -import { ProviderConfig } from '@backstage-community/plugin-mcp-chat-backend'; -import { Tool } from '@backstage-community/plugin-mcp-chat-backend'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; +import { ProviderConfig } from '@backstage-community/plugin-mcp-chat-common'; +import { Tool } from '@backstage-community/plugin-mcp-chat-common'; // @public const _default: BackendFeature; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/knip-report.md new file mode 100644 index 00000000000..2661c353270 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/knip-report.md @@ -0,0 +1,2 @@ +# Knip report + diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/report.api.md index 44d8318a34a..1ff5cf06177 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/report.api.md @@ -4,12 +4,12 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; -import { ChatMessage } from '@backstage-community/plugin-mcp-chat-backend'; -import { ChatResponse } from '@backstage-community/plugin-mcp-chat-backend'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-backend'; -import { MCPServerFullConfig } from '@backstage-community/plugin-mcp-chat-backend'; -import { ResponsesApiResponse } from '@backstage-community/plugin-mcp-chat-backend'; -import { Tool } from '@backstage-community/plugin-mcp-chat-backend'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; +import { MCPServerFullConfig } from '@backstage-community/plugin-mcp-chat-common'; +import { ResponsesApiResponse } from '@backstage-community/plugin-mcp-chat-common'; +import { Tool } from '@backstage-community/plugin-mcp-chat-common'; // @public const _default: BackendFeature; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/knip-report.md index 28921c328dd..2661c353270 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/knip-report.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/knip-report.md @@ -1 +1,2 @@ # Knip report + diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/report.api.md index 53ded455763..0353c17dec7 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/report.api.md @@ -4,10 +4,10 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; -import { ChatMessage } from '@backstage-community/plugin-mcp-chat-backend'; -import { ChatResponse } from '@backstage-community/plugin-mcp-chat-backend'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-backend'; -import { Tool } from '@backstage-community/plugin-mcp-chat-backend'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; +import { Tool } from '@backstage-community/plugin-mcp-chat-common'; // @public const _default: BackendFeature; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/dev/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/dev/index.ts index 707e99fdc78..57733100b2f 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/dev/index.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/dev/index.ts @@ -44,4 +44,7 @@ backend.add(import('../src')); backend.add( import('@backstage-community/plugin-mcp-chat-backend-module-openai'), ); +backend.add( + import('@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock'), +); backend.start(); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json index 3c5e89e91d8..9447d80be36 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json @@ -43,6 +43,7 @@ "uuid": "^9.0.0" }, "devDependencies": { + "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock": "workspace:^", "@backstage-community/plugin-mcp-chat-backend-module-openai": "workspace:^", "@backstage/backend-test-utils": "^1.6.0", "@backstage/cli": "^0.33.0", diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-common/knip-report.md new file mode 100644 index 00000000000..2661c353270 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/knip-report.md @@ -0,0 +1,2 @@ +# Knip report + diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/package.json b/workspaces/mcp-chat/plugins/mcp-chat-common/package.json index 2814c8d7b3e..e163dcc3b6b 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-common/package.json +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/package.json @@ -16,9 +16,9 @@ "role": "common-library", "pluginId": "mcp-chat", "pluginPackages": [ + "@backstage-community/plugin-mcp-chat", "@backstage-community/plugin-mcp-chat-common", - "@backstage-community/plugin-mcp-chat-backend", - "@backstage-community/plugin-mcp-chat" + "@backstage-community/plugin-mcp-chat-node" ] }, "sideEffects": false, diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-node/knip-report.md new file mode 100644 index 00000000000..2661c353270 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/knip-report.md @@ -0,0 +1,2 @@ +# Knip report + diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/package.json b/workspaces/mcp-chat/plugins/mcp-chat-node/package.json index 4617440a40d..418b6b722e0 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-node/package.json +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/package.json @@ -15,9 +15,9 @@ "role": "node-library", "pluginId": "mcp-chat", "pluginPackages": [ - "@backstage-community/plugin-mcp-chat-node", + "@backstage-community/plugin-mcp-chat", "@backstage-community/plugin-mcp-chat-common", - "@backstage-community/plugin-mcp-chat-backend" + "@backstage-community/plugin-mcp-chat-node" ] }, "scripts": { diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-node/report.api.md new file mode 100644 index 00000000000..99613a00f77 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/report.api.md @@ -0,0 +1,16 @@ +## API Report File for "@backstage-community/plugin-mcp-chat-node" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { ExtensionPoint } from '@backstage/backend-plugin-api'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; + +// @public +export interface LlmProviderExtensionPoint { + registerProvider(type: string, provider: LLMProvider): void; +} + +// @public +export const llmProviderExtensionPoint: ExtensionPoint; +``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat/package.json b/workspaces/mcp-chat/plugins/mcp-chat/package.json index b62c020746a..d5c874319ee 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat/package.json +++ b/workspaces/mcp-chat/plugins/mcp-chat/package.json @@ -29,7 +29,9 @@ "supported-versions": "1.40.0", "pluginPackage": "@backstage-community/plugin-mcp-chat", "pluginPackages": [ - "@backstage-community/plugin-mcp-chat" + "@backstage-community/plugin-mcp-chat", + "@backstage-community/plugin-mcp-chat-common", + "@backstage-community/plugin-mcp-chat-node" ] }, "sideEffects": false, diff --git a/workspaces/mcp-chat/yarn.lock b/workspaces/mcp-chat/yarn.lock index 7793ef9e12e..d74d9b37bfe 100644 --- a/workspaces/mcp-chat/yarn.lock +++ b/workspaces/mcp-chat/yarn.lock @@ -165,6 +165,61 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-bedrock-runtime@npm:^3.0.0": + version: 3.1015.0 + resolution: "@aws-sdk/client-bedrock-runtime@npm:3.1015.0" + dependencies: + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/core": "npm:^3.973.24" + "@aws-sdk/credential-provider-node": "npm:^3.972.25" + "@aws-sdk/eventstream-handler-node": "npm:^3.972.11" + "@aws-sdk/middleware-eventstream": "npm:^3.972.8" + "@aws-sdk/middleware-host-header": "npm:^3.972.8" + "@aws-sdk/middleware-logger": "npm:^3.972.8" + "@aws-sdk/middleware-recursion-detection": "npm:^3.972.8" + "@aws-sdk/middleware-user-agent": "npm:^3.972.25" + "@aws-sdk/middleware-websocket": "npm:^3.972.13" + "@aws-sdk/region-config-resolver": "npm:^3.972.9" + "@aws-sdk/token-providers": "npm:3.1015.0" + "@aws-sdk/types": "npm:^3.973.6" + "@aws-sdk/util-endpoints": "npm:^3.996.5" + "@aws-sdk/util-user-agent-browser": "npm:^3.972.8" + "@aws-sdk/util-user-agent-node": "npm:^3.973.11" + "@smithy/config-resolver": "npm:^4.4.13" + "@smithy/core": "npm:^3.23.12" + "@smithy/eventstream-serde-browser": "npm:^4.2.12" + "@smithy/eventstream-serde-config-resolver": "npm:^4.3.12" + "@smithy/eventstream-serde-node": "npm:^4.2.12" + "@smithy/fetch-http-handler": "npm:^5.3.15" + "@smithy/hash-node": "npm:^4.2.12" + "@smithy/invalid-dependency": "npm:^4.2.12" + "@smithy/middleware-content-length": "npm:^4.2.12" + "@smithy/middleware-endpoint": "npm:^4.4.27" + "@smithy/middleware-retry": "npm:^4.4.44" + "@smithy/middleware-serde": "npm:^4.2.15" + "@smithy/middleware-stack": "npm:^4.2.12" + "@smithy/node-config-provider": "npm:^4.3.12" + "@smithy/node-http-handler": "npm:^4.5.0" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/smithy-client": "npm:^4.12.7" + "@smithy/types": "npm:^4.13.1" + "@smithy/url-parser": "npm:^4.2.12" + "@smithy/util-base64": "npm:^4.3.2" + "@smithy/util-body-length-browser": "npm:^4.2.2" + "@smithy/util-body-length-node": "npm:^4.2.3" + "@smithy/util-defaults-mode-browser": "npm:^4.3.43" + "@smithy/util-defaults-mode-node": "npm:^4.2.47" + "@smithy/util-endpoints": "npm:^3.3.3" + "@smithy/util-middleware": "npm:^4.2.12" + "@smithy/util-retry": "npm:^4.2.12" + "@smithy/util-stream": "npm:^4.5.20" + "@smithy/util-utf8": "npm:^4.2.2" + tslib: "npm:^2.6.2" + checksum: 10/da427a073f05daf1e47ed399e988aa6fc3f4ec502bd5587047c009ec9a71cec4e9b5931fd0a8ca74130a38763d659ead8f53816f1b57cdca34358a3958a69ae8 + languageName: node + linkType: hard + "@aws-sdk/client-codecommit@npm:^3.350.0": version: 3.1019.0 resolution: "@aws-sdk/client-codecommit@npm:3.1019.0" @@ -390,9 +445,30 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/crc64-nvme@npm:^3.972.5": - version: 3.972.5 - resolution: "@aws-sdk/crc64-nvme@npm:3.972.5" +"@aws-sdk/core@npm:^3.973.24": + version: 3.973.24 + resolution: "@aws-sdk/core@npm:3.973.24" + dependencies: + "@aws-sdk/types": "npm:^3.973.6" + "@aws-sdk/xml-builder": "npm:^3.972.15" + "@smithy/core": "npm:^3.23.12" + "@smithy/node-config-provider": "npm:^4.3.12" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/signature-v4": "npm:^5.3.12" + "@smithy/smithy-client": "npm:^4.12.7" + "@smithy/types": "npm:^4.13.1" + "@smithy/util-base64": "npm:^4.3.2" + "@smithy/util-middleware": "npm:^4.2.12" + "@smithy/util-utf8": "npm:^4.2.2" + tslib: "npm:^2.6.2" + checksum: 10/7008d625b0628e88c9b11793c5843a747d7ea2650d423019f5daacf00abdd57f51dbde60169f0ee8c2f3e100037a18d2b9b895c3436c1b595bd145c86389db4f + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-cognito-identity@npm:3.830.0": + version: 3.830.0 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.830.0" dependencies: "@smithy/types": "npm:^4.13.1" tslib: "npm:^2.6.2" @@ -413,9 +489,22 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:^3.972.23": - version: 3.972.23 - resolution: "@aws-sdk/credential-provider-env@npm:3.972.23" +"@aws-sdk/credential-provider-env@npm:^3.972.22": + version: 3.972.22 + resolution: "@aws-sdk/credential-provider-env@npm:3.972.22" + dependencies: + "@aws-sdk/core": "npm:^3.973.24" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/b8d6eb6f3ce55720048cb8f69fcb06c3266e1967d163f77c90854fae6b515aeaae799590b61dece713f863e48924f806627c2eb573de45e9c268a5705eedab65 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-http@npm:3.826.0": + version: 3.826.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.826.0" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/types": "npm:^3.973.6" @@ -426,9 +515,27 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-http@npm:^3.972.25": - version: 3.972.25 - resolution: "@aws-sdk/credential-provider-http@npm:3.972.25" +"@aws-sdk/credential-provider-http@npm:^3.972.24": + version: 3.972.24 + resolution: "@aws-sdk/credential-provider-http@npm:3.972.24" + dependencies: + "@aws-sdk/core": "npm:^3.973.24" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/fetch-http-handler": "npm:^5.3.15" + "@smithy/node-http-handler": "npm:^4.5.0" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/smithy-client": "npm:^4.12.7" + "@smithy/types": "npm:^4.13.1" + "@smithy/util-stream": "npm:^4.5.20" + tslib: "npm:^2.6.2" + checksum: 10/7bda2d60e493aedf3b6aeabef35711fd53e64076e90f112d77268edf4c822ff052c333daa1070d582bcb02729eb06ba20397c4170f340c991aa25fdce41b84c6 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-ini@npm:3.830.0": + version: 3.830.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.830.0" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/types": "npm:^3.973.6" @@ -444,9 +551,47 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:^3.972.26": - version: 3.972.26 - resolution: "@aws-sdk/credential-provider-ini@npm:3.972.26" +"@aws-sdk/credential-provider-ini@npm:^3.972.24": + version: 3.972.24 + resolution: "@aws-sdk/credential-provider-ini@npm:3.972.24" + dependencies: + "@aws-sdk/core": "npm:^3.973.24" + "@aws-sdk/credential-provider-env": "npm:^3.972.22" + "@aws-sdk/credential-provider-http": "npm:^3.972.24" + "@aws-sdk/credential-provider-login": "npm:^3.972.24" + "@aws-sdk/credential-provider-process": "npm:^3.972.22" + "@aws-sdk/credential-provider-sso": "npm:^3.972.24" + "@aws-sdk/credential-provider-web-identity": "npm:^3.972.24" + "@aws-sdk/nested-clients": "npm:^3.996.14" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/credential-provider-imds": "npm:^4.2.12" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/shared-ini-file-loader": "npm:^4.4.7" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/455ab66d6e0d97f9c7e18edba25b060637cee2408af237bb2bab54b56d4701546047a372423e1c3f1ff9db49b48445e9c9b7d0214bca39b8b467f01eeec6942d + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-login@npm:^3.972.24": + version: 3.972.24 + resolution: "@aws-sdk/credential-provider-login@npm:3.972.24" + dependencies: + "@aws-sdk/core": "npm:^3.973.24" + "@aws-sdk/nested-clients": "npm:^3.996.14" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/shared-ini-file-loader": "npm:^4.4.7" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/f6a7b790ec48d62509e13b763c73f2fe72d19249b44d31928e7f8b08fb5bc9f1a10365cc15adc575b9dc5012822ba091aaf7b647df00e3742078f5cbb9253dab + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-node@npm:3.830.0": + version: 3.830.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.830.0" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/credential-provider-env": "npm:^3.972.23" @@ -466,9 +611,29 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-login@npm:^3.972.26": - version: 3.972.26 - resolution: "@aws-sdk/credential-provider-login@npm:3.972.26" +"@aws-sdk/credential-provider-node@npm:^3.350.0, @aws-sdk/credential-provider-node@npm:^3.972.25": + version: 3.972.25 + resolution: "@aws-sdk/credential-provider-node@npm:3.972.25" + dependencies: + "@aws-sdk/credential-provider-env": "npm:^3.972.22" + "@aws-sdk/credential-provider-http": "npm:^3.972.24" + "@aws-sdk/credential-provider-ini": "npm:^3.972.24" + "@aws-sdk/credential-provider-process": "npm:^3.972.22" + "@aws-sdk/credential-provider-sso": "npm:^3.972.24" + "@aws-sdk/credential-provider-web-identity": "npm:^3.972.24" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/credential-provider-imds": "npm:^4.2.12" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/shared-ini-file-loader": "npm:^4.4.7" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/9cf17eaf074aeeed9d3927b0c6729bcc079a08ac02fe028a9a731835cdd61746745fc21a612b40093fdd9d3a1b0f3eb7b62f3162206635bb7d06f89164be0e03 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-process@npm:3.826.0": + version: 3.826.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.826.0" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/nested-clients": "npm:^3.996.16" @@ -482,9 +647,23 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:^3.350.0, @aws-sdk/credential-provider-node@npm:^3.972.27": - version: 3.972.27 - resolution: "@aws-sdk/credential-provider-node@npm:3.972.27" +"@aws-sdk/credential-provider-process@npm:^3.972.22": + version: 3.972.22 + resolution: "@aws-sdk/credential-provider-process@npm:3.972.22" + dependencies: + "@aws-sdk/core": "npm:^3.973.24" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/shared-ini-file-loader": "npm:^4.4.7" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/6f455ed8d56732e08a256fe7c9df250a234478eaf4e6e5d2bdd6359763329e9fcb61352cc5dcd7a340d9ebfbeef67ad61e2e64335290247d889f6b167d7f82a0 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-sso@npm:3.830.0": + version: 3.830.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.830.0" dependencies: "@aws-sdk/credential-provider-env": "npm:^3.972.23" "@aws-sdk/credential-provider-http": "npm:^3.972.25" @@ -502,9 +681,25 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:^3.972.23": - version: 3.972.23 - resolution: "@aws-sdk/credential-provider-process@npm:3.972.23" +"@aws-sdk/credential-provider-sso@npm:^3.972.24": + version: 3.972.24 + resolution: "@aws-sdk/credential-provider-sso@npm:3.972.24" + dependencies: + "@aws-sdk/core": "npm:^3.973.24" + "@aws-sdk/nested-clients": "npm:^3.996.14" + "@aws-sdk/token-providers": "npm:3.1015.0" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/shared-ini-file-loader": "npm:^4.4.7" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/dab037f6d91c522b0a6c2f587e1fa8b36043a253523351c9cb9541dac2d1559af70fbd81ea1fe3202bf5e88d2d0e80df02950a0bf3b7c21ac30501499667f10d + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-web-identity@npm:3.830.0": + version: 3.830.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.830.0" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/types": "npm:^3.973.6" @@ -547,6 +742,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-web-identity@npm:^3.972.24": + version: 3.972.24 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.24" + dependencies: + "@aws-sdk/core": "npm:^3.973.24" + "@aws-sdk/nested-clients": "npm:^3.996.14" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/shared-ini-file-loader": "npm:^4.4.7" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/12f90ac10dae3669ed7b1069d30cf7a423346af912e0aeb64469e85f65782ec4746733431027c374820f1a060a1593de7e540b8b6c69b82bd09e0306bdba7ad4 + languageName: node + linkType: hard + "@aws-sdk/credential-providers@npm:^3.350.0": version: 3.1019.0 resolution: "@aws-sdk/credential-providers@npm:3.1019.0" @@ -575,9 +785,21 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:^3.972.8": - version: 3.972.8 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.972.8" +"@aws-sdk/eventstream-handler-node@npm:^3.972.11": + version: 3.972.11 + resolution: "@aws-sdk/eventstream-handler-node@npm:3.972.11" + dependencies: + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/eventstream-codec": "npm:^4.2.12" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/fdfd847f736cec809389b9507515328e7ed2288e1e9892dcba0ba43cafd82f6d42de0d4aad989542b1cc35c8d973fa7b63f7dcc93059f1ddd6f5bb266e83977e + languageName: node + linkType: hard + +"@aws-sdk/middleware-bucket-endpoint@npm:3.830.0": + version: 3.830.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.830.0" dependencies: "@aws-sdk/types": "npm:^3.973.6" "@aws-sdk/util-arn-parser": "npm:^3.972.3" @@ -590,9 +812,21 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:^3.972.8": +"@aws-sdk/middleware-eventstream@npm:^3.972.8": version: 3.972.8 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.972.8" + resolution: "@aws-sdk/middleware-eventstream@npm:3.972.8" + dependencies: + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/d69ea8e3787c30d1cec0f90568a1b1697f6a78db1368536bf2254becd2e4470c4b5009ab9742b74eab655086c7587e5a4c32df26a40af1b1693ac185ac7abb66 + languageName: node + linkType: hard + +"@aws-sdk/middleware-expect-continue@npm:3.821.0": + version: 3.821.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.821.0" dependencies: "@aws-sdk/types": "npm:^3.973.6" "@smithy/protocol-http": "npm:^5.3.12" @@ -636,9 +870,21 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-location-constraint@npm:^3.972.8": +"@aws-sdk/middleware-host-header@npm:^3.972.8": version: 3.972.8 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.972.8" + resolution: "@aws-sdk/middleware-host-header@npm:3.972.8" + dependencies: + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/1af0015aa4e1f243d20054501148c27f62af974cc92735a38723ed909396bc98f7cddbf76a1237c8e08b46ab4b54cbf7f47c239263002a441aad4807feb41750 + languageName: node + linkType: hard + +"@aws-sdk/middleware-location-constraint@npm:3.821.0": + version: 3.821.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.821.0" dependencies: "@aws-sdk/types": "npm:^3.973.6" "@smithy/types": "npm:^4.13.1" @@ -658,9 +904,20 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:^3.972.9": - version: 3.972.9 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.972.9" +"@aws-sdk/middleware-logger@npm:^3.972.8": + version: 3.972.8 + resolution: "@aws-sdk/middleware-logger@npm:3.972.8" + dependencies: + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/e6f56fb83fd5bdbe6d354648596ce3ffff5293c87a48d06365e1a9fd41bdc6da4f53240908bc7d3b69e735905506ef89078a5812d1252e7f46bcb82255e5999b + languageName: node + linkType: hard + +"@aws-sdk/middleware-recursion-detection@npm:3.821.0": + version: 3.821.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.821.0" dependencies: "@aws-sdk/types": "npm:^3.973.6" "@aws/lambda-invoke-store": "npm:^0.2.2" @@ -671,9 +928,22 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-sdk-s3@npm:^3.972.26": - version: 3.972.26 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.972.26" +"@aws-sdk/middleware-recursion-detection@npm:^3.972.8": + version: 3.972.8 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.972.8" + dependencies: + "@aws-sdk/types": "npm:^3.973.6" + "@aws/lambda-invoke-store": "npm:^0.2.2" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/64b7ed16e8e401d091bb6cd612abe639f5626f8f20350c1cc5e7ce55c10ee31506315aecf270f2f4920a7ea53bd649c604851e9209f60c18427e7b0b9e0e0fda + languageName: node + linkType: hard + +"@aws-sdk/middleware-sdk-s3@npm:3.826.0": + version: 3.826.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.826.0" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/types": "npm:^3.973.6" @@ -720,9 +990,45 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/nested-clients@npm:^3.996.16": - version: 3.996.16 - resolution: "@aws-sdk/nested-clients@npm:3.996.16" +"@aws-sdk/middleware-user-agent@npm:^3.972.25": + version: 3.972.25 + resolution: "@aws-sdk/middleware-user-agent@npm:3.972.25" + dependencies: + "@aws-sdk/core": "npm:^3.973.24" + "@aws-sdk/types": "npm:^3.973.6" + "@aws-sdk/util-endpoints": "npm:^3.996.5" + "@smithy/core": "npm:^3.23.12" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/types": "npm:^4.13.1" + "@smithy/util-retry": "npm:^4.2.12" + tslib: "npm:^2.6.2" + checksum: 10/b116df7632d2b05fb05e7a74440fdd0726c12bafb95149c867155b61fc8c43983ccc712a98a1c83470603079160700fb964c43c990dbba5c05b5ec8dbbf0a57e + languageName: node + linkType: hard + +"@aws-sdk/middleware-websocket@npm:^3.972.13": + version: 3.972.13 + resolution: "@aws-sdk/middleware-websocket@npm:3.972.13" + dependencies: + "@aws-sdk/types": "npm:^3.973.6" + "@aws-sdk/util-format-url": "npm:^3.972.8" + "@smithy/eventstream-codec": "npm:^4.2.12" + "@smithy/eventstream-serde-browser": "npm:^4.2.12" + "@smithy/fetch-http-handler": "npm:^5.3.15" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/signature-v4": "npm:^5.3.12" + "@smithy/types": "npm:^4.13.1" + "@smithy/util-base64": "npm:^4.3.2" + "@smithy/util-hex-encoding": "npm:^4.2.2" + "@smithy/util-utf8": "npm:^4.2.2" + tslib: "npm:^2.6.2" + checksum: 10/8eae454c8466d11107c6fefb740a97097fa3691f826a7a1f446940bda1009796f6016a7a301592feae10181a144b4dda35fb57fe55dd4d951332514c00438ba6 + languageName: node + linkType: hard + +"@aws-sdk/nested-clients@npm:3.830.0": + version: 3.830.0 + resolution: "@aws-sdk/nested-clients@npm:3.830.0" dependencies: "@aws-crypto/sha256-browser": "npm:5.2.0" "@aws-crypto/sha256-js": "npm:5.2.0" @@ -766,9 +1072,55 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/region-config-resolver@npm:^3.972.10": - version: 3.972.10 - resolution: "@aws-sdk/region-config-resolver@npm:3.972.10" +"@aws-sdk/nested-clients@npm:^3.996.14": + version: 3.996.14 + resolution: "@aws-sdk/nested-clients@npm:3.996.14" + dependencies: + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/core": "npm:^3.973.24" + "@aws-sdk/middleware-host-header": "npm:^3.972.8" + "@aws-sdk/middleware-logger": "npm:^3.972.8" + "@aws-sdk/middleware-recursion-detection": "npm:^3.972.8" + "@aws-sdk/middleware-user-agent": "npm:^3.972.25" + "@aws-sdk/region-config-resolver": "npm:^3.972.9" + "@aws-sdk/types": "npm:^3.973.6" + "@aws-sdk/util-endpoints": "npm:^3.996.5" + "@aws-sdk/util-user-agent-browser": "npm:^3.972.8" + "@aws-sdk/util-user-agent-node": "npm:^3.973.11" + "@smithy/config-resolver": "npm:^4.4.13" + "@smithy/core": "npm:^3.23.12" + "@smithy/fetch-http-handler": "npm:^5.3.15" + "@smithy/hash-node": "npm:^4.2.12" + "@smithy/invalid-dependency": "npm:^4.2.12" + "@smithy/middleware-content-length": "npm:^4.2.12" + "@smithy/middleware-endpoint": "npm:^4.4.27" + "@smithy/middleware-retry": "npm:^4.4.44" + "@smithy/middleware-serde": "npm:^4.2.15" + "@smithy/middleware-stack": "npm:^4.2.12" + "@smithy/node-config-provider": "npm:^4.3.12" + "@smithy/node-http-handler": "npm:^4.5.0" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/smithy-client": "npm:^4.12.7" + "@smithy/types": "npm:^4.13.1" + "@smithy/url-parser": "npm:^4.2.12" + "@smithy/util-base64": "npm:^4.3.2" + "@smithy/util-body-length-browser": "npm:^4.2.2" + "@smithy/util-body-length-node": "npm:^4.2.3" + "@smithy/util-defaults-mode-browser": "npm:^4.3.43" + "@smithy/util-defaults-mode-node": "npm:^4.2.47" + "@smithy/util-endpoints": "npm:^3.3.3" + "@smithy/util-middleware": "npm:^4.2.12" + "@smithy/util-retry": "npm:^4.2.12" + "@smithy/util-utf8": "npm:^4.2.2" + tslib: "npm:^2.6.2" + checksum: 10/3e6fffc8fb3bb315653e34be7076dd7cdafb3525565df7dcb623c4472a6fb40fa75c1f1164709b45116488ee4d51cb2d969e053ce612d57014890e69c2af2583 + languageName: node + linkType: hard + +"@aws-sdk/region-config-resolver@npm:3.821.0": + version: 3.821.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.821.0" dependencies: "@aws-sdk/types": "npm:^3.973.6" "@smithy/config-resolver": "npm:^4.4.13" @@ -779,9 +1131,22 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/signature-v4-multi-region@npm:^3.996.14": - version: 3.996.14 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.996.14" +"@aws-sdk/region-config-resolver@npm:^3.972.9": + version: 3.972.9 + resolution: "@aws-sdk/region-config-resolver@npm:3.972.9" + dependencies: + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/config-resolver": "npm:^4.4.13" + "@smithy/node-config-provider": "npm:^4.3.12" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/ee63dc5d193db23830c53b67d6b6b2b163102a396f8a5f390f136b4a00bd5bd80ef7ef4f9112605d81eaa5c7c2b17ddc5e4b1f91ccb13173aa788ebad65aac22 + languageName: node + linkType: hard + +"@aws-sdk/signature-v4-multi-region@npm:3.826.0": + version: 3.826.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.826.0" dependencies: "@aws-sdk/middleware-sdk-s3": "npm:^3.972.26" "@aws-sdk/types": "npm:^3.973.6" @@ -793,9 +1158,24 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.1019.0": - version: 3.1019.0 - resolution: "@aws-sdk/token-providers@npm:3.1019.0" +"@aws-sdk/token-providers@npm:3.1015.0": + version: 3.1015.0 + resolution: "@aws-sdk/token-providers@npm:3.1015.0" + dependencies: + "@aws-sdk/core": "npm:^3.973.24" + "@aws-sdk/nested-clients": "npm:^3.996.14" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/shared-ini-file-loader": "npm:^4.4.7" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/d364bbe0f2c6187b1aeb68e917397d4d18276c773f62d8de978a62f7901e0cab38facca202730f5687bce3fcad0705b850c529d0f39340464867e35f83003c7d + languageName: node + linkType: hard + +"@aws-sdk/token-providers@npm:3.830.0": + version: 3.830.0 + resolution: "@aws-sdk/token-providers@npm:3.830.0" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/nested-clients": "npm:^3.996.16" @@ -818,6 +1198,16 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/types@npm:3.821.0": + version: 3.821.0 + resolution: "@aws-sdk/types@npm:3.821.0" + dependencies: + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/74f0ef0da96aab5e9a2838c02a0ecbf3cda5cba09711378c1eb980f66ce511eb6929e3f46743538f64854d75fe27d23bf7b67790df6df09a10bedf0a7a5ccb7f + languageName: node + linkType: hard + "@aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0, @aws-sdk/types@npm:^3.973.6": version: 3.973.6 resolution: "@aws-sdk/types@npm:3.973.6" @@ -828,9 +1218,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-arn-parser@npm:^3.310.0, @aws-sdk/util-arn-parser@npm:^3.972.3": - version: 3.972.3 - resolution: "@aws-sdk/util-arn-parser@npm:3.972.3" +"@aws-sdk/util-arn-parser@npm:3.804.0, @aws-sdk/util-arn-parser@npm:^3.310.0": + version: 3.804.0 + resolution: "@aws-sdk/util-arn-parser@npm:3.804.0" dependencies: tslib: "npm:^2.6.2" checksum: 10/140a30615c914bcb37a5bb6ff825e8b6d2bedea757c2b03a4f5abb986003683ceadc322c0ee9f9a3ba4d5925357515ed7be01ef13c56c3b0126d4e1bd7292a33 @@ -850,6 +1240,31 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-endpoints@npm:^3.996.5": + version: 3.996.5 + resolution: "@aws-sdk/util-endpoints@npm:3.996.5" + dependencies: + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/types": "npm:^4.13.1" + "@smithy/url-parser": "npm:^4.2.12" + "@smithy/util-endpoints": "npm:^3.3.3" + tslib: "npm:^2.6.2" + checksum: 10/44c43c71f69981afc5238e25292fbe56a4552295ab0589a17215cf0d476ea63679a62142aeab9e30c76ae65b5f408a0d5e11513255be14c2d7dbeaaa2cc428c5 + languageName: node + linkType: hard + +"@aws-sdk/util-format-url@npm:^3.972.8": + version: 3.972.8 + resolution: "@aws-sdk/util-format-url@npm:3.972.8" + dependencies: + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/querystring-builder": "npm:^4.2.12" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/37aa7d0e47b32fbfbb9b6d2c7ec03512191cac3eab7ce45c996dd19b77d5317cf2e1636d90de87313a5604c3c7fb2f8a426c8fbb6f39f672f3774ca8a5e72d19 + languageName: node + linkType: hard + "@aws-sdk/util-locate-window@npm:^3.0.0": version: 3.965.5 resolution: "@aws-sdk/util-locate-window@npm:3.965.5" @@ -871,9 +1286,21 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:^3.973.12": - version: 3.973.12 - resolution: "@aws-sdk/util-user-agent-node@npm:3.973.12" +"@aws-sdk/util-user-agent-browser@npm:^3.972.8": + version: 3.972.8 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.972.8" + dependencies: + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/types": "npm:^4.13.1" + bowser: "npm:^2.11.0" + tslib: "npm:^2.6.2" + checksum: 10/cb0f9b1daa8ce90e174d75c60d0b42360d952a710fef0c3bed21d3bfbabf814e1137e94a0edb3fa4eb8f5d4ee166fd94b9f56deb5878495b818c1ddbfe04e543 + languageName: node + linkType: hard + +"@aws-sdk/util-user-agent-node@npm:3.828.0": + version: 3.828.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.828.0" dependencies: "@aws-sdk/middleware-user-agent": "npm:^3.972.26" "@aws-sdk/types": "npm:^3.973.6" @@ -890,9 +1317,28 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/xml-builder@npm:^3.972.16": - version: 3.972.16 - resolution: "@aws-sdk/xml-builder@npm:3.972.16" +"@aws-sdk/util-user-agent-node@npm:^3.973.11": + version: 3.973.11 + resolution: "@aws-sdk/util-user-agent-node@npm:3.973.11" + dependencies: + "@aws-sdk/middleware-user-agent": "npm:^3.972.25" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/node-config-provider": "npm:^4.3.12" + "@smithy/types": "npm:^4.13.1" + "@smithy/util-config-provider": "npm:^4.2.2" + tslib: "npm:^2.6.2" + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + checksum: 10/1e55e1562750a2fc4147623e187299939d07891d39ad2e1a1335595d8883d97a22f5fe4544a5be8fdde85f45aa35cf8f04efe6dd207d5c90c6ce9655d6c37df9 + languageName: node + linkType: hard + +"@aws-sdk/xml-builder@npm:3.821.0": + version: 3.821.0 + resolution: "@aws-sdk/xml-builder@npm:3.821.0" dependencies: "@smithy/types": "npm:^4.13.1" fast-xml-parser: "npm:5.5.8" @@ -908,6 +1354,24 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/xml-builder@npm:^3.972.15": + version: 3.972.15 + resolution: "@aws-sdk/xml-builder@npm:3.972.15" + dependencies: + "@smithy/types": "npm:^4.13.1" + fast-xml-parser: "npm:5.5.8" + tslib: "npm:^2.6.2" + checksum: 10/03574e017f58a3317682210f43aa9c8db37396efd679bdddb49bdfbd85d54db055d07f95644981dba6244d8c9d3cb2ae360572b35a740bf3f5463cc8a96022bf + languageName: node + linkType: hard + +"@aws/lambda-invoke-store@npm:^0.2.2": + version: 0.2.4 + resolution: "@aws/lambda-invoke-store@npm:0.2.4" + checksum: 10/47e73cf73141be73854c69722502e928a435b3d908ffa693a9545c1099dd7b2dd3f67c43c523d786a75911100e77ed52dce1f88d09363a67526448c5b7c804d5 + languageName: node + linkType: hard + "@azure/abort-controller@npm:^2.0.0, @azure/abort-controller@npm:^2.1.2": version: 2.1.2 resolution: "@azure/abort-controller@npm:2.1.2" @@ -1267,6 +1731,19 @@ __metadata: languageName: node linkType: hard +"@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock@workspace:^, @backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock@workspace:plugins/mcp-chat-backend-module-amazon-bedrock": + version: 0.0.0-use.local + resolution: "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock@workspace:plugins/mcp-chat-backend-module-amazon-bedrock" + dependencies: + "@aws-sdk/client-bedrock-runtime": "npm:^3.0.0" + "@backstage-community/plugin-mcp-chat-common": "workspace:^" + "@backstage-community/plugin-mcp-chat-node": "workspace:^" + "@backstage/backend-plugin-api": "npm:^1.4.0" + "@backstage/cli": "npm:^0.33.0" + "@backstage/config": "npm:^1.3.0" + languageName: unknown + linkType: soft + "@backstage-community/plugin-mcp-chat-backend-module-anthropic@workspace:plugins/mcp-chat-backend-module-anthropic": version: 0.0.0-use.local resolution: "@backstage-community/plugin-mcp-chat-backend-module-anthropic@workspace:plugins/mcp-chat-backend-module-anthropic" @@ -1345,6 +1822,7 @@ __metadata: version: 0.0.0-use.local resolution: "@backstage-community/plugin-mcp-chat-backend@workspace:plugins/mcp-chat-backend" dependencies: + "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock": "workspace:^" "@backstage-community/plugin-mcp-chat-backend-module-openai": "workspace:^" "@backstage-community/plugin-mcp-chat-common": "workspace:^" "@backstage-community/plugin-mcp-chat-node": "workspace:^" @@ -8955,9 +9433,9 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^4.0.4": - version: 4.0.4 - resolution: "@smithy/abort-controller@npm:4.0.4" +"@smithy/abort-controller@npm:^4.0.4, @smithy/abort-controller@npm:^4.2.12": + version: 4.2.12 + resolution: "@smithy/abort-controller@npm:4.2.12" dependencies: "@smithy/types": "npm:^4.13.1" tslib: "npm:^2.6.2" @@ -8984,7 +9462,7 @@ __metadata: languageName: node linkType: hard -"@smithy/config-resolver@npm:^4.4.13": +"@smithy/config-resolver@npm:^4.1.4, @smithy/config-resolver@npm:^4.4.13": version: 4.4.13 resolution: "@smithy/config-resolver@npm:4.4.13" dependencies: @@ -8998,7 +9476,7 @@ __metadata: languageName: node linkType: hard -"@smithy/core@npm:^3.23.12": +"@smithy/core@npm:^3.23.12, @smithy/core@npm:^3.5.3": version: 3.23.12 resolution: "@smithy/core@npm:3.23.12" dependencies: @@ -9016,7 +9494,7 @@ __metadata: languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^4.2.12": +"@smithy/credential-provider-imds@npm:^4.0.6, @smithy/credential-provider-imds@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/credential-provider-imds@npm:4.2.12" dependencies: @@ -9041,7 +9519,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^4.2.12": +"@smithy/eventstream-serde-browser@npm:^4.0.4, @smithy/eventstream-serde-browser@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/eventstream-serde-browser@npm:4.2.12" dependencies: @@ -9052,7 +9530,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-config-resolver@npm:^4.3.12": +"@smithy/eventstream-serde-config-resolver@npm:^4.1.2, @smithy/eventstream-serde-config-resolver@npm:^4.3.12": version: 4.3.12 resolution: "@smithy/eventstream-serde-config-resolver@npm:4.3.12" dependencies: @@ -9062,7 +9540,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^4.2.12": +"@smithy/eventstream-serde-node@npm:^4.0.4, @smithy/eventstream-serde-node@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/eventstream-serde-node@npm:4.2.12" dependencies: @@ -9084,7 +9562,7 @@ __metadata: languageName: node linkType: hard -"@smithy/fetch-http-handler@npm:^5.3.15": +"@smithy/fetch-http-handler@npm:^5.0.4, @smithy/fetch-http-handler@npm:^5.3.15": version: 5.3.15 resolution: "@smithy/fetch-http-handler@npm:5.3.15" dependencies: @@ -9109,7 +9587,7 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-node@npm:^4.2.12": +"@smithy/hash-node@npm:^4.0.4, @smithy/hash-node@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/hash-node@npm:4.2.12" dependencies: @@ -9132,7 +9610,7 @@ __metadata: languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^4.2.12": +"@smithy/invalid-dependency@npm:^4.0.4, @smithy/invalid-dependency@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/invalid-dependency@npm:4.2.12" dependencies: @@ -9151,7 +9629,7 @@ __metadata: languageName: node linkType: hard -"@smithy/is-array-buffer@npm:^4.2.2": +"@smithy/is-array-buffer@npm:^4.0.0, @smithy/is-array-buffer@npm:^4.2.2": version: 4.2.2 resolution: "@smithy/is-array-buffer@npm:4.2.2" dependencies: @@ -9171,7 +9649,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^4.2.12": +"@smithy/middleware-content-length@npm:^4.0.4, @smithy/middleware-content-length@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/middleware-content-length@npm:4.2.12" dependencies: @@ -9182,7 +9660,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^4.4.27": +"@smithy/middleware-endpoint@npm:^4.1.11, @smithy/middleware-endpoint@npm:^4.4.27": version: 4.4.27 resolution: "@smithy/middleware-endpoint@npm:4.4.27" dependencies: @@ -9198,7 +9676,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-retry@npm:^4.4.44": +"@smithy/middleware-retry@npm:^4.1.12, @smithy/middleware-retry@npm:^4.4.44": version: 4.4.44 resolution: "@smithy/middleware-retry@npm:4.4.44" dependencies: @@ -9215,7 +9693,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-serde@npm:^4.2.15": +"@smithy/middleware-serde@npm:^4.0.8, @smithy/middleware-serde@npm:^4.2.15": version: 4.2.15 resolution: "@smithy/middleware-serde@npm:4.2.15" dependencies: @@ -9227,7 +9705,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-stack@npm:^4.2.12": +"@smithy/middleware-stack@npm:^4.0.4, @smithy/middleware-stack@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/middleware-stack@npm:4.2.12" dependencies: @@ -9237,7 +9715,7 @@ __metadata: languageName: node linkType: hard -"@smithy/node-config-provider@npm:^4.3.12": +"@smithy/node-config-provider@npm:^4.1.3, @smithy/node-config-provider@npm:^4.3.12": version: 4.3.12 resolution: "@smithy/node-config-provider@npm:4.3.12" dependencies: @@ -9249,7 +9727,7 @@ __metadata: languageName: node linkType: hard -"@smithy/node-http-handler@npm:^4.5.0": +"@smithy/node-http-handler@npm:^4.0.6, @smithy/node-http-handler@npm:^4.5.0": version: 4.5.0 resolution: "@smithy/node-http-handler@npm:4.5.0" dependencies: @@ -9262,7 +9740,7 @@ __metadata: languageName: node linkType: hard -"@smithy/property-provider@npm:^4.2.12": +"@smithy/property-provider@npm:^4.0.4, @smithy/property-provider@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/property-provider@npm:4.2.12" dependencies: @@ -9272,7 +9750,7 @@ __metadata: languageName: node linkType: hard -"@smithy/protocol-http@npm:^5.3.12": +"@smithy/protocol-http@npm:^5.1.2, @smithy/protocol-http@npm:^5.3.12": version: 5.3.12 resolution: "@smithy/protocol-http@npm:5.3.12" dependencies: @@ -9312,7 +9790,7 @@ __metadata: languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^4.4.7": +"@smithy/shared-ini-file-loader@npm:^4.0.4, @smithy/shared-ini-file-loader@npm:^4.4.7": version: 4.4.7 resolution: "@smithy/shared-ini-file-loader@npm:4.4.7" dependencies: @@ -9322,7 +9800,7 @@ __metadata: languageName: node linkType: hard -"@smithy/signature-v4@npm:^5.3.12": +"@smithy/signature-v4@npm:^5.1.2, @smithy/signature-v4@npm:^5.3.12": version: 5.3.12 resolution: "@smithy/signature-v4@npm:5.3.12" dependencies: @@ -9338,7 +9816,7 @@ __metadata: languageName: node linkType: hard -"@smithy/smithy-client@npm:^4.12.7": +"@smithy/smithy-client@npm:^4.12.7, @smithy/smithy-client@npm:^4.4.3": version: 4.12.7 resolution: "@smithy/smithy-client@npm:4.12.7" dependencies: @@ -9362,7 +9840,7 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^4.13.1": +"@smithy/types@npm:^4.13.1, @smithy/types@npm:^4.3.1": version: 4.13.1 resolution: "@smithy/types@npm:4.13.1" dependencies: @@ -9371,7 +9849,7 @@ __metadata: languageName: node linkType: hard -"@smithy/url-parser@npm:^4.2.12": +"@smithy/url-parser@npm:^4.0.4, @smithy/url-parser@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/url-parser@npm:4.2.12" dependencies: @@ -9382,7 +9860,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-base64@npm:^4.3.2": +"@smithy/util-base64@npm:^4.0.0, @smithy/util-base64@npm:^4.3.2": version: 4.3.2 resolution: "@smithy/util-base64@npm:4.3.2" dependencies: @@ -9393,7 +9871,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-body-length-browser@npm:^4.2.2": +"@smithy/util-body-length-browser@npm:^4.0.0, @smithy/util-body-length-browser@npm:^4.2.2": version: 4.2.2 resolution: "@smithy/util-body-length-browser@npm:4.2.2" dependencies: @@ -9402,7 +9880,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-body-length-node@npm:^4.2.3": +"@smithy/util-body-length-node@npm:^4.0.0, @smithy/util-body-length-node@npm:^4.2.3": version: 4.2.3 resolution: "@smithy/util-body-length-node@npm:4.2.3" dependencies: @@ -9431,7 +9909,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-config-provider@npm:^4.2.2": +"@smithy/util-config-provider@npm:^4.0.0, @smithy/util-config-provider@npm:^4.2.2": version: 4.2.2 resolution: "@smithy/util-config-provider@npm:4.2.2" dependencies: @@ -9440,7 +9918,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^4.3.43": +"@smithy/util-defaults-mode-browser@npm:^4.0.19, @smithy/util-defaults-mode-browser@npm:^4.3.43": version: 4.3.43 resolution: "@smithy/util-defaults-mode-browser@npm:4.3.43" dependencies: @@ -9452,7 +9930,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^4.2.47": +"@smithy/util-defaults-mode-node@npm:^4.0.19, @smithy/util-defaults-mode-node@npm:^4.2.47": version: 4.2.47 resolution: "@smithy/util-defaults-mode-node@npm:4.2.47" dependencies: @@ -9467,7 +9945,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-endpoints@npm:^3.3.3": +"@smithy/util-endpoints@npm:^3.0.6, @smithy/util-endpoints@npm:^3.3.3": version: 3.3.3 resolution: "@smithy/util-endpoints@npm:3.3.3" dependencies: @@ -9487,7 +9965,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-middleware@npm:^4.2.12": +"@smithy/util-middleware@npm:^4.0.4, @smithy/util-middleware@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/util-middleware@npm:4.2.12" dependencies: @@ -9497,7 +9975,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-retry@npm:^4.2.12": +"@smithy/util-retry@npm:^4.0.5, @smithy/util-retry@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/util-retry@npm:4.2.12" dependencies: @@ -9508,7 +9986,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-stream@npm:^4.5.20": +"@smithy/util-stream@npm:^4.2.2, @smithy/util-stream@npm:^4.5.20": version: 4.5.20 resolution: "@smithy/util-stream@npm:4.5.20" dependencies: @@ -9543,7 +10021,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-utf8@npm:^4.2.2": +"@smithy/util-utf8@npm:^4.0.0, @smithy/util-utf8@npm:^4.2.2": version: 4.2.2 resolution: "@smithy/util-utf8@npm:4.2.2" dependencies: @@ -9583,6 +10061,15 @@ __metadata: languageName: node linkType: hard +"@smithy/uuid@npm:^1.1.2": + version: 1.1.2 + resolution: "@smithy/uuid@npm:1.1.2" + dependencies: + tslib: "npm:^2.6.2" + checksum: 10/35b77a2483a37755c2be1faf66036f5e0b7939a7c608b93982fce9d4f137f1778784f101a2874a6756d9fd25092c6a95dd07314df12dcb9a0a03244b4cc4d8c4 + languageName: node + linkType: hard + "@spotify/eslint-config-base@npm:^15.0.0": version: 15.0.0 resolution: "@spotify/eslint-config-base@npm:15.0.0" @@ -16547,7 +17034,16 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:5.5.8": +"fast-xml-parser@npm:4.4.1": + version: 4.4.1 + resolution: "fast-xml-parser@npm:4.4.1" + dependencies: + path-expression-matcher: "npm:^1.1.3" + checksum: 10/32937866aaf5a90e69d1f4ee6e15e875248d5b5d2afd70277e9e8323074de4980cef24575a591b8e43c29f405d5f12377b3bad3842dc412b0c5c17a3eaee4b6b + languageName: node + linkType: hard + +"fast-xml-parser@npm:5.5.8, fast-xml-parser@npm:^5.0.7": version: 5.5.8 resolution: "fast-xml-parser@npm:5.5.8" dependencies: @@ -16560,16 +17056,16 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:^5.0.7, fast-xml-parser@npm:^5.3.4": - version: 5.5.9 - resolution: "fast-xml-parser@npm:5.5.9" +"fast-xml-parser@npm:^4.4.1": + version: 4.5.3 + resolution: "fast-xml-parser@npm:4.5.3" dependencies: fast-xml-builder: "npm:^1.1.4" path-expression-matcher: "npm:^1.2.0" - strnum: "npm:^2.2.2" + strnum: "npm:^2.2.0" bin: fxparser: src/cli/cli.js - checksum: 10/5f1a1a8b524406af21e9adb24f846b0da6b629c86b1eeedb54757cc293c24ed4f79ff9570b82206265b6951d68acd2dc93e74687ea5d7da0beafa09536cee73f + checksum: 10/888f9a5d345e65e34b70d394798a1542603a216f06c140a9671d031b80b42c01ef2e68f2a0ceea45e7703fa80549f0e06da710f5a2faafdc910d1b6b354f0fa0 languageName: node linkType: hard @@ -27370,9 +27866,16 @@ __metadata: languageName: node linkType: hard -"strtok3@npm:^10.3.4": - version: 10.3.5 - resolution: "strtok3@npm:10.3.5" +"strnum@npm:^2.2.0": + version: 2.2.2 + resolution: "strnum@npm:2.2.2" + checksum: 10/c55813cfded750dc84556b4881ffc7cee91382ff15a48f1fba0ff7a678e1640ed96ca40806fbd55724940fd7d51cf752469b2d862e196e4adefb6c7d5d9cd73b + languageName: node + linkType: hard + +"strtok3@npm:^10.2.0": + version: 10.3.1 + resolution: "strtok3@npm:10.3.1" dependencies: "@tokenizer/token": "npm:^0.3.0" checksum: 10/7279dc97a7207a5664ea07cf5304b94968db4f02d64d2732be8e7a3a31a876375126749cd36a00d0bd54c891875f3e47175f8194d40c64118f3265dbc241aaca From 04186610db3d21d4a9da935ac387399911726212 Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Tue, 24 Mar 2026 11:09:07 -0400 Subject: [PATCH 04/17] fix(mcp-chat): replace internal types references by the isomorphic package Signed-off-by: Florian JUDITH --- .../report.api.md | 35 ++ .../tsconfig.tsbuildinfo | 1 - .../report.api.md | 8 +- .../plugins/mcp-chat-backend/report.api.md | 331 +----------------- .../plugins/mcp-chat-backend/src/index.ts | 47 --- .../mcp-chat-backend/src/plugin.test.ts | 2 +- .../mcp-chat-backend/src/router.test.ts | 2 +- .../services/ChatConversationStore.test.ts | 5 +- .../src/services/ChatConversationStore.ts | 6 +- .../src/services/MCPClientService.ts | 2 +- .../src/services/MCPClientServiceImpl.test.ts | 6 +- .../src/services/MCPClientServiceImpl.ts | 2 +- .../src/services/SummarizationService.test.ts | 2 +- .../src/services/SummarizationService.ts | 2 +- .../plugins/mcp-chat-backend/src/types.ts | 56 --- .../mcp-chat-backend/src/utils.test.ts | 2 +- .../plugins/mcp-chat-backend/src/utils.ts | 2 +- .../plugins/mcp-chat-common/report.api.md | 320 +++++++++++++++++ .../plugins/mcp-chat-common/src/types.ts | 2 +- 19 files changed, 399 insertions(+), 434 deletions(-) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.tsbuildinfo delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/types.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-common/report.api.md diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md new file mode 100644 index 00000000000..9c47a191d14 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md @@ -0,0 +1,35 @@ +## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; +import { ProviderConfig } from '@backstage-community/plugin-mcp-chat-common'; +import { Tool } from '@backstage-community/plugin-mcp-chat-common'; + +// @public +export class BedrockProvider extends LLMProvider { + constructor(config: ProviderConfig); + // (undocumented) + protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; + // (undocumented) + protected getHeaders(): Record; + // (undocumented) + protected parseResponse(response: any): ChatResponse; + // (undocumented) + sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; + // (undocumented) + testConnection(): Promise<{ + connected: boolean; + models?: string[]; + error?: string; + }>; +} + +// @public +const _default: BackendFeature; +export default _default; +``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.tsbuildinfo b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.tsbuildinfo deleted file mode 100644 index 379c50b25c2..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.tsbuildinfo +++ /dev/null @@ -1 +0,0 @@ -{"program":{"fileNames":["../../node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../node_modules/typescript/lib/lib.scripthost.d.ts","../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/typescript/lib/lib.es2022.sharedmemory.d.ts","../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/abort-handler.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/abort.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/auth.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/HttpApiKeyAuth.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/identity/identity.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/response.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/command.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoint.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/feature-ids.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/logger.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/uri.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/http.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/util.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/middleware.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/HttpSigner.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/IdentityProviderConfig.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/HttpAuthScheme.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/HttpAuthSchemeProvider.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/auth/index.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transform/exact.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/externals-check/browser-externals-check.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/blob/blob-payload-input-types.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/crypto.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/checksum.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/client.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/connection/config.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transfer.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/connection/manager.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/connection/pool.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/connection/index.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/eventStream.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/encode.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoints/shared.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoints/EndpointRuleObject.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoints/ErrorRuleObject.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoints/TreeRuleObject.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoints/RuleSetObject.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/endpoints/index.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/extensions/checksum.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/extensions/defaultClientConfiguration.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/shapes.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/retry.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/extensions/retry.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/extensions/defaultExtensionConfiguration.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/extensions/index.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/http/httpHandlerInitialization.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/identity/apiKeyIdentity.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/identity/awsCredentialIdentity.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/identity/tokenIdentity.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/identity/index.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/pagination.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/profile.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/serde.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/schema/sentinels.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/schema/static-schemas.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/schema/traits.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/schema/schema.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/schema/schema-deprecated.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/signature.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/stream.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/streaming-payload/streaming-blob-common-types.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/streaming-payload/streaming-blob-payload-input-types.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/streaming-payload/streaming-blob-payload-output-types.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transform/type-transform.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transform/client-method-transforms.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transform/client-payload-blob-type-narrow.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transform/mutable.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/transform/no-undefined.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/waiter.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/node_modules/@smithy/types/dist-types/index.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/dist-types/eventStreamConfiguration.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/dist-types/eventStreamHandlingMiddleware.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/dist-types/eventStreamHeaderMiddleware.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/dist-types/getEventStreamPlugin.d.ts","../../node_modules/@aws-sdk/middleware-eventstream/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/types/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/middleware-host-header/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/middleware-user-agent/dist-types/configurations.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/abort.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/auth.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/blob/blob-types.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/checksum.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/client.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/command.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/connection.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/identity/Identity.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/identity/AnonymousIdentity.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/feature-ids.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/identity/AwsCredentialIdentity.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/identity/LoginIdentity.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/identity/TokenIdentity.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/identity/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/util.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/credentials.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/crypto.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/dns.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/encode.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/endpoint.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/eventStream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/extensions/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/function.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/http.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/logger.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/middleware.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/pagination.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/profile.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/request.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/response.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/retry.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/serde.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/shapes.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/signature.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/stream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/token.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/transfer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/uri.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/waiter.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/types/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/middleware-user-agent/dist-types/user-agent-middleware.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/middleware-user-agent/dist-types/index.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/types/dist-types/index.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/httpRequest.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/httpResponse.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/httpHandler.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/extensions/httpExtensionConfiguration.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/extensions/index.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/Field.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/Fields.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/isValidHostname.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/types.d.ts","../../node_modules/@aws-sdk/middleware-websocket/node_modules/@smithy/protocol-http/dist-types/index.d.ts","../../node_modules/@aws-sdk/middleware-websocket/dist-types/WebSocketFetchHandler.d.ts","../../node_modules/@aws-sdk/middleware-websocket/dist-types/getWebSocketPlugin.d.ts","../../node_modules/@aws-sdk/middleware-websocket/dist-types/resolveWebSocketConfig.d.ts","../../node_modules/@aws-sdk/middleware-websocket/dist-types/ws-eventstream/eventStreamPayloadHandlerProvider.d.ts","../../node_modules/@aws-sdk/middleware-websocket/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/node-config-provider/dist-types/fromEnv.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/getHomeDir.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/getProfileName.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/getSSOTokenFilepath.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/getSSOTokenFromFile.d.ts","../../node_modules/@smithy/shared-ini-file-loader/node_modules/@smithy/types/dist-types/index.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/constants.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/loadSharedConfigFiles.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/loadSsoSessionData.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/parseKnownFiles.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/externalDataInterceptor.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/types.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/readFile.d.ts","../../node_modules/@smithy/shared-ini-file-loader/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/node-config-provider/dist-types/fromSharedConfigFiles.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/node-config-provider/dist-types/fromStatic.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/node-config-provider/dist-types/configLoader.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/node-config-provider/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/endpointsConfig/NodeUseDualstackEndpointConfigOptions.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/endpointsConfig/NodeUseFipsEndpointConfigOptions.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/endpointsConfig/resolveEndpointsConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/endpointsConfig/resolveCustomEndpointsConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/endpointsConfig/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionConfig/config.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionConfig/resolveRegionConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionConfig/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionInfo/EndpointVariantTag.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionInfo/EndpointVariant.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionInfo/PartitionHash.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionInfo/RegionHash.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionInfo/getRegionInfo.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/regionInfo/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/config-resolver/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/eventstream-serde-config-resolver/dist-types/EventStreamSerdeConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/eventstream-serde-config-resolver/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/resolveEndpointConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/types.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/adaptors/getEndpointFromInstructions.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/adaptors/toEndpointV1.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/adaptors/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/endpointMiddleware.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/getEndpointPlugin.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/resolveEndpointRequiredConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-endpoint/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/types.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/AdaptiveRetryStrategy.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/StandardRetryStrategy.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/ConfiguredRetryStrategy.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/DefaultRateLimiter.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/config.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/constants.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-retry/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/types.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/StandardRetryStrategy.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/AdaptiveRetryStrategy.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/configurations.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/delayDecider.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/omitRetryHeadersMiddleware.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/retryDecider.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/retryMiddleware.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/middleware-retry/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/protocol-http/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/client.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/blob/Uint8ArrayBlobAdapter.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/checksum/ChecksumStream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/checksum/ChecksumStream.browser.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/checksum/createChecksumStream.browser.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/checksum/createChecksumStream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/createBufferedReadable.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/getAwsChunkedEncodingStream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/headStream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/sdk-stream-mixin.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/splitStream.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/stream-type-check.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/util-stream/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/collect-stream-body.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/extended-encode-uri-component.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/deref.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/middleware/schema-middleware-types.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/middleware/getSchemaSerdePlugin.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/Schema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/ListSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/MapSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/OperationSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/operation.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/StructureSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/ErrorSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/NormalizedSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/SimpleSchema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/sentinels.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/schemas/translateTraits.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/TypeRegistry.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/schema/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/schema.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/event-streams/EventStreamSerde.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/event-streams/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/event-streams.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/SerdeContext.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/HttpProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/HttpBindingProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/RpcProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/requestBuilder.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/resolve-path.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/serde/FromStringShapeDeserializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/serde/HttpInterceptingShapeDeserializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/serde/ToStringShapeSerializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/serde/HttpInterceptingShapeSerializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/serde/determineTimestampFormat.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/protocols/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/protocols.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/collect-stream-body.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/command.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/constants.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/create-aggregated-client.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/default-error-handler.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/defaults-mode.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/emitWarningIfUnsupportedVersion.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/exceptions.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/extended-encode-uri-component.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/extensions/checksum.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/extensions/retry.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/extensions/defaultExtensionConfiguration.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/extensions/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/get-array-if-single-item.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/get-value-from-text-node.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/is-serializable-header-value.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/NoOpLogger.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/object-mapping.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/resolve-path.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/ser-utils.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/serde-json.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/copyDocumentWithTransform.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/date-utils.d.ts","../../node_modules/@smithy/uuid/dist-types/v4.d.ts","../../node_modules/@smithy/uuid/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/generateIdempotencyToken.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/lazy-json.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/parse-utils.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/quote-header.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/schema-serde-lib/schema-date-utils.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/split-every.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/split-header.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/value/NumericValue.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/serde/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/serde.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/smithy-client/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/client/emitWarningIfUnsupportedVersion.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/client/setCredentialFeature.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/client/setFeature.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/client/setTokenFeature.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/client/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/aws_sdk/resolveAwsSdkSigV4AConfig.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/aws_sdk/AwsSdkSigV4Signer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/aws_sdk/AwsSdkSigV4ASigner.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/aws_sdk/NODE_AUTH_SCHEME_PREFERENCE_OPTIONS.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/SignatureV4Base.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/SignatureV4.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/constants.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/getCanonicalHeaders.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/getCanonicalQuery.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/getPayloadHash.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/moveHeadersToQuery.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/prepareRequest.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/credentialDerivation.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/headerUtil.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/signature-v4a-container.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/signature-v4/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/aws_sdk/resolveAwsSdkSigV4Config.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/aws_sdk/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/utils/getBearerTokenEnvKey.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/httpAuthSchemes/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/cbor/cbor.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/cbor/cbor-types.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/cbor/parseCborBody.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/cbor/CborCodec.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/cbor/SmithyRpcV2CborProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/dist-types/submodules/cbor/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@smithy/core/cbor.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/cbor/AwsSmithyRpcV2CborProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/coercing-serializers.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/ConfigurableSerdeContext.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/JsonShapeDeserializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/JsonShapeSerializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/JsonCodec.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/AwsJsonRpcProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/AwsJson1_0Protocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/AwsJson1_1Protocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/AwsRestJsonProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/awsExpectUnion.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/json/parseJsonBody.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/XmlShapeSerializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/XmlCodec.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/XmlShapeDeserializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/QuerySerializerSettings.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/QueryShapeSerializer.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/AwsQueryProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/query/AwsEc2QueryProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/AwsRestXmlProtocol.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/xml/parseXmlBody.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/submodules/protocols/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/node_modules/@aws-sdk/core/dist-types/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/auth/httpAuthSchemeProvider.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/models/enums.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/models/BedrockRuntimeServiceException.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/models/errors.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/models/models_0.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/ApplyGuardrailCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/ConverseCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/ConverseStreamCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/CountTokensCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/GetAsyncInvokeCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/InvokeModelCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/InvokeModelWithBidirectionalStreamCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/InvokeModelWithResponseStreamCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/ListAsyncInvokesCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/StartAsyncInvokeCommand.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/endpoint/EndpointParameters.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/auth/httpAuthExtensionConfiguration.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/extensionConfiguration.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/runtimeExtensions.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/BedrockRuntimeClient.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/BedrockRuntime.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/commands/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/schemas/schemas_0.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/pagination/Interfaces.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/pagination/ListAsyncInvokesPaginator.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/pagination/index.d.ts","../../node_modules/@aws-sdk/client-bedrock-runtime/dist-types/index.d.ts","../../node_modules/@backstage/types/dist/index.d.ts","../../node_modules/@backstage/errors/dist/index.d.ts","../mcp-chat-common/src/types.ts","../mcp-chat-common/src/base-provider.ts","../mcp-chat-common/src/index.ts","./src/BedrockProvider.ts","../../node_modules/@types/node/ts5.6/compatibility/float16array.d.ts","../../node_modules/@types/node/compatibility/iterators.d.ts","../../node_modules/@types/node/ts5.6/globals.typedarray.d.ts","../../node_modules/@types/node/ts5.6/buffer.buffer.d.ts","../../node_modules/buffer/index.d.ts","../../node_modules/@types/node/node_modules/undici-types/utility.d.ts","../../node_modules/@types/node/node_modules/undici-types/header.d.ts","../../node_modules/@types/node/node_modules/undici-types/readable.d.ts","../../node_modules/@types/node/node_modules/undici-types/fetch.d.ts","../../node_modules/@types/node/node_modules/undici-types/formdata.d.ts","../../node_modules/@types/node/node_modules/undici-types/connector.d.ts","../../node_modules/@types/node/node_modules/undici-types/client.d.ts","../../node_modules/@types/node/node_modules/undici-types/errors.d.ts","../../node_modules/@types/node/node_modules/undici-types/dispatcher.d.ts","../../node_modules/@types/node/node_modules/undici-types/global-dispatcher.d.ts","../../node_modules/@types/node/node_modules/undici-types/global-origin.d.ts","../../node_modules/@types/node/node_modules/undici-types/pool-stats.d.ts","../../node_modules/@types/node/node_modules/undici-types/pool.d.ts","../../node_modules/@types/node/node_modules/undici-types/handlers.d.ts","../../node_modules/@types/node/node_modules/undici-types/balanced-pool.d.ts","../../node_modules/@types/node/node_modules/undici-types/h2c-client.d.ts","../../node_modules/@types/node/node_modules/undici-types/agent.d.ts","../../node_modules/@types/node/node_modules/undici-types/mock-interceptor.d.ts","../../node_modules/@types/node/node_modules/undici-types/mock-call-history.d.ts","../../node_modules/@types/node/node_modules/undici-types/mock-agent.d.ts","../../node_modules/@types/node/node_modules/undici-types/mock-client.d.ts","../../node_modules/@types/node/node_modules/undici-types/mock-pool.d.ts","../../node_modules/@types/node/node_modules/undici-types/mock-errors.d.ts","../../node_modules/@types/node/node_modules/undici-types/proxy-agent.d.ts","../../node_modules/@types/node/node_modules/undici-types/env-http-proxy-agent.d.ts","../../node_modules/@types/node/node_modules/undici-types/retry-handler.d.ts","../../node_modules/@types/node/node_modules/undici-types/retry-agent.d.ts","../../node_modules/@types/node/node_modules/undici-types/api.d.ts","../../node_modules/@types/node/node_modules/undici-types/cache-interceptor.d.ts","../../node_modules/@types/node/node_modules/undici-types/interceptors.d.ts","../../node_modules/@types/node/node_modules/undici-types/util.d.ts","../../node_modules/@types/node/node_modules/undici-types/cookies.d.ts","../../node_modules/@types/node/node_modules/undici-types/patch.d.ts","../../node_modules/@types/node/node_modules/undici-types/websocket.d.ts","../../node_modules/@types/node/node_modules/undici-types/eventsource.d.ts","../../node_modules/@types/node/node_modules/undici-types/diagnostics-channel.d.ts","../../node_modules/@types/node/node_modules/undici-types/content-type.d.ts","../../node_modules/@types/node/node_modules/undici-types/cache.d.ts","../../node_modules/@types/node/node_modules/undici-types/index.d.ts","../../node_modules/@types/node/globals.d.ts","../../node_modules/@types/node/assert.d.ts","../../node_modules/@types/node/assert/strict.d.ts","../../node_modules/@types/node/async_hooks.d.ts","../../node_modules/@types/node/buffer.d.ts","../../node_modules/@types/node/child_process.d.ts","../../node_modules/@types/node/cluster.d.ts","../../node_modules/@types/node/console.d.ts","../../node_modules/@types/node/constants.d.ts","../../node_modules/@types/node/crypto.d.ts","../../node_modules/@types/node/dgram.d.ts","../../node_modules/@types/node/diagnostics_channel.d.ts","../../node_modules/@types/node/dns.d.ts","../../node_modules/@types/node/dns/promises.d.ts","../../node_modules/@types/node/domain.d.ts","../../node_modules/@types/node/dom-events.d.ts","../../node_modules/@types/node/events.d.ts","../../node_modules/@types/node/fs.d.ts","../../node_modules/@types/node/fs/promises.d.ts","../../node_modules/@types/node/http.d.ts","../../node_modules/@types/node/http2.d.ts","../../node_modules/@types/node/https.d.ts","../../node_modules/@types/node/inspector.d.ts","../../node_modules/@types/node/module.d.ts","../../node_modules/@types/node/net.d.ts","../../node_modules/@types/node/os.d.ts","../../node_modules/@types/node/path.d.ts","../../node_modules/@types/node/perf_hooks.d.ts","../../node_modules/@types/node/process.d.ts","../../node_modules/@types/node/punycode.d.ts","../../node_modules/@types/node/querystring.d.ts","../../node_modules/@types/node/readline.d.ts","../../node_modules/@types/node/readline/promises.d.ts","../../node_modules/@types/node/repl.d.ts","../../node_modules/@types/node/sea.d.ts","../../node_modules/@types/node/sqlite.d.ts","../../node_modules/@types/node/stream.d.ts","../../node_modules/@types/node/stream/promises.d.ts","../../node_modules/@types/node/stream/consumers.d.ts","../../node_modules/@types/node/stream/web.d.ts","../../node_modules/@types/node/string_decoder.d.ts","../../node_modules/@types/node/test.d.ts","../../node_modules/@types/node/timers.d.ts","../../node_modules/@types/node/timers/promises.d.ts","../../node_modules/@types/node/tls.d.ts","../../node_modules/@types/node/trace_events.d.ts","../../node_modules/@types/node/tty.d.ts","../../node_modules/@types/node/url.d.ts","../../node_modules/@types/node/util.d.ts","../../node_modules/@types/node/v8.d.ts","../../node_modules/@types/node/vm.d.ts","../../node_modules/@types/node/wasi.d.ts","../../node_modules/@types/node/worker_threads.d.ts","../../node_modules/@types/node/zlib.d.ts","../../node_modules/@types/node/ts5.6/index.d.ts","../../node_modules/@types/mime/index.d.ts","../../node_modules/@types/send/index.d.ts","../../node_modules/@types/qs/index.d.ts","../../node_modules/@types/range-parser/index.d.ts","../../node_modules/@types/express-serve-static-core/index.d.ts","../../node_modules/@types/http-errors/index.d.ts","../../node_modules/@types/serve-static/index.d.ts","../../node_modules/@types/connect/index.d.ts","../../node_modules/@types/body-parser/index.d.ts","../../node_modules/@types/express/index.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/helpers/typeAliases.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/helpers/util.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/ZodError.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/locales/en.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/errors.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/helpers/parseUtil.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/helpers/enumUtil.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/helpers/errorUtil.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/helpers/partialUtil.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/standard-schema.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/types.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/external.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod/v3/index.d.cts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/any.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/errorMessages.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/array.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/bigint.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/boolean.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/number.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/date.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/enum.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/intersection.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/literal.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/string.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/record.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/map.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/nativeEnum.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/never.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/null.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/nullable.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/object.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/set.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/tuple.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/undefined.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/union.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/unknown.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parseTypes.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/Refs.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/Options.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/getRelativePath.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parseDef.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/branded.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/catch.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/default.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/effects.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/optional.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/pipeline.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/promise.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/parsers/readonly.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/selectParser.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/zodToJsonSchema.d.ts","../../node_modules/@backstage/plugin-permission-common/node_modules/zod-to-json-schema/dist/types/index.d.ts","../../node_modules/@backstage/config/dist/index.d.ts","../../node_modules/@backstage/plugin-permission-common/dist/index.d.ts","../../node_modules/tarn/dist/PromiseInspection.d.ts","../../node_modules/tarn/dist/utils.d.ts","../../node_modules/tarn/dist/PendingOperation.d.ts","../../node_modules/tarn/dist/Resource.d.ts","../../node_modules/tarn/dist/Pool.d.ts","../../node_modules/tarn/dist/TimeoutError.d.ts","../../node_modules/tarn/dist/tarn.d.ts","../../node_modules/knex/types/result.d.ts","../../node_modules/knex/types/tables.d.ts","../../node_modules/knex/types/index.d.ts","../../node_modules/@backstage/plugin-permission-node/node_modules/zod/v3/external.d.cts","../../node_modules/@backstage/plugin-permission-node/node_modules/zod/v3/index.d.cts","../../node_modules/@backstage/catalog-model/dist/index.d.ts","../../node_modules/@backstage/plugin-search-common/dist/index.d.ts","../../node_modules/@backstage/plugin-catalog-common/dist/index.d.ts","../../node_modules/@backstage/filter-predicates/node_modules/zod/v3/external.d.cts","../../node_modules/@backstage/filter-predicates/node_modules/zod/v3/index.d.cts","../../node_modules/@backstage/filter-predicates/dist/index.d.ts","../../node_modules/@backstage/catalog-client/dist/index.d.ts","../../node_modules/@types/passport/node_modules/@types/express-serve-static-core/index.d.ts","../../node_modules/@types/passport/node_modules/@types/express/index.d.ts","../../node_modules/@types/passport/index.d.ts","../../node_modules/@backstage/plugin-auth-node/node_modules/zod/v3/external.d.cts","../../node_modules/@backstage/plugin-auth-node/node_modules/zod/v3/index.d.cts","../../node_modules/@backstage/plugin-auth-node/dist/index.d.ts","../../node_modules/@backstage/plugin-permission-node/dist/index.d.ts","../../node_modules/@types/luxon/src/zone.d.ts","../../node_modules/@types/luxon/src/settings.d.ts","../../node_modules/@types/luxon/src/_util.d.ts","../../node_modules/@types/luxon/src/misc.d.ts","../../node_modules/@types/luxon/src/duration.d.ts","../../node_modules/@types/luxon/src/interval.d.ts","../../node_modules/@types/luxon/src/datetime.d.ts","../../node_modules/@types/luxon/src/info.d.ts","../../node_modules/@types/luxon/src/luxon.d.ts","../../node_modules/@types/luxon/index.d.ts","../../node_modules/@backstage/backend-plugin-api/node_modules/@backstage/cli-common/dist/index.d.ts","../../node_modules/@backstage/backend-plugin-api/dist/index.d.ts","../mcp-chat-node/src/extensions.ts","../mcp-chat-node/src/index.ts","./src/module.ts","./src/index.ts","../../node_modules/@jest/expect-utils/build/index.d.ts","../../node_modules/chalk/index.d.ts","../../node_modules/@jest/schemas/node_modules/@sinclair/typebox/typebox.d.ts","../../node_modules/@jest/schemas/build/index.d.ts","../../node_modules/pretty-format/build/index.d.ts","../../node_modules/jest-diff/build/index.d.ts","../../node_modules/jest-matcher-utils/build/index.d.ts","../../node_modules/expect/build/index.d.ts","../../node_modules/@types/jest/index.d.ts","../../node_modules/@types/webpack-env/index.d.ts"],"fileInfos":[{"version":"824cb491a40f7e8fdeb56f1df5edf91b23f3e3ee6b4cde84d4a99be32338faee","affectsGlobalScope":true},"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","9a68c0c07ae2fa71b44384a839b7b8d81662a236d4b9ac30916718f7510b1b2d","5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","5514e54f17d6d74ecefedc73c504eadffdeda79c7ea205cf9febead32d45c4bc",{"version":"87d693a4920d794a73384b3c779cadcb8548ac6945aa7a925832fe2418c9527a","affectsGlobalScope":true},{"version":"76f838d5d49b65de83bc345c04aa54c62a3cfdb72a477dc0c0fce89a30596c30","affectsGlobalScope":true},{"version":"cd034f499c6cdca722b60c04b5b1b78e058487a7085a8e0d6fb50809947ee573","affectsGlobalScope":true},{"version":"138fb588d26538783b78d1e3b2c2cc12d55840b97bf5e08bca7f7a174fbe2f17","affectsGlobalScope":true},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true},{"version":"4443e68b35f3332f753eacc66a04ac1d2053b8b035a0e0ac1d455392b5e243b3","affectsGlobalScope":true},{"version":"bc47685641087c015972a3f072480889f0d6c65515f12bd85222f49a98952ed7","affectsGlobalScope":true},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true},{"version":"93495ff27b8746f55d19fcbcdbaccc99fd95f19d057aed1bd2c0cafe1335fbf0","affectsGlobalScope":true},{"version":"6fc23bb8c3965964be8c597310a2878b53a0306edb71d4b5a4dfe760186bcc01","affectsGlobalScope":true},{"version":"ea011c76963fb15ef1cdd7ce6a6808b46322c527de2077b6cfdf23ae6f5f9ec7","affectsGlobalScope":true},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true},{"version":"bb42a7797d996412ecdc5b2787720de477103a0b2e53058569069a0e2bae6c7e","affectsGlobalScope":true},{"version":"4738f2420687fd85629c9efb470793bb753709c2379e5f85bc1815d875ceadcd","affectsGlobalScope":true},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true},{"version":"9fc46429fbe091ac5ad2608c657201eb68b6f1b8341bd6d670047d32ed0a88fa","affectsGlobalScope":true},{"version":"61c37c1de663cf4171e1192466e52c7a382afa58da01b1dc75058f032ddf0839","affectsGlobalScope":true},{"version":"b541a838a13f9234aba650a825393ffc2292dc0fc87681a5d81ef0c96d281e7a","affectsGlobalScope":true},{"version":"b20fe0eca9a4e405f1a5ae24a2b3290b37cf7f21eba6cbe4fc3fab979237d4f3","affectsGlobalScope":true},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true},{"version":"49ed889be54031e1044af0ad2c603d627b8bda8b50c1a68435fe85583901d072","affectsGlobalScope":true},{"version":"e93d098658ce4f0c8a0779e6cab91d0259efb88a318137f686ad76f8410ca270","affectsGlobalScope":true},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true},{"version":"bf14a426dbbf1022d11bd08d6b8e709a2e9d246f0c6c1032f3b2edb9a902adbe","affectsGlobalScope":true},{"version":"5e07ed3809d48205d5b985642a59f2eba47c402374a7cf8006b686f79efadcbd","affectsGlobalScope":true},{"version":"2b72d528b2e2fe3c57889ca7baef5e13a56c957b946906d03767c642f386bbc3","affectsGlobalScope":true},{"version":"8073890e29d2f46fdbc19b8d6d2eb9ea58db9a2052f8640af20baff9afbc8640","affectsGlobalScope":true},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true},{"version":"51e547984877a62227042850456de71a5c45e7fe86b7c975c6e68896c86fa23b","affectsGlobalScope":true},{"version":"956d27abdea9652e8368ce029bb1e0b9174e9678a273529f426df4b3d90abd60","affectsGlobalScope":true},{"version":"4fa6ed14e98aa80b91f61b9805c653ee82af3502dc21c9da5268d3857772ca05","affectsGlobalScope":true},{"version":"e6633e05da3ff36e6da2ec170d0d03ccf33de50ca4dc6f5aeecb572cedd162fb","affectsGlobalScope":true},{"version":"d8670852241d4c6e03f2b89d67497a4bbefe29ecaa5a444e2c11a9b05e6fccc6","affectsGlobalScope":true},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true},{"version":"caccc56c72713969e1cfe5c3d44e5bab151544d9d2b373d7dbe5a1e4166652be","affectsGlobalScope":true},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true},{"version":"50d53ccd31f6667aff66e3d62adf948879a3a16f05d89882d1188084ee415bbc","affectsGlobalScope":true},{"version":"15b98a533864d324e5f57cd3cfc0579b231df58c1c0f6063ea0fcb13c3c74ff9","affectsGlobalScope":true},{"version":"33358442698bb565130f52ba79bfd3d4d484ac85fe33f3cb1759c54d18201393","affectsGlobalScope":true},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true},"b40885a4e39fb67eb251fb009bf990f3571ccf7279dccad26c2261b4e5c8ebcd","2d0e63718a9ab15554cca1ef458a269ff938aea2ad379990a018a49e27aadf40","530e5c7e4f74267b7800f1702cf0c576282296a960acbdb2960389b2b1d0875b","1c483cc60a58a0d4c9a068bdaa8d95933263e6017fbea33c9f99790cf870f0a8","07863eea4f350458f803714350e43947f7f73d1d67a9ddf747017065d36b073a","396c2c14fa408707235d761a965bd84ce3d4fc3117c3b9f1404d6987d98a30d6","0c46e15efeb2ff6db7c6830c801204e1048ccf0c8cc9ab1556b0b95832c9d1c9","c475aa6e8f0a20c76b5684658e0adaf7e1ba275a088ee6a5641e1f7fe9130b8a","a42db31dacd0fa00d7b13608396ca4c9a5494ae794ad142e9fb4aa6597e5ca54","4d2b263907b8c03c5b2df90e6c1f166e9da85bd87bf439683f150afc91fce7e7","db6eec0bf471520d5de8037e42a77349c920061fb0eb82d7dc8917262cbf0f17","13c83c04f3cbd2da8276c6290b75f295edf309b4f907f667f1b775d5f048f47e","ca70001e8ea975754a3994379faca469a99f81d00e1ff5b95cabac5e993359aa","b70bd59e0e52447f0c0afe7935145ef53de813368f9dd02832fa01bb872c1846","3bdc578841f58bfd1087e14f81394ece5efd56b953362ef100bdd5bd179cd625","2bc15addade46dc6480df2817c6761d84794c67819b81e9880ab5ce82afb1289","247d6e003639b4106281694e58aa359613b4a102b02906c277e650269eaecede","fe37c7dc4acc6be457da7c271485fcd531f619d1e0bfb7df6a47d00fca76f19c","159af954f2633a12fdee68605009e7e5b150dbeb6d70c46672fd41059c154d53","a1b36a1f91a54daf2e89e12b834fa41fb7338bc044d1f08a80817efc93c99ee5","8bb4a5b632dd5a868f3271750895cb61b0e20cff82032d87e89288faee8dd6e2","2a3e6dfb299953d5c8ba2aca69d61021bd6da24acea3d301c5fa1d6492fcb0ec","017de6fdabea79015d493bf71e56cbbff092525253c1d76003b3d58280cd82a0","cf94e5027dd533d4ee448b6076be91bc4186d70f9dc27fac3f3db58f1285d0be","74293f7ca4a5ddf3dab767560f1ac03f500d43352b62953964bf73ee8e235d3d","6745b52ab638aaf33756400375208300271d69a4db9d811007016e60a084830f","90ee466f5028251945ee737787ee5e920ee447122792ad3c68243f15efa08414","34c17533b08bd962570d7bdb838fcaf5bcf7b913c903bc9241b0696a635b8115","1d567a058fe33c75604d2f973f5f10010131ab2b46cf5dddd2f7f5ee64928f07","5af5ebe8c9b84f667cd047cfcf1942d53e3b369dbd63fbea2a189bbf381146c6","5e126f7796301203e1d1048c1e5709ff9251f872a19f5ac0ee1f375d8128ef9b","147734cfd0973548fb6ef75d1e7d2c0b56bb59aad72b280784e811d914dc47d6","d2594d95d465026ebbee361f4819dc7b3146f4a8b42091ffb5dd90f9ceb345ab","e399d54c1b272a400ed446ca35d5e43d6b820723c2e5727b188ebea261e7cc2e","123568587c36c9f2a75091d8cdf8f287193855ba5aa10797b4fc320c80920b7f","6deffa531bdb8817b363505e88d957653d0c454f42c69e31588d00102cd1a076","973551068756351486afe706b240eb4dc83678ab2d829a1c6b1a19871394fd5f","e647d13de80e1b6b4e1d94363ea6f5f8f77dfb95d562748b488a7248af25aabf","9b7b0209a8841f5ffa60ccdfae26f7dc70ea4e7e446a603ef4732e84f1bb1b4f","5edc4b81a61ea5e0319b32d8f581d9643cb747cf44477b16af048f62d358c433","d47c9f84b00def208cbfdd820f8d10425ead9dbf36350d77fb55d5ef6857dabc","7629bedb475a5f5d04cdf8c69f29f2cf52a1d92dd13c39661c3e865ad997bd7e","20cf19c8028a7b958e9c2000281d0f4c4cd12502fef7d63b088d44647cdd607b","799780c3726407eaa2e09e709c376ec459582f6f9c41d9643f863580cecf7ff8","37280465f8f9b2ea21d490979952b18b7f4d1f0d8fab2d627618fb2cfa1828e3",{"version":"52e29afa525973fc7cff28c4b6b359d91ad030d4aa198f060f813d4abcadb099","affectsGlobalScope":true},"a890cccdc380629c6cd9e9d92fff4ca69b9adddde84cc503296ada99429b5a3b","168b6da36cf7b832173d7832e017bc6c6c7b4023bf6b2de293efb991b96bca44","05b39d7219bb2f55f865bca39a3772e1c0a396ea562967929d6b666560c85617","bcae62618c23047e36d373f0feac5b13f09689e4cd08e788af13271dbe73a139","2c49c6d7da43f6d21e2ca035721c31b642ebf12a1e5e64cbf25f9e2d54723c36","5ae003688265a1547bbcb344bf0e26cb994149ac2c032756718e9039302dfac8","e1744dbace6ba2051a32da3c6b40e0fc690810a87b9ad4a1925b59f8f7157a34","ba8a615335e3dfdf0773558357f15edfff0461db9aa0aef99c6b60ebd7c40344","6921769648e4b83bb10e8fcf7011ea2d8f7de5d056daacf661648935a407376e","dd21167f276d648aa8a6d0aacd796e205d822406a51420b7d7f5aa18a6d9d6d9","3dea56c1745af2c31af0c84ecc6082044dc14cfa4d7366251e5bf91693eecd8b","eb6360635bc14b96a243bd5134e471f3ad26b0ecaf52d9d28621e443edb56e5c","e6f25eb7de8d9854badecb42caec553fb50c7ec37926473e3fb7f6df45bc945f","62a64260ea1dada7d643377c1a0ef3495363f4cca36adf7345e8566e7d7f419b","8b15e8af2fc862870418d0a082a9da2c2511b962844874cf3c2bad6b2763ca10","3d399835c3b3626e8e00fefc37868efe23dbb660cce8742486347ad29d334edd","b262699ba3cc0cae81dae0d9ff1262accf9832b2b7ee6548c626d74076bff8fe","057cac07c7bc5abdcfba44325fcea4906dff7919a3d7d82d4ec40f8b4c90cf2f","d94034601782f828aa556791279c86c37f09f7034a2ab873eefe136f77a6046b","fd25b101370ee175be080544387c4f29c137d4e23cad4de6c40c044bed6ecf99","8175f51ec284200f7bd403cb353d578e49a719e80416c18e9a12ebf2c4021b2b","e3acb4eb63b7fc659d7c2ac476140f7c85842a516b98d0e8698ba81650a1abd4","04d4c47854061cc5cefc3089f38e006375ae283c559ab2ce00763bca2e49516b","6a2146116c2fa9ca4fefa5c1d3de821462fc22e5330cda1196be15d439728c51","f4f1499db1953093d2fa6b5a4bb8852f0b8b353ff7df6aac12dc09dbb4f99176","db183df77deb66843c904baf2fc00ebb70d271466a1cb92dd1a5cb861bb612c5","809dcd114fb92a5190bb0cbc2b60774d3dbead29c3474be9dd1044409ddfa0a1","a69aa0011f1c8862b9d417aebd4b8c9e8e5945d1ac53dc1fceb53af8312009fe","093ae9227ee6102da600c1f50f4053f7179fba242815f69ba56728a6c60ee93a","6a2146116c2fa9ca4fefa5c1d3de821462fc22e5330cda1196be15d439728c51","b30cc18b84468d3fa20ac04ca5ba9bed5a03431fc8a22bcf2c266c132baa1d3f","a9452e81c28c642c2f095844c3473d979eba5ae89726ad52b15ea86b3e112ee2","a54f60678f44415d01a810ca27244e04b4dde3d9b6d9492874262f1a95e56c7d","84058607d19ac1fdef225a04832d7480478808c094cbaedbceda150fa87c7e25","27abd2f2ed5aaac951b12b8332aac7970c9cf0cfd88c458f0f016228180b4293","901c640dced9243875645e850705362cb0a9a7f2eea1a82bb95ed53d162f38dd","ebb0d92294fe20f62a07925ce590a93012d6323a6c77ddce92b7743fa1e9dd20","b499f398b4405b9f073b99ad853e47a6394ae6e1b7397c5d2f19c23a4081f213","ef2cbb05dee40c0167de4e459b9da523844707ab4b3b32e40090c649ad5616e9","068a22b89ecc0bed7182e79724a3d4d3d05daacfe3b6e6d3fd2fa3d063d94f44","e70d18d1352550a028f48d74e126a919c830267b38c76ddae4dc1571476a462a","5624b09ca38ea604954f0422a9354e79ada3100305362a0da79555b3dd86f578","24830e279f5773a4108e0cbde02bdcb6c20b1d347ff1509f63eed031bf8b3190","8899fd9f8ab5ce2b3af7ba0e1a47eede6a2a30a269283cc4a934ab755d0aadaa","f10759ece76e17645f840c7136b99cf9a2159b3eabf58e3eac9904cadc22eee5","363dd28f6a218239fbd45bbcc37202ad6a9a40b533b3e208e030137fa8037b03","c6986e90cf95cf639f7f55d8ca49c7aaf0d561d47e6d70ab6879e40f73518c8d","224d293a02b7d22edb77b4ab89c0d4f63b95ecd7c0698776719f33863a77ffdc","1518707348d7bd6154e30d49487ba92d47b6bd9a32d320cd8e602b59700b5317","ede55f9bac348427d5b32a45ad7a24cc6297354289076d50c68f1692add61bce","d53a7e00791305f0bd04ea6e4d7ea9850ccc3538877f070f55308b3222f0a793","4ea5b45c6693288bb66b2007041a950a9d2fe765e376738377ba445950e927f6","7f25e826bfabe77a159a5fec52af069c13378d0a09d2712c6373ff904ba55d4b","7ffef1ed1c2bc7d9cf2fc134a7e8c68b10416cdbe8e70da8a4bd7ad5c8698d9c","63c0926fcd1c3d6d9456f73ab17a6affcdfc41f7a0fa5971428a57e9ea5cf9e0","eb524eabfa1809d54dd289374c0ce0ed4f145abb878687e4fd5e67f91d7d08a6","4ef0a17c5bcae3d68227136b562a4d54a4db18cfa058354e52a9ac167d275bbb","b748dd4ccc072a2b7194b898dc8996a2cb56bfa15ccdb60ac0d2f9eaa8e28e9d","64269ed536e2647e12239481e8287509f9ee029cbb11169793796519cc37ecd4","c06fd8688dd064796b41170733bba3dcacfaf7e711045859364f4f778263fc7b","b0a8bf71fea54a788588c181c0bffbdd2c49904075a7c9cb8c98a3106ad6aa6d","434c5a40f2d5defeede46ae03fb07ed8b8c1d65e10412abd700291b24953c578","c5a6184688526f9cf53e3c9f216beb2123165bfa1ffcbfc7b1c3a925d031abf7",{"version":"cd548f9fcd3cebe99b5ba91ae0ec61c3eae50bed9bc3cfd29d42dcfc201b68b5","affectsGlobalScope":true},"14a8ec10f9faf6e0baff58391578250a51e19d2e14abcc6fc239edb0fb4df7c5","81b0cf8cd66ae6736fd5496c5bbb9e19759713e29c9ed414b00350bd13d89d70","4992afbc8b2cb81e0053d989514a87d1e6c68cc7dedfe71f4b6e1ba35e29b77a","1810b0b14614e53075d4d1b3e6be512bde19b1ed3a287925c0d24bae8585fa1b","1c390420d6e444195fd814cb9dc2d9ca65e86eb2df9c1e14ff328098e1dc48ae","ec8b45e83323be47c740f3b573760a6f444964d19bbe20d34e3bca4b0304b3ad","ab8b86168ceb965a16e6fc39989b601c0857e1fd3fd63ff8289230163b114171","62d2f0134c9b53d00823c0731128d446defe4f2434fb84557f4697de70a62789","dc4a2cf12254395c8ae3fb4c61e6fd9f7c16110be66483599f9641941416988f","82b4045609dc0918319f835de4f6cb6a931fd729602292921c443a732a6bb811","6a2146116c2fa9ca4fefa5c1d3de821462fc22e5330cda1196be15d439728c51","654bcc87bc095d6a2248a5889ec057b38cae6052744b48f4d2922a7efac4554f","cad0f26943006174f5e7508c0542873c87ef77fa71d265968e5aa1239ad4459c","0be66c79867b62eabb489870ba9661c60c32a5b7295cce269e07e88e7bee5bf3","eed82e8db4b66b1ea1746a64cd8699a7779138b8e45d495306016ce918b28440","3a19286bcc9303c9352c03d68bb4b63cecbf5c9b7848465847bb6c9ceafa1484","6cdf8f9ca64918a2f3c2679bc146d55f07490f7f5e91310b642bc1a587f2e17e","3b55c93b5d7a44834d9d0060ca8bad7166cf83e13ef0ed0e736da4c3dbe490a2","d1f8a829c5e90734bb47a1d1941b8819aeee6e81a2a772c3c0f70b30e3693fa9","3517c54fba6f0623919137ab4bdb3b3c16e64b8578f025b0372b99be48227ad7","19b3d0c212d241c237f79009b4cd0051e54971747fd89dc70a74f874d1192534","50ee70672a1889b61ceaed0fae5d5fae75cf470f0c126a750d8f6fe279b4d3a1","7ef6623abd38e20a54000fa123a2c0ad3b9975f3576b043e66fc0fd7f06f1dde","e6d4f862924429ccb8e8eb4849f7ce7dd69f6d9bb7ec928f183deca371a80ca4","431f831d369b17f10d0034f9925cc23eac6fd285a8d60ff9ab00a7dcb515d2fc","6f35f273680e256b2702a1a230b032be883a6d82ecd2dbe5a6a4f49f1eb95e06","3b10140aae26eca9f0619c299921e202351c891b34e7245762e0641469864ffd","c0c0b22cefd1896b92d805556fcabda18720d24981b8cb74e08ffea1f73f96c2","ceec94a0cd2b3a121166b6bfe968a069f33974b48d9c3b45f6158e342396e6b2","49e35a90f8bd2aa4533286d7013d9c9ff4f1d9f2547188752c4a88c040e42885","3261b6d56270a3d8535f34c2fdad217cfba860d0f74f154f0a6a2031d0c8daf9","6a2146116c2fa9ca4fefa5c1d3de821462fc22e5330cda1196be15d439728c51","7eca5b6e1cd1c28637103d2b6c44e8b89035a53e515ff31ae3babc82e6c8e1f9","49c9c8316d59f6175e6e0439b1d5ef1218f02ce622d1a599449de30645559eed","e4c48be0ffac936fb60b19394739847145674582cbc7e24000d9fd35ab037365","215de2c70639abaf351b8ff69041e44a767ecffc5e8d2ac13ca3f201853fa1fb","d228c7773484140fac7286c9ca4f0e04db4a62acb792a606a2dda24bef70dc21","8e464886b1ff36711539ffa15ec2482472220271100768c1d98acfdf355a23ba","fb0135c4906ff44d3064feebd84bae323ebb7b59b8ce7053d34e7283d27c9076","178c8707a575baddc8f529a6dbd5d574a090e3498b2d525753db7938c74227c3","ae81e464a7db70637d07b93582b051487c7d119ac7e1bab1b1582a96e631b3f7","148634fcee440c7bd8c1339b97455aaadc196b0229ffc8dc8b85965a7d65b380","d3c60c4cf88594f84f7f5ca5f87d59090787bfcf032e86d4f03d58394b826910","f3c3f17825c6a78681186da04c2f3a0f1c60cfa95f3d4b82bbbd6ebd57214a6a","8a2c67c55dfab4ea1f6e378cfa4b5cb60d8e8931316500f5b59c201674f6105c","b7b45ff1345f8e6bd6109a5b6ef0394c2e3bcbe48830516d9e78e20592ce468a","e5eb4863b7fc8515078dc09cd2f98fd179ff1a55216ecdc57d2dec7ce13e36c1","81785a3ea03d6db981ddfcf8fb1bd1377f985564def845c55e49e16f171deec4","537a2b61594512c5e75fad7e29d25c23922e27e5a1506eb4fce74fe858472a6e","8f9a2a6ddbd11ecbbc430ae8ce25528e696206f799ef1f22528569caf6ce580c","e05e03e1687d7f80f1569fdae117bb7b97feef1e839a61e1b3c61ffca8cc67c9","b311d973a0028d6bc19dfbaae891ad3f7c5057684eb105cfbeec992ab71fbc13","8a49e533b98d5c18a8d515cd3ae3bab9d02b6d4a9ac916e1dba9092ca0ebff15","fcb26ad5a6c39ce71dfac5dc16b3ed0e1a06a6dc8b9ac69112c935ad95fcad69","6acdef608420511aa0c9e3290b37d671bab4f719ffc2a2992c2e63a24605a657","291df5da0d84d1452cd68abfbcca08a3f96af610bf0e748528ba8d25784ce2b1","176cda558a7f76813f463a46af4607a81f10de5330c0f7a43d55982163aa0493","6621af294bd4af8f3f9dd9bd99bd83ed8d2facd16faa6690a5b02d305abd98ab","5eada4495ab95470990b51f467c78d47aecfccc42365df4b1e7e88a2952af1a3","6b08ada439e3c7fba3e6d18c19f934e7bbea3f34979f2490074f0623b849e8e4","40e9c2028b34c6c1e3281818d062f7008705254ee992d9857d051c603391e0f4","07a9aa7f3facdfac577ed4aa0c166295d54637508942a2154566d87804a33ae2","4a34de405e3017bf9e153850386aacdf6d26bbcd623073d13ab3c42c2ae7314c","993bcd7e2dd9479781f33daab41ec297b8d6e6ccc4c8f9b629a60cc41e07e5c8","714a7869be4ff21fa7be0dc183569db5e6818ca22882a79d2bb3a7801f5bfab4","dfa99386b9a1c1803eb20df3f6d3adc9e44effc84fa7c2ab6537ed1cb5cc8cfb","4cb85ba4cf75f1b950bd228949ae508f229296de60cf999593e4dd776f7e84e8","e39730c031200579280cae4ea331ec4e0aa42f8f7ad19c3ec4b0b90414e40113","e90bd7922cb6d591efd7330d0ba8247ec3edf4c511b81346fd49fff5184e6935","1b581d7fcfacd6bbdabb2ceae32af31e59bf7ef61a2c78de1a69ca879b104168","4720efe0341867600b139bca9a8fa7858b56b3a13a4a665bd98c77052ca64ea4","a0f62f1335e4c627a04eed453d4fa709f19ef60fd11c65e1fdfc96de9df374a5","37446d15751f05bb3ecde3ad5346b2ccfa7f4578411e9e699b38a867327ffbf9","11792ab82e35e82f93690040fd634689cad71e98ab56e0e31c3758662fc85736","8551ca11a261b2384e0db64bbd09ee78a2043a908251746db3a522b6a646e960","6c53c05df974ece61aca769df915345dc6d5b7649a01dc715b7da1809ce00a77","18c505381728b8cc6ea6986728403c1969f0d81216ed04163a867780af89f839","d121a48de03095d7dd5cd09d39e1a1c4892b520dad4c1d9c339c5d5008cfb536","3a6ce66cd39bc030697a52508cfda7c248167467848964cc40bd992bd9ce71e0","b4ec75c8a71c180e886ffccb4b5391a5217d7e7077038de966e2b79553850412","f8117362c4a91da9e2a29466d682334fe522d4e5d6cc652d95c38797b41f4546","ecf85664c5bbbb0db1190cd1a57ebdedf7ecbc0dbbbfd548106f069e0c38666c","b43a0693d7162abf3a5b3b9e78acfafd0d4713af4d54d1778900e30c11bc4f83","efb3cb71ed3e03cee59cd95bffa5c7eb365b0c637dd4d8efc358d8a34b396052","aed88228359e87a1b1a4d3d45f5b6555724c01ac81ecd34aa56d4a0a01ba6910","6365e9d7645838ef3e98c0a9f52c03ce6b00962a67f1e3e945f155a6b12e0578","f4dc28fbbba727722cb1fd82f51a7b9540fbe410ed04ddf35cab191d6aa2ba10","19b3d0c212d241c237f79009b4cd0051e54971747fd89dc70a74f874d1192534","4adc1491e1338de6745d009222786747f50d67ac34d901420fbaefbf1b51b58c","4cfbd2a7a4afee212bfb0c9c3cb6e4c7d48366e0565bf5b43a4cd96c91cf14bf","37c175e28375e157933b40ca98eeb608e05f2583821a0fae564dc04614d2d95e","3f20a041a051abfb2b47a66611cf4bcbf263605f5469ed7e8b51b3977892d83f","7de33f94f482eee2f6d1d8f24427b737e2c4006792ec4c2b87da0a426e741c4d","79134a050ccec1692c31f1dacccd05ce4fcdacdf98f0fa56546b98eb8bdefead","24f1b6865be734484de2baf99146122137654c5f5f28086c5cee97b998bfcd5c","398feb1537ae0409646b0489bac99a9f0d757a2048f0009255f8e35e9c0f9828","3da4432a9c24123f98f6f1ddc5cda9c9eedf0a8853d06321803dbc5a116e5270","afc60e07200c5eae65b702f95d83096de54d99fa6eb2e0154e83b5e11c520bda","f4651affee2900f19746d1bf0fb1c45e77f57576197561ddc90b7272835c3f37","19527fc5a08c68414a234b02ae9b9619cdb4b811435d12c0af528e5640236f6b","20a629bc3f82d238f596230637365b8aec8284c963d13dafdd4c8e2746be5e64","01c48e5bf524d3fc2a3fa5c08a2e18d113ad1985bc3caea0503a4ea3a9eee64a","68969a0efd9030866f60c027aedbd600f66ea09e1c9290853cc24c2dcc92000f","4dbfad496657abd078dc75749cd7853cdc0d58f5be6dfb39f3e28be4fe7e7af5","348d2fe7d7b187f09ea6488ead5eae9bfbdb86742a2bad53b03dff593a7d40d1","becdfb07610e16293af2937e5f315a760f90a40fec4ffd76eb46ebcb0b3d6e16","710926665f4ada6c854b47da86b727005cc0e0831097d43f8c30727a7499788c","3888f0e43cd987a0dfa4fc16dd2096459deea150be49a2d30d6cf29d47801c92","f4300c38f9809cf811d5a9196893e91639a9e2bb6edf9a4f7e640c3c4ce765ec","676c3327721e3410b7387b13af857f4be96f2be91b3813a724eedc06b9ce52d7","10716e50bcd2a25cecf2dd993f0aadf76f12a390d2f7e91dc2cac794831e865e","81a8f1f6218d0acc8cd2cf8b5089d21b45cf812bb5820affe3bab058b46cba7b","fa69921924cf112fa523a18215a3bfb352ac3f498b46e66b879e50ca46cc9203","9b82a268ba0a85015cb04cd558582c7949a1b91b6761292b9360d093c18e1dd1","ccfb77fcac04c34442ffca82ae90c8dd2a0ec1689ace547fab9a0ae337dd4752","7b464488950d74ca5037da375308fc0c94a539378fd0e9554556df45483aad02","beebde754323e430b4ecf5b9f837a05b1667b3df86bd924b52c4f80f20b3d660","2d97de1377bad99c7b9df395330201195ef1d7f861a07087f2d42aa0d4daccbd","c790db6044ce1bbafc46f13bde46b9f0065de155b26a199f442fe064f6b05d63","05a618d1e5019598f7d2256ce7a51d4bf70b682cbb8604d847c186e1df619a65","f405e934163ed30905b4682eb542bb2d446e59c477871be9d29f92ab474d522a","8294ddd1c6ea4ed9ec190a2d41500539c1623e274d5a67786d6b09849cb98d45","aab16135be8081c563dcbb33c25bb4bbf2065c7026d7228e6f1cd8153d8587e7","666d6d6d9f2298f8d8d17ac7a34ac9ca9a59e09fc97b1ae505df6ab4934e2dbe","f3941ac359b8377c0ccce596a2bd3cde8986279f42d75290b0272f3ab1aa604d","de3d39262355af808ff74b3df62aaad0ad3cbde76c13fb4fa6fb6e4cc817e78e","a5042497dfcd9aa8864af2db95b386bd345559edac65c3d8910684ce68e551fc","757f7967151a9b1f043aba090f09c1bdb0abe54f229efd3b7a656eb6da616bf4","786691c952fe3feac79aca8f0e7e580d95c19afc8a4c6f8765e99fb756d8d9d7","734614c9c05d178ceb1acf2808e1ca7c092cf39d435efc47417d8f744f3e4c0b","d65a7ea85e27f032d99e183e664a92f5be67c7bc7b31940957af6beaaf696844","5c26ad04f6048b6433f87556619fd2e50ba6601dcdf3276c826c65681197f79d","9c752e91fe237ce4857fbbef141bee357821e1e50c2f33a72c6df845703c87d5","f926160895757a498af7715653e2aedb952c2579a7cb5cc79d7b13538f9090bd","255be579a134ab321af2fefb52ace369a11ffb4df09d1fbfc1ed1a43c1e5eec5","7abc0a41bf6ba89ea19345f74e1b02795e8fda80ddcfe058d0a043b8870e1e23","ab0926fedbd1f97ec02ed906cf4b1cf74093ab7458a835c3617dba60f1950ba3","f1a661906cd0e7fa5b049b15bdef4b20a99abca08faac457eeb2b6407f30d12f","7f5a6eac3d3d334e2f2eba41f659e9618c06361958762869055e22219f341554","626291e7b45a4b6871649c908fbbc5ac98009a5182e2594fbfe80b860f513c77","4093c47f69ea7acf0931095d5e01bfe1a0fa78586dbf13f4ae1142f190d82cc4","4fc9939c86a7d80ab6a361264e5666336d37e080a00d831d9358ad83575267da","f4ba385eedea4d7be1feeeac05aaa05d6741d931251a85ab48e0610271d001ce","348d5347f700d1e6000cbdd1198730979e65bfb7d6c12cc1adedf19f0c7f7fca","6fa6ceb04be38c932343d6435eb6a4054c3170829993934b013b110273fe40af","396e7b817fc4f5461b92f9a03325c2ebb09711aebcee5c41c5fd3e738eb78526","4116c4d61baab4676b52f2558f26fe9c9b5ca02c2792f9c36a577e7813029551","a294d0b1a9b16f85768553fdbf1d47f360dbff03649a84015c83fd3a582ba527","8f2644578a3273f43fd700803b89b842d2cd09c1fba2421db45737357e50f5b1","639f94fe145a72ce520d3d7b9b3b6c9049624d90cbf85cff46fb47fb28d1d8fe","8327a51d574987a2b0f61ea40df4adddf959f67bc48c303d4b33d47ba3be114a","00e1da5fce4ae9975f7b3ca994dcb188cf4c21aee48643e1d6d4b44e72df21ee","b991d92a0c3a48764edd073a5d28b6b4591ec9b7d4b2381067a57f36293637d0","51b4ab145645785c8ced29238192f870dbb98f1968a7c7ef2580cd40663b2940","100802c3378b835a3ce31f5d108de149bd152b45b555f22f50c2cafb3a962ead","fd4fef81d1930b60c464872e311f4f2da3586a2a398a1bdf346ffc7b8863150f","354f47aa8d895d523ebc47aea561b5fedb44590ac2f0eae94b56839a0f08056a","b152c7b474d7e084e78fa5eb610261a0bfe0810e4fd7290e848fdc88812f4504","67f2cd6e208e68fdfa366967d1949575df6ccf90c104fc9747b3f1bdb69ad55a","603395070ec53375882d53b585430e8f2dc6f77f4b381b22680d26c0a9595edc","cef16d87ff9aed3c5b96b47e0ac4277916c1c530f10eedfce4acaeacefddd3bb","fab33f402019d670257c8c833ffd78a7c9a99b4f7c23271e656cdbea1e89571f","976d20bb5533077a2135f456a2b48b7adb7149e78832b182066930bad94f053a","589713fefe7282fd008a2672c5fbacc4a94f31138bae6a03db2c7b5453dc8788","26f7f55345682291a8280c99bb672e386722961063c890c77120aaca462ac2f9","bdc2312da906d4129217238545d7e01e1d00b191beea1a9529b660de8b78834f","62b753ed351fba7e0f6b57103529ce90f2e11b949b8fc69c39464fe958535c25","514321f6616d04f0c879ac9f06374ed9cb8eac63e57147ac954e8c0e7440ce00","3c583256798adf31ef79fd5e51cd28a6fc764db87c105b0270214642cf1988aa","abdb70e24d3b39bf89aa07e769b33667c2d6f4ddcb4724735d72a941de6d4631","ff4aeeeaf4f7f3dc3e099c2e2b2bb4ec80edda30b88466c4ddf1dd169c73bf26","151aa7caace0a8e58772bff6e3505d06191508692d8638cd93e7ca5ecfa8cd1b","3d59b606bca764ce06d7dd69130c48322d4a93a3acb26bb2968d4e79e1461c3c","0231f8c8413370642c1c061e66b5a03f075084edebf22af88e30f5ce8dbf69f4","474d9ca594140dffc0585ce4d4acdcfba9d691f30ae2cafacc86c97981101f5c","8e1884a47d3cfddccf98bc921d13042988da5ebfd94664127fa02384d5267fc3","ea7d883df1c6b48eb839eb9b17c39d9cecf2e967a5214a410920a328e0edd14e","82f75b2de1456b0be46945c6c68547f032f11238d07db45bbc9c93fca6abfe41","812e55580eb591f3c04245345be8c9dce378b26238fb59d704e54a61e6e37c83","1de7ee494c7ac185e6abf94428afe270e98a59f1bb4768e4bea7804645a0d57d","2c12f912bab4b1eb797b2fded3f295fee98736f8053a08d0032becbecb4b34b1","5776c61de0f11da1c3cf8aafc3df524e8445201c96a7c5065a36dc74c2dc0ef6","c110c6e2b6a8494ff722db0c32ff143bcf0ed04ecdb993a58b8d4c1ef5d8e1d3","7f0f90d0ffdd54875c464b940afaa0f711396f65392f20e9ffafc0af12ccbf14","483255952a9b6240575a67f7beb4768bd850999a32d44d2c6d0ae6dfcdafe35c","a1957cc53ce2402d4dc5c51b7ccc76b30581ab67bea12a030a76300be67c51d8","8149e534c91fc2bcb3bf59f7c1fab7584382abfc5348055e7f84d2552c3de987","c280ec77789efcf60ea1f6fd7159774422f588104dae9dfa438c9c921f5ab168","2826b3526af4f0e2c8f303e7a9a9a6bb8632e4a96fece2c787f2df286a696cea","77ced89806322a43991a88a9bd267d6dc9e03fd207a65e879804fa760292a03b","c8ff3a75cd1c990cbe56080b1d254695c989136c9521cb1252c739788fe55c83","485f7d76af9e2b5af78aac874b0ac5563c2ae8c0a7833f62b24d837df8561fb9","8bdf41d41ff195838a5f9e92e5cb3dfcdc4665bcca9882b8d2f82a370a52384e","2b234fce994b272403881b675d6ae2e2afb2a8be8bdec71002ff8ff2d5b59bd0","97ba9ccb439e5269a46562c6201063fbf6310922012fd58172304670958c21f6","50edac457bdc21b0c2f56e539b62b768f81b36c6199a87fbb63a89865b2348f0","d090654a3a57a76b5988f15b7bb7edc2cdc9c056a00985c7edd1c47a13881680","12a6a37d9676938a3a443a6bd9e8321d7221b6ad67b4485753322dc82a91e2a1","6c4833182ba7a753200bf30986d254653c1ac58855d784edd8dfe82f5db98954","69eeee4818209fdb59544d6f74bd6ff024944bdd4050a33577f62376d5cada8e","fa05a4a765755e92c1dcab306ef3648fa4aa108494b6e10d2329db8b89e89908","ea385ec05b32ad43bbd1002a7c553bbc6935754504d60dc38ee64cc8b3c21768","d61821435a95c7a660d5850ce6fe9c4400787595009853d982343b8089724319","c8ccc40088528bb10294d097da7440b9fa8f310b6f55de33412451183ca3a46d","3e56d3093cd84dac94761258d6d98226671481d43e93321f9825692940fcc0c2","25091d25f74760301f1e094456e2e6af52ceb6ef1ece48910463528e499992d8","ed79978235b685e7e9d2ac149c6ddaf602ce7e3a30725c20023e57f011760593","3345fc785abb65f2263f91ba092bb77470d949eddb41fc208256b964c2ccd5cb","dacdfa1d138a592734377df139ae70f203669bc3f9ac45e931aa0e6f2e567c8a","8a49075f007383f24df5b52376e41198e341a7b715da34a90b2c54b8fc8d4bcc","83f5494ed714e7898414a220e56886e00ffb58c80cbf745ecc45d6aae55f051a","28a019a0ebc44efd6b9148bbaf688bed1778d6977950da3d277f09e17687a46a","a67eff604aaeeae1c93f410dd9f176ab75a3fac2d2761e0bd9d83f933ec3e657","76a0210cd218dd17365ac0b7a99936804ede147c0a899d6bd2a9ac29cc8d4fea","853d02f4f46ca9700fefd0d45062f5b82c9335ba2224ca4d7bd34d6ae4fc4a7f","5f9ab7ba179f92fa3c5dddafec778a621fe9f64e2ba8c264ddf76fe5cf9eaf93","a0bce0fb40b88d17305f113ed02c4014329be52e8168b01fe825c049e9a37028","364e53fe15122e9d37aa8ee2c8eb037cde59bf5890b46a8205f4516b529501c0","1a577fdc45901cf461d4edc7697860c63a60526f60b7b2ba8ff7c89a9e7a1932","a6da29e6495bf303eb5f0b65dca3f92711b9cd6729eb1bed3e29dbc8b0fc2604","c35bd33a53356146889d87a05b34fc5a130ba93bc1bb36d021c0a7c817c4cc8d","f6067be38e8661d7e68287db5a602501897e2fbb385dfa2ecd170dd9f4524e8a","506b96750c75c5e5af820ac8356f27b2bcd0b077a02d33d90e87be9f0604f59d","d9c87237f57a1ca503eebb89514f65c48800b10b5574f7cda978addab1474dfb","b3cc1bb7311f35569b531e781d4a42d2b91f8dfd8bc194cc310c8b61011d6e43","33cff836b608822d3b4a52f523d964472c5437d08d81dbd1171ccf743276a223","8ca2d01f5f3d4d4067aadea230570afa4c91e24e485fbe2e9d53ead3b33f80d0","f43f73148ca38e22ee1afbf538fe9e8bcee6d86afc2b9d57daadfe6245e6ad4c","57aa6a9a1c79c2c73dfdf23b26019e6f91a3fe9e08b0bd7832c724dd7d0fe7a2","110996aad86ee528a4a46527cd47aaf767de0cb8cca8fdb0b7b87da749c68052","6cca39f12cd8b42e48c6203fedfdd0a9f9c96134eb465a8be68df76a089f9959","cde88efad8081aedb4e9968b4aa443cb6088f5113d8678003f5f177722d905e2","abc2ab38b312bbc76ff52e8d8ef90598eb19ce1c6f1c5ebb38685f93dba470ca","ccbecdcc8a5e9516ec17a9258e80a168c62a76c544ce55888feb6c22664eae8d","cc0a058997c09abe1ed57e0372cd7657d877be64d0b4b9fbe20ff247d61d6612","d26904f264c521b8dd44a2b9ea1ba5bd64a2d871c8fc059f0fa1a3e4a269fd0b","27e453271f5ad1d46c71457eb5132f7144e23eb11c72b73c3a4c8e8b0149d453","c72bebdcfcfb7f2daa857b9d403cb1b8e0696c0a860b74f970e4ca48f4d406ab","ca0a18352359b0d495c1b95717de28af03f861c01e3dec8105a2397a841f484f","60fceb1c8cd74f7363b22f08b63f3dcea558041573c738334e2756aee7d6fa65","0eafef0d23b57d331a9607682598ce1aae265c3b94f731cbc7ed7338fee7f41b","a2dec58c87acdef8e1212b95be760571c3d0cbd7b21a0bcd2f553c4943f1b4ba","db382b318bc333eb7548cc1f0dcd149794d7e1d4969d54f9586f2533b287b5ac","9761bf5d22d558d20d9010370ae7ac73d49c02cfc931babd7a010b0f3d56727c","48b794b2e593bf76f2f2f7f7a391ac40644ac623426e566674c2cf01cfe0a8d5","2be3cf1dfff9359a87e80c98015a393ed253ed9fd5bb8a8d6489a65bac681343","e57080da20379bbc001330a90d1ac46359001666976231d2be34c81564be9a2b","c12f6c5202b036760f8610d32fc7d4f1d69d694b8440d19ee5479b6a46df1e15","c36a4fc691d1480d4d1651a50a0c5c3b19a792c5aff0b87f4fcab3530772ecc8","da7939bdd11118ecfd4e0391375c466a7f8c99f03abf68c361e0c4d978dcf080","9b9493208641585c4ec62fb629e9b7d5564d126ca22a5f36fe8eeb97d6bf2be4","99115d3526d38a41eb206e970e85a2ba41408e12a0d432c33675d20869e1080c","47f564c90fc3dc3f12b24eb8fd25235105a69a6aba8f8f2e4e8615ab3091f705","78b8a5461c34d953f0a2c863d564b5e749202b54d4a151341e1b11bd0543619c",{"version":"52e5443b5f27e0ad643e58ff690c138e4d251ff1a0811f0f28b14b99f8411234","affectsGlobalScope":true},"101c69a3ac1b79f607792ef1c77d5809b25e482683d9bbd3921b462c2f336f9a","30c5e6a4b2e08989544b546a9ac44a575cff576aaa3741f10652263c72d7d622","d01a18b75a98f3bf36f27935b989d16067b606253de50abafec56866da3e9aba","6dd35f934b9f3b3ae2a14fc8204de1f5a59f8b5334479303c4829780d44e845e",{"version":"c39e8eb7e18b15427e691321a9a45d9561435f0f43ac0c5d02f667d1f013dfbf","signature":"308abf4ff004fdd297cab7acc64e00a87751ced6ba22cfebfb14d2b3bf634300"},{"version":"394fda71d5d6bd00a372437dff510feab37b92f345861e592f956d6995e9c1ce","affectsGlobalScope":true},{"version":"d153a11543fd884b596587ccd97aebbeed950b26933ee000f94009f1ab142848","affectsGlobalScope":true},{"version":"c564fc7c6f57b43ebe0b69bc6719d38ff753f6afe55dadf2dba36fb3558f39b6","affectsGlobalScope":true},{"version":"109b9c280e8848c08bf4a78fff1fed0750a6ca1735671b5cf08b71bae5448c03","affectsGlobalScope":true},"4967529644e391115ca5592184d4b63980569adf60ee685f968fd59ab1557188","cdcf9ea426ad970f96ac930cd176d5c69c6c24eebd9fc580e1572d6c6a88f62c","23cd712e2ce083d68afe69224587438e5914b457b8acf87073c22494d706a3d0","487b694c3de27ddf4ad107d4007ad304d29effccf9800c8ae23c2093638d906a","e525f9e67f5ddba7b5548430211cae2479070b70ef1fd93550c96c10529457bd","ccf4552357ce3c159ef75f0f0114e80401702228f1898bdc9402214c9499e8c0","c6fd2c5a395f2432786c9cb8deb870b9b0e8ff7e22c029954fabdd692bff6195","17fe9131bec653b07b0a1a8b99a830216e3e43fe0ea2605be318dc31777c8bbf","3c8e93af4d6ce21eb4c8d005ad6dc02e7b5e6781f429d52a35290210f495a674","2c9875466123715464539bfd69bcaccb8ff6f3e217809428e0d7bd6323416d01","ea6bc8de8b59f90a7a3960005fd01988f98fd0784e14bc6922dde2e93305ec7d","36107995674b29284a115e21a0618c4c2751b32a8766dd4cb3ba740308b16d59","914a0ae30d96d71915fc519ccb4efbf2b62c0ddfb3a3fc6129151076bc01dc60","2472ef4c28971272a897fdb85d4155df022e1f5d9a474a526b8fc2ef598af94e","6c8e442ba33b07892169a14f7757321e49ab0f1032d676d321a1fdab8a67d40c","b41767d372275c154c7ea6c9d5449d9a741b8ce080f640155cc88ba1763e35b3","1cd673d367293fc5cb31cd7bf03d598eb368e4f31f39cf2b908abbaf120ab85a","19851a6596401ca52d42117108d35e87230fc21593df5c4d3da7108526b6111c","3825bf209f1662dfd039010a27747b73d0ef379f79970b1d05601ec8e8a4249f","0b6e25234b4eec6ed96ab138d96eb70b135690d7dd01f3dd8a8ab291c35a683a","40bfc70953be2617dc71979c14e9e99c5e65c940a4f1c9759ddb90b0f8ff6b1a","da52342062e70c77213e45107921100ba9f9b3a30dd019444cf349e5fb3470c4","e9ace91946385d29192766bf783b8460c7dbcbfc63284aa3c9cae6de5155c8bc","40b463c6766ca1b689bfcc46d26b5e295954f32ad43e37ee6953c0a677e4ae2b","561c60d8bfe0fec2c08827d09ff039eca0c1f9b50ef231025e5a549655ed0298","1e30c045732e7db8f7a82cf90b516ebe693d2f499ce2250a977ec0d12e44a529","84b736594d8760f43400202859cda55607663090a43445a078963031d47e25e7","499e5b055a5aba1e1998f7311a6c441a369831c70905cc565ceac93c28083d53","54c3e2371e3d016469ad959697fd257e5621e16296fa67082c2575d0bf8eced0","beb8233b2c220cfa0feea31fbe9218d89fa02faa81ef744be8dce5acb89bb1fd","78b29846349d4dfdd88bd6650cc5d2baaa67f2e89dc8a80c8e26ef7995386583","5d0375ca7310efb77e3ef18d068d53784faf62705e0ad04569597ae0e755c401","59af37caec41ecf7b2e76059c9672a49e682c1a2aa6f9d7dc78878f53aa284d6","addf417b9eb3f938fddf8d81e96393a165e4be0d4a8b6402292f9c634b1cb00d","e38d4fdf79e1eadd92ed7844c331dbaa40f29f21541cfee4e1acff4db09cda33","8bd86b8e8f6a6aa6c49b71e14c4ffe1211a0e97c80f08d2c8cc98838006e4b88","7c10a32ae6f3962672e6869ee2c794e8055d8225ef35c91c0228e354b4e5d2d3","2e85db9e6fd73cfa3d7f28e0ab6b55417ea18931423bd47b409a96e4a169e8e6","c46e079fe54c76f95c67fb89081b3e399da2c7d109e7dca8e4b58d83e332e605","99f569b42ea7e7c5fe404b2848c0893f3e1a56e0547c1cd0f74d5dbb9a9de27e",{"version":"f4b4faedc57701ae727d78ba4a83e466a6e3bdcbe40efbf913b17e860642897c","affectsGlobalScope":true},"bbcfd9cd76d92c3ee70475270156755346c9086391e1b9cb643d072e0cf576b8","7394959e5a741b185456e1ef5d64599c36c60a323207450991e7a42e08911419","72c1f5e0a28e473026074817561d1bc9647909cf253c8d56c41d1df8d95b85f7",{"version":"59c893bb05d8d6da5c6b85b6670f459a66f93215246a92b6345e78796b86a9a7","affectsGlobalScope":true},"938f94db8400d0b479626b9006245a833d50ce8337f391085fad4af540279567","c4e8e8031808b158cfb5ac5c4b38d4a26659aec4b57b6a7e2ba0a141439c208c",{"version":"2c91d8366ff2506296191c26fd97cc1990bab3ee22576275d28b654a21261a44","affectsGlobalScope":true},"5524481e56c48ff486f42926778c0a3cce1cc85dc46683b92b1271865bcf015a",{"version":"12fb9c13f24845000d7bd9660d11587e27ef967cbd64bd9df19ae3e6aa9b52d4","affectsGlobalScope":true},"289e9894a4668c61b5ffed09e196c1f0c2f87ca81efcaebdf6357cfb198dac14","25a1105595236f09f5bce42398be9f9ededc8d538c258579ab662d509aa3b98e","9de8df30f620738193bd68ee503dc76e5f47fc426fe971cfbd89c109fd90b32e","e009777bef4b023a999b2e5b9a136ff2cde37dc3f77c744a02840f05b18be8ff","ad1cc0ed328f3f708771272021be61ab146b32ecf2b78f3224959ff1e2cd2a5c",{"version":"71450bbc2d82821d24ca05699a533e72758964e9852062c53b30f31c36978ab8","affectsGlobalScope":true},{"version":"62f572306e0b173cc5dfc4c583471151f16ef3779cf27ab96922c92ec82a3bc8","affectsGlobalScope":true},"2f32444438ecb1fa4519f6ec3977d69ce0e3acfa18b803e5cd725c204501f350","0ab3c844f1eb5a1d94c90edc346a25eb9d3943af7a7812f061bf2d627d8afac0","ecfb45485e692f3eb3d0aef6e460adeabf670cef2d07e361b2be20cecfd0046b","161f09445a8b4ba07f62ae54b27054e4234e7957062e34c6362300726dabd315","77fced47f495f4ff29bb49c52c605c5e73cd9b47d50080133783032769a9d8a6","e6057f9e7b0c64d4527afeeada89f313f96a53291705f069a9193c18880578cb",{"version":"3cdbad1bb6929fd0220715d7da689c0b69df42c8239036ff75afe4f2232222ea","affectsGlobalScope":true},"0f5cda0282e1d18198e2887387eb2f026372ebc4e11c4e4516fef8a19ee4d514","e99b0e71f07128fc32583e88ccd509a1aaa9524c290efb2f48c22f9bf8ba83b1","76957a6d92b94b9e2852cf527fea32ad2dc0ef50f67fe2b14bd027c9ceef2d86",{"version":"237581f5ec4620a17e791d3bb79bad3af01e27a274dbee875ac9b0721a4fe97d","affectsGlobalScope":true},{"version":"a8a99a5e6ed33c4a951b67cc1fd5b64fd6ad719f5747845c165ca12f6c21ba16","affectsGlobalScope":true},"a58a15da4c5ba3df60c910a043281256fa52d36a0fcdef9b9100c646282e88dd","b36beffbf8acdc3ebc58c8bb4b75574b31a2169869c70fc03f82895b93950a12","de263f0089aefbfd73c89562fb7254a7468b1f33b61839aafc3f035d60766cb4","70b57b5529051497e9f6482b76d91c0dcbb103d9ead8a0549f5bab8f65e5d031","e6d81b1f7ab11dc1b1ad7ad29fcfad6904419b36baf55ed5e80df48d56ac3aff","1013eb2e2547ad8c100aca52ef9df8c3f209edee32bb387121bb3227f7c00088","b6b8e3736383a1d27e2592c484a940eeb37ec4808ba9e74dd57679b2453b5865","d6f36b683c59ac0d68a1d5ee906e578e2f5e9a285bca80ff95ce61cdc9ddcdeb","37ba7b45141a45ce6e80e66f2a96c8a5ab1bcef0fc2d0f56bb58df96ec67e972","125d792ec6c0c0f657d758055c494301cc5fdb327d9d9d5960b3f129aff76093",{"version":"27e4532aaaa1665d0dd19023321e4dc12a35a741d6b8e1ca3517fcc2544e0efe","affectsGlobalScope":true},"ea713aa14a670b1ea0fbaaca4fd204e645f71ca7653a834a8ec07ee889c45de6",{"version":"cd9c0ecbe36a3be0775bfc16ae30b95af2a4a1f10e7949ceab284c98750bcebd","affectsGlobalScope":true},{"version":"2918b7c516051c30186a1055ebcdb3580522be7190f8a2fff4100ea714c7c366","affectsGlobalScope":true},"ae86f30d5d10e4f75ce8dcb6e1bd3a12ecec3d071a21e8f462c5c85c678efb41","982efeb2573605d4e6d5df4dc7e40846bda8b9e678e058fc99522ab6165c479e","e03460fe72b259f6d25ad029f085e4bedc3f90477da4401d8fbc1efa9793230e","4286a3a6619514fca656089aee160bb6f2e77f4dd53dc5a96b26a0b4fc778055",{"version":"d67fc92a91171632fc74f413ce42ff1aa7fbcc5a85b127101f7ec446d2039a1f","affectsGlobalScope":true},{"version":"d40e4631100dbc067268bce96b07d7aff7f28a541b1bfb7ef791c64a696b3d33","affectsGlobalScope":true},"64bc5859f99559a3587c031ec6862c671f6fdd54e61d43d8ffd02a9422092677","42180b657831d1b8fead051698618b31da623fb71ff37f002cb9d932cfa775f1","4f98d6fb4fe7cbeaa04635c6eaa119d966285d4d39f0eb55b2654187b0b27446",{"version":"e4c653466d0497d87fa9ffd00e59a95f33bc1c1722c3f5c84dab2e950c18da70","affectsGlobalScope":true},"e6dcc3b933e864e91d4bea94274ad69854d5d2a1311a4b0e20408a57af19e95d","525882f5d67944cd6fa0ef70b8e7ade7757cb10d94b80968eb777d1a8ace4a52","d3f2d715f57df3f04bf7b16dde01dec10366f64fce44503c92b8f78f614c1769","cb90077223cc1365fa21ef0911a1f9b8f2f878943523d97350dc557973ca3823","baac9896d29bcc55391d769e408ff400d61273d832dd500f21de766205255acb","2f5747b1508ccf83fad0c251ba1e5da2f5a30b78b09ffa1cfaf633045160afed",{"version":"a45c25e77c911c1f2a04cade78f6f42b4d7d896a3882d4e226efd3a3fcd5f2c4","affectsGlobalScope":true},"b71c603a539078a5e3a039b20f2b0a0d1708967530cf97dec8850a9ca45baa2b","18f1541b81b80d806120a3489af683edfb811deb91aeca19735d9bb2613e6311","104c67f0da1bdf0d94865419247e20eded83ce7f9911a1aa75fc675c077ca66e","cc0d0b339f31ce0ab3b7a5b714d8e578ce698f1e13d7f8c60bfb766baeb1d35c","232f118ae64ab84dcd26ddb60eaed5a6e44302d36249abf05e9e3fc2cbb701a2","d3cfde44f8089768ebb08098c96d01ca260b88bccf238d55eee93f1c620ff5a5","293eadad9dead44c6fd1db6de552663c33f215c55a1bfa2802a1bceed88ff0ec","36eb5babc665b890786550d4a8cb20ef7105673a6d5551fbdd7012877bb26942","fec412ded391a7239ef58f455278154b62939370309c1fed322293d98c8796a6","e3498cf5e428e6c6b9e97bd88736f26d6cf147dedbfa5a8ad3ed8e05e059af8a","dba3f34531fd9b1b6e072928b6f885aa4d28dd6789cbd0e93563d43f4b62da53","f672c876c1a04a223cf2023b3d91e8a52bb1544c576b81bf64a8fec82be9969c","e4b03ddcf8563b1c0aee782a185286ed85a255ce8a30df8453aade2188bbc904","2329d90062487e1eaca87b5e06abcbbeeecf80a82f65f949fd332cfcf824b87b","25b3f581e12ede11e5739f57a86e8668fbc0124f6649506def306cad2c59d262","93c3e73824ad57f98fd23b39335dbdae2db0bd98199b0dc0b9ccc60bf3c5134a","a9ebb67d6bbead6044b43714b50dcb77b8f7541ffe803046fdec1714c1eba206","833e92c058d033cde3f29a6c7603f517001d1ddd8020bc94d2067a3bc69b2a8e","ef38456e22b0bffcd9ff28dc1a7138e84918a212e6960dd620cc3000341c0ebe","07a1cea63a067c0845029ea6e1933af842783efa3006510f504b1f09bd2ebff0","814187370f99638f6bb69c838d19dcdb20a41cb65627cfc16a04d9cc4522fc82","7df3ea6fcd7e74ab59724700357df41a12d8f57e22f3e5da36dc645f20753152","0e8edbe744dfc3ce65e9fa2283f1f0eb2c0aaaec4df19765f51c346e45452cda","a7559733f2f5f9ae4d071cef99c505870e167ee830c75faf121f34408b99afbe","9b6e899f6fa0cf536eead034fcae436ab6ecd9442153ee06a0fb5b01475bff85","1b399336f32abd1c83610e5c95337fdcf2dd5414cf4b44c1ff4927d2cd8f1cf2","55ddb00c1810d07a092af6a816f89a6e63c3c4ef04c9c27d36a7dd59bf59b5ae","5ecb3df85ac1c4a7e7a1e9761a5bfb52a65eef8e94e1280e1bff6389cd453099","9af342002e6b793ca8a69b322cf8347250c129b45dbca8731baaa66ec553561b","e01ab496375025f3e54f832d43f840c589e57eb2e5986421f791f51bbcbc494e","539cc98696e783f3fe32422a89f8a34479ce056adb211dd60b6a89550d3b9b7f","11d5d9c9b11fbd1537ecec72ec38f993d0358c42f7c98569998a04bbbf57d07c","c26c383b08e47dfbd741193ef1e7f8f002ac3b0d2f6bf3d4b6b9a99ee2d9378e","75473b178a514d8768d6ead4a4da267aa6bedeeb792cd9437e45b46fa2dcf608","e82a6fc9b90adc5270daa1e467feb3a2ae5393180839d7a347acd1d9ebe04493","3d877e9f51aabdb77efeea746c0c09464274dcaf7364e6e64880e9c2eaa8c990","9830d91d01b457b113b36b56d4534ba8fc42bc3c195a2108dc3431e9f77340c7","1e7d16304d31f287ec09753214b755eb78e1122432d06dc771f5c123199273b1","acca4486b08bf5dc91c23d65f47181bd13f82571969c85e8df474fa6bc5c2a88","296dcaf11fa0122dfe78a1d97bea96aa9bccb73098bc739ab253281ad192dffb","971dc452ac09307ee049acb21bbd30a82d1c163377465d6b33fd4d677ed2385d","226b58896f4f01f4c669d908f32c657bcab1a83f3aebb2f3d711a4fe7ba2a2d6","8a818c9cf372e5c5818d846d761ff59c531caa3b0aa62c5686be1df31dc08296","f01c60b06afe23316efccaaa8b6ccb5f507b8e6eadf5e2a84c6fe350aebaa1bd","9a447607a90667c6db7737f30d2429f6f06efde55a47a2a3eeebc52e866d153e","ecc6f977713316ef4339f32631ecb619a40a3061fa86ff3776591920d9977e24","0aea84fed0ab80d54f32a40aaf5f4d58c8a5259dd5f9fe39dbcd584575dbb100","a1769100f50f3e190c2ea2ed2a711e6798c70f9ad806b54c597a5b64488007b0","8105a77b1ce063fd0f60080d8985e01cb92516237cb4a254547ce7548e8916e5","dc6b3b3383218cc2c556687fd7ac7b6b1d9ad3abaf50da7f04a2d7a01abaee19","879443705ef53b56d8f5b944ea2c24bd5b37a1341eb0142789c2e2567d6bb6e1","44c18ff24c5c5b7883ca2e1b1d4236db715ca5cfd9b87705e1a7e4591b4b445e","3cceb8a1fe59bc1d233764bfef78e6c72a468e2af1e06a92e282b1848c78bc31","ed96d25fa3170958d1d376e653ade8e653638d3fb819a4792a503a5505eea849","a005dc547fff460703595b4c0faccb7ec68a5870a4d0e5a2932dc1fd59cc9856","dccbbf8ce85ea99cdbdc2269d55f75bc1fbad77d96c40fd82bd73af3fb8f39e4","449babe88138e129aef94c1696b527898f9e13ab62bce129daee0e85266e48a7","17a8d5ef1c541cd5382df1542ed21cd90a1f08aea0d5fea080c5b6e1f82c3233","a27859c0e69512ee3fd878dfa0182ad9caec5bab32b7d0a0a2ff2f93964600e2","7c54c4b7f7752b0315f14b9ae63f00d7a3f39308e598c670d8a96afdcb8e0a4e","9f559e612c27cce4bc181decc88ba90b00e5be42b6ed7fe9316d6c61476d7439","03dfcf3d00c60a769e705eb5b080c3674cd59ae830ee7ad82aed8f1883f60f06","ca8cec5a09c4323e1fcd9e0f0f84727c9b0818802fabae4ecf7f42a380483037","92d06124389a259ec6f17fa490dd2da4a8aff8fd9055047036e63211793a556b","aa8c0e10f176c156cfea40f5acdbc08cb44a43ba5411c743be645743ed3b1c02","b1bf7de0413303c8bd9424cf4955b433606e90eb31339202c8bffdb1dec982e9","979a151b6741901c83c365c97b7e55dcaccd92402fe6095dedd7be206bb23bae","ec982ebee52d26bdc7a7520612216c9c55e7a44e6fe0f654fb26e6ee41bc16c4","706132295c6d7639a0de0deaca13aa2ed5b823495dfebb5fc6a6c396ae324a7f","a9ebb67d6bbead6044b43714b50dcb77b8f7541ffe803046fdec1714c1eba206","833e92c058d033cde3f29a6c7603f517001d1ddd8020bc94d2067a3bc69b2a8e","78758d13c4ec1c04593c7920ac588579e54635549c1492b36dcf6ad09d9bef31","231f38789bfa215aaac440b83a816ab08a9d01d29d93ab657f95d0f629accd79","4cdf9eb4d324d141478333ee72b68eedb4e9f40bc3503a4d747606ba3f278113","a9ebb67d6bbead6044b43714b50dcb77b8f7541ffe803046fdec1714c1eba206","833e92c058d033cde3f29a6c7603f517001d1ddd8020bc94d2067a3bc69b2a8e","3bc5d8f6d191265ba9369b9607ad2d3803fb3527e03a5113cff68d9681f478a2","a54a900fb766fb34ee5ffc442a00f20db741bb9b376c8c18d62acbb77cb48d61",{"version":"86ea91bfa7fef1eeb958056f30f1db4e0680bc9b5132e5e9d6e9cfd773c0c4fd","affectsGlobalScope":true},"d26a79f97f25eb1c5fc36a8552e4decc7ad11104a016d31b1307c3afaf48feb1",{"version":"ff155930718467b27e379e4a195e4607ce277f805cad9d2fa5f4fd5dec224df6","affectsGlobalScope":true},"a9ebb67d6bbead6044b43714b50dcb77b8f7541ffe803046fdec1714c1eba206","833e92c058d033cde3f29a6c7603f517001d1ddd8020bc94d2067a3bc69b2a8e","56972217f61c7e5321c132a32423bf892fc39847b112019905b3478d77117ad1","ded701a77c87375fda31920102ed40995704c26c9844dd546d1861f24297d3e0","5339f84dfcb7b04aa1c2b4d7713d6128039381447f07abc2e48d36685e2eef44","fb35a61a39c933d31b5b2549d906b2c932a1486622958586f662dbd4b2fe72e6","24e2728268be1ad2407bab004549d2753a49b2acb0f117a04c4e28ffb3ecdd4f","aff159b14eba59afe98a88fe6f57881ba02895fb9763512dda9083497bdcd0e6","b6bc775d112a7761a50594fc589aeaa8893c139ffe3db2b4999756e17f367a8d","79f8edca4c97e2fa77473df1d8fda43daf4501a4c721af66d389ab771dcff207","7ca4605ebe31b24536fbcda17567275c6355c64ef4ac8ed9ff9b19b59adeb2f2","26080058b725ac0b480241751255b4391f722263778e84e66a62068705aafd3c","46afbf46c3d62eac2afead3a2011d506637bf4f2c05e1fd64bbf7e2bb2947b7c","02f634f868780eaaff5e2d3fb4570dac8e7f018a8650bb9a0ac1deb4915df8d1","302e3cfe08d08266460fa3c9884a8fb60261d100e75298eb14370b378f8e861a","74a5090f489072850111e8fdc8534f35a093c83e7796c0c434b17482abf8c99c","9c02420a1f4be45dcbef3f7ce90ebe600dc52ae66ca66e554162cb3b06ab3ebb","9522ce17a83f1f005313beb9c8647070094ce3585f2534530c71d596068ce02b",{"version":"5456f5a4488477d9118f2a40e7a5a9fe0e955b5c72ff661ff15ce86e323c2a8e","signature":"293b3ab21f016ad8dd17adbe7ec0a6d0f90f982b752e7764e50752cac480dce7"},{"version":"64c398bd7f55a96ec1ceeceb39c460b7b525b34b9e33756908dad5680a4b9d2d","signature":"36673e5d8139cc19499fda8cf6b76c2771863dbbbecdba99238badf9bd593e47"},"cdcc132f207d097d7d3aa75615ab9a2e71d6a478162dde8b67f88ea19f3e54de","0d14fa22c41fdc7277e6f71473b20ebc07f40f00e38875142335d5b63cdfc9d2","c085e9aa62d1ae1375794c1fb927a445fa105fed891a7e24edbb1c3300f7384a","f315e1e65a1f80992f0509e84e4ae2df15ecd9ef73df975f7c98813b71e4c8da","5b9586e9b0b6322e5bfbd2c29bd3b8e21ab9d871f82346cb71020e3d84bae73e","3e70a7e67c2cb16f8cd49097360c0309fe9d1e3210ff9222e9dac1f8df9d4fb6","ab68d2a3e3e8767c3fba8f80de099a1cfc18c0de79e42cb02ae66e22dfe14a66","d96cc6598148bf1a98fb2e8dcf01c63a4b3558bdaec6ef35e087fd0562eb40ec",{"version":"f8db4fea512ab759b2223b90ecbbe7dae919c02f8ce95ec03f7fb1cf757cfbeb","affectsGlobalScope":true},{"version":"ebf3ec92378d6eae07f236180ac6caba814464947ee2c90b347202e9f35c6379","affectsGlobalScope":true}],"root":[431,635,636],"options":{"allowImportingTsExtensions":true,"allowJs":true,"declaration":true,"declarationMap":false,"emitDeclarationOnly":true,"esModuleInterop":true,"experimentalDecorators":false,"importHelpers":false,"jsx":2,"module":99,"noFallthroughCasesInSwitch":true,"noImplicitAny":true,"noImplicitReturns":true,"noImplicitThis":true,"noUnusedLocals":true,"noUnusedParameters":true,"outDir":"./dist","removeComments":false,"rootDir":"./src","skipLibCheck":true,"sourceMap":false,"strict":true,"strictBindCallApply":true,"strictFunctionTypes":true,"strictNullChecks":true,"strictPropertyInitialization":true,"stripInternal":true,"target":9,"useDefineForClassFields":true},"fileIdsList":[[131,404,405,406,407,408,409,410,411,412,413,418,435,480],[131,136,138,179,181,192,197,230,232,241,258,343,399,404,405,406,407,408,409,410,411,412,413,414,417,435,480],[131,399,435,480],[131,398,418,435,480],[131,241,343,403,418,435,480],[131,241,272,343,403,418,435,480],[404,405,406,407,408,409,410,411,412,413,435,480],[131,435,480],[131,179,192,415,435,480],[400,401,402,403,414,416,417,418,419,420,421,424,435,480],[343,435,480],[435,480],[343,401,435,480],[131,400,402,435,480],[131,418,435,480],[131,412,422,435,480],[422,423,435,480],[416,435,480],[131,291,435,480],[348,368,397,435,480],[344,345,346,347,435,480],[179,435,480],[131,350,435,480],[131,349,435,480],[215,435,480],[349,350,351,352,365,435,480],[131,215,435,480],[131,179,364,435,480],[366,367,435,480],[131,291,375,435,480],[376,377,379,380,381,382,383,384,385,386,387,388,389,390,391,392,393,394,395,396,435,480],[291,381,382,435,480],[131,291,307,381,435,480],[131,378,379,380,435,480],[131,378,381,435,480],[131,291,378,381,435,480],[291,393,435,480],[131,291,307,390,392,435,480],[131,378,391,435,480],[131,291,307,389,435,480],[131,378,388,390,435,480],[131,378,389,435,480],[139,180,435,480],[131,139,179,435,480],[131,153,154,435,480],[147,435,480],[131,149,435,480],[147,148,150,151,152,435,480],[140,141,142,143,144,145,146,149,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,435,480],[153,154,435,480],[216,217,218,219,435,480],[131,218,435,480],[220,223,229,435,480],[221,222,435,480],[224,435,480],[225,435,480],[131,226,227,435,480],[226,227,228,435,480],[374,435,480],[131,307,435,480],[131,291,307,372,435,480],[369,370,371,372,373,435,480],[131,192,370,435,480],[292,435,480],[131,192,291,296,435,480],[131,291,294,295,435,480],[131,291,296,435,480],[131,272,435,480],[273,274,295,296,297,298,299,300,301,302,303,304,305,435,480],[131,192,435,480],[131,295,435,480],[131,303,435,480],[131,284,435,480],[275,277,278,279,280,281,282,283,284,285,286,287,288,289,435,480],[131,276,435,480],[131,283,435,480],[131,278,435,480],[332,435,480],[329,330,333,334,335,336,337,338,339,340,435,480],[293,435,480],[306,435,480],[290,435,480],[341,435,480],[231,435,480],[131,233,234,435,480],[235,236,435,480],[233,234,237,238,239,240,435,480],[131,249,251,435,480],[131,250,435,480],[251,252,253,254,255,256,257,435,480],[131,253,435,480],[131,198,212,213,435,480],[131,211,435,480],[198,212,213,214,435,480],[183,184,185,187,188,189,190,191,435,480],[131,353,435,480],[353,354,355,356,357,358,359,360,361,362,363,435,480],[307,435,480],[131,241,435,480],[260,435,480],[131,317,318,435,480],[319,435,480],[131,260,308,309,310,311,312,313,314,315,316,320,321,322,323,324,325,326,327,328,342,435,480],[63,67,68,69,70,71,72,73,74,75,80,83,84,85,86,88,91,92,93,99,102,103,106,107,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,127,128,129,130,435,480],[131,242,435,480],[131,244,435,480],[242,435,480],[242,243,244,245,246,247,248,435,480],[131,435,480,512],[263,435,480],[262,264,435,480,512],[435,480,512],[261,262,265,266,267,268,269,270,271,435,480],[131,132,435,480],[132,133,134,135,435,480],[63,435,480],[62,435,480],[66,75,76,77,435,480],[75,78,435,480],[66,73,435,480],[66,78,435,480],[64,65,76,77,78,79,435,480],[82,435,480,512],[84,435,480],[67,68,74,75,435,480],[67,75,435,480],[87,89,90,435,480],[87,88,435,480],[92,435,480],[64,435,480],[69,94,435,480],[94,435,480],[97,435,480],[94,95,96,435,480],[94,95,96,97,98,435,480],[71,435,480],[67,73,75,435,480],[84,85,435,480],[100,435,480],[100,104,435,480],[100,101,104,105,435,480],[74,103,435,480],[81,435,480],[63,72,435,480],[71,73,435,480,495,497],[66,435,480],[66,108,109,110,435,480],[64,68,69,70,71,74,78,435,480],[68,86,435,480],[102,435,480],[67,69,75,114,116,118,435,480],[67,69,75,114,115,116,117,435,480],[118,435,480],[73,74,88,118,435,480],[67,73,435,480],[73,92,435,480],[74,84,85,435,480],[82,114,435,480,495,512],[67,68,124,125,435,480],[68,73,86,114,123,124,125,126,435,480,495,496],[68,86,102,435,480],[73,435,480],[193,194,195,196,435,480],[131,188,435,480],[185,435,480],[186,435,480],[131,183,184,435,480],[426,435,480,512,540,593,594,604,620,630,631],[427,435,480,481],[427,435,480,607,609,612],[426,435,480],[426,435,480,593,611],[435,480,541,542,543,545,546,551],[435,480,552],[426,435,480,540,593,607,613,616,618,632],[435,480,607,608],[426,435,480,592,593],[435,480,553,577,578],[435,480,553,577,579],[435,480,577,578],[435,480,554,555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591],[435,480,554,556,557,558,559,560,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576],[435,480,578],[435,480,553,555,577,578],[435,480,553,555,578],[435,480,553,555,559,578,579],[435,480,553],[435,480,553,578],[435,480,553,565,577,578],[435,480,554,578],[435,480,553,569,577,578],[435,480,553,562,577,578],[435,480,553,561,564,577,578],[435,480,541,542,553],[435,480,543,544],[435,480,542,543],[435,480,551],[435,480,543],[435,480,541,542,543,546,547,548,549,550],[435,480,540,593,594,606,619,632],[426,435,480,512,594],[435,480,639],[199,200,201,202,205,206,207,208,209,210,435,480],[131,204,435,480],[131,205,435,480],[331,435,480],[435,480,495,530,538],[435,480,495,530],[435,480,492,495,530,532,533,534],[435,480,533,535,537,539],[435,480,641,644],[435,480,629],[435,480,622],[435,480,621,623,625,626,630],[435,480,623,624,627],[435,480,621,624,627],[435,480,623,625,627],[435,480,621,622,624,625,626,627,628],[435,480,621,627],[435,480,623],[435,477,480],[435,479,480],[435,480,485,515],[435,480,481,486,492,493,500,512,523],[435,480,481,482,492,500],[435,480,483,524],[435,480,484,485,493,501],[435,480,485,512,520],[435,480,486,488,492,500],[435,479,480,487],[435,480,488,489],[435,480,490,492],[435,479,480,492],[435,480,492,493,494,512,523],[435,480,492,493,494,507,512,515],[435,475,480],[435,475,480,488,492,495,500,512,523],[435,480,492,493,495,496,500,512,520,523],[435,480,495,497,512,520,523],[435,480,492,498],[435,480,499,523],[435,480,488,492,500,512],[435,445,449,480,523],[435,445,480,512,523],[435,440,480],[435,442,445,480,523],[435,480,500,520],[435,480,530],[435,440,480,530],[435,442,445,480,500,523],[435,437,438,439,441,444,480,492,512,523],[435,445,453,480],[435,438,443,480],[435,445,469,470,480],[435,438,441,445,480,515,523,530],[435,445,480],[435,437,480],[435,440,441,442,443,444,445,446,447,449,450,451,452,453,454,455,456,457,458,459,460,461,462,463,464,465,466,467,468,470,471,472,473,474,480],[435,445,462,465,480,488],[435,445,453,454,455,480],[435,443,445,454,456,480],[435,444,480],[435,438,440,445,480],[435,445,449,454,456,480],[435,449,480],[435,443,445,448,480,523],[435,438,442,445,453,480],[435,445,462,480],[435,440,445,469,480,515,528,530],[435,480,501],[435,480,502],[435,479,480,503],[435,477,478,479,480,481,482,483,484,485,486,487,488,489,490,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529],[435,480,505],[435,480,506],[435,480,492,507,508],[435,480,507,509,524,526],[435,480,492,512,513,515],[435,480,514,515],[435,480,512,513],[435,480,515],[435,480,516],[435,477,480,512],[435,480,492,518,519],[435,480,518,519],[435,480,485,500,512,520],[435,480,521],[480],[432,433,434,435,476,477,478,479,480,481,482,483,484,485,486,487,488,489,490,491,492,493,494,495,496,497,498,499,500,501,502,503,504,505,506,507,508,509,510,511,512,513,514,515,516,517,518,519,520,521,522,523,524,525,526,527,528,529],[435,480,500,522],[435,480,495,506,523],[435,480,485,524],[435,480,512,525],[435,480,499,526],[435,480,527],[435,480,492,494,503,512,515,523,525,526,528],[435,480,512,529],[435,480,495,615],[435,480,535,537,539,614],[435,480,493,512,530,531],[435,480,495,530,532,536],[435,480,637,643],[435,480,641],[435,480,638,642],[435,480,492,512,520,601,602,603],[435,480,640],[435,480,596],[435,480,492,530,595,597,598],[435,480,599,600],[435,480,595],[425,430,435,480],[431,435,480,635],[431,435,480,593,632,634],[427,428,435,480],[428,429,435,480],[430,435,480,632],[435,480,633],[131,290,435,480],[131,290,374,435,480],[290,381,382,435,480],[131,290,306,381,435,480],[131,290,378,381,435,480],[290,393,435,480],[131,290,306,390,392,435,480],[131,290,306,389,435,480],[131,306,435,480],[131,290,306,372,435,480],[131,192,290,296,435,480],[131,290,293,295,435,480],[131,290,296,435,480],[131,260,308,309,310,311,312,313,314,315,316,320,321,322,323,324,325,326,327,328,341,435,480],[426,435,480,553,593],[426,435,480,540,553,593,607,613,616,632],[435,480,540,553,593,594,619,632],[430],[431,635],[632]],"referencedMap":[[419,1],[418,2],[415,3],[399,4],[404,5],[405,5],[406,5],[407,5],[408,5],[409,6],[410,5],[411,5],[412,5],[413,5],[420,7],[414,8],[416,9],[425,10],[401,11],[400,12],[402,13],[403,14],[422,15],[423,16],[424,17],[417,18],[421,19],[398,20],[344,12],[348,21],[345,22],[346,22],[347,22],[351,23],[350,24],[352,25],[366,26],[349,27],[365,28],[368,29],[367,12],[378,8],[376,30],[377,12],[397,31],[383,32],[384,32],[382,33],[385,33],[381,34],[379,35],[380,36],[386,12],[387,8],[394,37],[393,38],[391,8],[392,39],[395,40],[389,41],[390,42],[388,42],[396,8],[138,8],[139,8],[181,43],[180,44],[140,8],[141,8],[142,8],[143,8],[144,8],[145,8],[146,8],[155,45],[156,8],[157,12],[158,8],[159,8],[160,8],[161,8],[149,12],[162,12],[163,8],[148,46],[150,47],[147,8],[151,46],[152,47],[153,48],[179,49],[164,8],[165,47],[166,8],[167,8],[168,12],[169,8],[170,8],[171,8],[172,8],[173,8],[174,8],[175,50],[176,8],[177,8],[154,8],[178,8],[216,25],[217,25],[220,51],[219,52],[218,8],[230,53],[221,25],[223,54],[222,8],[225,55],[224,12],[226,56],[227,56],[228,57],[229,58],[375,59],[372,60],[373,61],[370,12],[369,12],[374,62],[371,63],[292,19],[293,64],[297,65],[296,66],[298,67],[295,8],[273,68],[274,12],[306,69],[299,70],[300,12],[301,71],[302,71],[304,72],[303,71],[305,19],[289,73],[275,8],[290,74],[277,75],[276,8],[284,76],[279,77],[280,77],[285,8],[281,77],[278,8],[286,77],[283,77],[282,8],[287,8],[288,8],[329,8],[330,12],[333,78],[341,79],[334,12],[335,12],[336,12],[337,12],[338,12],[339,12],[340,12],[294,80],[307,81],[291,82],[342,83],[231,8],[232,84],[235,85],[237,86],[236,8],[238,85],[239,85],[241,87],[233,8],[240,8],[234,12],[252,88],[251,89],[253,27],[254,12],[258,90],[255,8],[256,8],[257,91],[250,8],[214,92],[198,8],[212,93],[213,8],[215,94],[259,95],[354,96],[353,8],[355,12],[361,8],[356,8],[357,8],[358,8],[362,8],[364,97],[359,8],[360,8],[363,8],[324,8],[260,8],[308,98],[309,99],[310,12],[311,100],[312,12],[313,12],[314,12],[315,8],[316,98],[317,8],[319,101],[320,102],[318,8],[321,12],[322,12],[343,103],[323,12],[325,12],[326,98],[327,12],[328,12],[137,104],[243,105],[245,106],[246,107],[244,8],[247,12],[248,12],[249,108],[242,12],[261,12],[263,8],[262,109],[264,110],[265,111],[266,109],[267,109],[268,112],[272,113],[269,109],[270,112],[271,12],[132,8],[133,114],[134,8],[135,114],[136,115],[62,116],[63,117],[65,12],[78,118],[79,119],[76,120],[77,121],[64,12],[80,122],[83,123],[85,124],[86,125],[68,126],[87,12],[91,127],[89,128],[90,12],[84,12],[93,129],[69,130],[95,131],[96,132],[98,133],[97,134],[99,135],[94,136],[92,137],[100,138],[101,139],[105,140],[106,141],[104,142],[82,143],[70,12],[73,144],[107,145],[108,146],[109,146],[66,12],[111,147],[110,146],[131,104],[71,12],[75,148],[112,149],[113,12],[67,12],[103,150],[119,151],[118,152],[115,12],[116,153],[117,12],[114,154],[102,155],[120,156],[121,157],[122,123],[123,123],[124,158],[88,12],[126,159],[127,160],[81,12],[128,12],[129,161],[125,12],[72,162],[74,137],[130,116],[193,70],[194,8],[197,163],[195,8],[196,8],[188,8],[189,164],[186,165],[187,166],[185,167],[183,8],[184,8],[192,95],[190,12],[191,8],[182,104],[632,168],[631,169],[613,170],[607,171],[593,171],[427,171],[612,172],[610,173],[611,174],[619,175],[617,173],[618,174],[609,176],[594,177],[579,178],[578,179],[555,180],[580,12],[592,181],[581,178],[577,182],[554,183],[556,184],[557,185],[558,12],[582,178],[583,178],[560,186],[584,178],[585,178],[561,187],[562,178],[563,188],[566,189],[567,187],[568,190],[569,183],[570,191],[559,185],[571,178],[586,178],[587,192],[588,178],[589,178],[565,193],[572,184],[564,185],[573,178],[574,190],[575,178],[576,190],[590,178],[591,179],[543,194],[545,195],[552,173],[547,12],[548,12],[546,196],[549,197],[541,12],[542,12],[553,174],[544,198],[550,12],[551,199],[620,200],[605,173],[606,174],[608,201],[426,12],[637,12],[640,202],[639,12],[204,12],[208,12],[199,12],[200,12],[201,12],[202,12],[211,203],[205,204],[206,8],[207,205],[210,12],[209,8],[203,104],[332,206],[331,12],[539,207],[538,208],[535,209],[540,210],[536,12],[645,211],[630,212],[623,213],[627,214],[625,215],[628,216],[626,217],[629,218],[624,12],[622,219],[621,220],[531,12],[477,221],[478,221],[479,222],[480,223],[481,224],[482,225],[433,12],[483,226],[484,227],[485,228],[486,229],[487,230],[488,231],[489,231],[491,12],[490,232],[492,233],[493,234],[494,235],[476,236],[495,237],[496,238],[497,239],[498,240],[499,241],[500,242],[453,243],[464,244],[451,243],[465,112],[474,245],[443,246],[442,247],[473,248],[468,249],[472,250],[445,251],[461,252],[444,253],[471,254],[440,255],[441,249],[446,256],[447,12],[452,246],[450,256],[438,257],[475,258],[466,259],[456,260],[455,256],[457,261],[459,262],[454,263],[458,264],[469,248],[448,265],[449,266],[460,267],[439,112],[463,268],[462,256],[467,12],[437,12],[470,269],[501,270],[502,271],[503,272],[504,273],[505,274],[506,275],[507,276],[508,276],[509,277],[510,12],[511,12],[512,278],[514,279],[513,280],[515,281],[516,282],[517,283],[518,284],[519,285],[520,286],[521,287],[435,288],[432,12],[434,12],[530,289],[522,290],[523,291],[524,292],[525,293],[526,294],[527,295],[528,296],[529,297],[616,298],[614,209],[615,299],[533,12],[534,12],[532,300],[537,301],[646,12],[436,12],[638,12],[644,302],[642,303],[643,304],[604,305],[602,12],[603,12],[641,306],[597,307],[599,308],[595,12],[598,307],[600,12],[601,309],[596,310],[60,12],[61,12],[10,12],[11,12],[14,12],[13,12],[2,12],[15,12],[16,12],[17,12],[18,12],[19,12],[20,12],[21,12],[22,12],[3,12],[23,12],[4,12],[24,12],[28,12],[25,12],[26,12],[27,12],[29,12],[30,12],[31,12],[5,12],[32,12],[33,12],[34,12],[35,12],[6,12],[39,12],[36,12],[37,12],[38,12],[40,12],[7,12],[41,12],[46,12],[47,12],[42,12],[43,12],[44,12],[45,12],[8,12],[51,12],[48,12],[49,12],[50,12],[52,12],[9,12],[53,12],[54,12],[55,12],[58,12],[56,12],[57,12],[1,12],[59,12],[12,12],[431,311],[636,312],[635,313],[429,314],[430,315],[428,12],[633,316],[634,317]],"exportedModulesMap":[[419,1],[418,2],[415,3],[399,4],[404,5],[405,5],[406,5],[407,5],[408,5],[409,6],[410,5],[411,5],[412,5],[413,5],[420,7],[414,8],[416,9],[425,10],[401,11],[400,12],[402,13],[403,14],[422,15],[423,16],[424,17],[417,18],[421,318],[398,20],[344,12],[348,21],[345,22],[346,22],[347,22],[351,23],[350,24],[352,25],[366,26],[349,27],[365,28],[368,29],[367,12],[378,8],[376,319],[377,12],[397,31],[383,320],[384,320],[382,321],[385,321],[381,34],[379,35],[380,322],[386,12],[387,8],[394,323],[393,324],[391,8],[392,39],[395,325],[389,41],[390,42],[388,42],[396,8],[138,8],[139,8],[181,43],[180,44],[140,8],[141,8],[142,8],[143,8],[144,8],[145,8],[146,8],[155,45],[156,8],[157,12],[158,8],[159,8],[160,8],[161,8],[149,12],[162,12],[163,8],[148,46],[150,47],[147,8],[151,46],[152,47],[153,48],[179,49],[164,8],[165,47],[166,8],[167,8],[168,12],[169,8],[170,8],[171,8],[172,8],[173,8],[174,8],[175,50],[176,8],[177,8],[154,8],[178,8],[216,25],[217,25],[220,51],[219,52],[218,8],[230,53],[221,25],[223,54],[222,8],[225,55],[224,12],[226,56],[227,56],[228,57],[229,58],[375,59],[372,326],[373,327],[370,12],[369,12],[374,62],[371,63],[292,318],[293,64],[297,328],[296,329],[298,330],[295,8],[273,68],[274,12],[306,69],[299,70],[300,12],[301,71],[302,71],[304,72],[303,71],[305,318],[289,73],[275,8],[290,74],[277,75],[276,8],[284,76],[279,77],[280,77],[285,8],[281,77],[278,8],[286,77],[283,77],[282,8],[287,8],[288,8],[329,8],[330,12],[333,78],[341,79],[334,12],[335,12],[336,12],[337,12],[338,12],[339,12],[340,12],[294,80],[307,81],[291,82],[342,83],[231,8],[232,84],[235,85],[237,86],[236,8],[238,85],[239,85],[241,87],[233,8],[240,8],[234,12],[252,88],[251,89],[253,27],[254,12],[258,90],[255,8],[256,8],[257,91],[250,8],[214,92],[198,8],[212,93],[213,8],[215,94],[259,95],[354,96],[353,8],[355,12],[361,8],[356,8],[357,8],[358,8],[362,8],[364,97],[359,8],[360,8],[363,8],[324,8],[260,8],[308,81],[309,99],[310,12],[311,100],[312,12],[313,12],[314,12],[315,8],[316,81],[317,8],[319,101],[320,102],[318,8],[321,12],[322,12],[343,331],[323,12],[325,12],[326,81],[327,12],[328,12],[137,104],[243,105],[245,106],[246,107],[244,8],[247,12],[248,12],[249,108],[242,12],[261,12],[263,8],[262,109],[264,110],[265,111],[266,109],[267,109],[268,112],[272,113],[269,109],[270,112],[271,12],[132,8],[133,114],[134,8],[135,114],[136,115],[62,116],[63,117],[65,12],[78,118],[79,119],[76,120],[77,121],[64,12],[80,122],[83,123],[85,124],[86,125],[68,126],[87,12],[91,127],[89,128],[90,12],[84,12],[93,129],[69,130],[95,131],[96,132],[98,133],[97,134],[99,135],[94,136],[92,137],[100,138],[101,139],[105,140],[106,141],[104,142],[82,143],[70,12],[73,144],[107,145],[108,146],[109,146],[66,12],[111,147],[110,146],[131,104],[71,12],[75,148],[112,149],[113,12],[67,12],[103,150],[119,151],[118,152],[115,12],[116,153],[117,12],[114,154],[102,155],[120,156],[121,157],[122,123],[123,123],[124,158],[88,12],[126,159],[127,160],[81,12],[128,12],[129,161],[125,12],[72,162],[74,137],[130,116],[193,70],[194,8],[197,163],[195,8],[196,8],[188,8],[189,164],[186,165],[187,166],[185,167],[183,8],[184,8],[192,95],[190,12],[191,8],[182,104],[632,168],[631,169],[613,170],[607,171],[593,171],[427,171],[612,332],[610,173],[611,174],[619,333],[617,173],[618,174],[609,176],[594,177],[579,178],[578,179],[555,180],[580,12],[592,181],[581,178],[577,182],[554,183],[556,184],[557,185],[558,12],[582,178],[583,178],[560,186],[584,178],[585,178],[561,187],[562,178],[563,188],[566,189],[567,187],[568,190],[569,183],[570,191],[559,185],[571,178],[586,178],[587,192],[588,178],[589,178],[565,193],[572,184],[564,185],[573,178],[574,190],[575,178],[576,190],[590,178],[591,179],[543,194],[545,195],[552,173],[547,12],[548,12],[546,196],[549,197],[541,12],[542,12],[553,174],[544,198],[550,12],[551,199],[620,334],[605,173],[606,174],[608,201],[426,12],[637,12],[640,202],[639,12],[204,12],[208,12],[199,12],[200,12],[201,12],[202,12],[211,203],[205,204],[206,8],[207,205],[210,12],[209,8],[203,104],[332,206],[331,12],[539,207],[538,208],[535,209],[540,210],[536,12],[645,211],[630,212],[623,213],[627,214],[625,215],[628,216],[626,217],[629,218],[624,12],[622,219],[621,220],[531,12],[477,221],[478,221],[479,222],[480,223],[481,224],[482,225],[433,12],[483,226],[484,227],[485,228],[486,229],[487,230],[488,231],[489,231],[491,12],[490,232],[492,233],[493,234],[494,235],[476,236],[495,237],[496,238],[497,239],[498,240],[499,241],[500,242],[453,243],[464,244],[451,243],[465,112],[474,245],[443,246],[442,247],[473,248],[468,249],[472,250],[445,251],[461,252],[444,253],[471,254],[440,255],[441,249],[446,256],[447,12],[452,246],[450,256],[438,257],[475,258],[466,259],[456,260],[455,256],[457,261],[459,262],[454,263],[458,264],[469,248],[448,265],[449,266],[460,267],[439,112],[463,268],[462,256],[467,12],[437,12],[470,269],[501,270],[502,271],[503,272],[504,273],[505,274],[506,275],[507,276],[508,276],[509,277],[510,12],[511,12],[512,278],[514,279],[513,280],[515,281],[516,282],[517,283],[518,284],[519,285],[520,286],[521,287],[435,288],[432,12],[434,12],[530,289],[522,290],[523,291],[524,292],[525,293],[526,294],[527,295],[528,296],[529,297],[616,298],[614,209],[615,299],[533,12],[534,12],[532,300],[537,301],[646,12],[436,12],[638,12],[644,302],[642,303],[643,304],[604,305],[602,12],[603,12],[641,306],[597,307],[599,308],[595,12],[598,307],[600,12],[601,309],[596,310],[60,12],[61,12],[10,12],[11,12],[14,12],[13,12],[2,12],[15,12],[16,12],[17,12],[18,12],[19,12],[20,12],[21,12],[22,12],[3,12],[23,12],[4,12],[24,12],[28,12],[25,12],[26,12],[27,12],[29,12],[30,12],[31,12],[5,12],[32,12],[33,12],[34,12],[35,12],[6,12],[39,12],[36,12],[37,12],[38,12],[40,12],[7,12],[41,12],[46,12],[47,12],[42,12],[43,12],[44,12],[45,12],[8,12],[51,12],[48,12],[49,12],[50,12],[52,12],[9,12],[53,12],[54,12],[55,12],[58,12],[56,12],[57,12],[1,12],[59,12],[12,12],[431,335],[636,336],[635,337],[429,314],[430,315],[428,12],[633,316],[634,317]],"semanticDiagnosticsPerFile":[419,418,415,399,404,405,406,407,408,409,410,411,412,413,420,414,416,425,401,400,402,403,422,423,424,417,421,398,344,348,345,346,347,351,350,352,366,349,365,368,367,378,376,377,397,383,384,382,385,381,379,380,386,387,394,393,391,392,395,389,390,388,396,138,139,181,180,140,141,142,143,144,145,146,155,156,157,158,159,160,161,149,162,163,148,150,147,151,152,153,179,164,165,166,167,168,169,170,171,172,173,174,175,176,177,154,178,216,217,220,219,218,230,221,223,222,225,224,226,227,228,229,375,372,373,370,369,374,371,292,293,297,296,298,295,273,274,306,299,300,301,302,304,303,305,289,275,290,277,276,284,279,280,285,281,278,286,283,282,287,288,329,330,333,341,334,335,336,337,338,339,340,294,307,291,342,231,232,235,237,236,238,239,241,233,240,234,252,251,253,254,258,255,256,257,250,214,198,212,213,215,259,354,353,355,361,356,357,358,362,364,359,360,363,324,260,308,309,310,311,312,313,314,315,316,317,319,320,318,321,322,343,323,325,326,327,328,137,243,245,246,244,247,248,249,242,261,263,262,264,265,266,267,268,272,269,270,271,132,133,134,135,136,62,63,65,78,79,76,77,64,80,83,85,86,68,87,91,89,90,84,93,69,95,96,98,97,99,94,92,100,101,105,106,104,82,70,73,107,108,109,66,111,110,131,71,75,112,113,67,103,119,118,115,116,117,114,102,120,121,122,123,124,88,126,127,81,128,129,125,72,74,130,193,194,197,195,196,188,189,186,187,185,183,184,192,190,191,182,632,631,613,607,593,427,612,610,611,619,617,618,609,594,579,578,555,580,592,581,577,554,556,557,558,582,583,560,584,585,561,562,563,566,567,568,569,570,559,571,586,587,588,589,565,572,564,573,574,575,576,590,591,543,545,552,547,548,546,549,541,542,553,544,550,551,620,605,606,608,426,637,640,639,204,208,199,200,201,202,211,205,206,207,210,209,203,332,331,539,538,535,540,536,645,630,623,627,625,628,626,629,624,622,621,531,477,478,479,480,481,482,433,483,484,485,486,487,488,489,491,490,492,493,494,476,495,496,497,498,499,500,453,464,451,465,474,443,442,473,468,472,445,461,444,471,440,441,446,447,452,450,438,475,466,456,455,457,459,454,458,469,448,449,460,439,463,462,467,437,470,501,502,503,504,505,506,507,508,509,510,511,512,514,513,515,516,517,518,519,520,521,435,432,434,530,522,523,524,525,526,527,528,529,616,614,615,533,534,532,537,646,436,638,644,642,643,604,602,603,641,597,599,595,598,600,601,596,60,61,10,11,14,13,2,15,16,17,18,19,20,21,22,3,23,4,24,28,25,26,27,29,30,31,5,32,33,34,35,6,39,36,37,38,40,7,41,46,47,42,43,44,45,8,51,48,49,50,52,9,53,54,55,58,56,57,1,59,12,431,636,635,429,430,428,633,634]},"version":"5.4.5"} \ No newline at end of file diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/report.api.md index 2c2addc9001..63b634eaf3d 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/report.api.md @@ -4,10 +4,10 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; -import { ChatMessage } from '@backstage-community/plugin-mcp-chat-backend'; -import { ChatResponse } from '@backstage-community/plugin-mcp-chat-backend'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-backend'; -import { Tool } from '@backstage-community/plugin-mcp-chat-backend'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; +import { Tool } from '@backstage-community/plugin-mcp-chat-common'; // @public export class ClaudeProvider extends LLMProvider { diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend/report.api.md index 376a0dfafec..1ceff286f45 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/report.api.md @@ -4,14 +4,27 @@ ```ts import { BackendFeature } from '@backstage/backend-plugin-api'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { Config } from '@backstage/config'; +import { ConversationRecord } from '@backstage-community/plugin-mcp-chat-common'; import { DatabaseService } from '@backstage/backend-plugin-api'; import express from 'express'; -import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { HttpAuthService } from '@backstage/backend-plugin-api'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; +import { LlmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; +import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; import { LoggerService } from '@backstage/backend-plugin-api'; +import { MCPServer } from '@backstage-community/plugin-mcp-chat-common'; +import { MCPServerFullConfig } from '@backstage-community/plugin-mcp-chat-common'; +import { MCPServerStatusData } from '@backstage-community/plugin-mcp-chat-common'; +import { MessageValidationResult } from '@backstage-community/plugin-mcp-chat-common'; +import { ProviderStatusData } from '@backstage-community/plugin-mcp-chat-common'; +import { QueryResponse } from '@backstage-community/plugin-mcp-chat-common'; import { RootConfigService } from '@backstage/backend-plugin-api'; +import { ServerTool } from '@backstage-community/plugin-mcp-chat-common'; +import { ToolCall } from '@backstage-community/plugin-mcp-chat-common'; +import { ToolExecutionResult } from '@backstage-community/plugin-mcp-chat-common'; // @public export class ChatConversationStore { @@ -48,44 +61,6 @@ export interface ChatConversationStoreOptions { logger: LoggerService; } -// @public -export interface ChatMessage { - content: string | null; - role: 'system' | 'user' | 'assistant' | 'tool'; - tool_call_id?: string; - tool_calls?: ToolCall[]; -} - -// @public -export interface ChatResponse { - choices: [ - { - message: { - role: 'assistant'; - content: string | null; - tool_calls?: ToolCall[]; - }; - }, - ]; - usage?: { - prompt_tokens: number; - completion_tokens: number; - total_tokens: number; - }; -} - -// @public -export interface ConversationRecord { - createdAt: Date; - id: string; - isStarred: boolean; - messages: ChatMessage[]; - title?: string; - toolsUsed?: string[]; - updatedAt: Date; - userId: string; -} - // @public export function createRouter(options: RouterOptions): Promise; @@ -99,67 +74,11 @@ export function executeToolCall( // @public export function findNpxPath(): Promise; -// @public -export abstract class LLMProvider { - constructor(config: ProviderConfig); - // (undocumented) - protected apiKey?: string; - // (undocumented) - protected baseUrl: string; - // (undocumented) - protected abstract formatRequest( - messages: ChatMessage[], - tools?: Tool[], - ): any; - getBaseUrl(): string; - // (undocumented) - protected abstract getHeaders(): Record; - getLastResponseOutput(): any; - getModel(): string; - getType(): string; - // (undocumented) - protected logger?: LoggerService; - // (undocumented) - protected makeRequest(endpoint: string, body: any): Promise; - // (undocumented) - protected model: string; - // (undocumented) - protected abstract parseResponse(response: any): ChatResponse; - // (undocumented) - abstract sendMessage( - messages: ChatMessage[], - tools?: Tool[], - ): Promise; - setMcpServerConfigs(_configs: MCPServerFullConfig[]): void; - supportsNativeMcp(): boolean; - // (undocumented) - abstract testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; - // (undocumented) - protected truncateForLogging(data: string, maxLength?: number): string; - // (undocumented) - protected type: string; -} +export { LLMProvider }; -// @public -export interface LlmProviderExtensionPoint { - registerProvider(type: string, provider: LLMProvider): void; -} - -// @public -export const llmProviderExtensionPoint: ExtensionPoint; +export { LlmProviderExtensionPoint }; -// @public -export type LLMProviderType = - | 'openai' - | 'openai-responses' - | 'claude' - | 'gemini' - | 'ollama' - | 'litellm'; +export { llmProviderExtensionPoint }; // @public export function loadServerConfigs( @@ -207,185 +126,6 @@ export type MCPClientServiceOptions = { provider: LLMProvider; }; -// @public -export type MCPServer = MCPServerConfig & { - status: { - valid: boolean; - connected: boolean; - error?: string; - }; -}; - -// @public -export interface MCPServerConfig { - args?: string[]; - id: string; - name: string; - npxCommand?: string; - scriptPath?: string; - type: MCPServerType; - url?: string; -} - -// @public -export type MCPServerFullConfig = MCPServerConfig & MCPServerSecrets; - -// @public -export interface MCPServerSecrets { - env?: Record; - headers?: Record; -} - -// @public -export interface MCPServerStatusData { - active: number; - servers: MCPServer[]; - timestamp: string; - total: number; - valid: number; -} - -// @public -export enum MCPServerType { - // (undocumented) - STDIO = 'stdio', - // (undocumented) - STREAMABLE_HTTP = 'streamable-http', -} - -// @public -export interface MessageValidationResult { - error?: string; - isValid: boolean; -} - -// @public -export interface ProviderConfig { - apiKey?: string; - auth?: Record; - baseUrl: string; - logger?: LoggerService; - model: string; - type: string; -} - -// @public -export interface ProviderConnectionStatus { - connected: boolean; - error?: string; - models?: string[]; -} - -// @public -export interface ProviderInfo { - baseUrl: string; - connection: ProviderConnectionStatus; - id: string; - model: string; -} - -// @public -export interface ProviderStatusData { - providers: ProviderInfo[]; - summary: { - totalProviders: number; - healthyProviders: number; - error?: string; - }; - timestamp: string; -} - -// @public -export interface QueryResponse { - reply: string; - toolCalls: ToolCall[]; - toolResponses: ToolExecutionResult[]; -} - -// @public -export interface ResponsesApiMcpCall { - arguments: string; - error: string | null; - id: string; - name: string; - output: string; - server_label: string; - type: 'mcp_call'; -} - -// @public -export interface ResponsesApiMcpListTools { - id: string; - server_label: string; - tools: Array<{ - name: string; - description: string; - input_schema: Record; - }>; - type: 'mcp_list_tools'; -} - -// @public -export interface ResponsesApiMcpTool { - allowed_tools?: string[]; - headers?: Record; - require_approval: 'never' | 'always' | 'auto'; - server_label: string; - server_url: string; - type: 'mcp'; -} - -// @public -export interface ResponsesApiMessage { - content: Array<{ - type: 'output_text'; - text: string; - annotations?: unknown[]; - }>; - id: string; - role: 'assistant'; - status: 'completed' | 'failed'; - type: 'message'; -} - -// @public -export type ResponsesApiOutputEvent = - | ResponsesApiMcpListTools - | ResponsesApiMcpCall - | ResponsesApiMessage; - -// @public -export interface ResponsesApiResponse { - created_at: number; - error?: string | null; - id: string; - instructions?: string | null; - model: string; - object: 'response'; - output: ResponsesApiOutputEvent[]; - parallel_tool_calls?: boolean; - previous_response_id?: string | null; - status: 'completed' | 'failed' | 'cancelled'; - temperature?: number | null; - text?: { - format: { - type: string; - }; - }; - tools?: ResponsesApiMcpTool[]; - top_p?: number | null; - truncation?: unknown; - usage?: { - input_tokens: number; - output_tokens: number; - total_tokens: number; - input_tokens_details?: { - cached_tokens: number; - }; - output_tokens_details?: unknown; - }; -} - // @public export interface RouterOptions { // (undocumented) @@ -400,11 +140,6 @@ export interface RouterOptions { summarizationService: SummarizationService; } -// @public -export interface ServerTool extends Tool { - serverId: string; -} - // @public export class SummarizationService { constructor(options: SummarizationServiceOptions); @@ -421,38 +156,6 @@ export interface SummarizationServiceOptions { mcpClientService: MCPClientService; } -// @public -export interface Tool { - function: { - name: string; - description: string; - parameters: Record; - }; - type: 'function'; -} - -// @public -export interface ToolCall { - function: { - name: string; - arguments: string; - }; - id: string; - type: 'function'; -} - -// @public -export interface ToolExecutionResult { - arguments: Record; - id: string; - name: string; - result: string; - serverId: string; -} - -// @public -export const VALID_ROLES: readonly ['user', 'assistant', 'system', 'tool']; - // @public export const validateConfig: (config: RootConfigService) => void; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/index.ts index 95ebfd170fb..d9e6f696fa1 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/index.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/index.ts @@ -49,53 +49,6 @@ export { type SummarizationServiceOptions, } from './services/SummarizationService'; -// ============================================================================= -// Types -// ============================================================================= -export type { - // Provider types - ProviderConfig, - ProviderStatusData, - ProviderInfo, - ProviderConnectionStatus, - LLMProviderType, - - // MCP Server types - MCPServerConfig, - MCPServerSecrets, - MCPServerFullConfig, - MCPServer, - MCPServerStatusData, - - // Chat types - ChatMessage, - ChatResponse, - QueryResponse, - - // Tool types - Tool, - ToolCall, - ServerTool, - ToolExecutionResult, - - // Validation types - MessageValidationResult, - - // Conversation types - ConversationRecord, - - // OpenAI Responses API types - ResponsesApiMcpTool, - ResponsesApiMcpListTools, - ResponsesApiMcpCall, - ResponsesApiMessage, - ResponsesApiResponse, - ResponsesApiOutputEvent, -} from './types'; - -// Enums and Constants -export { MCPServerType, VALID_ROLES } from './types'; - // ============================================================================= // Utilities // ============================================================================= diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.test.ts index 27a6e54d394..9deb69a2cbb 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.test.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.test.ts @@ -18,7 +18,7 @@ import { mcpChatPlugin } from './plugin'; import { llmProviderExtensionPoint } from './extensions'; import request from 'supertest'; import { TestBackend } from '@backstage/backend-test-utils'; -import { MCPServerType } from './types'; +import { MCPServerType } from '@backstage-community/plugin-mcp-chat-common'; import { createBackendModule } from '@backstage/backend-plugin-api'; jest.mock('./services/MCPClientServiceImpl', () => ({ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/router.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/router.test.ts index 58b7ae66a85..9660eeab626 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/router.test.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/router.test.ts @@ -21,7 +21,7 @@ import { createRouter } from './router'; import { MCPClientService } from './services/MCPClientService'; import { ChatConversationStore } from './services/ChatConversationStore'; import { SummarizationService } from './services/SummarizationService'; -import { MCPServerType } from './types'; +import { MCPServerType } from '@backstage-community/plugin-mcp-chat-common'; describe('createRouter', () => { let app: express.Express; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/ChatConversationStore.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/ChatConversationStore.test.ts index c294bf4594d..37558125f6c 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/ChatConversationStore.test.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/ChatConversationStore.test.ts @@ -17,7 +17,10 @@ import { mockServices } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { ChatConversationStore } from './ChatConversationStore'; -import { ChatMessage, ConversationRow } from '../types'; +import { + ChatMessage, + ConversationRow, +} from '@backstage-community/plugin-mcp-chat-common'; // Helper to create a mock Knex query builder const createMockQueryBuilder = () => { diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/ChatConversationStore.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/ChatConversationStore.ts index b4a7ce616d9..8f79bdcb15b 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/ChatConversationStore.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/ChatConversationStore.ts @@ -22,7 +22,11 @@ import { resolvePackagePath, } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; -import { ChatMessage, ConversationRecord, ConversationRow } from '../types'; +import { + ChatMessage, + ConversationRecord, + ConversationRow, +} from '@backstage-community/plugin-mcp-chat-common'; const TABLE_NAME = 'mcp_chat_conversations'; const DEFAULT_DISPLAY_LIMIT = 10; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientService.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientService.ts index 6a7437acd1f..d9c11e064c9 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientService.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientService.ts @@ -21,7 +21,7 @@ import { ProviderStatusData, QueryResponse, ServerTool, -} from '../types'; +} from '@backstage-community/plugin-mcp-chat-common'; /** * Service interface for MCP (Model Context Protocol) client operations. diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.test.ts index 3031c7a1656..7bc955a61b7 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.test.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.test.ts @@ -16,7 +16,11 @@ import { mockServices } from '@backstage/backend-test-utils'; import { MCPClientServiceImpl } from './MCPClientServiceImpl'; -import { ChatResponse, ToolCall, MCPServerType } from '../types'; +import { + ChatResponse, + ToolCall, + MCPServerType, +} from '@backstage-community/plugin-mcp-chat-common'; jest.mock('@modelcontextprotocol/sdk/client/index.js'); jest.mock('@modelcontextprotocol/sdk/client/streamableHttp.js'); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.ts index 12344daff64..ac3fff064d6 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.ts @@ -35,7 +35,7 @@ import { MCPServerType, MCPServerFullConfig, ResponsesApiMcpCall, -} from '../types'; +} from '@backstage-community/plugin-mcp-chat-common'; /** * Options for creating an MCPClientServiceImpl instance. diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/SummarizationService.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/SummarizationService.test.ts index 82a2baf20b5..b95eed9e7d3 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/SummarizationService.test.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/SummarizationService.test.ts @@ -18,7 +18,7 @@ import { mockServices } from '@backstage/backend-test-utils'; import { ConfigReader } from '@backstage/config'; import { SummarizationService } from './SummarizationService'; import { MCPClientService } from './MCPClientService'; -import { ChatMessage } from '../types'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; describe('SummarizationService', () => { let service: SummarizationService; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/SummarizationService.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/SummarizationService.ts index ec532024559..27e9a8796f0 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/SummarizationService.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/SummarizationService.ts @@ -17,7 +17,7 @@ import { LoggerService } from '@backstage/backend-plugin-api'; import { Config } from '@backstage/config'; import { MCPClientService } from './MCPClientService'; -import { ChatMessage } from '../types'; +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; /** Default timeout for summarization requests in milliseconds */ const DEFAULT_SUMMARIZE_TIMEOUT = 3000; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/types.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/types.ts deleted file mode 100644 index bdbd7a2b8b6..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/types.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Re-exports all shared types from the common package for backward compatibility. - * New consumers should import directly from `@backstage-community/plugin-mcp-chat-common`. - */ -export { - // Constants and Enums - VALID_ROLES, - MCPServerType, - - // LLM Provider Base Class - LLMProvider, - - // Types - type LLMProviderType, - type MCPServerConfig, - type MCPServerSecrets, - type MCPServerFullConfig, - type MCPServer, - type MCPServerStatusData, - type ProviderConfig, - type ProviderInfo, - type ProviderConnectionStatus, - type ProviderStatusData, - type ChatMessage, - type ChatResponse, - type QueryResponse, - type Tool, - type ToolCall, - type ServerTool, - type ToolExecutionResult, - type MessageValidationResult, - type ResponsesApiMcpTool, - type ResponsesApiMcpListTools, - type ResponsesApiMcpCall, - type ResponsesApiMessage, - type ResponsesApiResponse, - type ResponsesApiOutputEvent, - type ConversationRecord, - type ConversationRow, -} from '@backstage-community/plugin-mcp-chat-common'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/utils.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/utils.test.ts index 4032a9c7cca..9dfd5e761c5 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/utils.test.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/utils.test.ts @@ -20,7 +20,7 @@ import { validateConfig, validateMessages, } from './utils'; -import { MCPServerType } from './types'; +import { MCPServerType } from '@backstage-community/plugin-mcp-chat-common'; jest.mock('@modelcontextprotocol/sdk/client/index.js', () => ({ Client: jest.fn(), diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/utils.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/utils.ts index b271c93ed6e..da656bd36da 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/utils.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/utils.ts @@ -25,7 +25,7 @@ import { ServerTool, ToolExecutionResult, MessageValidationResult, -} from './types'; +} from '@backstage-community/plugin-mcp-chat-common'; import { RootConfigService } from '@backstage/backend-plugin-api'; /** diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-common/report.api.md new file mode 100644 index 00000000000..789eeae959e --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/report.api.md @@ -0,0 +1,320 @@ +## API Report File for "@backstage-community/plugin-mcp-chat-common" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +// @public +export interface ChatMessage { + content: string | null; + role: 'system' | 'user' | 'assistant' | 'tool'; + tool_call_id?: string; + tool_calls?: ToolCall[]; +} + +// @public +export interface ChatResponse { + choices: [ + { + message: { + role: 'assistant'; + content: string | null; + tool_calls?: ToolCall[]; + }; + }, + ]; + usage?: { + prompt_tokens: number; + completion_tokens: number; + total_tokens: number; + }; +} + +// @public +export interface ConversationRecord { + createdAt: Date; + id: string; + isStarred: boolean; + messages: ChatMessage[]; + title?: string; + toolsUsed?: string[]; + updatedAt: Date; + userId: string; +} + +// @public +export interface ConversationRow { + created_at: Date; + id: string; + is_starred: boolean; + messages: string; + title: string | null; + tools_used: string | null; + updated_at: Date; + user_id: string; +} + +// @public +export abstract class LLMProvider { + constructor(config: ProviderConfig); + // (undocumented) + protected apiKey?: string; + // (undocumented) + protected baseUrl: string; + // (undocumented) + protected abstract formatRequest( + messages: ChatMessage[], + tools?: Tool[], + ): any; + getBaseUrl(): string; + // (undocumented) + protected abstract getHeaders(): Record; + getLastResponseOutput(): any; + getModel(): string; + getType(): string; + // (undocumented) + protected makeRequest(endpoint: string, body: any): Promise; + // (undocumented) + protected model: string; + // (undocumented) + protected abstract parseResponse(response: any): ChatResponse; + // (undocumented) + abstract sendMessage( + messages: ChatMessage[], + tools?: Tool[], + ): Promise; + setMcpServerConfigs(_configs: MCPServerFullConfig[]): void; + supportsNativeMcp(): boolean; + // (undocumented) + abstract testConnection(): Promise<{ + connected: boolean; + models?: string[]; + error?: string; + }>; + // (undocumented) + protected type: string; +} + +// @public +export type LLMProviderType = + | 'openai' + | 'openai-responses' + | 'claude' + | 'gemini' + | 'ollama' + | 'litellm'; + +// @public +export type MCPServer = MCPServerConfig & { + status: { + valid: boolean; + connected: boolean; + error?: string; + }; +}; + +// @public +export interface MCPServerConfig { + args?: string[]; + id: string; + name: string; + npxCommand?: string; + scriptPath?: string; + type: MCPServerType; + url?: string; +} + +// @public +export type MCPServerFullConfig = MCPServerConfig & MCPServerSecrets; + +// @public +export interface MCPServerSecrets { + env?: Record; + headers?: Record; +} + +// @public +export interface MCPServerStatusData { + active: number; + servers: MCPServer[]; + timestamp: string; + total: number; + valid: number; +} + +// @public +export enum MCPServerType { + // (undocumented) + STDIO = 'stdio', + // (undocumented) + STREAMABLE_HTTP = 'streamable-http', +} + +// @public +export interface MessageValidationResult { + error?: string; + isValid: boolean; +} + +// @public +export interface ProviderConfig { + apiKey?: string; + auth?: Record; + baseUrl: string; + model: string; + type: string; +} + +// @public +export interface ProviderConnectionStatus { + connected: boolean; + error?: string; + models?: string[]; +} + +// @public +export interface ProviderInfo { + baseUrl: string; + connection: ProviderConnectionStatus; + id: string; + model: string; +} + +// @public +export interface ProviderStatusData { + providers: ProviderInfo[]; + summary: { + totalProviders: number; + healthyProviders: number; + error?: string; + }; + timestamp: string; +} + +// @public +export interface QueryResponse { + reply: string; + toolCalls: ToolCall[]; + toolResponses: ToolExecutionResult[]; +} + +// @public +export interface ResponsesApiMcpCall { + arguments: string; + error: string | null; + id: string; + name: string; + output: string; + server_label: string; + type: 'mcp_call'; +} + +// @public +export interface ResponsesApiMcpListTools { + id: string; + server_label: string; + tools: Array<{ + name: string; + description: string; + input_schema: Record; + }>; + type: 'mcp_list_tools'; +} + +// @public +export interface ResponsesApiMcpTool { + allowed_tools?: string[]; + headers?: Record; + require_approval: 'never' | 'always' | 'auto'; + server_label: string; + server_url: string; + type: 'mcp'; +} + +// @public +export interface ResponsesApiMessage { + content: Array<{ + type: 'output_text'; + text: string; + annotations?: unknown[]; + }>; + id: string; + role: 'assistant'; + status: 'completed' | 'failed'; + type: 'message'; +} + +// @public +export type ResponsesApiOutputEvent = + | ResponsesApiMcpListTools + | ResponsesApiMcpCall + | ResponsesApiMessage; + +// @public +export interface ResponsesApiResponse { + created_at: number; + error?: string | null; + id: string; + instructions?: string | null; + model: string; + object: 'response'; + output: ResponsesApiOutputEvent[]; + parallel_tool_calls?: boolean; + previous_response_id?: string | null; + status: 'completed' | 'failed' | 'cancelled'; + temperature?: number | null; + text?: { + format: { + type: string; + }; + }; + tools?: ResponsesApiMcpTool[]; + top_p?: number | null; + truncation?: unknown; + usage?: { + input_tokens: number; + output_tokens: number; + total_tokens: number; + input_tokens_details?: { + cached_tokens: number; + }; + output_tokens_details?: unknown; + }; +} + +// @public +export interface ServerTool extends Tool { + serverId: string; +} + +// @public +export interface Tool { + function: { + name: string; + description: string; + parameters: Record; + }; + type: 'function'; +} + +// @public +export interface ToolCall { + function: { + name: string; + arguments: string; + }; + id: string; + type: 'function'; +} + +// @public +export interface ToolExecutionResult { + arguments: Record; + id: string; + name: string; + result: string; + serverId: string; +} + +// @public +export const VALID_ROLES: readonly ['user', 'assistant', 'system', 'tool']; +``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts b/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts index b4cb4727076..d9d686c1be9 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts @@ -562,7 +562,7 @@ export interface ConversationRecord { * Database row representation of a conversation. * Used internally for database operations. * - * @internal + * @public */ export interface ConversationRow { /** UUID primary key */ From 7af04740a544070f4fafccee3faebadac546ca3c Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Tue, 24 Mar 2026 21:50:44 -0400 Subject: [PATCH 05/17] feat(mcp-chat): manage authentication using backstage integration aws package Signed-off-by: Florian JUDITH --- .../package.json | 4 +- .../report.api.md | 9 ++++- .../src/BedrockProvider.ts | 39 +++++++++++-------- .../src/index.ts | 5 ++- .../src/module.ts | 16 +++++++- .../plugins/mcp-chat/report-alpha.api.md | 2 +- workspaces/mcp-chat/yarn.lock | 4 +- 7 files changed, 55 insertions(+), 24 deletions(-) diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/package.json index 8f63ee9bb18..3088e300686 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/package.json +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/package.json @@ -20,10 +20,12 @@ }, "dependencies": { "@aws-sdk/client-bedrock-runtime": "^3.0.0", + "@aws-sdk/types": "^3.0.0", "@backstage-community/plugin-mcp-chat-common": "workspace:^", "@backstage-community/plugin-mcp-chat-node": "workspace:^", "@backstage/backend-plugin-api": "^1.4.0", - "@backstage/config": "^1.3.0" + "@backstage/config": "^1.3.0", + "@backstage/integration-aws-node": "^0.1.20" }, "devDependencies": { "@backstage/cli": "^0.33.0" diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md index 9c47a191d14..0b9ab0b247c 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md @@ -3,6 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import type { AwsCredentialIdentityProvider } from '@aws-sdk/types'; import { BackendFeature } from '@backstage/backend-plugin-api'; import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; @@ -12,7 +13,7 @@ import { Tool } from '@backstage-community/plugin-mcp-chat-common'; // @public export class BedrockProvider extends LLMProvider { - constructor(config: ProviderConfig); + constructor(config: ProviderConfig, options: BedrockProviderOptions); // (undocumented) protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; // (undocumented) @@ -29,6 +30,12 @@ export class BedrockProvider extends LLMProvider { }>; } +// @public +export interface BedrockProviderOptions { + credentialProvider: AwsCredentialIdentityProvider; + region: string; +} + // @public const _default: BackendFeature; export default _default; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.ts index d6bd5ec16c9..3b7031fac67 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.ts @@ -21,6 +21,7 @@ import { type Message, type ContentBlock, } from '@aws-sdk/client-bedrock-runtime'; +import type { AwsCredentialIdentityProvider } from '@aws-sdk/types'; import { LLMProvider, type ChatMessage, @@ -30,16 +31,28 @@ import { type ToolCall, } from '@backstage-community/plugin-mcp-chat-common'; +/** + * Options for constructing a BedrockProvider with AWS credentials + * resolved via `@backstage/integration-aws-node`. + * + * @public + */ +export interface BedrockProviderOptions { + /** AWS region for the Bedrock Runtime client. */ + region: string; + /** Credential provider resolved from DefaultAwsCredentialsManager. */ + credentialProvider: AwsCredentialIdentityProvider; +} + /** * Amazon Bedrock Converse API provider. * * Uses the AWS SDK Bedrock Runtime client with the Converse API, * which provides a unified interface across all Bedrock foundation models. * - * Authentication is handled via the standard AWS credential chain - * (environment variables, IAM roles, SSO, etc.). Explicit credentials - * can be supplied through the `auth` config record with `accessKeyId`, - * `secretAccessKey`, and optionally `sessionToken`. + * Authentication is handled via `@backstage/integration-aws-node`, + * which resolves credentials from the Backstage `aws` app-config section + * (IAM roles, profiles, static keys, or the default SDK credential chain). * * @public */ @@ -47,22 +60,14 @@ export class BedrockProvider extends LLMProvider { private client: BedrockRuntimeClient; private lastTools?: Tool[]; - constructor(config: ProviderConfig) { + constructor(config: ProviderConfig, options: BedrockProviderOptions) { super(config); - const region = config.auth?.region || 'us-east-1'; - - const clientConfig: Record = { region }; - - if (config.auth?.accessKeyId && config.auth?.secretAccessKey) { - clientConfig.credentials = { - accessKeyId: config.auth.accessKeyId, - secretAccessKey: config.auth.secretAccessKey, - ...(config.auth.sessionToken && { - sessionToken: config.auth.sessionToken, - }), + const clientConfig: ConstructorParameters[0] = + { + region: options.region, + credentialDefaultProvider: () => options.credentialProvider, }; - } if (config.baseUrl) { clientConfig.endpoint = config.baseUrl; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/index.ts index 15a2822168e..0c492f675b3 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/index.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/index.ts @@ -21,4 +21,7 @@ */ export { default } from './module'; -export { BedrockProvider } from './BedrockProvider'; +export { + BedrockProvider, + type BedrockProviderOptions, +} from './BedrockProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/module.ts index de3136ffa7f..aa18542f1f7 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/module.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/module.ts @@ -19,6 +19,7 @@ import { coreServices, } from '@backstage/backend-plugin-api'; import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; +import { DefaultAwsCredentialsManager } from '@backstage/integration-aws-node'; import type { Config } from '@backstage/config'; import { BedrockProvider } from './BedrockProvider'; @@ -61,17 +62,28 @@ export default createBackendModule({ if (!entry) return; // Skip registration if not configured + const auth = readAuthRecord(entry); + const region = auth?.region || 'us-east-1'; + + const credsManager = DefaultAwsCredentialsManager.fromConfig(config); + const credProvider = await credsManager.getCredentialProvider({ + accountId: auth?.accountId, + }); + const providerConfig = { type: 'amazon-bedrock', apiKey: entry.getOptionalString('token'), baseUrl: entry.getOptionalString('baseUrl') || '', model: entry.getString('model'), - auth: readAuthRecord(entry), + auth, }; llmProviders.registerProvider( 'amazon-bedrock', - new BedrockProvider(providerConfig), + new BedrockProvider(providerConfig, { + region, + credentialProvider: credProvider.sdkCredentialProvider, + }), ); }, }); diff --git a/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md b/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md index 096193fb399..20c1e3a190c 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md @@ -55,7 +55,6 @@ const mcpChatPlugin: OverridableFrontendPlugin< path?: string | undefined; }; output: - | ExtensionDataRef | ExtensionDataRef | ExtensionDataRef< RouteRef_2, @@ -64,6 +63,7 @@ const mcpChatPlugin: OverridableFrontendPlugin< optional: true; } > + | ExtensionDataRef | ExtensionDataRef< string, 'core.title', diff --git a/workspaces/mcp-chat/yarn.lock b/workspaces/mcp-chat/yarn.lock index d74d9b37bfe..b5cf27973cc 100644 --- a/workspaces/mcp-chat/yarn.lock +++ b/workspaces/mcp-chat/yarn.lock @@ -1208,7 +1208,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0, @aws-sdk/types@npm:^3.973.6": +"@aws-sdk/types@npm:^3.0.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0, @aws-sdk/types@npm:^3.973.6": version: 3.973.6 resolution: "@aws-sdk/types@npm:3.973.6" dependencies: @@ -1736,11 +1736,13 @@ __metadata: resolution: "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock@workspace:plugins/mcp-chat-backend-module-amazon-bedrock" dependencies: "@aws-sdk/client-bedrock-runtime": "npm:^3.0.0" + "@aws-sdk/types": "npm:^3.0.0" "@backstage-community/plugin-mcp-chat-common": "workspace:^" "@backstage-community/plugin-mcp-chat-node": "workspace:^" "@backstage/backend-plugin-api": "npm:^1.4.0" "@backstage/cli": "npm:^0.33.0" "@backstage/config": "npm:^1.3.0" + "@backstage/integration-aws-node": "npm:^0.1.20" languageName: unknown linkType: soft From 79432a77dfd0a592af6e8f518b7498c5b64edadf Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Tue, 24 Mar 2026 22:05:05 -0400 Subject: [PATCH 06/17] feat(mcp-chat): added tests for amazon bedrock provider Signed-off-by: Florian JUDITH --- .../src/BedrockProvider.test.ts | 238 ++++++++++++++++++ .../plugins/mcp-chat/report-alpha.api.md | 2 +- 2 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.test.ts diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.test.ts new file mode 100644 index 00000000000..63064f9d009 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.test.ts @@ -0,0 +1,238 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BedrockProvider } from './BedrockProvider'; +import type { + ChatMessage, + Tool, + ProviderConfig, +} from '@backstage-community/plugin-mcp-chat-common'; +import type { BedrockProviderOptions } from './BedrockProvider'; + +// Mock the AWS SDK +const mockSend = jest.fn(); +jest.mock('@aws-sdk/client-bedrock-runtime', () => { + const actual = jest.requireActual('@aws-sdk/client-bedrock-runtime'); + return { + ...actual, + BedrockRuntimeClient: jest.fn().mockImplementation(() => ({ + send: mockSend, + })), + ConverseCommand: jest.fn().mockImplementation(input => ({ input })), + }; +}); + +const mockCredentialProvider = jest.fn().mockResolvedValue({ + accessKeyId: 'AKIAV3RY1N53CUR3MOCK', + secretAccessKey: 's4kv3rY1ns3CUR353cr3t4cC355k3y+mocked', +}); + +function createProvider( + configOverrides?: Partial, + optionOverrides?: Partial, +): BedrockProvider { + const config: ProviderConfig = { + type: 'amazon-bedrock', + baseUrl: '', + model: 'us.anthropic.claude-sonnet-4-20250514-v1:0', + ...configOverrides, + }; + const options: BedrockProviderOptions = { + region: 'us-east-1', + credentialProvider: mockCredentialProvider, + ...optionOverrides, + }; + return new BedrockProvider(config, options); +} + +function makeConverseResponse( + content: any[], + usage?: { inputTokens: number; outputTokens: number }, +) { + return { + output: { message: { role: 'assistant', content } }, + usage, + }; +} + +const sampleTool: Tool = { + type: 'function', + function: { + name: 'get_weather', + description: 'Get the weather', + parameters: { type: 'object', properties: { city: { type: 'string' } } }, + }, +}; + +describe('BedrockProvider', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('sends a basic user message and returns parsed response', async () => { + const provider = createProvider(); + mockSend.mockResolvedValueOnce( + makeConverseResponse([{ text: 'Hello there!' }], { + inputTokens: 10, + outputTokens: 5, + }), + ); + + const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; + const result = await provider.sendMessage(messages); + + expect(result.choices[0].message.role).toBe('assistant'); + expect(result.choices[0].message.content).toBe('Hello there!'); + expect(result.usage).toEqual({ + prompt_tokens: 10, + completion_tokens: 5, + total_tokens: 15, + }); + }); + + it('extracts system prompts into the system field', async () => { + const provider = createProvider(); + const { ConverseCommand } = require('@aws-sdk/client-bedrock-runtime'); + mockSend.mockResolvedValueOnce(makeConverseResponse([{ text: 'OK' }])); + + const messages: ChatMessage[] = [ + { role: 'system', content: 'You are helpful.' }, + { role: 'user', content: 'Hi' }, + ]; + await provider.sendMessage(messages); + + const commandInput = ConverseCommand.mock.calls[0][0]; + expect(commandInput.system).toEqual([{ text: 'You are helpful.' }]); + expect(commandInput.messages.every((m: any) => m.role !== 'system')).toBe( + true, + ); + }); + + it('parses tool use response blocks into tool_calls', async () => { + const provider = createProvider(); + mockSend.mockResolvedValueOnce( + makeConverseResponse([ + { + toolUse: { + toolUseId: 'call_123', + name: 'get_weather', + input: { city: 'Seattle' }, + }, + }, + ]), + ); + + const result = await provider.sendMessage( + [{ role: 'user', content: 'Weather in Seattle?' }], + [sampleTool], + ); + + expect(result.choices[0].message.tool_calls).toHaveLength(1); + expect(result.choices[0].message.tool_calls![0]).toEqual({ + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"Seattle"}', + }, + }); + }); + + it('converts tool_calls round-trip and re-attaches toolConfig on follow-up', async () => { + const provider = createProvider(); + const { ConverseCommand } = require('@aws-sdk/client-bedrock-runtime'); + + // First call — model requests a tool call + mockSend.mockResolvedValueOnce( + makeConverseResponse([ + { + toolUse: { + toolUseId: 'call_1', + name: 'get_weather', + input: { city: 'NYC' }, + }, + }, + ]), + ); + await provider.sendMessage( + [{ role: 'user', content: 'Weather?' }], + [sampleTool], + ); + + // Follow-up with tool result in history (no tools param) + mockSend.mockResolvedValueOnce( + makeConverseResponse([{ text: 'It is sunny in NYC.' }]), + ); + + const followUpMessages: ChatMessage[] = [ + { role: 'user', content: 'Weather?' }, + { + role: 'assistant', + content: null, + tool_calls: [ + { + id: 'call_1', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"NYC"}', + }, + }, + ], + }, + { role: 'tool', content: 'Sunny, 75°F', tool_call_id: 'call_1' }, + ]; + await provider.sendMessage(followUpMessages); + + const commandInput = ConverseCommand.mock.calls[1][0]; + + // Assistant tool_calls converted to Bedrock toolUse blocks + const assistantMsg = commandInput.messages.find( + (m: any) => m.role === 'assistant', + ); + expect(assistantMsg.content).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + toolUse: expect.objectContaining({ + toolUseId: 'call_1', + name: 'get_weather', + }), + }), + ]), + ); + + // Tool result converted to Bedrock toolResult block + const toolMsg = commandInput.messages.find( + (m: any) => m.role === 'user' && m.content.some((c: any) => c.toolResult), + ); + expect(toolMsg).toBeDefined(); + expect(toolMsg.content[0].toolResult.toolUseId).toBe('call_1'); + + // toolConfig re-attached from cached tools + expect(commandInput.toolConfig).toBeDefined(); + expect(commandInput.toolConfig.tools[0].toolSpec.name).toBe('get_weather'); + }); + + it('returns error on failed testConnection', async () => { + const provider = createProvider(); + mockSend.mockRejectedValueOnce(new Error('Access denied')); + + const result = await provider.testConnection(); + + expect(result.connected).toBe(false); + expect(result.error).toBe('Access denied'); + }); +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md b/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md index 20c1e3a190c..096193fb399 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md @@ -55,6 +55,7 @@ const mcpChatPlugin: OverridableFrontendPlugin< path?: string | undefined; }; output: + | ExtensionDataRef | ExtensionDataRef | ExtensionDataRef< RouteRef_2, @@ -63,7 +64,6 @@ const mcpChatPlugin: OverridableFrontendPlugin< optional: true; } > - | ExtensionDataRef | ExtensionDataRef< string, 'core.title', From a67dfc150c559594bb2d2aa161ef3a96c8ae7bab Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Wed, 25 Mar 2026 08:41:46 -0400 Subject: [PATCH 07/17] docs(mcp-chat): added configuration instructions for amazon bedrock Signed-off-by: Florian JUDITH --- .../README.md | 63 ++++++++++++++++++- 1 file changed, 61 insertions(+), 2 deletions(-) diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/README.md index 57ce018d439..1deb16faf12 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/README.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/README.md @@ -1,5 +1,64 @@ # @backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock -The Amazon Bedrock backend module for the mcp-chat plugin. +This plugin is a submodule for the `@backstage-community/plugin-mcp-chat-backend` module, which provides the chat interface with Amazon Bedrock. -_This plugin was created through the Backstage CLI_ +## Configuration + +Two configuration sections requires the following configuraiton sections: + +1. [AWS integration](#aws-integration) section to manage AWS credentials +2. [Amazon Bedrock integration](#amazon-bedrock-integration) to manage the model configuration + +### AWS Integration + +The module depends on the [@backstage/integration-aws-node](https://backstage.io/api/next/modules/_backstage_integration-aws-node.html) package to fetch AWS account credentials for the AWS SDK client included in this submodule. IAM user credentail, IAM roles, AWS CLI profile name and [IRSA](#iam-role-for-service-account) is supported. + +```yaml +aws: + mainAccount: + accessKeyId: ${MY_ACCESS_KEY_ID} + secretAccessKey: ${MY_SECRET_ACCESS_KEY} + accounts: + - accountId: '111111111111' + roleName: 'my-iam-role-name' + externalId: 'my-external-id' + - accountId: '222222222222' + partition: 'aws-other' + roleName: 'my-iam-role-name' + region: 'not-us-east-1' + accessKeyId: ${MY_ACCESS_KEY_ID_FOR_ANOTHER_PARTITION} + secretAccessKey: ${MY_SECRET_ACCESS_KEY_FOR_ANOTHER_PARTITION} + - accountId: '333333333333' + accessKeyId: ${MY_OTHER_ACCESS_KEY_ID} + secretAccessKey: ${MY_OTHER_SECRET_ACCESS_KEY} + - accountId: '444444444444' + profile: my-profile-name + - accountId: '555555555555' + accountDefaults: + roleName: 'my-backstage-role' + externalId: 'my-id' +``` + +#### IAM Role for Service Account + +When Backstage is deployed in a Amazon EKS cluster, [IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) is typically enabled to support the injection of AWS credential at pod startup. In this specific case the app-config should only contain the account id where bedrock will be accessed + +```yaml +aws: + accounts: + - accountId: '123456789012' +``` + +### Amazon Bedrock integration + +The ID of the model have to be `amazon-bedrock` and expects a model ID or an inference profile ID. +If not interrested by Amazon Bedrock in `us-east-1`, you should **always configure the region** as the model ID can varies depending on target AWS region. + +```yaml +mcpChat: + providers: + - id: amazon-bedrock + model: ca.amazon.nova-lite-v1:0 + auth: + region: ca-central-1 +``` From c43c0b49391216ea9a75cffeae653728cba693d2 Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Wed, 25 Mar 2026 16:06:14 -0400 Subject: [PATCH 08/17] feat(mcp-chat): restore unit tests for each llm provider Signed-off-by: Florian JUDITH --- .../src/ClaudeProvider.test.ts | 187 ++++++++++++++ .../src/GeminiProvider.test.ts | 242 ++++++++++++++++++ .../src/LiteLLMProvider.test.ts | 223 ++++++++++++++++ .../src/OllamaProvider.test.ts | 195 ++++++++++++++ .../src/OpenAIResponsesProvider.test.ts | 193 ++++++++++++++ .../src/OpenAIProvider.test.ts | 214 ++++++++++++++++ 6 files changed, 1254 insertions(+) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.test.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.test.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.test.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.test.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.test.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.test.ts diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.test.ts new file mode 100644 index 00000000000..0a4d84c3a83 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.test.ts @@ -0,0 +1,187 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ClaudeProvider } from './ClaudeProvider'; +import type { + ChatMessage, + Tool, + ProviderConfig, +} from '@backstage-community/plugin-mcp-chat-common'; + +// Mock global.fetch for makeRequest and testConnection +const mockFetch = jest.fn() as jest.Mock; +global.fetch = mockFetch; + +function createProvider( + configOverrides?: Partial, +): ClaudeProvider { + const config: ProviderConfig = { + type: 'anthropic', + baseUrl: 'https://api.anthropic.com/v1', + model: 'claude-sonnet-4-20250514', + apiKey: 'test-api-key', + ...configOverrides, + }; + return new ClaudeProvider(config); +} + +const sampleTool: Tool = { + type: 'function', + function: { + name: 'get_weather', + description: 'Get the weather', + parameters: { type: 'object', properties: { city: { type: 'string' } } }, + }, +}; + +describe('ClaudeProvider', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('sends a basic user message and returns parsed response', async () => { + const provider = createProvider(); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + content: [{ type: 'text', text: 'Hello there!' }], + usage: { input_tokens: 10, output_tokens: 5 }, + }), + }); + + const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; + const result = await provider.sendMessage(messages); + + expect(result.choices[0].message.role).toBe('assistant'); + expect(result.choices[0].message.content).toBe('Hello there!'); + expect(result.usage).toEqual({ + prompt_tokens: 10, + completion_tokens: 5, + total_tokens: 15, + }); + }); + + it('filters system messages from the array sent to the API', async () => { + const provider = createProvider(); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + content: [{ type: 'text', text: 'OK' }], + }), + }); + + const messages: ChatMessage[] = [ + { role: 'system', content: 'You are helpful.' }, + { role: 'user', content: 'Hi' }, + ]; + await provider.sendMessage(messages); + + const fetchCall = mockFetch.mock.calls[0]; + const body = JSON.parse(fetchCall[1].body); + expect(body.messages.every((m: any) => m.role !== 'system')).toBe(true); + expect(body.messages).toHaveLength(1); + expect(body.messages[0]).toEqual({ role: 'user', content: 'Hi' }); + }); + + it('parses tool_use blocks into ToolCall objects', async () => { + const provider = createProvider(); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + content: [ + { + type: 'tool_use', + id: 'call_123', + name: 'get_weather', + input: { city: 'Seattle' }, + }, + ], + }), + }); + + const result = await provider.sendMessage( + [{ role: 'user', content: 'Weather in Seattle?' }], + [sampleTool], + ); + + expect(result.choices[0].message.tool_calls).toHaveLength(1); + expect(result.choices[0].message.tool_calls![0]).toEqual({ + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"Seattle"}', + }, + }); + }); + + it('converts tool messages to user format with Tool result prefix and includes assistant tool_calls in history', async () => { + const provider = createProvider(); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + content: [{ type: 'text', text: 'It is sunny in NYC.' }], + }), + }); + + const messages: ChatMessage[] = [ + { role: 'user', content: 'Weather?' }, + { + role: 'assistant', + content: null, + tool_calls: [ + { + id: 'call_1', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"NYC"}', + }, + }, + ], + }, + { role: 'tool', content: 'Sunny, 75°F', tool_call_id: 'call_1' }, + ]; + await provider.sendMessage(messages); + + const fetchCall = mockFetch.mock.calls[0]; + const body = JSON.parse(fetchCall[1].body); + + // Tool message converted to user with "Tool result:" prefix + const toolMsg = body.messages.find( + (m: any) => + m.role === 'user' && + typeof m.content === 'string' && + m.content.startsWith('Tool result:'), + ); + expect(toolMsg).toBeDefined(); + expect(toolMsg.content).toBe('Tool result: Sunny, 75°F'); + + // Assistant message is included in history + const assistantMsg = body.messages.find((m: any) => m.role === 'assistant'); + expect(assistantMsg).toBeDefined(); + }); + + it('returns error on failed testConnection', async () => { + const provider = createProvider(); + mockFetch.mockRejectedValueOnce(new Error('Network error')); + + const result = await provider.testConnection(); + + expect(result.connected).toBe(false); + expect(result.error).toBe('Network error'); + }); +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.test.ts new file mode 100644 index 00000000000..b8eb282d9ba --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.test.ts @@ -0,0 +1,242 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { GeminiProvider } from './GeminiProvider'; +import type { + ChatMessage, + Tool, + ProviderConfig, +} from '@backstage-community/plugin-mcp-chat-common'; + +// Mock the @google/generative-ai SDK module +const mockGenerateContent = jest.fn(); +jest.mock('@google/generative-ai', () => ({ + GoogleGenerativeAI: jest.fn().mockImplementation(() => ({ + getGenerativeModel: jest.fn().mockReturnValue({ + generateContent: mockGenerateContent, + safetySettings: [], + }), + })), + HarmCategory: { + HARM_CATEGORY_HARASSMENT: 'HARM_CATEGORY_HARASSMENT', + HARM_CATEGORY_HATE_SPEECH: 'HARM_CATEGORY_HATE_SPEECH', + HARM_CATEGORY_SEXUALLY_EXPLICIT: 'HARM_CATEGORY_SEXUALLY_EXPLICIT', + HARM_CATEGORY_DANGEROUS_CONTENT: 'HARM_CATEGORY_DANGEROUS_CONTENT', + }, + HarmBlockThreshold: { + BLOCK_MEDIUM_AND_ABOVE: 'BLOCK_MEDIUM_AND_ABOVE', + }, +})); + +function createProvider( + configOverrides?: Partial, +): GeminiProvider { + const config: ProviderConfig = { + type: 'gemini', + baseUrl: '', + model: 'gemini-2.0-flash', + apiKey: 'test-api-key', + ...configOverrides, + }; + return new GeminiProvider(config); +} + +const sampleTool: Tool = { + type: 'function', + function: { + name: 'get_weather', + description: 'Get the weather', + parameters: { type: 'object', properties: { city: { type: 'string' } } }, + }, +}; + +describe('GeminiProvider', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('sends a basic user message and returns parsed response', async () => { + const provider = createProvider(); + mockGenerateContent.mockResolvedValueOnce({ + response: { + candidates: [ + { + content: { + parts: [{ text: 'Hello there!' }], + }, + }, + ], + usageMetadata: { + promptTokenCount: 10, + candidatesTokenCount: 5, + totalTokenCount: 15, + }, + }, + }); + + const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; + const result = await provider.sendMessage(messages); + + expect(result.choices[0].message.role).toBe('assistant'); + expect(result.choices[0].message.content).toBe('Hello there!'); + expect(result.usage).toEqual({ + prompt_tokens: 10, + completion_tokens: 5, + total_tokens: 15, + }); + }); + + it('extracts system message as systemInstruction and excludes it from contents', async () => { + const provider = createProvider(); + const { GoogleGenerativeAI } = require('@google/generative-ai'); + const mockGetGenerativeModel = + GoogleGenerativeAI.mock.results[0].value.getGenerativeModel; + + mockGenerateContent.mockResolvedValueOnce({ + response: { + candidates: [ + { + content: { + parts: [{ text: 'OK' }], + }, + }, + ], + }, + }); + + const messages: ChatMessage[] = [ + { role: 'system', content: 'You are helpful.' }, + { role: 'user', content: 'Hi' }, + ]; + await provider.sendMessage(messages); + + // getGenerativeModel is called again with systemInstruction when a system message is present + const lastModelCall = + mockGetGenerativeModel.mock.calls[ + mockGetGenerativeModel.mock.calls.length - 1 + ][0]; + expect(lastModelCall.systemInstruction).toBe('You are helpful.'); + + // generateContent is called with contents that exclude the system message + const generateCall = mockGenerateContent.mock.calls[0][0]; + const contents = generateCall.contents; + expect(contents.every((c: any) => c.role !== 'system')).toBe(true); + expect(contents).toHaveLength(1); + expect(contents[0]).toEqual({ + role: 'user', + parts: [{ text: 'Hi' }], + }); + }); + + it('parses functionCall parts into ToolCall objects', async () => { + const provider = createProvider(); + mockGenerateContent.mockResolvedValueOnce({ + response: { + candidates: [ + { + content: { + parts: [ + { + functionCall: { + name: 'get_weather', + args: { city: 'Seattle' }, + }, + }, + ], + }, + }, + ], + }, + }); + + const result = await provider.sendMessage( + [{ role: 'user', content: 'Weather in Seattle?' }], + [sampleTool], + ); + + expect(result.choices[0].message.tool_calls).toHaveLength(1); + const toolCall = result.choices[0].message.tool_calls![0]; + expect(toolCall.id).toBeDefined(); + expect(toolCall.type).toBe('function'); + expect(toolCall.function.name).toBe('get_weather'); + expect(toolCall.function.arguments).toBe('{"city":"Seattle"}'); + }); + + it('converts tool messages to functionResponse format with name from tool_calls history', async () => { + const provider = createProvider(); + mockGenerateContent.mockResolvedValueOnce({ + response: { + candidates: [ + { + content: { + parts: [{ text: 'It is sunny in NYC.' }], + }, + }, + ], + }, + }); + + const messages: ChatMessage[] = [ + { role: 'user', content: 'Weather?' }, + { + role: 'assistant', + content: null, + tool_calls: [ + { + id: 'call_1', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"NYC"}', + }, + }, + ], + }, + { role: 'tool', content: '{"temp":"75°F"}', tool_call_id: 'call_1' }, + ]; + const result = await provider.sendMessage(messages); + + const generateCall = mockGenerateContent.mock.calls[0][0]; + const contents = generateCall.contents; + + // Tool message converted to function role with functionResponse + const functionContent = contents.find((c: any) => c.role === 'function'); + expect(functionContent).toBeDefined(); + expect(functionContent.parts[0].functionResponse.name).toBe('get_weather'); + expect(functionContent.parts[0].functionResponse.response).toEqual({ + temp: '75°F', + }); + + // Assistant tool_calls converted to model role with functionCall + const modelContent = contents.find((c: any) => c.role === 'model'); + expect(modelContent).toBeDefined(); + expect(modelContent.parts[0].functionCall.name).toBe('get_weather'); + + // Follow-up response is parsed correctly + expect(result.choices[0].message.role).toBe('assistant'); + expect(result.choices[0].message.content).toBe('It is sunny in NYC.'); + }); + + it('returns error on failed testConnection', async () => { + const provider = createProvider(); + mockGenerateContent.mockRejectedValueOnce(new Error('API key invalid')); + + const result = await provider.testConnection(); + + expect(result.connected).toBe(false); + expect(result.error).toBe('API key invalid'); + }); +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.test.ts new file mode 100644 index 00000000000..a2e239210e9 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.test.ts @@ -0,0 +1,223 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { LiteLLMProvider } from './LiteLLMProvider'; +import type { + ChatMessage, + Tool, + ProviderConfig, +} from '@backstage-community/plugin-mcp-chat-common'; + +// Mock global.fetch for makeRequest and testConnection +const mockFetch = jest.fn() as jest.Mock; +global.fetch = mockFetch; + +function createProvider( + configOverrides?: Partial, +): LiteLLMProvider { + const config: ProviderConfig = { + type: 'litellm', + baseUrl: 'http://localhost:4000', + model: 'gpt-4o', + apiKey: 'test-api-key', + ...configOverrides, + }; + return new LiteLLMProvider(config); +} + +const sampleTool: Tool = { + type: 'function', + function: { + name: 'get_weather', + description: 'Get the weather', + parameters: { type: 'object', properties: { city: { type: 'string' } } }, + }, +}; + +describe('LiteLLMProvider', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('sends a basic user message and returns the response as-is (passthrough)', async () => { + const provider = createProvider(); + const apiResponse = { + choices: [ + { + message: { + role: 'assistant', + content: 'Hello there!', + }, + }, + ], + usage: { + prompt_tokens: 10, + completion_tokens: 5, + total_tokens: 15, + }, + }; + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => apiResponse, + }); + + const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; + const result = await provider.sendMessage(messages); + + expect(result.choices[0].message.role).toBe('assistant'); + expect(result.choices[0].message.content).toBe('Hello there!'); + expect(result.usage).toEqual({ + prompt_tokens: 10, + completion_tokens: 5, + total_tokens: 15, + }); + }); + + it('includes system messages as-is in the formatted request', async () => { + const provider = createProvider(); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + choices: [{ message: { role: 'assistant', content: 'OK' } }], + }), + }); + + const messages: ChatMessage[] = [ + { role: 'system', content: 'You are helpful.' }, + { role: 'user', content: 'Hi' }, + ]; + await provider.sendMessage(messages); + + const fetchCall = mockFetch.mock.calls[0]; + const body = JSON.parse(fetchCall[1].body); + expect(body.messages).toHaveLength(2); + expect(body.messages[0]).toEqual({ + role: 'system', + content: 'You are helpful.', + }); + expect(body.messages[1]).toEqual({ role: 'user', content: 'Hi' }); + }); + + it('returns native tool_calls directly and includes parallel_tool_calls in the request', async () => { + const provider = createProvider(); + const apiResponse = { + choices: [ + { + message: { + role: 'assistant', + content: null, + tool_calls: [ + { + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"Seattle"}', + }, + }, + ], + }, + }, + ], + }; + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => apiResponse, + }); + + const result = await provider.sendMessage( + [{ role: 'user', content: 'Weather in Seattle?' }], + [sampleTool], + ); + + // Verify tool_calls are returned directly + expect(result.choices[0].message.tool_calls).toHaveLength(1); + expect(result.choices[0].message.tool_calls![0]).toEqual({ + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"Seattle"}', + }, + }); + + // Verify parallel_tool_calls: true is in the request + const fetchCall = mockFetch.mock.calls[0]; + const body = JSON.parse(fetchCall[1].body); + expect(body.parallel_tool_calls).toBe(true); + }); + + it('passes tool messages with tool_call_id as-is in the request', async () => { + const provider = createProvider(); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + choices: [ + { + message: { role: 'assistant', content: 'It is sunny in NYC.' }, + }, + ], + }), + }); + + const messages: ChatMessage[] = [ + { role: 'user', content: 'Weather?' }, + { + role: 'assistant', + content: null, + tool_calls: [ + { + id: 'call_1', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"NYC"}', + }, + }, + ], + }, + { role: 'tool', content: 'Sunny, 75°F', tool_call_id: 'call_1' }, + ]; + await provider.sendMessage(messages); + + const fetchCall = mockFetch.mock.calls[0]; + const body = JSON.parse(fetchCall[1].body); + + // Tool message passed as-is with tool_call_id + const toolMsg = body.messages.find((m: any) => m.role === 'tool'); + expect(toolMsg).toBeDefined(); + expect(toolMsg.content).toBe('Sunny, 75°F'); + expect(toolMsg.tool_call_id).toBe('call_1'); + + // Assistant message with tool_calls is included in history + const assistantMsg = body.messages.find((m: any) => m.role === 'assistant'); + expect(assistantMsg).toBeDefined(); + expect(assistantMsg.tool_calls).toHaveLength(1); + }); + + it('returns error on failed testConnection when both /models and /health fail', async () => { + const provider = createProvider(); + // First call to /models fails + mockFetch.mockRejectedValueOnce(new Error('Network error')); + // Fallback call to /health also fails + mockFetch.mockRejectedValueOnce(new Error('Network error')); + + const result = await provider.testConnection(); + + expect(result.connected).toBe(false); + expect(result.error).toBe('Network error'); + }); +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.test.ts new file mode 100644 index 00000000000..c7e6b078de1 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.test.ts @@ -0,0 +1,195 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { OllamaProvider } from './OllamaProvider'; +import type { + ChatMessage, + Tool, + ProviderConfig, +} from '@backstage-community/plugin-mcp-chat-common'; + +// Mock the ollama SDK module +const mockChat = jest.fn(); +const mockList = jest.fn(); +jest.mock('ollama', () => ({ + Ollama: jest.fn().mockImplementation(() => ({ + chat: mockChat, + list: mockList, + })), +})); + +function createProvider( + configOverrides?: Partial, +): OllamaProvider { + const config: ProviderConfig = { + type: 'ollama', + baseUrl: 'http://localhost:11434/v1', + model: 'llama3', + ...configOverrides, + }; + return new OllamaProvider(config); +} + +const sampleTool: Tool = { + type: 'function', + function: { + name: 'get_weather', + description: 'Get the weather', + parameters: { type: 'object', properties: { city: { type: 'string' } } }, + }, +}; + +describe('OllamaProvider', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('sends a basic user message and returns parsed response', async () => { + const provider = createProvider(); + mockChat.mockResolvedValueOnce({ + message: { role: 'assistant', content: 'Hello there!' }, + prompt_eval_count: 10, + eval_count: 5, + }); + + const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; + const result = await provider.sendMessage(messages); + + expect(result.choices[0].message.role).toBe('assistant'); + expect(result.choices[0].message.content).toBe('Hello there!'); + expect(result.usage).toEqual({ + prompt_tokens: 10, + completion_tokens: 5, + total_tokens: 15, + }); + }); + + it('passes system messages as-is to the SDK in the messages array', async () => { + const provider = createProvider(); + mockChat.mockResolvedValueOnce({ + message: { role: 'assistant', content: 'OK' }, + }); + + const messages: ChatMessage[] = [ + { role: 'system', content: 'You are helpful.' }, + { role: 'user', content: 'Hi' }, + ]; + await provider.sendMessage(messages); + + const chatCall = mockChat.mock.calls[0][0]; + expect(chatCall.messages).toHaveLength(2); + expect(chatCall.messages[0]).toEqual( + expect.objectContaining({ role: 'system', content: 'You are helpful.' }), + ); + expect(chatCall.messages[1]).toEqual( + expect.objectContaining({ role: 'user', content: 'Hi' }), + ); + }); + + it('parses tool_calls with object arguments serialized to JSON string and assigns id', async () => { + const provider = createProvider(); + mockChat.mockResolvedValueOnce({ + message: { + role: 'assistant', + content: '', + tool_calls: [ + { + function: { + name: 'get_weather', + arguments: { city: 'Seattle' }, + }, + }, + ], + }, + }); + + const result = await provider.sendMessage( + [{ role: 'user', content: 'Weather in Seattle?' }], + [sampleTool], + ); + + expect(result.choices[0].message.tool_calls).toHaveLength(1); + expect(result.choices[0].message.tool_calls![0]).toEqual({ + id: 'call_0', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"Seattle"}', + }, + }); + }); + + it('handles tool messages round-trip with tool_call_id and parses follow-up response', async () => { + const provider = createProvider(); + mockChat.mockResolvedValueOnce({ + message: { role: 'assistant', content: 'It is sunny in NYC.' }, + }); + + const messages: ChatMessage[] = [ + { role: 'user', content: 'Weather?' }, + { + role: 'assistant', + content: null, + tool_calls: [ + { + id: 'call_1', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"NYC"}', + }, + }, + ], + }, + { role: 'tool', content: 'Sunny, 75°F', tool_call_id: 'call_1' }, + ]; + const result = await provider.sendMessage(messages); + + const chatCall = mockChat.mock.calls[0][0]; + + // Tool message with tool_call_id is passed to the SDK + const toolMsg = chatCall.messages.find((m: any) => m.role === 'tool'); + expect(toolMsg).toBeDefined(); + expect(toolMsg.tool_call_id).toBe('call_1'); + expect(toolMsg.content).toBe('Sunny, 75°F'); + + // Assistant message with tool_calls is included in history + const assistantMsg = chatCall.messages.find( + (m: any) => m.role === 'assistant', + ); + expect(assistantMsg).toBeDefined(); + expect(assistantMsg.tool_calls).toBeDefined(); + expect(assistantMsg.tool_calls[0].function.name).toBe('get_weather'); + // Arguments are deserialized back to object for Ollama SDK + expect(assistantMsg.tool_calls[0].function.arguments).toEqual({ + city: 'NYC', + }); + + // Follow-up response is parsed correctly + expect(result.choices[0].message.role).toBe('assistant'); + expect(result.choices[0].message.content).toBe('It is sunny in NYC.'); + }); + + it('returns error on failed testConnection', async () => { + const provider = createProvider(); + mockList.mockRejectedValueOnce(new Error('Connection refused')); + + const result = await provider.testConnection(); + + expect(result.connected).toBe(false); + expect(result.error).toBe('Connection refused'); + }); +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.test.ts new file mode 100644 index 00000000000..5795a7912de --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.test.ts @@ -0,0 +1,193 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { OpenAIResponsesProvider } from './OpenAIResponsesProvider'; +import type { + ChatMessage, + Tool, + ProviderConfig, +} from '@backstage-community/plugin-mcp-chat-common'; + +// Mock global.fetch — OpenAIResponsesProvider overrides makeRequest and uses fetch directly +const mockFetch = jest.fn() as jest.Mock; +global.fetch = mockFetch; + +function createProvider( + configOverrides?: Partial, +): OpenAIResponsesProvider { + const config: ProviderConfig = { + type: 'openai-responses', + baseUrl: 'https://api.openai.com/v1', + model: 'gpt-4o', + apiKey: 'test-api-key', + ...configOverrides, + }; + return new OpenAIResponsesProvider(config); +} + +const sampleTool: Tool = { + type: 'function', + function: { + name: 'get_weather', + description: 'Get the weather', + parameters: { type: 'object', properties: { city: { type: 'string' } } }, + }, +}; + +describe('OpenAIResponsesProvider', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('sends a basic user message and returns parsed response with usage', async () => { + const provider = createProvider(); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + output: [ + { + type: 'message', + id: 'msg_1', + role: 'assistant', + status: 'completed', + content: [{ type: 'output_text', text: 'Hello there!' }], + }, + ], + usage: { + input_tokens: 10, + output_tokens: 5, + total_tokens: 15, + }, + }), + }); + + const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; + const result = await provider.sendMessage(messages); + + expect(result.choices[0].message.role).toBe('assistant'); + expect(result.choices[0].message.content).toBe('Hello there!'); + expect(result.usage).toEqual({ + prompt_tokens: 10, + completion_tokens: 5, + total_tokens: 15, + }); + }); + + it('places system message content in instructions and last message in input', async () => { + const provider = createProvider(); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + output: [ + { + type: 'message', + id: 'msg_1', + role: 'assistant', + status: 'completed', + content: [{ type: 'output_text', text: 'OK' }], + }, + ], + }), + }); + + const messages: ChatMessage[] = [ + { role: 'system', content: 'You are helpful.' }, + { role: 'user', content: 'Hi' }, + ]; + await provider.sendMessage(messages); + + const fetchCall = mockFetch.mock.calls[0]; + const body = JSON.parse(fetchCall[1].body); + expect(body.instructions).toBe('You are helpful.'); + expect(body.input).toBe('Hi'); + }); + + it('parses mcp_call events into ToolCall objects', async () => { + const provider = createProvider(); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + output: [ + { + type: 'mcp_call', + id: 'call_123', + name: 'get_weather', + arguments: '{"city":"Seattle"}', + server_label: 'weather-server', + error: null, + output: '{"temp":72}', + }, + ], + }), + }); + + const result = await provider.sendMessage( + [{ role: 'user', content: 'Weather in Seattle?' }], + [sampleTool], + ); + + expect(result.choices[0].message.tool_calls).toHaveLength(1); + expect(result.choices[0].message.tool_calls![0]).toEqual({ + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"Seattle"}', + }, + }); + }); + + it('correctly extracts instructions and input when history contains system + user', async () => { + const provider = createProvider(); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + output: [ + { + type: 'message', + id: 'msg_1', + role: 'assistant', + status: 'completed', + content: [{ type: 'output_text', text: 'It is sunny in NYC.' }], + }, + ], + }), + }); + + const messages: ChatMessage[] = [ + { role: 'system', content: 'You are a weather assistant.' }, + { role: 'user', content: 'What is the weather in NYC?' }, + ]; + await provider.sendMessage(messages); + + const fetchCall = mockFetch.mock.calls[0]; + const body = JSON.parse(fetchCall[1].body); + + expect(body.instructions).toBe('You are a weather assistant.'); + expect(body.input).toBe('What is the weather in NYC?'); + expect(body.model).toBe('gpt-4o'); + }); + + it('returns error on failed testConnection', async () => { + const provider = createProvider(); + mockFetch.mockRejectedValueOnce(new Error('Network error')); + + const result = await provider.testConnection(); + + expect(result.connected).toBe(false); + expect(result.error).toBe('Network error'); + }); +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.test.ts new file mode 100644 index 00000000000..ac73bdd56e0 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.test.ts @@ -0,0 +1,214 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { OpenAIProvider } from './OpenAIProvider'; +import type { + ChatMessage, + Tool, + ProviderConfig, +} from '@backstage-community/plugin-mcp-chat-common'; + +// Mock global.fetch for makeRequest and testConnection +const mockFetch = jest.fn() as jest.Mock; +global.fetch = mockFetch; + +function createProvider( + configOverrides?: Partial, +): OpenAIProvider { + const config: ProviderConfig = { + type: 'openai', + baseUrl: 'https://api.openai.com/v1', + model: 'gpt-4o', + apiKey: 'test-api-key', + ...configOverrides, + }; + return new OpenAIProvider(config); +} + +const sampleTool: Tool = { + type: 'function', + function: { + name: 'get_weather', + description: 'Get the weather', + parameters: { type: 'object', properties: { city: { type: 'string' } } }, + }, +}; + +describe('OpenAIProvider', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('sends a basic user message and returns the response as-is (passthrough)', async () => { + const provider = createProvider(); + const apiResponse = { + choices: [ + { + message: { + role: 'assistant', + content: 'Hello there!', + }, + }, + ], + usage: { + prompt_tokens: 10, + completion_tokens: 5, + total_tokens: 15, + }, + }; + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => apiResponse, + }); + + const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; + const result = await provider.sendMessage(messages); + + expect(result.choices[0].message.role).toBe('assistant'); + expect(result.choices[0].message.content).toBe('Hello there!'); + expect(result.usage).toEqual({ + prompt_tokens: 10, + completion_tokens: 5, + total_tokens: 15, + }); + }); + + it('includes system messages as-is in the formatted request', async () => { + const provider = createProvider(); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + choices: [{ message: { role: 'assistant', content: 'OK' } }], + }), + }); + + const messages: ChatMessage[] = [ + { role: 'system', content: 'You are helpful.' }, + { role: 'user', content: 'Hi' }, + ]; + await provider.sendMessage(messages); + + const fetchCall = mockFetch.mock.calls[0]; + const body = JSON.parse(fetchCall[1].body); + expect(body.messages).toHaveLength(2); + expect(body.messages[0]).toEqual({ + role: 'system', + content: 'You are helpful.', + }); + expect(body.messages[1]).toEqual({ role: 'user', content: 'Hi' }); + }); + + it('returns native OpenAI tool_calls directly in the response', async () => { + const provider = createProvider(); + const apiResponse = { + choices: [ + { + message: { + role: 'assistant', + content: null, + tool_calls: [ + { + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"Seattle"}', + }, + }, + ], + }, + }, + ], + }; + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => apiResponse, + }); + + const result = await provider.sendMessage( + [{ role: 'user', content: 'Weather in Seattle?' }], + [sampleTool], + ); + + expect(result.choices[0].message.tool_calls).toHaveLength(1); + expect(result.choices[0].message.tool_calls![0]).toEqual({ + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"Seattle"}', + }, + }); + }); + + it('passes tool messages with tool_call_id as-is in the request', async () => { + const provider = createProvider(); + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + choices: [ + { + message: { role: 'assistant', content: 'It is sunny in NYC.' }, + }, + ], + }), + }); + + const messages: ChatMessage[] = [ + { role: 'user', content: 'Weather?' }, + { + role: 'assistant', + content: null, + tool_calls: [ + { + id: 'call_1', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"city":"NYC"}', + }, + }, + ], + }, + { role: 'tool', content: 'Sunny, 75°F', tool_call_id: 'call_1' }, + ]; + await provider.sendMessage(messages); + + const fetchCall = mockFetch.mock.calls[0]; + const body = JSON.parse(fetchCall[1].body); + + // Tool message passed as-is with tool_call_id + const toolMsg = body.messages.find((m: any) => m.role === 'tool'); + expect(toolMsg).toBeDefined(); + expect(toolMsg.content).toBe('Sunny, 75°F'); + expect(toolMsg.tool_call_id).toBe('call_1'); + + // Assistant message with tool_calls is included in history + const assistantMsg = body.messages.find((m: any) => m.role === 'assistant'); + expect(assistantMsg).toBeDefined(); + expect(assistantMsg.tool_calls).toHaveLength(1); + }); + + it('returns error on failed testConnection', async () => { + const provider = createProvider(); + mockFetch.mockRejectedValueOnce(new Error('Network error')); + + const result = await provider.testConnection(); + + expect(result.connected).toBe(false); + expect(result.error).toBe('Network error'); + }); +}); From 1aee73294272c24c5d4aabefcbb75da41014016d Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Fri, 27 Mar 2026 19:36:38 -0400 Subject: [PATCH 09/17] fix(mcp-chat): restored examples Signed-off-by: Florian JUDITH --- .../plugins/mcp-chat-common/src/types.ts | 120 +++++++++++++++++- 1 file changed, 118 insertions(+), 2 deletions(-) diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts b/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts index d9d686c1be9..d0ef33242b6 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts @@ -61,6 +61,26 @@ export type LLMProviderType = * Configuration for an MCP server. * Supports multiple connection types: STDIO and Streamable HTTP. * + * @example + * ```typescript + * // STDIO server using npx + * const stdioServer: MCPServerConfig = { + * id: 'filesystem', + * name: 'File System', + * type: MCPServerType.STDIO, + * npxCommand: '@modelcontextprotocol/server-filesystem', + * args: ['/path/to/directory'] + * }; + * + * // HTTP server + * const httpServer: MCPServerConfig = { + * id: 'remote-api', + * name: 'Remote API', + * type: MCPServerType.STREAMABLE_HTTP, + * url: 'https://api.example.com/mcp' + * }; + * ``` + * * @public */ export interface MCPServerConfig { @@ -84,6 +104,19 @@ export interface MCPServerConfig { * Sensitive configuration for an MCP server. * Contains environment variables and HTTP headers that may include secrets. * + * @example + * ```typescript + * const secrets: MCPServerSecrets = { + * env: { + * API_KEY: 'your-secret-key', + * DATABASE_URL: 'postgres://...' + * }, + * headers: { + * 'Authorization': 'Bearer token123' + * } + * }; + * ``` + * * @public */ export interface MCPServerSecrets { @@ -143,6 +176,22 @@ export interface MCPServerStatusData { /** * Configuration for an LLM provider. * + * @example + * ```typescript + * const openaiConfig: ProviderConfig = { + * type: 'openai', + * apiKey: 'sk-...', + * baseUrl: 'https://api.openai.com/v1', + * model: 'gpt-4' + * }; + * + * const ollamaConfig: ProviderConfig = { + * type: 'ollama', + * baseUrl: 'http://localhost:11434', + * model: 'llama2' + * }; + * ``` + * * @public */ export interface ProviderConfig { @@ -154,8 +203,6 @@ export interface ProviderConfig { baseUrl: string; /** Model identifier to use */ model: string; - /** Optional auth record for provider-specific authentication (IAM, session, etc.) */ - auth?: Record; } /** @@ -218,6 +265,33 @@ export interface ProviderStatusData { * A chat message in the conversation. * Compatible with OpenAI's Chat Completions API message format. * + * @example + * ```typescript + * // User message + * const userMsg: ChatMessage = { + * role: 'user', + * content: 'What files are in the current directory?' + * }; + * + * // Assistant message with tool call + * const assistantMsg: ChatMessage = { + * role: 'assistant', + * content: null, + * tool_calls: [{ + * id: 'call_123', + * type: 'function', + * function: { name: 'list_files', arguments: '{"path": "."}' } + * }] + * }; + * + * // Tool response + * const toolMsg: ChatMessage = { + * role: 'tool', + * content: '["file1.txt", "file2.txt"]', + * tool_call_id: 'call_123' + * }; + * ``` + * * @public */ export interface ChatMessage { @@ -285,6 +359,25 @@ export interface QueryResponse { * Tool definition in OpenAI function calling format. * Describes a tool that the LLM can invoke. * + * @example + * ```typescript + * const tool: Tool = { + * type: 'function', + * function: { + * name: 'get_weather', + * description: 'Get the current weather for a location', + * parameters: { + * type: 'object', + * properties: { + * location: { type: 'string', description: 'City name' }, + * unit: { type: 'string', enum: ['celsius', 'fahrenheit'] } + * }, + * required: ['location'] + * } + * } + * }; + * ``` + * * @public */ export interface Tool { @@ -305,6 +398,21 @@ export interface Tool { * A tool call made by the LLM. * Represents the model's request to invoke a specific tool. * + * @example + * ```typescript + * const toolCall: ToolCall = { + * id: 'call_abc123', + * type: 'function', + * function: { + * name: 'get_weather', + * arguments: '{"location": "San Francisco", "unit": "celsius"}' + * } + * }; + * + * // Parse the arguments + * const args = JSON.parse(toolCall.function.arguments); + * ``` + * * @public */ export interface ToolCall { @@ -357,6 +465,14 @@ export interface ToolExecutionResult { /** * Result of validating chat messages. * + * @example + * ```typescript + * const result = validateMessages(messages); + * if (!result.isValid) { + * console.error('Validation failed:', result.error); + * } + * ``` + * * @public */ export interface MessageValidationResult { From a3e7aa184961e9ff8bc79fa86cff25e6d5d70ef6 Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Sat, 28 Mar 2026 09:57:20 -0400 Subject: [PATCH 10/17] feat(mcp-chat): removed LLMProviderType Signed-off-by: Florian JUDITH --- .../mcp-chat/plugins/mcp-chat-common/src/index.ts | 1 - .../mcp-chat/plugins/mcp-chat-common/src/types.ts | 14 -------------- 2 files changed, 15 deletions(-) diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-common/src/index.ts index 25cdd2fa5b8..5b7618a42c1 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-common/src/index.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/src/index.ts @@ -34,7 +34,6 @@ export type { ProviderStatusData, ProviderInfo, ProviderConnectionStatus, - LLMProviderType, // MCP Server types MCPServerConfig, diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts b/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts index d0ef33242b6..a5cfd1a7ec5 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts @@ -39,20 +39,6 @@ export enum MCPServerType { STREAMABLE_HTTP = 'streamable-http', } -/** - * Supported LLM provider types. - * Use this type for type-safe provider selection. - * - * @public - */ -export type LLMProviderType = - | 'openai' - | 'openai-responses' - | 'claude' - | 'gemini' - | 'ollama' - | 'litellm'; - // ============================================================================= // MCP Server Configuration Types // ============================================================================= From f1b43c5da40aa5a8e65921e5405e0225316bf927 Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Sun, 29 Mar 2026 11:25:36 -0400 Subject: [PATCH 11/17] feat(mcp-chat): catchup latest upstream changes Signed-off-by: Florian JUDITH --- .../src/GeminiProvider.test.ts | 826 ++- .../src/GeminiProvider.ts | 9 +- .../plugins/mcp-chat-backend/package.json | 3 +- .../plugins/mcp-chat/report-alpha.api.md | 25 +- .../mcp-chat/plugins/mcp-chat/report.api.md | 2 +- workspaces/mcp-chat/yarn.lock | 4502 +++++++++++------ 6 files changed, 3676 insertions(+), 1691 deletions(-) diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.test.ts index b8eb282d9ba..442d670d4d7 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.test.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.test.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +import { GoogleGenAI } from '@google/genai'; import { GeminiProvider } from './GeminiProvider'; import type { ChatMessage, @@ -21,222 +22,755 @@ import type { ProviderConfig, } from '@backstage-community/plugin-mcp-chat-common'; -// Mock the @google/generative-ai SDK module -const mockGenerateContent = jest.fn(); -jest.mock('@google/generative-ai', () => ({ - GoogleGenerativeAI: jest.fn().mockImplementation(() => ({ - getGenerativeModel: jest.fn().mockReturnValue({ - generateContent: mockGenerateContent, - safetySettings: [], - }), - })), - HarmCategory: { - HARM_CATEGORY_HARASSMENT: 'HARM_CATEGORY_HARASSMENT', - HARM_CATEGORY_HATE_SPEECH: 'HARM_CATEGORY_HATE_SPEECH', - HARM_CATEGORY_SEXUALLY_EXPLICIT: 'HARM_CATEGORY_SEXUALLY_EXPLICIT', - HARM_CATEGORY_DANGEROUS_CONTENT: 'HARM_CATEGORY_DANGEROUS_CONTENT', - }, - HarmBlockThreshold: { - BLOCK_MEDIUM_AND_ABOVE: 'BLOCK_MEDIUM_AND_ABOVE', - }, -})); - -function createProvider( - configOverrides?: Partial, -): GeminiProvider { +jest.mock('@google/genai'); + +const MockGoogleGenAI = GoogleGenAI as jest.MockedClass; + +describe('GeminiProvider', () => { + let provider: GeminiProvider; + let mockGenerateContent: jest.Mock; + const config: ProviderConfig = { type: 'gemini', - baseUrl: '', - model: 'gemini-2.0-flash', apiKey: 'test-api-key', - ...configOverrides, + baseUrl: 'https://generativelanguage.googleapis.com', + model: 'gemini-pro', }; - return new GeminiProvider(config); -} - -const sampleTool: Tool = { - type: 'function', - function: { - name: 'get_weather', - description: 'Get the weather', - parameters: { type: 'object', properties: { city: { type: 'string' } } }, - }, -}; -describe('GeminiProvider', () => { beforeEach(() => { jest.clearAllMocks(); + + mockGenerateContent = jest.fn(); + MockGoogleGenAI.mockImplementation( + () => + ({ + models: { + generateContent: mockGenerateContent, + }, + } as any), + ); + + provider = new GeminiProvider(config); }); - it('sends a basic user message and returns parsed response', async () => { - const provider = createProvider(); - mockGenerateContent.mockResolvedValueOnce({ - response: { + describe('constructor', () => { + it('should initialize with valid config', () => { + expect(MockGoogleGenAI).toHaveBeenCalledWith({ apiKey: 'test-api-key' }); + }); + + it('should throw error when API key is missing', () => { + const invalidConfig = { ...config, apiKey: undefined }; + + expect(() => new GeminiProvider(invalidConfig)).toThrow( + 'Gemini API key is required', + ); + }); + }); + + describe('sendMessage', () => { + it('should send simple message without tools', async () => { + const messages: ChatMessage[] = [ + { role: 'user', content: 'Hello, how are you?' }, + ]; + + mockGenerateContent.mockResolvedValue({ candidates: [ { content: { - parts: [{ text: 'Hello there!' }], + parts: [{ text: 'I am doing well, thank you!' }], }, }, ], usageMetadata: { promptTokenCount: 10, - candidatesTokenCount: 5, - totalTokenCount: 15, + candidatesTokenCount: 15, + totalTokenCount: 25, }, - }, - }); + }); + + const result = await provider.sendMessage(messages); - const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; - const result = await provider.sendMessage(messages); + expect(mockGenerateContent).toHaveBeenCalledWith({ + model: 'gemini-pro', + contents: [ + { + role: 'user', + parts: [{ text: 'Hello, how are you?' }], + }, + ], + config: expect.objectContaining({ + temperature: 0.7, + maxOutputTokens: 8192, + safetySettings: expect.any(Array), + }), + }); - expect(result.choices[0].message.role).toBe('assistant'); - expect(result.choices[0].message.content).toBe('Hello there!'); - expect(result.usage).toEqual({ - prompt_tokens: 10, - completion_tokens: 5, - total_tokens: 15, + expect(result).toEqual({ + choices: [ + { + message: { + role: 'assistant', + content: 'I am doing well, thank you!', + tool_calls: undefined, + }, + }, + ], + usage: { + prompt_tokens: 10, + completion_tokens: 15, + total_tokens: 25, + }, + }); }); - }); - it('extracts system message as systemInstruction and excludes it from contents', async () => { - const provider = createProvider(); - const { GoogleGenerativeAI } = require('@google/generative-ai'); - const mockGetGenerativeModel = - GoogleGenerativeAI.mock.results[0].value.getGenerativeModel; + it('should handle system message correctly', async () => { + const messages: ChatMessage[] = [ + { role: 'system', content: 'You are a helpful assistant.' }, + { role: 'user', content: 'Hello!' }, + ]; - mockGenerateContent.mockResolvedValueOnce({ - response: { + mockGenerateContent.mockResolvedValue({ candidates: [ { content: { - parts: [{ text: 'OK' }], + parts: [{ text: 'Hello! How can I help you?' }], }, }, ], - }, - }); - - const messages: ChatMessage[] = [ - { role: 'system', content: 'You are helpful.' }, - { role: 'user', content: 'Hi' }, - ]; - await provider.sendMessage(messages); + }); - // getGenerativeModel is called again with systemInstruction when a system message is present - const lastModelCall = - mockGetGenerativeModel.mock.calls[ - mockGetGenerativeModel.mock.calls.length - 1 - ][0]; - expect(lastModelCall.systemInstruction).toBe('You are helpful.'); + await provider.sendMessage(messages); - // generateContent is called with contents that exclude the system message - const generateCall = mockGenerateContent.mock.calls[0][0]; - const contents = generateCall.contents; - expect(contents.every((c: any) => c.role !== 'system')).toBe(true); - expect(contents).toHaveLength(1); - expect(contents[0]).toEqual({ - role: 'user', - parts: [{ text: 'Hi' }], + expect(mockGenerateContent).toHaveBeenCalledWith({ + model: 'gemini-pro', + contents: [{ role: 'user', parts: [{ text: 'Hello!' }] }], + config: expect.objectContaining({ + temperature: 0.7, + maxOutputTokens: 8192, + safetySettings: expect.any(Array), + systemInstruction: 'You are a helpful assistant.', + }), + }); }); - }); - it('parses functionCall parts into ToolCall objects', async () => { - const provider = createProvider(); - mockGenerateContent.mockResolvedValueOnce({ - response: { + it('should handle tools correctly', async () => { + const messages: ChatMessage[] = [ + { role: 'user', content: 'What is the weather like?' }, + ]; + + const tools: Tool[] = [ + { + type: 'function', + function: { + name: 'get_weather', + description: 'Get current weather information', + parameters: { + type: 'object', + properties: { + location: { + type: 'string', + description: 'The city and state', + }, + }, + required: ['location'], + }, + }, + }, + ]; + + mockGenerateContent.mockResolvedValue({ candidates: [ { content: { parts: [ + { text: 'I can help you get weather information.' }, { functionCall: { name: 'get_weather', - args: { city: 'Seattle' }, + args: { location: 'New York' }, }, }, ], }, }, ], - }, + }); + + const result = await provider.sendMessage(messages, tools); + + expect(mockGenerateContent).toHaveBeenCalledWith({ + model: 'gemini-pro', + contents: [ + { + role: 'user', + parts: [{ text: 'What is the weather like?' }], + }, + ], + config: expect.objectContaining({ + temperature: 0.7, + maxOutputTokens: 8192, + safetySettings: expect.any(Array), + tools: [ + { + functionDeclarations: [ + { + name: 'get_weather', + description: 'Get current weather information', + parameters: { + type: 'object', + properties: { + location: { + type: 'string', + description: 'The city and state', + }, + }, + required: ['location'], + }, + }, + ], + }, + ], + }), + }); + + expect(result.choices[0].message.tool_calls).toHaveLength(1); + expect(result.choices[0].message.tool_calls![0]).toMatchObject({ + type: 'function', + function: { + name: 'get_weather', + arguments: '{"location":"New York"}', + }, + }); }); - const result = await provider.sendMessage( - [{ role: 'user', content: 'Weather in Seattle?' }], - [sampleTool], - ); + it('should handle tool response messages', async () => { + const messages: ChatMessage[] = [ + { role: 'user', content: 'What is the weather?' }, + { + role: 'assistant', + content: 'Let me check the weather for you.', + tool_calls: [ + { + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"location":"New York"}', + }, + }, + ], + }, + { + role: 'tool', + content: '{"temperature":"72F","condition":"sunny"}', + tool_call_id: 'call_123', + }, + ]; - expect(result.choices[0].message.tool_calls).toHaveLength(1); - const toolCall = result.choices[0].message.tool_calls![0]; - expect(toolCall.id).toBeDefined(); - expect(toolCall.type).toBe('function'); - expect(toolCall.function.name).toBe('get_weather'); - expect(toolCall.function.arguments).toBe('{"city":"Seattle"}'); - }); + mockGenerateContent.mockResolvedValue({ + candidates: [ + { + content: { + parts: [{ text: 'The weather in New York is 72F and sunny.' }], + }, + }, + ], + }); + + await provider.sendMessage(messages); - it('converts tool messages to functionResponse format with name from tool_calls history', async () => { - const provider = createProvider(); - mockGenerateContent.mockResolvedValueOnce({ - response: { + expect(mockGenerateContent).toHaveBeenCalledWith({ + model: 'gemini-pro', + contents: [ + { role: 'user', parts: [{ text: 'What is the weather?' }] }, + { + role: 'model', + parts: [ + { text: 'Let me check the weather for you.' }, + { + functionCall: { + name: 'get_weather', + args: { location: 'New York' }, + }, + }, + ], + }, + { + role: 'function', + parts: [ + { + functionResponse: { + name: 'get_weather', + response: { temperature: '72F', condition: 'sunny' }, + }, + }, + ], + }, + ], + config: expect.objectContaining({ + temperature: 0.7, + maxOutputTokens: 8192, + safetySettings: expect.any(Array), + }), + }); + }); + + it('should handle tool response with invalid JSON', async () => { + const messages: ChatMessage[] = [ + { + role: 'assistant', + content: 'Let me check that for you.', + tool_calls: [ + { + id: 'call_123', + type: 'function', + function: { + name: 'test_function', + arguments: '{}', + }, + }, + ], + }, + { + role: 'tool', + content: 'Invalid JSON response', + tool_call_id: 'call_123', + }, + ]; + + mockGenerateContent.mockResolvedValue({ candidates: [ { content: { - parts: [{ text: 'It is sunny in NYC.' }], + parts: [{ text: 'I understand.' }], + }, + }, + ], + }); + + await provider.sendMessage(messages); + + expect(mockGenerateContent).toHaveBeenCalledWith({ + model: 'gemini-pro', + contents: [ + { + role: 'model', + parts: [ + { text: 'Let me check that for you.' }, + { + functionCall: { + name: 'test_function', + args: {}, + }, + }, + ], + }, + { + role: 'function', + parts: [ + { + functionResponse: { + name: 'test_function', + response: { result: 'Invalid JSON response' }, + }, + }, + ], + }, + ], + config: expect.objectContaining({ + temperature: 0.7, + maxOutputTokens: 8192, + safetySettings: expect.any(Array), + }), + }); + }); + + it('should handle API errors', async () => { + const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; + + mockGenerateContent.mockRejectedValue(new Error('API Error')); + + await expect(provider.sendMessage(messages)).rejects.toThrow('API Error'); + }); + + it('should not leak tools or systemInstruction across calls', async () => { + const tools: Tool[] = [ + { + type: 'function', + function: { + name: 'get_weather', + description: 'Get weather', + parameters: { type: 'object', properties: {} }, + }, + }, + ]; + + mockGenerateContent.mockResolvedValue({ + candidates: [{ content: { parts: [{ text: 'response' }] } }], + }); + + await provider.sendMessage( + [ + { role: 'system', content: 'Be helpful' }, + { role: 'user', content: 'First call' }, + ], + tools, + ); + + const firstCallConfig = mockGenerateContent.mock.calls[0][0].config; + expect(firstCallConfig.tools).toBeDefined(); + expect(firstCallConfig.systemInstruction).toBe('Be helpful'); + + await provider.sendMessage([ + { role: 'user', content: 'Second call without tools or system' }, + ]); + + const secondCallConfig = mockGenerateContent.mock.calls[1][0].config; + expect(secondCallConfig.tools).toBeUndefined(); + expect(secondCallConfig.systemInstruction).toBeUndefined(); + }); + + it('should handle empty response', async () => { + const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; + + mockGenerateContent.mockResolvedValue({ + candidates: [], + }); + + const result = await provider.sendMessage(messages); + + expect(result).toEqual({ + choices: [ + { + message: { + role: 'assistant', + content: '', + tool_calls: undefined, }, }, ], - }, + usage: undefined, + }); }); + }); - const messages: ChatMessage[] = [ - { role: 'user', content: 'Weather?' }, - { - role: 'assistant', - content: null, - tool_calls: [ + describe('testConnection', () => { + it('should return connected when API is working', async () => { + mockGenerateContent.mockResolvedValue({ + candidates: [ { - id: 'call_1', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"NYC"}', + content: { + parts: [{ text: 'Hello' }], }, }, ], - }, - { role: 'tool', content: '{"temp":"75°F"}', tool_call_id: 'call_1' }, - ]; - const result = await provider.sendMessage(messages); + }); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: true, + models: ['gemini-pro'], + }); + + expect(mockGenerateContent).toHaveBeenCalledWith({ + model: 'gemini-pro', + contents: [{ role: 'user', parts: [{ text: 'Hello' }] }], + config: expect.objectContaining({ + maxOutputTokens: 1, + temperature: 0.7, + safetySettings: expect.any(Array), + }), + }); + }); + + it('should return not connected when API throws error', async () => { + mockGenerateContent.mockRejectedValue(new Error('API connection failed')); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: false, + error: 'API connection failed', + }); + }); + + it('should handle non-Error exceptions', async () => { + mockGenerateContent.mockRejectedValue('String error'); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: false, + error: 'Failed to connect to Gemini API', + }); + }); + + it('should return not connected when no response', async () => { + mockGenerateContent.mockResolvedValue(null as any); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: false, + error: 'No response received from Gemini API', + }); + }); + }); + + describe('cleanJsonSchemaForGemini', () => { + it('should remove unsupported schema properties', () => { + const schema = { + $schema: 'http://json-schema.org/draft-07/schema#', + type: 'object', + additionalProperties: false, + $id: 'test-schema', + $ref: '#/definitions/Test', + definitions: { Test: {} }, + $defs: { Test: {} }, + properties: { + name: { + type: 'string', + $schema: 'nested', + additionalProperties: true, + }, + }, + items: { + type: 'string', + additionalProperties: false, + }, + anyOf: [ + { type: 'string', additionalProperties: true }, + { type: 'number' }, + ], + oneOf: [{ type: 'string', $schema: 'test' }], + allOf: [{ type: 'object', definitions: {} }], + }; + + // Access the private method through type assertion + const cleanedSchema = (provider as any).cleanJsonSchemaForGemini(schema); + + expect(cleanedSchema).toEqual({ + type: 'object', + properties: { + name: { + type: 'string', + }, + }, + items: { + type: 'string', + }, + anyOf: [{ type: 'string' }, { type: 'number' }], + oneOf: [{ type: 'string' }], + allOf: [{ type: 'object' }], + }); + }); + + it('should handle non-object schemas', () => { + expect((provider as any).cleanJsonSchemaForGemini(null)).toBeNull(); + expect((provider as any).cleanJsonSchemaForGemini('string')).toBe( + 'string', + ); + expect((provider as any).cleanJsonSchemaForGemini(123)).toBe(123); + }); + + it('should handle empty schema', () => { + const result = (provider as any).cleanJsonSchemaForGemini({}); + expect(result).toEqual({}); + }); + }); - const generateCall = mockGenerateContent.mock.calls[0][0]; - const contents = generateCall.contents; + describe('convertToGeminiFormat', () => { + it('should convert basic messages correctly', () => { + const messages: ChatMessage[] = [ + { role: 'user', content: 'Hello' }, + { role: 'assistant', content: 'Hi there!' }, + ]; - // Tool message converted to function role with functionResponse - const functionContent = contents.find((c: any) => c.role === 'function'); - expect(functionContent).toBeDefined(); - expect(functionContent.parts[0].functionResponse.name).toBe('get_weather'); - expect(functionContent.parts[0].functionResponse.response).toEqual({ - temp: '75°F', + const result = (provider as any).convertToGeminiFormat(messages); + + expect(result).toEqual([ + { role: 'user', parts: [{ text: 'Hello' }] }, + { role: 'model', parts: [{ text: 'Hi there!' }] }, + ]); }); - // Assistant tool_calls converted to model role with functionCall - const modelContent = contents.find((c: any) => c.role === 'model'); - expect(modelContent).toBeDefined(); - expect(modelContent.parts[0].functionCall.name).toBe('get_weather'); + it('should handle messages with null content', () => { + const messages: ChatMessage[] = [ + { role: 'user', content: null }, + { role: 'assistant', content: null }, + ]; + + const result = (provider as any).convertToGeminiFormat(messages); + + expect(result).toEqual([ + { role: 'user', parts: [{ text: '' }] }, + { role: 'model', parts: [{ text: '' }] }, + ]); + }); - // Follow-up response is parsed correctly - expect(result.choices[0].message.role).toBe('assistant'); - expect(result.choices[0].message.content).toBe('It is sunny in NYC.'); + it('should skip system messages in conversion', () => { + const messages: ChatMessage[] = [ + { role: 'system', content: 'You are helpful' }, + { role: 'user', content: 'Hello' }, + ]; + + const result = (provider as any).convertToGeminiFormat(messages); + + expect(result).toEqual([{ role: 'user', parts: [{ text: 'Hello' }] }]); + }); }); - it('returns error on failed testConnection', async () => { - const provider = createProvider(); - mockGenerateContent.mockRejectedValueOnce(new Error('API key invalid')); + describe('convertToGeminiTools', () => { + it('should convert tools to Gemini format', () => { + const tools: Tool[] = [ + { + type: 'function', + function: { + name: 'get_weather', + description: 'Get weather information', + parameters: { + type: 'object', + properties: { + location: { type: 'string' }, + }, + required: ['location'], + additionalProperties: false, + }, + }, + }, + ]; + + const result = (provider as any).convertToGeminiTools(tools); + + expect(result).toEqual([ + { + functionDeclarations: [ + { + name: 'get_weather', + description: 'Get weather information', + parameters: { + type: 'object', + properties: { + location: { type: 'string' }, + }, + required: ['location'], + }, + }, + ], + }, + ]); + }); + }); + + describe('parseResponse', () => { + it('should parse response with only text', () => { + const mockResult = { + candidates: [ + { + content: { + parts: [{ text: 'Hello world' }], + }, + }, + ], + } as any; + + const result = (provider as any).parseResponse(mockResult); + + expect(result).toEqual({ + choices: [ + { + message: { + role: 'assistant', + content: 'Hello world', + tool_calls: undefined, + }, + }, + ], + usage: undefined, + }); + }); + + it('should parse response with function calls', () => { + const mockResult = { + candidates: [ + { + content: { + parts: [ + { text: 'Let me check that for you.' }, + { + functionCall: { + name: 'get_weather', + args: { location: 'New York' }, + }, + }, + ], + }, + }, + ], + } as any; + + const result = (provider as any).parseResponse(mockResult); - const result = await provider.testConnection(); + expect(result.choices[0].message.content).toBe( + 'Let me check that for you.', + ); + expect(result.choices[0].message.tool_calls).toHaveLength(1); + expect(result.choices[0].message.tool_calls![0]).toMatchObject({ + type: 'function', + function: { + name: 'get_weather', + arguments: '{"location":"New York"}', + }, + }); + }); - expect(result.connected).toBe(false); - expect(result.error).toBe('API key invalid'); + it('should generate unique IDs for tool calls', () => { + const mockResult = { + candidates: [ + { + content: { + parts: [ + { + functionCall: { + name: 'function1', + args: {}, + }, + }, + { + functionCall: { + name: 'function2', + args: {}, + }, + }, + ], + }, + }, + ], + } as any; + + const result = (provider as any).parseResponse(mockResult); + + expect(result.choices[0].message.tool_calls).toHaveLength(2); + expect(result.choices[0].message.tool_calls![0].id).toBeDefined(); + expect(result.choices[0].message.tool_calls![1].id).toBeDefined(); + expect(result.choices[0].message.tool_calls![0].id).not.toBe( + result.choices[0].message.tool_calls![1].id, + ); + }); + }); + + describe('getHeaders', () => { + it('should return empty headers', () => { + const headers = (provider as any).getHeaders(); + expect(headers).toEqual({}); + }); + }); + + describe('formatRequest', () => { + it('should return empty object', () => { + const request = (provider as any).formatRequest([], []); + expect(request).toEqual({}); + }); }); }); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.ts index a1341d71c03..a51d6692a16 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.ts @@ -138,7 +138,10 @@ export class GeminiProvider extends LLMProvider { error?: string; }> { try { - const result = await this.geminiModel.generateContent({ + // Gemini doesn't have a models list endpoint in the same way + // We'll test by making a simple generateContent request + const response = await this.genAI.models.generateContent({ + model: this.model, contents: [{ role: 'user', parts: [{ text: 'Hello' }] }], config: { ...this.baseModelConfig, @@ -146,11 +149,11 @@ export class GeminiProvider extends LLMProvider { }, }); - const response = await result.response; + // If we get here without error, the connection is working if (response) { return { connected: true, - models: [this.model], + models: [this.model], // Gemini doesn't list models, so return the configured one }; } return { diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json index 9447d80be36..36225815dba 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json @@ -35,12 +35,11 @@ "@backstage/config": "^1.3.0", "@backstage/errors": "^1.2.7", "@backstage/plugin-catalog-node": "^2.1.0", - "@google/genai": "^1.41.0", "@modelcontextprotocol/sdk": "^1.25.2", "express": "^4.22.0", "express-promise-router": "^4.1.0", "knex": "^3.1.0", - "uuid": "^9.0.0" + "uuid": "^11.0.0" }, "devDependencies": { "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock": "workspace:^", diff --git a/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md b/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md index 096193fb399..0709ef07b40 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md @@ -12,6 +12,7 @@ import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionBlueprintParams } from '@backstage/frontend-plugin-api'; import { ExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionInput } from '@backstage/frontend-plugin-api'; +import { IconComponent } from '@backstage/frontend-plugin-api'; import { IconElement } from '@backstage/frontend-plugin-api'; import { JSX as JSX_2 } from 'react'; import { OverridableExtensionDefinition } from '@backstage/frontend-plugin-api'; @@ -43,6 +44,27 @@ const mcpChatPlugin: OverridableFrontendPlugin< params: ApiFactory, ) => ExtensionBlueprintParams; }>; + 'nav-item:mcp-chat': OverridableExtensionDefinition<{ + kind: 'nav-item'; + name: undefined; + config: {}; + configInput: {}; + output: ExtensionDataRef< + { + title: string; + icon: IconComponent; + routeRef: RouteRef_2; + }, + 'core.nav-item.target', + {} + >; + inputs: {}; + params: { + title: string; + icon: IconComponent; + routeRef: RouteRef_2; + }; + }>; 'page:mcp-chat': OverridableExtensionDefinition<{ kind: 'page'; name: undefined; @@ -55,7 +77,6 @@ const mcpChatPlugin: OverridableFrontendPlugin< path?: string | undefined; }; output: - | ExtensionDataRef | ExtensionDataRef | ExtensionDataRef< RouteRef_2, @@ -64,6 +85,7 @@ const mcpChatPlugin: OverridableFrontendPlugin< optional: true; } > + | ExtensionDataRef | ExtensionDataRef< string, 'core.title', @@ -111,6 +133,7 @@ const mcpChatPlugin: OverridableFrontendPlugin< >; }; params: { + defaultPath?: [Error: "Use the 'path' param instead"] | undefined; path: string; title?: string | undefined; icon?: IconElement | undefined; diff --git a/workspaces/mcp-chat/plugins/mcp-chat/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat/report.api.md index 1187852c303..68ebe236ce0 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat/report.api.md @@ -3,7 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { ApiRef } from '@backstage/core-plugin-api'; +import { ApiRef } from '@backstage/frontend-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; import { ComponentType } from 'react'; import { JSX as JSX_2 } from 'react/jsx-runtime'; diff --git a/workspaces/mcp-chat/yarn.lock b/workspaces/mcp-chat/yarn.lock index b5cf27973cc..f962faa0585 100644 --- a/workspaces/mcp-chat/yarn.lock +++ b/workspaces/mcp-chat/yarn.lock @@ -166,26 +166,26 @@ __metadata: linkType: hard "@aws-sdk/client-bedrock-runtime@npm:^3.0.0": - version: 3.1015.0 - resolution: "@aws-sdk/client-bedrock-runtime@npm:3.1015.0" + version: 3.1019.0 + resolution: "@aws-sdk/client-bedrock-runtime@npm:3.1019.0" dependencies: "@aws-crypto/sha256-browser": "npm:5.2.0" "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:^3.973.24" - "@aws-sdk/credential-provider-node": "npm:^3.972.25" - "@aws-sdk/eventstream-handler-node": "npm:^3.972.11" + "@aws-sdk/core": "npm:^3.973.25" + "@aws-sdk/credential-provider-node": "npm:^3.972.27" + "@aws-sdk/eventstream-handler-node": "npm:^3.972.12" "@aws-sdk/middleware-eventstream": "npm:^3.972.8" "@aws-sdk/middleware-host-header": "npm:^3.972.8" "@aws-sdk/middleware-logger": "npm:^3.972.8" - "@aws-sdk/middleware-recursion-detection": "npm:^3.972.8" - "@aws-sdk/middleware-user-agent": "npm:^3.972.25" - "@aws-sdk/middleware-websocket": "npm:^3.972.13" - "@aws-sdk/region-config-resolver": "npm:^3.972.9" - "@aws-sdk/token-providers": "npm:3.1015.0" + "@aws-sdk/middleware-recursion-detection": "npm:^3.972.9" + "@aws-sdk/middleware-user-agent": "npm:^3.972.26" + "@aws-sdk/middleware-websocket": "npm:^3.972.14" + "@aws-sdk/region-config-resolver": "npm:^3.972.10" + "@aws-sdk/token-providers": "npm:3.1019.0" "@aws-sdk/types": "npm:^3.973.6" "@aws-sdk/util-endpoints": "npm:^3.996.5" "@aws-sdk/util-user-agent-browser": "npm:^3.972.8" - "@aws-sdk/util-user-agent-node": "npm:^3.973.11" + "@aws-sdk/util-user-agent-node": "npm:^3.973.12" "@smithy/config-resolver": "npm:^4.4.13" "@smithy/core": "npm:^3.23.12" "@smithy/eventstream-serde-browser": "npm:^4.2.12" @@ -216,7 +216,7 @@ __metadata: "@smithy/util-stream": "npm:^4.5.20" "@smithy/util-utf8": "npm:^4.2.2" tslib: "npm:^2.6.2" - checksum: 10/da427a073f05daf1e47ed399e988aa6fc3f4ec502bd5587047c009ec9a71cec4e9b5931fd0a8ca74130a38763d659ead8f53816f1b57cdca34358a3958a69ae8 + checksum: 10/698b5448e7028fb8f7c679c3e007ebbb45f70fe67c73f0e53ec4c829ef7b97813b91b764a431ea4d3a39498dc487508bb643dc7c0b5a946a48f686139d77ff66 languageName: node linkType: hard @@ -445,30 +445,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/core@npm:^3.973.24": - version: 3.973.24 - resolution: "@aws-sdk/core@npm:3.973.24" - dependencies: - "@aws-sdk/types": "npm:^3.973.6" - "@aws-sdk/xml-builder": "npm:^3.972.15" - "@smithy/core": "npm:^3.23.12" - "@smithy/node-config-provider": "npm:^4.3.12" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/signature-v4": "npm:^5.3.12" - "@smithy/smithy-client": "npm:^4.12.7" - "@smithy/types": "npm:^4.13.1" - "@smithy/util-base64": "npm:^4.3.2" - "@smithy/util-middleware": "npm:^4.2.12" - "@smithy/util-utf8": "npm:^4.2.2" - tslib: "npm:^2.6.2" - checksum: 10/7008d625b0628e88c9b11793c5843a747d7ea2650d423019f5daacf00abdd57f51dbde60169f0ee8c2f3e100037a18d2b9b895c3436c1b595bd145c86389db4f - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-cognito-identity@npm:3.830.0": - version: 3.830.0 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.830.0" +"@aws-sdk/crc64-nvme@npm:^3.972.5": + version: 3.972.5 + resolution: "@aws-sdk/crc64-nvme@npm:3.972.5" dependencies: "@smithy/types": "npm:^4.13.1" tslib: "npm:^2.6.2" @@ -489,22 +468,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-env@npm:^3.972.22": - version: 3.972.22 - resolution: "@aws-sdk/credential-provider-env@npm:3.972.22" - dependencies: - "@aws-sdk/core": "npm:^3.973.24" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/b8d6eb6f3ce55720048cb8f69fcb06c3266e1967d163f77c90854fae6b515aeaae799590b61dece713f863e48924f806627c2eb573de45e9c268a5705eedab65 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-http@npm:3.826.0": - version: 3.826.0 - resolution: "@aws-sdk/credential-provider-http@npm:3.826.0" +"@aws-sdk/credential-provider-env@npm:^3.972.23": + version: 3.972.23 + resolution: "@aws-sdk/credential-provider-env@npm:3.972.23" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/types": "npm:^3.973.6" @@ -515,27 +481,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-http@npm:^3.972.24": - version: 3.972.24 - resolution: "@aws-sdk/credential-provider-http@npm:3.972.24" - dependencies: - "@aws-sdk/core": "npm:^3.973.24" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/fetch-http-handler": "npm:^5.3.15" - "@smithy/node-http-handler": "npm:^4.5.0" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/smithy-client": "npm:^4.12.7" - "@smithy/types": "npm:^4.13.1" - "@smithy/util-stream": "npm:^4.5.20" - tslib: "npm:^2.6.2" - checksum: 10/7bda2d60e493aedf3b6aeabef35711fd53e64076e90f112d77268edf4c822ff052c333daa1070d582bcb02729eb06ba20397c4170f340c991aa25fdce41b84c6 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-ini@npm:3.830.0": - version: 3.830.0 - resolution: "@aws-sdk/credential-provider-ini@npm:3.830.0" +"@aws-sdk/credential-provider-http@npm:^3.972.25": + version: 3.972.25 + resolution: "@aws-sdk/credential-provider-http@npm:3.972.25" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/types": "npm:^3.973.6" @@ -551,47 +499,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:^3.972.24": - version: 3.972.24 - resolution: "@aws-sdk/credential-provider-ini@npm:3.972.24" - dependencies: - "@aws-sdk/core": "npm:^3.973.24" - "@aws-sdk/credential-provider-env": "npm:^3.972.22" - "@aws-sdk/credential-provider-http": "npm:^3.972.24" - "@aws-sdk/credential-provider-login": "npm:^3.972.24" - "@aws-sdk/credential-provider-process": "npm:^3.972.22" - "@aws-sdk/credential-provider-sso": "npm:^3.972.24" - "@aws-sdk/credential-provider-web-identity": "npm:^3.972.24" - "@aws-sdk/nested-clients": "npm:^3.996.14" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/credential-provider-imds": "npm:^4.2.12" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/shared-ini-file-loader": "npm:^4.4.7" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/455ab66d6e0d97f9c7e18edba25b060637cee2408af237bb2bab54b56d4701546047a372423e1c3f1ff9db49b48445e9c9b7d0214bca39b8b467f01eeec6942d - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-login@npm:^3.972.24": - version: 3.972.24 - resolution: "@aws-sdk/credential-provider-login@npm:3.972.24" - dependencies: - "@aws-sdk/core": "npm:^3.973.24" - "@aws-sdk/nested-clients": "npm:^3.996.14" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/shared-ini-file-loader": "npm:^4.4.7" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/f6a7b790ec48d62509e13b763c73f2fe72d19249b44d31928e7f8b08fb5bc9f1a10365cc15adc575b9dc5012822ba091aaf7b647df00e3742078f5cbb9253dab - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-node@npm:3.830.0": - version: 3.830.0 - resolution: "@aws-sdk/credential-provider-node@npm:3.830.0" +"@aws-sdk/credential-provider-ini@npm:^3.972.26": + version: 3.972.26 + resolution: "@aws-sdk/credential-provider-ini@npm:3.972.26" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/credential-provider-env": "npm:^3.972.23" @@ -611,29 +521,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:^3.350.0, @aws-sdk/credential-provider-node@npm:^3.972.25": - version: 3.972.25 - resolution: "@aws-sdk/credential-provider-node@npm:3.972.25" - dependencies: - "@aws-sdk/credential-provider-env": "npm:^3.972.22" - "@aws-sdk/credential-provider-http": "npm:^3.972.24" - "@aws-sdk/credential-provider-ini": "npm:^3.972.24" - "@aws-sdk/credential-provider-process": "npm:^3.972.22" - "@aws-sdk/credential-provider-sso": "npm:^3.972.24" - "@aws-sdk/credential-provider-web-identity": "npm:^3.972.24" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/credential-provider-imds": "npm:^4.2.12" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/shared-ini-file-loader": "npm:^4.4.7" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/9cf17eaf074aeeed9d3927b0c6729bcc079a08ac02fe028a9a731835cdd61746745fc21a612b40093fdd9d3a1b0f3eb7b62f3162206635bb7d06f89164be0e03 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-process@npm:3.826.0": - version: 3.826.0 - resolution: "@aws-sdk/credential-provider-process@npm:3.826.0" +"@aws-sdk/credential-provider-login@npm:^3.972.26": + version: 3.972.26 + resolution: "@aws-sdk/credential-provider-login@npm:3.972.26" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/nested-clients": "npm:^3.996.16" @@ -647,23 +537,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-process@npm:^3.972.22": - version: 3.972.22 - resolution: "@aws-sdk/credential-provider-process@npm:3.972.22" - dependencies: - "@aws-sdk/core": "npm:^3.973.24" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/shared-ini-file-loader": "npm:^4.4.7" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/6f455ed8d56732e08a256fe7c9df250a234478eaf4e6e5d2bdd6359763329e9fcb61352cc5dcd7a340d9ebfbeef67ad61e2e64335290247d889f6b167d7f82a0 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-sso@npm:3.830.0": - version: 3.830.0 - resolution: "@aws-sdk/credential-provider-sso@npm:3.830.0" +"@aws-sdk/credential-provider-node@npm:^3.350.0, @aws-sdk/credential-provider-node@npm:^3.972.27": + version: 3.972.27 + resolution: "@aws-sdk/credential-provider-node@npm:3.972.27" dependencies: "@aws-sdk/credential-provider-env": "npm:^3.972.23" "@aws-sdk/credential-provider-http": "npm:^3.972.25" @@ -681,25 +557,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:^3.972.24": - version: 3.972.24 - resolution: "@aws-sdk/credential-provider-sso@npm:3.972.24" - dependencies: - "@aws-sdk/core": "npm:^3.973.24" - "@aws-sdk/nested-clients": "npm:^3.996.14" - "@aws-sdk/token-providers": "npm:3.1015.0" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/shared-ini-file-loader": "npm:^4.4.7" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/dab037f6d91c522b0a6c2f587e1fa8b36043a253523351c9cb9541dac2d1559af70fbd81ea1fe3202bf5e88d2d0e80df02950a0bf3b7c21ac30501499667f10d - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-web-identity@npm:3.830.0": - version: 3.830.0 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.830.0" +"@aws-sdk/credential-provider-process@npm:^3.972.23": + version: 3.972.23 + resolution: "@aws-sdk/credential-provider-process@npm:3.972.23" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/types": "npm:^3.973.6" @@ -742,21 +602,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:^3.972.24": - version: 3.972.24 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.24" - dependencies: - "@aws-sdk/core": "npm:^3.973.24" - "@aws-sdk/nested-clients": "npm:^3.996.14" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/shared-ini-file-loader": "npm:^4.4.7" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/12f90ac10dae3669ed7b1069d30cf7a423346af912e0aeb64469e85f65782ec4746733431027c374820f1a060a1593de7e540b8b6c69b82bd09e0306bdba7ad4 - languageName: node - linkType: hard - "@aws-sdk/credential-providers@npm:^3.350.0": version: 3.1019.0 resolution: "@aws-sdk/credential-providers@npm:3.1019.0" @@ -785,21 +630,21 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/eventstream-handler-node@npm:^3.972.11": - version: 3.972.11 - resolution: "@aws-sdk/eventstream-handler-node@npm:3.972.11" +"@aws-sdk/eventstream-handler-node@npm:^3.972.12": + version: 3.972.12 + resolution: "@aws-sdk/eventstream-handler-node@npm:3.972.12" dependencies: "@aws-sdk/types": "npm:^3.973.6" "@smithy/eventstream-codec": "npm:^4.2.12" "@smithy/types": "npm:^4.13.1" tslib: "npm:^2.6.2" - checksum: 10/fdfd847f736cec809389b9507515328e7ed2288e1e9892dcba0ba43cafd82f6d42de0d4aad989542b1cc35c8d973fa7b63f7dcc93059f1ddd6f5bb266e83977e + checksum: 10/6f90ac1cb9faf204984c9dead9022ec79325b6565f03d87137f4636e653ff6ad03944ee0417b136effdcc5591419587673b54fc065e4f02c9ca67f42f8f8dbed languageName: node linkType: hard -"@aws-sdk/middleware-bucket-endpoint@npm:3.830.0": - version: 3.830.0 - resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.830.0" +"@aws-sdk/middleware-bucket-endpoint@npm:^3.972.8": + version: 3.972.8 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.972.8" dependencies: "@aws-sdk/types": "npm:^3.973.6" "@aws-sdk/util-arn-parser": "npm:^3.972.3" @@ -824,9 +669,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-expect-continue@npm:3.821.0": - version: 3.821.0 - resolution: "@aws-sdk/middleware-expect-continue@npm:3.821.0" +"@aws-sdk/middleware-expect-continue@npm:^3.972.8": + version: 3.972.8 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.972.8" dependencies: "@aws-sdk/types": "npm:^3.973.6" "@smithy/protocol-http": "npm:^5.3.12" @@ -870,21 +715,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-host-header@npm:^3.972.8": +"@aws-sdk/middleware-location-constraint@npm:^3.972.8": version: 3.972.8 - resolution: "@aws-sdk/middleware-host-header@npm:3.972.8" - dependencies: - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/1af0015aa4e1f243d20054501148c27f62af974cc92735a38723ed909396bc98f7cddbf76a1237c8e08b46ab4b54cbf7f47c239263002a441aad4807feb41750 - languageName: node - linkType: hard - -"@aws-sdk/middleware-location-constraint@npm:3.821.0": - version: 3.821.0 - resolution: "@aws-sdk/middleware-location-constraint@npm:3.821.0" + resolution: "@aws-sdk/middleware-location-constraint@npm:3.972.8" dependencies: "@aws-sdk/types": "npm:^3.973.6" "@smithy/types": "npm:^4.13.1" @@ -904,20 +737,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-logger@npm:^3.972.8": - version: 3.972.8 - resolution: "@aws-sdk/middleware-logger@npm:3.972.8" - dependencies: - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/e6f56fb83fd5bdbe6d354648596ce3ffff5293c87a48d06365e1a9fd41bdc6da4f53240908bc7d3b69e735905506ef89078a5812d1252e7f46bcb82255e5999b - languageName: node - linkType: hard - -"@aws-sdk/middleware-recursion-detection@npm:3.821.0": - version: 3.821.0 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.821.0" +"@aws-sdk/middleware-recursion-detection@npm:^3.972.9": + version: 3.972.9 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.972.9" dependencies: "@aws-sdk/types": "npm:^3.973.6" "@aws/lambda-invoke-store": "npm:^0.2.2" @@ -928,22 +750,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-recursion-detection@npm:^3.972.8": - version: 3.972.8 - resolution: "@aws-sdk/middleware-recursion-detection@npm:3.972.8" - dependencies: - "@aws-sdk/types": "npm:^3.973.6" - "@aws/lambda-invoke-store": "npm:^0.2.2" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/64b7ed16e8e401d091bb6cd612abe639f5626f8f20350c1cc5e7ce55c10ee31506315aecf270f2f4920a7ea53bd649c604851e9209f60c18427e7b0b9e0e0fda - languageName: node - linkType: hard - -"@aws-sdk/middleware-sdk-s3@npm:3.826.0": - version: 3.826.0 - resolution: "@aws-sdk/middleware-sdk-s3@npm:3.826.0" +"@aws-sdk/middleware-sdk-s3@npm:^3.972.26": + version: 3.972.26 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.972.26" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/types": "npm:^3.973.6" @@ -990,25 +799,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:^3.972.25": - version: 3.972.25 - resolution: "@aws-sdk/middleware-user-agent@npm:3.972.25" - dependencies: - "@aws-sdk/core": "npm:^3.973.24" - "@aws-sdk/types": "npm:^3.973.6" - "@aws-sdk/util-endpoints": "npm:^3.996.5" - "@smithy/core": "npm:^3.23.12" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/types": "npm:^4.13.1" - "@smithy/util-retry": "npm:^4.2.12" - tslib: "npm:^2.6.2" - checksum: 10/b116df7632d2b05fb05e7a74440fdd0726c12bafb95149c867155b61fc8c43983ccc712a98a1c83470603079160700fb964c43c990dbba5c05b5ec8dbbf0a57e - languageName: node - linkType: hard - -"@aws-sdk/middleware-websocket@npm:^3.972.13": - version: 3.972.13 - resolution: "@aws-sdk/middleware-websocket@npm:3.972.13" +"@aws-sdk/middleware-websocket@npm:^3.972.14": + version: 3.972.14 + resolution: "@aws-sdk/middleware-websocket@npm:3.972.14" dependencies: "@aws-sdk/types": "npm:^3.973.6" "@aws-sdk/util-format-url": "npm:^3.972.8" @@ -1022,13 +815,13 @@ __metadata: "@smithy/util-hex-encoding": "npm:^4.2.2" "@smithy/util-utf8": "npm:^4.2.2" tslib: "npm:^2.6.2" - checksum: 10/8eae454c8466d11107c6fefb740a97097fa3691f826a7a1f446940bda1009796f6016a7a301592feae10181a144b4dda35fb57fe55dd4d951332514c00438ba6 + checksum: 10/ed114e4d0f8222dec2dfdde9ad3742014bd258ee02dab2e79236dd77f64147162be4ced63aeb0f00bc70c144e47fd252ca3254a757125fc6d385df8f0a6651ad languageName: node linkType: hard -"@aws-sdk/nested-clients@npm:3.830.0": - version: 3.830.0 - resolution: "@aws-sdk/nested-clients@npm:3.830.0" +"@aws-sdk/nested-clients@npm:^3.996.16": + version: 3.996.16 + resolution: "@aws-sdk/nested-clients@npm:3.996.16" dependencies: "@aws-crypto/sha256-browser": "npm:5.2.0" "@aws-crypto/sha256-js": "npm:5.2.0" @@ -1072,55 +865,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/nested-clients@npm:^3.996.14": - version: 3.996.14 - resolution: "@aws-sdk/nested-clients@npm:3.996.14" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:^3.973.24" - "@aws-sdk/middleware-host-header": "npm:^3.972.8" - "@aws-sdk/middleware-logger": "npm:^3.972.8" - "@aws-sdk/middleware-recursion-detection": "npm:^3.972.8" - "@aws-sdk/middleware-user-agent": "npm:^3.972.25" - "@aws-sdk/region-config-resolver": "npm:^3.972.9" - "@aws-sdk/types": "npm:^3.973.6" - "@aws-sdk/util-endpoints": "npm:^3.996.5" - "@aws-sdk/util-user-agent-browser": "npm:^3.972.8" - "@aws-sdk/util-user-agent-node": "npm:^3.973.11" - "@smithy/config-resolver": "npm:^4.4.13" - "@smithy/core": "npm:^3.23.12" - "@smithy/fetch-http-handler": "npm:^5.3.15" - "@smithy/hash-node": "npm:^4.2.12" - "@smithy/invalid-dependency": "npm:^4.2.12" - "@smithy/middleware-content-length": "npm:^4.2.12" - "@smithy/middleware-endpoint": "npm:^4.4.27" - "@smithy/middleware-retry": "npm:^4.4.44" - "@smithy/middleware-serde": "npm:^4.2.15" - "@smithy/middleware-stack": "npm:^4.2.12" - "@smithy/node-config-provider": "npm:^4.3.12" - "@smithy/node-http-handler": "npm:^4.5.0" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/smithy-client": "npm:^4.12.7" - "@smithy/types": "npm:^4.13.1" - "@smithy/url-parser": "npm:^4.2.12" - "@smithy/util-base64": "npm:^4.3.2" - "@smithy/util-body-length-browser": "npm:^4.2.2" - "@smithy/util-body-length-node": "npm:^4.2.3" - "@smithy/util-defaults-mode-browser": "npm:^4.3.43" - "@smithy/util-defaults-mode-node": "npm:^4.2.47" - "@smithy/util-endpoints": "npm:^3.3.3" - "@smithy/util-middleware": "npm:^4.2.12" - "@smithy/util-retry": "npm:^4.2.12" - "@smithy/util-utf8": "npm:^4.2.2" - tslib: "npm:^2.6.2" - checksum: 10/3e6fffc8fb3bb315653e34be7076dd7cdafb3525565df7dcb623c4472a6fb40fa75c1f1164709b45116488ee4d51cb2d969e053ce612d57014890e69c2af2583 - languageName: node - linkType: hard - -"@aws-sdk/region-config-resolver@npm:3.821.0": - version: 3.821.0 - resolution: "@aws-sdk/region-config-resolver@npm:3.821.0" +"@aws-sdk/region-config-resolver@npm:^3.972.10": + version: 3.972.10 + resolution: "@aws-sdk/region-config-resolver@npm:3.972.10" dependencies: "@aws-sdk/types": "npm:^3.973.6" "@smithy/config-resolver": "npm:^4.4.13" @@ -1131,22 +878,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/region-config-resolver@npm:^3.972.9": - version: 3.972.9 - resolution: "@aws-sdk/region-config-resolver@npm:3.972.9" - dependencies: - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/config-resolver": "npm:^4.4.13" - "@smithy/node-config-provider": "npm:^4.3.12" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/ee63dc5d193db23830c53b67d6b6b2b163102a396f8a5f390f136b4a00bd5bd80ef7ef4f9112605d81eaa5c7c2b17ddc5e4b1f91ccb13173aa788ebad65aac22 - languageName: node - linkType: hard - -"@aws-sdk/signature-v4-multi-region@npm:3.826.0": - version: 3.826.0 - resolution: "@aws-sdk/signature-v4-multi-region@npm:3.826.0" +"@aws-sdk/signature-v4-multi-region@npm:^3.996.14": + version: 3.996.14 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.996.14" dependencies: "@aws-sdk/middleware-sdk-s3": "npm:^3.972.26" "@aws-sdk/types": "npm:^3.973.6" @@ -1158,24 +892,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.1015.0": - version: 3.1015.0 - resolution: "@aws-sdk/token-providers@npm:3.1015.0" - dependencies: - "@aws-sdk/core": "npm:^3.973.24" - "@aws-sdk/nested-clients": "npm:^3.996.14" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/shared-ini-file-loader": "npm:^4.4.7" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/d364bbe0f2c6187b1aeb68e917397d4d18276c773f62d8de978a62f7901e0cab38facca202730f5687bce3fcad0705b850c529d0f39340464867e35f83003c7d - languageName: node - linkType: hard - -"@aws-sdk/token-providers@npm:3.830.0": - version: 3.830.0 - resolution: "@aws-sdk/token-providers@npm:3.830.0" +"@aws-sdk/token-providers@npm:3.1019.0": + version: 3.1019.0 + resolution: "@aws-sdk/token-providers@npm:3.1019.0" dependencies: "@aws-sdk/core": "npm:^3.973.25" "@aws-sdk/nested-clients": "npm:^3.996.16" @@ -1198,16 +917,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:3.821.0": - version: 3.821.0 - resolution: "@aws-sdk/types@npm:3.821.0" - dependencies: - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/74f0ef0da96aab5e9a2838c02a0ecbf3cda5cba09711378c1eb980f66ce511eb6929e3f46743538f64854d75fe27d23bf7b67790df6df09a10bedf0a7a5ccb7f - languageName: node - linkType: hard - "@aws-sdk/types@npm:^3.0.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0, @aws-sdk/types@npm:^3.973.6": version: 3.973.6 resolution: "@aws-sdk/types@npm:3.973.6" @@ -1218,9 +927,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-arn-parser@npm:3.804.0, @aws-sdk/util-arn-parser@npm:^3.310.0": - version: 3.804.0 - resolution: "@aws-sdk/util-arn-parser@npm:3.804.0" +"@aws-sdk/util-arn-parser@npm:^3.310.0, @aws-sdk/util-arn-parser@npm:^3.972.3": + version: 3.972.3 + resolution: "@aws-sdk/util-arn-parser@npm:3.972.3" dependencies: tslib: "npm:^2.6.2" checksum: 10/140a30615c914bcb37a5bb6ff825e8b6d2bedea757c2b03a4f5abb986003683ceadc322c0ee9f9a3ba4d5925357515ed7be01ef13c56c3b0126d4e1bd7292a33 @@ -1240,19 +949,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-endpoints@npm:^3.996.5": - version: 3.996.5 - resolution: "@aws-sdk/util-endpoints@npm:3.996.5" - dependencies: - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/types": "npm:^4.13.1" - "@smithy/url-parser": "npm:^4.2.12" - "@smithy/util-endpoints": "npm:^3.3.3" - tslib: "npm:^2.6.2" - checksum: 10/44c43c71f69981afc5238e25292fbe56a4552295ab0589a17215cf0d476ea63679a62142aeab9e30c76ae65b5f408a0d5e11513255be14c2d7dbeaaa2cc428c5 - languageName: node - linkType: hard - "@aws-sdk/util-format-url@npm:^3.972.8": version: 3.972.8 resolution: "@aws-sdk/util-format-url@npm:3.972.8" @@ -1286,21 +982,9 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-browser@npm:^3.972.8": - version: 3.972.8 - resolution: "@aws-sdk/util-user-agent-browser@npm:3.972.8" - dependencies: - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/types": "npm:^4.13.1" - bowser: "npm:^2.11.0" - tslib: "npm:^2.6.2" - checksum: 10/cb0f9b1daa8ce90e174d75c60d0b42360d952a710fef0c3bed21d3bfbabf814e1137e94a0edb3fa4eb8f5d4ee166fd94b9f56deb5878495b818c1ddbfe04e543 - languageName: node - linkType: hard - -"@aws-sdk/util-user-agent-node@npm:3.828.0": - version: 3.828.0 - resolution: "@aws-sdk/util-user-agent-node@npm:3.828.0" +"@aws-sdk/util-user-agent-node@npm:^3.973.12": + version: 3.973.12 + resolution: "@aws-sdk/util-user-agent-node@npm:3.973.12" dependencies: "@aws-sdk/middleware-user-agent": "npm:^3.972.26" "@aws-sdk/types": "npm:^3.973.6" @@ -1317,51 +1001,14 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:^3.973.11": - version: 3.973.11 - resolution: "@aws-sdk/util-user-agent-node@npm:3.973.11" +"@aws-sdk/xml-builder@npm:^3.972.16": + version: 3.972.16 + resolution: "@aws-sdk/xml-builder@npm:3.972.16" dependencies: - "@aws-sdk/middleware-user-agent": "npm:^3.972.25" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/node-config-provider": "npm:^4.3.12" "@smithy/types": "npm:^4.13.1" - "@smithy/util-config-provider": "npm:^4.2.2" + fast-xml-parser: "npm:5.5.8" tslib: "npm:^2.6.2" - peerDependencies: - aws-crt: ">=1.0.0" - peerDependenciesMeta: - aws-crt: - optional: true - checksum: 10/1e55e1562750a2fc4147623e187299939d07891d39ad2e1a1335595d8883d97a22f5fe4544a5be8fdde85f45aa35cf8f04efe6dd207d5c90c6ce9655d6c37df9 - languageName: node - linkType: hard - -"@aws-sdk/xml-builder@npm:3.821.0": - version: 3.821.0 - resolution: "@aws-sdk/xml-builder@npm:3.821.0" - dependencies: - "@smithy/types": "npm:^4.13.1" - fast-xml-parser: "npm:5.5.8" - tslib: "npm:^2.6.2" - checksum: 10/6e67c69b4f101d60b3cb7394ea71c463bfeac68a3e4bd0a70773e59c00b0cbc87f808949c1d7cd72d4bb7e849373ba6af7ef5a27f1f9e87b1f2b4f79f9b6d4c0 - languageName: node - linkType: hard - -"@aws/lambda-invoke-store@npm:^0.2.2": - version: 0.2.4 - resolution: "@aws/lambda-invoke-store@npm:0.2.4" - checksum: 10/47e73cf73141be73854c69722502e928a435b3d908ffa693a9545c1099dd7b2dd3f67c43c523d786a75911100e77ed52dce1f88d09363a67526448c5b7c804d5 - languageName: node - linkType: hard - -"@aws-sdk/xml-builder@npm:^3.972.15": - version: 3.972.15 - resolution: "@aws-sdk/xml-builder@npm:3.972.15" - dependencies: - "@smithy/types": "npm:^4.13.1" - fast-xml-parser: "npm:5.5.8" - tslib: "npm:^2.6.2" - checksum: 10/03574e017f58a3317682210f43aa9c8db37396efd679bdddb49bdfbd85d54db055d07f95644981dba6244d8c9d3cb2ae360572b35a740bf3f5463cc8a96022bf + checksum: 10/6e67c69b4f101d60b3cb7394ea71c463bfeac68a3e4bd0a70773e59c00b0cbc87f808949c1d7cd72d4bb7e849373ba6af7ef5a27f1f9e87b1f2b4f79f9b6d4c0 languageName: node linkType: hard @@ -1589,9 +1236,9 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.26.2, @babel/code-frame@npm:^7.27.1, @babel/code-frame@npm:^7.8.3": - version: 7.28.6 - resolution: "@babel/code-frame@npm:7.28.6" +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.28.6, @babel/code-frame@npm:^7.29.0, @babel/code-frame@npm:^7.8.3": + version: 7.29.0 + resolution: "@babel/code-frame@npm:7.29.0" dependencies: "@babel/helper-validator-identifier": "npm:^7.28.5" js-tokens: "npm:^4.0.0" @@ -1600,91 +1247,1348 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.27.3": - version: 7.27.5 - resolution: "@babel/generator@npm:7.27.5" +"@babel/compat-data@npm:^7.28.6, @babel/compat-data@npm:^7.29.0": + version: 7.29.0 + resolution: "@babel/compat-data@npm:7.29.0" + checksum: 10/7f21beedb930ed8fbf7eabafc60e6e6521c1d905646bf1317a61b2163339157fe797efeb85962bf55136e166b01fd1a6b526a15974b92a8b877d564dcb6c9580 + languageName: node + linkType: hard + +"@babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.19.6, @babel/core@npm:^7.23.9": + version: 7.29.0 + resolution: "@babel/core@npm:7.29.0" + dependencies: + "@babel/code-frame": "npm:^7.29.0" + "@babel/generator": "npm:^7.29.0" + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-module-transforms": "npm:^7.28.6" + "@babel/helpers": "npm:^7.28.6" + "@babel/parser": "npm:^7.29.0" + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + "@jridgewell/remapping": "npm:^2.3.5" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^6.3.1" + checksum: 10/25f4e91688cdfbaf1365831f4f245b436cdaabe63d59389b75752013b8d61819ee4257101b52fc328b0546159fd7d0e74457ed7cf12c365fea54be4fb0a40229 + languageName: node + linkType: hard + +"@babel/generator@npm:^7.29.0, @babel/generator@npm:^7.7.2": + version: 7.29.1 + resolution: "@babel/generator@npm:7.29.1" + dependencies: + "@babel/parser": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + "@jridgewell/gen-mapping": "npm:^0.3.12" + "@jridgewell/trace-mapping": "npm:^0.3.28" + jsesc: "npm:^3.0.2" + checksum: 10/61fe4ddd6e817aa312a14963ccdbb5c9a8c57e8b97b98d19a8a99ccab2215fda1a5f52bc8dd8d2e3c064497ddeb3ab8ceb55c76fa0f58f8169c34679d2256fe0 + languageName: node + linkType: hard + +"@babel/helper-annotate-as-pure@npm:^7.27.1, @babel/helper-annotate-as-pure@npm:^7.27.3": + version: 7.27.3 + resolution: "@babel/helper-annotate-as-pure@npm:7.27.3" + dependencies: + "@babel/types": "npm:^7.27.3" + checksum: 10/63863a5c936ef82b546ca289c9d1b18fabfc24da5c4ee382830b124e2e79b68d626207febc8d4bffc720f50b2ee65691d7d12cc0308679dee2cd6bdc926b7190 + languageName: node + linkType: hard + +"@babel/helper-compilation-targets@npm:^7.27.1, @babel/helper-compilation-targets@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-compilation-targets@npm:7.28.6" + dependencies: + "@babel/compat-data": "npm:^7.28.6" + "@babel/helper-validator-option": "npm:^7.27.1" + browserslist: "npm:^4.24.0" + lru-cache: "npm:^5.1.1" + semver: "npm:^6.3.1" + checksum: 10/f512a5aeee4dfc6ea8807f521d085fdca8d66a7d068a6dd5e5b37da10a6081d648c0bbf66791a081e4e8e6556758da44831b331540965dfbf4f5275f3d0a8788 + languageName: node + linkType: hard + +"@babel/helper-create-class-features-plugin@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-create-class-features-plugin@npm:7.28.6" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + "@babel/helper-member-expression-to-functions": "npm:^7.28.5" + "@babel/helper-optimise-call-expression": "npm:^7.27.1" + "@babel/helper-replace-supers": "npm:^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.6" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/11f55607fcf66827ade745c0616aa3c6086aa655c0fab665dd3c4961829752e4c94c942262db30c4831ef9bce37ad444722e85ef1b7136587e28c6b1ef8ad43c + languageName: node + linkType: hard + +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.27.1, @babel/helper-create-regexp-features-plugin@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.28.5" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + regexpu-core: "npm:^6.3.1" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/d8791350fe0479af0909aa5efb6dfd3bacda743c7c3f8fa1b0bb18fe014c206505834102ee24382df1cfe5a83b4e4083220e97f420a48b2cec15bb1ad6c7c9d3 + languageName: node + linkType: hard + +"@babel/helper-define-polyfill-provider@npm:^0.6.8": + version: 0.6.8 + resolution: "@babel/helper-define-polyfill-provider@npm:0.6.8" + dependencies: + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + debug: "npm:^4.4.3" + lodash.debounce: "npm:^4.0.8" + resolve: "npm:^1.22.11" + peerDependencies: + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 10/a6f9fbb82578464da35eec88c7f3e70bdd95237bfc1d3ebb9cf4536a86a577b7c6e587f9a6797b01ee08629599ee2bc6fdab39e99de505751a30d9b4877202ab + languageName: node + linkType: hard + +"@babel/helper-globals@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/helper-globals@npm:7.28.0" + checksum: 10/91445f7edfde9b65dcac47f4f858f68dc1661bf73332060ab67ad7cc7b313421099a2bfc4bda30c3db3842cfa1e86fffbb0d7b2c5205a177d91b22c8d7d9cb47 + languageName: node + linkType: hard + +"@babel/helper-member-expression-to-functions@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/helper-member-expression-to-functions@npm:7.28.5" + dependencies: + "@babel/traverse": "npm:^7.28.5" + "@babel/types": "npm:^7.28.5" + checksum: 10/05e0857cf7913f03d88ca62952d3888693c21a4f4d7cfc141c630983f71fc0a64393e05cecceb7701dfe98298f7cc38fcb735d892e3c8c6f56f112c85ee1b154 + languageName: node + linkType: hard + +"@babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-module-imports@npm:7.28.6" + dependencies: + "@babel/traverse": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + checksum: 10/64b1380d74425566a3c288074d7ce4dea56d775d2d3325a3d4a6df1dca702916c1d268133b6f385de9ba5b822b3c6e2af5d3b11ac88e5453d5698d77264f0ec0 + languageName: node + linkType: hard + +"@babel/helper-module-transforms@npm:^7.27.1, @babel/helper-module-transforms@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-module-transforms@npm:7.28.6" + dependencies: + "@babel/helper-module-imports": "npm:^7.28.6" + "@babel/helper-validator-identifier": "npm:^7.28.5" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/2e421c7db743249819ee51e83054952709dc2e197c7d5d415b4bdddc718580195704bfcdf38544b3f674efc2eccd4d29a65d38678fc827ed3934a7690984cd8b + languageName: node + linkType: hard + +"@babel/helper-optimise-call-expression@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-optimise-call-expression@npm:7.27.1" + dependencies: + "@babel/types": "npm:^7.27.1" + checksum: 10/0fb7ee824a384529d6b74f8a58279f9b56bfe3cce332168067dddeab2552d8eeb56dc8eaf86c04a3a09166a316cb92dfc79c4c623cd034ad4c563952c98b464f + languageName: node + linkType: hard + +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.27.1, @babel/helper-plugin-utils@npm:^7.28.6, @babel/helper-plugin-utils@npm:^7.8.0": + version: 7.28.6 + resolution: "@babel/helper-plugin-utils@npm:7.28.6" + checksum: 10/21c853bbc13dbdddf03309c9a0477270124ad48989e1ad6524b83e83a77524b333f92edd2caae645c5a7ecf264ec6d04a9ebe15aeb54c7f33c037b71ec521e4a + languageName: node + linkType: hard + +"@babel/helper-remap-async-to-generator@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-remap-async-to-generator@npm:7.27.1" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.1" + "@babel/helper-wrap-function": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/0747397ba013f87dbf575454a76c18210d61c7c9af0f697546b4bcac670b54ddc156330234407b397f0c948738c304c228e0223039bc45eab4fbf46966a5e8cc + languageName: node + linkType: hard + +"@babel/helper-replace-supers@npm:^7.27.1, @babel/helper-replace-supers@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-replace-supers@npm:7.28.6" + dependencies: + "@babel/helper-member-expression-to-functions": "npm:^7.28.5" + "@babel/helper-optimise-call-expression": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/ad2724713a4d983208f509e9607e8f950855f11bd97518a700057eb8bec69d687a8f90dc2da0c3c47281d2e3b79cf1d14ecf1fe3e1ee0a8e90b61aee6759c9a7 + languageName: node + linkType: hard + +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.27.1" + dependencies: + "@babel/traverse": "npm:^7.27.1" + "@babel/types": "npm:^7.27.1" + checksum: 10/4f380c5d0e0769fa6942a468b0c2d7c8f0c438f941aaa88f785f8752c103631d0904c7b4e76207a3b0e6588b2dec376595370d92ca8f8f1b422c14a69aa146d4 + languageName: node + linkType: hard + +"@babel/helper-string-parser@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-string-parser@npm:7.27.1" + checksum: 10/0ae29cc2005084abdae2966afdb86ed14d41c9c37db02c3693d5022fba9f5d59b011d039380b8e537c34daf117c549f52b452398f576e908fb9db3c7abbb3a00 + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.25.9, @babel/helper-validator-identifier@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/helper-validator-identifier@npm:7.28.5" + checksum: 10/8e5d9b0133702cfacc7f368bf792f0f8ac0483794877c6dca5fcb73810ee138e27527701826fb58a40a004f3a5ec0a2f3c3dd5e326d262530b119918f3132ba7 + languageName: node + linkType: hard + +"@babel/helper-validator-option@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-option@npm:7.27.1" + checksum: 10/db73e6a308092531c629ee5de7f0d04390835b21a263be2644276cb27da2384b64676cab9f22cd8d8dbd854c92b1d7d56fc8517cf0070c35d1c14a8c828b0903 + languageName: node + linkType: hard + +"@babel/helper-wrap-function@npm:^7.27.1": + version: 7.28.6 + resolution: "@babel/helper-wrap-function@npm:7.28.6" + dependencies: + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + checksum: 10/d8a895a75399904746f4127db33593a20021fc55d1a5b5dfeb060b87cc13a8dceea91e70a4951bcd376ba9bd8232b0c04bff9a86c1dab83d691e01852c3b5bcd + languageName: node + linkType: hard + +"@babel/helpers@npm:^7.28.6": + version: 7.29.2 + resolution: "@babel/helpers@npm:7.29.2" + dependencies: + "@babel/template": "npm:^7.28.6" + "@babel/types": "npm:^7.29.0" + checksum: 10/ad77706f3f917bd224e037fd0fbc67c45b240d2a45981321b093f70b7c535bee9bbddb0a19e34c362cb000ae21cdd8638f8a87a5f305a5bd7547e93fdcc524fe + languageName: node + linkType: hard + +"@babel/highlight@npm:^7.0.0": + version: 7.25.9 + resolution: "@babel/highlight@npm:7.25.9" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.25.9" + chalk: "npm:^2.4.2" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.0.0" + checksum: 10/0d165283dd4eb312292cea8fec3ae0d376874b1885f476014f0136784ed5b564b2c2ba2d270587ed546ee92505056dab56493f7960c01c4e6394d71d1b2e7db6 + languageName: node + linkType: hard + +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.28.6, @babel/parser@npm:^7.29.0": + version: 7.29.2 + resolution: "@babel/parser@npm:7.29.2" + dependencies: + "@babel/types": "npm:^7.29.0" + bin: + parser: ./bin/babel-parser.js + checksum: 10/45d050bf75aa5194b3255f156173e8553d615ff5a2434674cc4a10cdc7c261931befb8618c996a1c449b87f0ef32a3407879af2ac967d95dc7b4fdbae7037efa + languageName: node + linkType: hard + +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.28.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.5" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/750de98b34e6d09b545ded6e635b43cbab02fe319622964175259b98f41b16052e5931c4fbd45bad8cd0a37ebdd381233edecec9ee395b8ec51f47f47d1dbcd4 + languageName: node + linkType: hard + +"@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-bugfix-safari-class-field-initializer-scope@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/eb7f4146dc01f1198ce559a90b077e58b951a07521ec414e3c7d4593bf6c4ab5c2af22242a7e9fec085e20299e0ba6ea97f44a45e84ab148141bf9eb959ad25e + languageName: node + linkType: hard + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/621cfddfcc99a81e74f8b6f9101fd260b27500cb1a568e3ceae9cc8afe9aee45ac3bca3900a2b66c612b1a2366d29ef67d4df5a1c975be727eaad6906f98c2c6 + languageName: node + linkType: hard + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + "@babel/plugin-transform-optional-chaining": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.13.0 + checksum: 10/f07aa80272bd7a46b7ba11a4644da6c9b6a5a64e848dfaffdad6f02663adefd512e1aaebe664c4dd95f7ed4f80c872c7f8db8d8e34b47aae0930b412a28711a0 + languageName: node + linkType: hard + +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/9377897aa7cba3a0b78a7c6015799ff71504b2b203329357e42ab3185d44aab07344ba33f5dd53f14d5340c1dc5a2587346343e0859538947bbab0484e72b914 + languageName: node + linkType: hard + +"@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2": + version: 7.21.0-placeholder-for-preset-env.2 + resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/fab70f399aa869275690ec6c7cedb4ef361d4e8b6f55c3d7b04bfee61d52fb93c87cec2c65d73cddbaca89fb8ef5ec0921fce675c9169d9d51f18305ab34e78a + languageName: node + linkType: hard + +"@babel/plugin-syntax-async-generators@npm:^7.8.4": + version: 7.8.4 + resolution: "@babel/plugin-syntax-async-generators@npm:7.8.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/7ed1c1d9b9e5b64ef028ea5e755c0be2d4e5e4e3d6cf7df757b9a8c4cfa4193d268176d0f1f7fbecdda6fe722885c7fda681f480f3741d8a2d26854736f05367 + languageName: node + linkType: hard + +"@babel/plugin-syntax-bigint@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-bigint@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/3a10849d83e47aec50f367a9e56a6b22d662ddce643334b087f9828f4c3dd73bdc5909aaeabe123fed78515767f9ca43498a0e621c438d1cd2802d7fae3c9648 + languageName: node + linkType: hard + +"@babel/plugin-syntax-class-properties@npm:^7.12.13": + version: 7.12.13 + resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.12.13" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/24f34b196d6342f28d4bad303612d7ff566ab0a013ce89e775d98d6f832969462e7235f3e7eaf17678a533d4be0ba45d3ae34ab4e5a9dcbda5d98d49e5efa2fc + languageName: node + linkType: hard + +"@babel/plugin-syntax-class-static-block@npm:^7.14.5": + version: 7.14.5 + resolution: "@babel/plugin-syntax-class-static-block@npm:7.14.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.14.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/3e80814b5b6d4fe17826093918680a351c2d34398a914ce6e55d8083d72a9bdde4fbaf6a2dcea0e23a03de26dc2917ae3efd603d27099e2b98380345703bf948 + languageName: node + linkType: hard + +"@babel/plugin-syntax-import-assertions@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/25017235e1e2c4ed892aa327a3fa10f4209cc618c6dd7806fc40c07d8d7d24a39743d3d5568b8d1c8f416cffe03c174e78874ded513c9338b07a7ab1dcbab050 + languageName: node + linkType: hard + +"@babel/plugin-syntax-import-attributes@npm:^7.24.7, @babel/plugin-syntax-import-attributes@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/6c8c6a5988dbb9799d6027360d1a5ba64faabf551f2ef11ba4eade0c62253b5c85d44ddc8eb643c74b9acb2bcaa664a950bd5de9a5d4aef291c4f2a48223bb4b + languageName: node + linkType: hard + +"@babel/plugin-syntax-import-meta@npm:^7.10.4": + version: 7.10.4 + resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.10.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/166ac1125d10b9c0c430e4156249a13858c0366d38844883d75d27389621ebe651115cb2ceb6dc011534d5055719fa1727b59f39e1ab3ca97820eef3dcab5b9b + languageName: node + linkType: hard + +"@babel/plugin-syntax-json-strings@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-json-strings@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/bf5aea1f3188c9a507e16efe030efb996853ca3cadd6512c51db7233cc58f3ac89ff8c6bdfb01d30843b161cfe7d321e1bf28da82f7ab8d7e6bc5464666f354a + languageName: node + linkType: hard + +"@babel/plugin-syntax-jsx@npm:^7.27.1, @babel/plugin-syntax-jsx@npm:^7.28.6, @babel/plugin-syntax-jsx@npm:^7.7.2": + version: 7.28.6 + resolution: "@babel/plugin-syntax-jsx@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/572e38f5c1bb4b8124300e7e3dd13e82ae84a21f90d3f0786c98cd05e63c78ca1f32d1cfe462dfbaf5e7d5102fa7cd8fd741dfe4f3afc2e01a3b2877dcc8c866 + languageName: node + linkType: hard + +"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": + version: 7.10.4 + resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.10.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/aff33577037e34e515911255cdbb1fd39efee33658aa00b8a5fd3a4b903585112d037cce1cc9e4632f0487dc554486106b79ccd5ea63a2e00df4363f6d4ff886 + languageName: node + linkType: hard + +"@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-nullish-coalescing-operator@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/87aca4918916020d1fedba54c0e232de408df2644a425d153be368313fdde40d96088feed6c4e5ab72aac89be5d07fef2ddf329a15109c5eb65df006bf2580d1 + languageName: node + linkType: hard + +"@babel/plugin-syntax-numeric-separator@npm:^7.10.4": + version: 7.10.4 + resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.10.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/01ec5547bd0497f76cc903ff4d6b02abc8c05f301c88d2622b6d834e33a5651aa7c7a3d80d8d57656a4588f7276eba357f6b7e006482f5b564b7a6488de493a1 + languageName: node + linkType: hard + +"@babel/plugin-syntax-object-rest-spread@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-object-rest-spread@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/fddcf581a57f77e80eb6b981b10658421bc321ba5f0a5b754118c6a92a5448f12a0c336f77b8abf734841e102e5126d69110a306eadb03ca3e1547cab31f5cbf + languageName: node + linkType: hard + +"@babel/plugin-syntax-optional-catch-binding@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-optional-catch-binding@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/910d90e72bc90ea1ce698e89c1027fed8845212d5ab588e35ef91f13b93143845f94e2539d831dc8d8ededc14ec02f04f7bd6a8179edd43a326c784e7ed7f0b9 + languageName: node + linkType: hard + +"@babel/plugin-syntax-optional-chaining@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-optional-chaining@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/eef94d53a1453361553c1f98b68d17782861a04a392840341bc91780838dd4e695209c783631cf0de14c635758beafb6a3a65399846ffa4386bff90639347f30 + languageName: node + linkType: hard + +"@babel/plugin-syntax-private-property-in-object@npm:^7.14.5": + version: 7.14.5 + resolution: "@babel/plugin-syntax-private-property-in-object@npm:7.14.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.14.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/b317174783e6e96029b743ccff2a67d63d38756876e7e5d0ba53a322e38d9ca452c13354a57de1ad476b4c066dbae699e0ca157441da611117a47af88985ecda + languageName: node + linkType: hard + +"@babel/plugin-syntax-top-level-await@npm:^7.14.5": + version: 7.14.5 + resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.14.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/bbd1a56b095be7820029b209677b194db9b1d26691fe999856462e66b25b281f031f3dfd91b1619e9dcf95bebe336211833b854d0fb8780d618e35667c2d0d7e + languageName: node + linkType: hard + +"@babel/plugin-syntax-typescript@npm:^7.28.6, @babel/plugin-syntax-typescript@npm:^7.7.2": + version: 7.28.6 + resolution: "@babel/plugin-syntax-typescript@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/5c55f9c63bd36cf3d7e8db892294c8f85000f9c1526c3a1cc310d47d1e174f5c6f6605e5cc902c4636d885faba7a9f3d5e5edc6b35e4f3b1fd4c2d58d0304fa5 + languageName: node + linkType: hard + +"@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.18.6" + "@babel/helper-plugin-utils": "npm:^7.18.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/a651d700fe63ff0ddfd7186f4ebc24447ca734f114433139e3c027bc94a900d013cf1ef2e2db8430425ba542e39ae160c3b05f06b59fd4656273a3df97679e9c + languageName: node + linkType: hard + +"@babel/plugin-transform-arrow-functions@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-arrow-functions@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/62c2cc0ae2093336b1aa1376741c5ed245c0987d9e4b4c5313da4a38155509a7098b5acce582b6781cc0699381420010da2e3086353344abe0a6a0ec38961eb7 + languageName: node + linkType: hard + +"@babel/plugin-transform-async-generator-functions@npm:^7.29.0": + version: 7.29.0 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.29.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-remap-async-to-generator": "npm:^7.27.1" + "@babel/traverse": "npm:^7.29.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/e2c064a5eb212cbdf14f7c0113e069b845ca0f0ba431c1cc04607d3fc4f3bf1ed70f5c375fe7c61338a45db88bc1a79d270c8d633ce12256e1fce3666c1e6b93 + languageName: node + linkType: hard + +"@babel/plugin-transform-async-to-generator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-async-to-generator@npm:7.28.6" + dependencies: + "@babel/helper-module-imports": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-remap-async-to-generator": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/bca5774263ec01dd2bf71c74bbaf7baa183bf03576636b7826c3346be70c8c8cb15cff549112f2983c36885131a0afde6c443591278c281f733ee17f455aa9b1 + languageName: node + linkType: hard + +"@babel/plugin-transform-block-scoped-functions@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/7fb4988ca80cf1fc8345310d5edfe38e86b3a72a302675cdd09404d5064fe1d1fe1283ebe658ad2b71445ecef857bfb29a748064306b5f6c628e0084759c2201 + languageName: node + linkType: hard + +"@babel/plugin-transform-block-scoping@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-block-scoping@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/7ab8a0856024a5360ba16c3569b739385e939bc5a15ad7d811bec8459361a9aa5ee7c5f154a4e2ce79f5d66779c19464e7532600c31a1b6f681db4eb7e1c7bde + languageName: node + linkType: hard + +"@babel/plugin-transform-class-properties@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-class-properties@npm:7.28.6" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/200f30d44b36a768fa3a8cf690db9e333996af2ad14d9fa1b4c91a427ed9302907873b219b4ce87517ca1014a810eb2e929a6a66be68473f72b546fc64d04fbc + languageName: node + linkType: hard + +"@babel/plugin-transform-class-static-block@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-class-static-block@npm:7.28.6" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.12.0 + checksum: 10/bea7836846deefd02d9976ad1b30b5ade0d6329ecd92866db789dcf6aacfaf900b7a77031e25680f8de5ad636a771a5bdca8961361e6218d45d538ec5d9b71cc + languageName: node + linkType: hard + +"@babel/plugin-transform-classes@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-classes@npm:7.28.6" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-globals": "npm:^7.28.0" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-replace-supers": "npm:^7.28.6" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/9c3278a314d1c4bcda792bb22aced20e30c735557daf9bcc56397c0f3eb54761b21c770219e4581036a10dabda3e597321ed093bc245d5f4d561e19ceff66a6d + languageName: node + linkType: hard + +"@babel/plugin-transform-computed-properties@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-computed-properties@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/template": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/4a5e270f7e1f1e9787cf7cf133d48e3c1e38eb935d29a90331a1324d7c720f589b7b626b2e6485cd5521a7a13f2dbdc89a3e46ecbe7213d5bbb631175267c4aa + languageName: node + linkType: hard + +"@babel/plugin-transform-destructuring@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/plugin-transform-destructuring@npm:7.28.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/traverse": "npm:^7.28.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/9cc67d3377bc5d8063599f2eb4588f5f9a8ab3abc9b64a40c24501fb3c1f91f4d5cf281ea9f208fd6b2ef8d9d8b018dacf1bed9493334577c966cd32370a7036 + languageName: node + linkType: hard + +"@babel/plugin-transform-dotall-regex@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-dotall-regex@npm:7.28.6" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/866ffbbdee77fa955063b37c75593db8dbbe46b1ebb64cc788ea437e3a9aa41cb7b9afcee617c678a32b6705baa0892ec8e5d4b8af3bbb0ab1b254514ccdbd37 + languageName: node + linkType: hard + +"@babel/plugin-transform-duplicate-keys@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-duplicate-keys@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/987b718d2fab7626f61b72325c8121ead42341d6f46ad3a9b5e5f67f3ec558c903f1b8336277ffc43caac504ce00dd23a5456b5d1da23913333e1da77751f08d + languageName: node + linkType: hard + +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:^7.29.0": + version: 7.29.0 + resolution: "@babel/plugin-transform-duplicate-named-capturing-groups-regex@npm:7.29.0" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/7fa7b773259a578c9e01c80946f75ecc074520064aa7a87a65db06c7df70766e2fa6be78cda55fa9418a14e30b2b9d595484a46db48074d495d9f877a4276065 + languageName: node + linkType: hard + +"@babel/plugin-transform-dynamic-import@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-dynamic-import@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/7a9fbc8d17148b7f11a1d1ca3990d2c2cd44bd08a45dcaf14f20a017721235b9044b20e6168b6940282bb1b48fb78e6afbdfb9dd9d82fde614e15baa7d579932 + languageName: node + linkType: hard + +"@babel/plugin-transform-explicit-resource-management@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-explicit-resource-management@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/plugin-transform-destructuring": "npm:^7.28.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/36d638a253dbdaee5548b4ddd21c04ee4e39914b207437bb64cf79bb41c2caadb4321768d3dba308c1016702649bc44efe751e2052de393004563c7376210d86 + languageName: node + linkType: hard + +"@babel/plugin-transform-exponentiation-operator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/b232152499370435c7cd4bf3321f58e189150e35ca3722ea16533d33434b97294df1342f5499671ec48e62b71c34cdea0ca8cf317ad12594a10f6fc670315e62 + languageName: node + linkType: hard + +"@babel/plugin-transform-export-namespace-from@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-export-namespace-from@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/85082923eca317094f08f4953d8ea2a6558b3117826c0b740676983902b7236df1f4213ad844cb38c2dae104753dbe8f1cc51f01567835d476d32f5f544a4385 + languageName: node + linkType: hard + +"@babel/plugin-transform-for-of@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-for-of@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/705c591d17ef263c309bba8c38e20655e8e74ff7fd21883a9cdaf5bf1df42d724383ad3d88ac01f42926e15b1e1e66f2f7f8c4e87de955afffa290d52314b019 + languageName: node + linkType: hard + +"@babel/plugin-transform-function-name@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-function-name@npm:7.27.1" + dependencies: + "@babel/helper-compilation-targets": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/traverse": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/26a2a183c3c52a96495967420a64afc5a09f743a230272a131668abf23001e393afa6371e6f8e6c60f4182bea210ed31d1caf866452d91009c1daac345a52f23 + languageName: node + linkType: hard + +"@babel/plugin-transform-json-strings@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-json-strings@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/69d82a1a0a72ed6e6f7969e09cf330516599d79b2b4e680e9dd3c57616a8c6af049b5103456e370ab56642815e80e46ed88bb81e9e059304a85c5fe0bf137c29 + languageName: node + linkType: hard + +"@babel/plugin-transform-literals@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-literals@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/0a76d12ab19f32dd139964aea7da48cecdb7de0b75e207e576f0f700121fe92367d788f328bf4fb44b8261a0f605c97b44e62ae61cddbb67b14e94c88b411f95 + languageName: node + linkType: hard + +"@babel/plugin-transform-logical-assignment-operators@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/36095d5d1cfc680e95298b5389a16016da800ae3379b130dabf557e94652c47b06610407e9fa44aaa03e9b0a5aa7b4b93348123985d44a45e369bf5f3497d149 + languageName: node + linkType: hard + +"@babel/plugin-transform-member-expression-literals@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-member-expression-literals@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/804121430a6dcd431e6ffe99c6d1fbbc44b43478113b79c677629e7f877b4f78a06b69c6bfb2747fd84ee91879fe2eb32e4620b53124603086cf5b727593ebe8 + languageName: node + linkType: hard + +"@babel/plugin-transform-modules-amd@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-modules-amd@npm:7.27.1" + dependencies: + "@babel/helper-module-transforms": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/5ca9257981f2bbddd9dccf9126f1368de1cb335e7a5ff5cca9282266825af5b18b5f06c144320dcf5d2a200d2b53b6d22d9b801a55dc0509ab5a5838af7e61b7 + languageName: node + linkType: hard + +"@babel/plugin-transform-modules-commonjs@npm:^7.27.1, @babel/plugin-transform-modules-commonjs@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.28.6" + dependencies: + "@babel/helper-module-transforms": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/ec6ea2958e778a7e0220f4a75cb5816cecddc6bd98efa10499fff7baabaa29a594d50d787a4ebf8a8ba66fefcf76ca2ded602be0b4554ae3317e53b3b3375b37 + languageName: node + linkType: hard + +"@babel/plugin-transform-modules-systemjs@npm:^7.29.0": + version: 7.29.0 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.29.0" + dependencies: + "@babel/helper-module-transforms": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-validator-identifier": "npm:^7.28.5" + "@babel/traverse": "npm:^7.29.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/b3e64728eef02d829510778226da4c06be740fe52e0d45d4aa68b24083096d8ad7df67f2e9e67198b2e85f3237d42bd66f5771f85846f7a746105d05ca2e0cae + languageName: node + linkType: hard + +"@babel/plugin-transform-modules-umd@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-modules-umd@npm:7.27.1" + dependencies: + "@babel/helper-module-transforms": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/7388932863b4ee01f177eb6c2e2df9e2312005e43ada99897624d5565db4b9cef1e30aa7ad2c79bbe5373f284cfcddea98d8fe212714a24c6aba223272163058 + languageName: node + linkType: hard + +"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.29.0": + version: 7.29.0 + resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.29.0" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/ed8c27699ca82a6c01cbfd39f3de16b90cfea4f8146a358057f76df290d308a66a8bd2e6734e6a87f68c18576e15d2d70548a84cd474d26fdf256c3f5ae44d8c + languageName: node + linkType: hard + +"@babel/plugin-transform-new-target@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-new-target@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/620d78ee476ae70960989e477dc86031ffa3d554b1b1999e6ec95261629f7a13e5a7b98579c63a009f9fdf14def027db57de1f0ae1f06fb6eaed8908ff65cf68 + languageName: node + linkType: hard + +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/88106952ca4f4fea8f97222a25f9595c6859d458d76905845dfa54f54e7d345e3dc338932e8c84a9c57a6c88b2f6d9ebff47130ce508a49c2b6e6a9f03858750 + languageName: node + linkType: hard + +"@babel/plugin-transform-numeric-separator@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-numeric-separator@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/4b5ca60e481e22f0842761a3badca17376a230b5a7e5482338604eb95836c2d0c9c9bde53bdc5c2de1c6a12ae6c12de7464d098bf74b0943f85905ca358f0b68 + languageName: node + linkType: hard + +"@babel/plugin-transform-object-rest-spread@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.28.6" + dependencies: + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/plugin-transform-destructuring": "npm:^7.28.5" + "@babel/plugin-transform-parameters": "npm:^7.27.7" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/9c8c51a515a5ec98a33a715e82d49f873e58b04b53fa1e826f3c2009f7133cd396d6730553a53d265e096dbfbea17dd100ae38815d0b506c094cb316a7a5519e + languageName: node + linkType: hard + +"@babel/plugin-transform-object-super@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-object-super@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-replace-supers": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/46b819cb9a6cd3cfefe42d07875fee414f18d5e66040366ae856116db560ad4e16f3899a0a7fddd6773e0d1458444f94b208b67c0e3b6977a27ea17a5c13dbf6 + languageName: node + linkType: hard + +"@babel/plugin-transform-optional-catch-binding@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/ee24a17defec056eb9ef01824d7e4a1f65d531af6b4b79acfd0bcb95ce0b47926e80c61897f36f8c01ce733b069c9acdb1c9ce5ec07a729d0dbf9e8d859fe992 + languageName: node + linkType: hard + +"@babel/plugin-transform-optional-chaining@npm:^7.27.1, @babel/plugin-transform-optional-chaining@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/c7cf29f99384a9a98748f04489a122c0106e0316aa64a2e61ef8af74c1057b587b96d9a08eb4e33d2ac17d1aaff1f0a86fae658d429fa7bcce4ef977e0ad684b + languageName: node + linkType: hard + +"@babel/plugin-transform-parameters@npm:^7.27.7": + version: 7.27.7 + resolution: "@babel/plugin-transform-parameters@npm:7.27.7" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/ba0aa8c977a03bf83030668f64c1d721e4e82d8cce89cdde75a2755862b79dbe9e7f58ca955e68c721fd494d6ee3826e46efad3fbf0855fcc92cb269477b4777 + languageName: node + linkType: hard + +"@babel/plugin-transform-private-methods@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-private-methods@npm:7.28.6" + dependencies: + "@babel/helper-create-class-features-plugin": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/b80179b28f6a165674d0b0d6c6349b13a01dd282b18f56933423c0a33c23fc0626c8f011f859fc20737d021fe966eb8474a5233e4596401482e9ee7fb00e2aa2 + languageName: node + linkType: hard + +"@babel/plugin-transform-private-property-in-object@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-private-property-in-object@npm:7.28.6" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + "@babel/helper-create-class-features-plugin": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/d02008c62fd32ff747b850b8581ab5076b717320e1cb01c7fc66ebf5169095bd922e18cfb269992f85bc7fbd2cc61e5b5af25e2b54aad67411474b789ea94d5f + languageName: node + linkType: hard + +"@babel/plugin-transform-property-literals@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-property-literals@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/7caec27d5ed8870895c9faf4f71def72745d69da0d8e77903146a4e135fd7bed5778f5f9cebb36c5fba86338e6194dd67a08c033fc84b4299b7eceab6d9630cb + languageName: node + linkType: hard + +"@babel/plugin-transform-react-constant-elements@npm:^7.18.12": + version: 7.27.1 + resolution: "@babel/plugin-transform-react-constant-elements@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/906ea336502a42ca942f492f386111db4041c28c08f9dcc63eb816b75a1a96121505c1522c5e721dd192bf42a244799b78a8991e4abbf3fa17748dac1b6f142e + languageName: node + linkType: hard + +"@babel/plugin-transform-react-display-name@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/plugin-transform-react-display-name@npm:7.28.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/d623644a078086f410b1952429d82c10e2833ebffb97800b25f55ab7f3ffafde34e57a4a71958da73f4abfcef39b598e2ca172f2b43531f98b3f12e0de17c219 + languageName: node + linkType: hard + +"@babel/plugin-transform-react-jsx-development@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-react-jsx-development@npm:7.27.1" + dependencies: + "@babel/plugin-transform-react-jsx": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/b88865d5b8c018992f2332da939faa15c4d4a864c9435a5937beaff3fe43781432cc42e0a5d5631098e0bd4066fc33f5fa72203b388b074c3545fe7aaa21e474 + languageName: node + linkType: hard + +"@babel/plugin-transform-react-jsx@npm:^7.27.1": + version: 7.28.6 + resolution: "@babel/plugin-transform-react-jsx@npm:7.28.6" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + "@babel/helper-module-imports": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/plugin-syntax-jsx": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/c6eade7309f0710b6aac9e747f8c3305633801c035a35efc5e2436742cc466e457ed5848d3dd5dade36e34332cfc50ac92d69a33f7803d66ae2d72f13a76c3bc + languageName: node + linkType: hard + +"@babel/plugin-transform-react-pure-annotations@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.27.1" + dependencies: + "@babel/helper-annotate-as-pure": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/a6f591c5e85a1ab0685d4a25afe591fe8d11dc0b73c677cf9560ff8d540d036a1cce9efcb729fc9092def4d854dc304ffdc063a89a9247900b69c516bf971a4c + languageName: node + linkType: hard + +"@babel/plugin-transform-regenerator@npm:^7.29.0": + version: 7.29.0 + resolution: "@babel/plugin-transform-regenerator@npm:7.29.0" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/c8fa9da74371568c5d34fd7d53de018752550cb10334040ca59e41f34b27f127974bdc5b4d1a1a8e8f3ebcf3cb7f650aa3f2df3b7bf1b7edf67c04493b9e3cb8 + languageName: node + linkType: hard + +"@babel/plugin-transform-regexp-modifiers@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-regexp-modifiers@npm:7.28.6" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/5aacc570034c085afa0165137bb9a04cd4299b86eb9092933a96dcc1132c8f591d9d534419988f5f762b2f70d43a3c719a6b8fa05fdd3b2b1820d01cf85500da + languageName: node + linkType: hard + +"@babel/plugin-transform-reserved-words@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-reserved-words@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/dea0b66742d2863b369c06c053e11e15ba785892ea19cccf7aef3c1bdaa38b6ab082e19984c5ea7810d275d9445c5400fcc385ad71ce707ed9256fadb102af3b + languageName: node + linkType: hard + +"@babel/plugin-transform-shorthand-properties@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-shorthand-properties@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/fbba6e2aef0b69681acb68202aa249c0598e470cc0853d7ff5bd0171fd6a7ec31d77cfabcce9df6360fc8349eded7e4a65218c32551bd3fc0caaa1ac899ac6d4 + languageName: node + linkType: hard + +"@babel/plugin-transform-spread@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-spread@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/1fa02ac60ae5e49d46fa2966aaf3f7578cf37255534c2ecf379d65855088a1623c3eea28b9ee6a0b1413b0199b51f9019d0da3fe9da89986bc47e07242415f60 + languageName: node + linkType: hard + +"@babel/plugin-transform-sticky-regex@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-sticky-regex@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/e1414a502efba92c7974681767e365a8cda6c5e9e5f33472a9eaa0ce2e75cea0a9bef881ff8dda37c7810ad902f98d3c00ead92a3ac3b73a79d011df85b5a189 + languageName: node + linkType: hard + +"@babel/plugin-transform-template-literals@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-template-literals@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/93aad782503b691faef7c0893372d5243df3219b07f1f22cfc32c104af6a2e7acd6102c128439eab15336d048f1b214ca134b87b0630d8cd568bf447f78b25ce + languageName: node + linkType: hard + +"@babel/plugin-transform-typeof-symbol@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.27.1" dependencies: - "@babel/parser": "npm:^7.27.5" - "@babel/types": "npm:^7.27.3" - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.25" - jsesc: "npm:^3.0.2" - checksum: 10/f5e6942670cb32156b3ac2d75ce09b373558823387f15dd1413c27fe9eb5756a7c6011fc7f956c7acc53efb530bfb28afffa24364d46c4e9ffccc4e5c8b3b094 + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/812d736402a6f9313b86b8adf36740394400be7a09c48e51ee45ab4a383a3f46fc618d656dd12e44934665e42ae71cf143e25b95491b699ef7c737950dbdb862 languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.16.7": - version: 7.27.1 - resolution: "@babel/helper-module-imports@npm:7.27.1" +"@babel/plugin-transform-typescript@npm:^7.28.5": + version: 7.28.6 + resolution: "@babel/plugin-transform-typescript@npm:7.28.6" dependencies: - "@babel/traverse": "npm:^7.27.1" - "@babel/types": "npm:^7.27.1" - checksum: 10/58e792ea5d4ae71676e0d03d9fef33e886a09602addc3bd01388a98d87df9fcfd192968feb40ac4aedb7e287ec3d0c17b33e3ecefe002592041a91d8a1998a8d + "@babel/helper-annotate-as-pure": "npm:^7.27.3" + "@babel/helper-create-class-features-plugin": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.27.1" + "@babel/plugin-syntax-typescript": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/a0bccc531fa8710a45b0b593140273741e0e4a0721b1ef6ef9dfefae0bbe61528440d65aab7936929551fd76793272257d74f60cf66891352f793294930a4b67 languageName: node linkType: hard -"@babel/helper-string-parser@npm:^7.27.1": +"@babel/plugin-transform-unicode-escapes@npm:^7.27.1": version: 7.27.1 - resolution: "@babel/helper-string-parser@npm:7.27.1" - checksum: 10/0ae29cc2005084abdae2966afdb86ed14d41c9c37db02c3693d5022fba9f5d59b011d039380b8e537c34daf117c549f52b452398f576e908fb9db3c7abbb3a00 + resolution: "@babel/plugin-transform-unicode-escapes@npm:7.27.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/87b9e49dee4ab6e78f4cdcdbdd837d7784f02868a96bfc206c8dbb17dd85db161b5a0ecbe95b19a42e8aea0ce57e80249e1facbf9221d7f4114d52c3b9136c9e languageName: node linkType: hard -"@babel/helper-validator-identifier@npm:^7.25.9, @babel/helper-validator-identifier@npm:^7.28.5": - version: 7.28.5 - resolution: "@babel/helper-validator-identifier@npm:7.28.5" - checksum: 10/8e5d9b0133702cfacc7f368bf792f0f8ac0483794877c6dca5fcb73810ee138e27527701826fb58a40a004f3a5ec0a2f3c3dd5e326d262530b119918f3132ba7 +"@babel/plugin-transform-unicode-property-regex@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.28.6" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/d14e8c51aa73f592575c1543400fd67d96df6410d75c9dc10dd640fd7eecb37366a2f2368bbdd7529842532eda4af181c921bda95146c6d373c64ea59c6e9991 languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.27.1": +"@babel/plugin-transform-unicode-regex@npm:^7.27.1": version: 7.27.1 - resolution: "@babel/helper-validator-option@npm:7.27.1" - checksum: 10/db73e6a308092531c629ee5de7f0d04390835b21a263be2644276cb27da2384b64676cab9f22cd8d8dbd854c92b1d7d56fc8517cf0070c35d1c14a8c828b0903 + resolution: "@babel/plugin-transform-unicode-regex@npm:7.27.1" + dependencies: + "@babel/helper-create-regexp-features-plugin": "npm:^7.27.1" + "@babel/helper-plugin-utils": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/a34d89a2b75fb78e66d97c3dc90d4877f7e31f43316b52176f95a5dee20e9bb56ecf158eafc42a001676ddf7b393d9e67650bad6b32f5405780f25fb83cd68e3 languageName: node linkType: hard -"@babel/helper-wrap-function@npm:^7.27.1": +"@babel/plugin-transform-unicode-sets-regex@npm:^7.28.6": version: 7.28.6 - resolution: "@babel/helper-wrap-function@npm:7.28.6" + resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.28.6" dependencies: - "@babel/template": "npm:^7.28.6" - "@babel/traverse": "npm:^7.28.6" - "@babel/types": "npm:^7.28.6" - checksum: 10/d8a895a75399904746f4127db33593a20021fc55d1a5b5dfeb060b87cc13a8dceea91e70a4951bcd376ba9bd8232b0c04bff9a86c1dab83d691e01852c3b5bcd + "@babel/helper-create-regexp-features-plugin": "npm:^7.28.5" + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10/423971fe2eef9d18782b1c30f5f42613ee510e5b9c08760c5538a0997b36c34495acce261e0e37a27831f81330359230bd1f33c2e1822de70241002b45b7d68e languageName: node linkType: hard -"@babel/helpers@npm:^7.28.6": +"@babel/preset-env@npm:^7.19.4": version: 7.29.2 - resolution: "@babel/helpers@npm:7.29.2" + resolution: "@babel/preset-env@npm:7.29.2" + dependencies: + "@babel/compat-data": "npm:^7.29.0" + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-plugin-utils": "npm:^7.28.6" + "@babel/helper-validator-option": "npm:^7.27.1" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "npm:^7.28.5" + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "npm:^7.27.1" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.27.1" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "npm:^7.27.1" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "npm:^7.28.6" + "@babel/plugin-proposal-private-property-in-object": "npm:7.21.0-placeholder-for-preset-env.2" + "@babel/plugin-syntax-import-assertions": "npm:^7.28.6" + "@babel/plugin-syntax-import-attributes": "npm:^7.28.6" + "@babel/plugin-syntax-unicode-sets-regex": "npm:^7.18.6" + "@babel/plugin-transform-arrow-functions": "npm:^7.27.1" + "@babel/plugin-transform-async-generator-functions": "npm:^7.29.0" + "@babel/plugin-transform-async-to-generator": "npm:^7.28.6" + "@babel/plugin-transform-block-scoped-functions": "npm:^7.27.1" + "@babel/plugin-transform-block-scoping": "npm:^7.28.6" + "@babel/plugin-transform-class-properties": "npm:^7.28.6" + "@babel/plugin-transform-class-static-block": "npm:^7.28.6" + "@babel/plugin-transform-classes": "npm:^7.28.6" + "@babel/plugin-transform-computed-properties": "npm:^7.28.6" + "@babel/plugin-transform-destructuring": "npm:^7.28.5" + "@babel/plugin-transform-dotall-regex": "npm:^7.28.6" + "@babel/plugin-transform-duplicate-keys": "npm:^7.27.1" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "npm:^7.29.0" + "@babel/plugin-transform-dynamic-import": "npm:^7.27.1" + "@babel/plugin-transform-explicit-resource-management": "npm:^7.28.6" + "@babel/plugin-transform-exponentiation-operator": "npm:^7.28.6" + "@babel/plugin-transform-export-namespace-from": "npm:^7.27.1" + "@babel/plugin-transform-for-of": "npm:^7.27.1" + "@babel/plugin-transform-function-name": "npm:^7.27.1" + "@babel/plugin-transform-json-strings": "npm:^7.28.6" + "@babel/plugin-transform-literals": "npm:^7.27.1" + "@babel/plugin-transform-logical-assignment-operators": "npm:^7.28.6" + "@babel/plugin-transform-member-expression-literals": "npm:^7.27.1" + "@babel/plugin-transform-modules-amd": "npm:^7.27.1" + "@babel/plugin-transform-modules-commonjs": "npm:^7.28.6" + "@babel/plugin-transform-modules-systemjs": "npm:^7.29.0" + "@babel/plugin-transform-modules-umd": "npm:^7.27.1" + "@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.29.0" + "@babel/plugin-transform-new-target": "npm:^7.27.1" + "@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.28.6" + "@babel/plugin-transform-numeric-separator": "npm:^7.28.6" + "@babel/plugin-transform-object-rest-spread": "npm:^7.28.6" + "@babel/plugin-transform-object-super": "npm:^7.27.1" + "@babel/plugin-transform-optional-catch-binding": "npm:^7.28.6" + "@babel/plugin-transform-optional-chaining": "npm:^7.28.6" + "@babel/plugin-transform-parameters": "npm:^7.27.7" + "@babel/plugin-transform-private-methods": "npm:^7.28.6" + "@babel/plugin-transform-private-property-in-object": "npm:^7.28.6" + "@babel/plugin-transform-property-literals": "npm:^7.27.1" + "@babel/plugin-transform-regenerator": "npm:^7.29.0" + "@babel/plugin-transform-regexp-modifiers": "npm:^7.28.6" + "@babel/plugin-transform-reserved-words": "npm:^7.27.1" + "@babel/plugin-transform-shorthand-properties": "npm:^7.27.1" + "@babel/plugin-transform-spread": "npm:^7.28.6" + "@babel/plugin-transform-sticky-regex": "npm:^7.27.1" + "@babel/plugin-transform-template-literals": "npm:^7.27.1" + "@babel/plugin-transform-typeof-symbol": "npm:^7.27.1" + "@babel/plugin-transform-unicode-escapes": "npm:^7.27.1" + "@babel/plugin-transform-unicode-property-regex": "npm:^7.28.6" + "@babel/plugin-transform-unicode-regex": "npm:^7.27.1" + "@babel/plugin-transform-unicode-sets-regex": "npm:^7.28.6" + "@babel/preset-modules": "npm:0.1.6-no-external-plugins" + babel-plugin-polyfill-corejs2: "npm:^0.4.15" + babel-plugin-polyfill-corejs3: "npm:^0.14.0" + babel-plugin-polyfill-regenerator: "npm:^0.6.6" + core-js-compat: "npm:^3.48.0" + semver: "npm:^6.3.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/25a2dd82483d0f5bc781a939cebf502b80415d057806c87073f00f9a943c440b9862a265ca445ea1cba1fa79ee6361d05485465cdfc7797a0ec6d6493cf5d95b + languageName: node + linkType: hard + +"@babel/preset-modules@npm:0.1.6-no-external-plugins": + version: 0.1.6-no-external-plugins + resolution: "@babel/preset-modules@npm:0.1.6-no-external-plugins" dependencies: - "@babel/template": "npm:^7.28.6" - "@babel/types": "npm:^7.29.0" - checksum: 10/ad77706f3f917bd224e037fd0fbc67c45b240d2a45981321b093f70b7c535bee9bbddb0a19e34c362cb000ae21cdd8638f8a87a5f305a5bd7547e93fdcc524fe + "@babel/helper-plugin-utils": "npm:^7.0.0" + "@babel/types": "npm:^7.4.4" + esutils: "npm:^2.0.2" + peerDependencies: + "@babel/core": ^7.0.0-0 || ^8.0.0-0 <8.0.0 + checksum: 10/039aba98a697b920d6440c622aaa6104bb6076d65356b29dad4b3e6627ec0354da44f9621bafbeefd052cd4ac4d7f88c9a2ab094efcb50963cb352781d0c6428 languageName: node linkType: hard -"@babel/highlight@npm:^7.0.0": - version: 7.25.9 - resolution: "@babel/highlight@npm:7.25.9" +"@babel/preset-react@npm:^7.18.6": + version: 7.28.5 + resolution: "@babel/preset-react@npm:7.28.5" dependencies: - "@babel/helper-validator-identifier": "npm:^7.25.9" - chalk: "npm:^2.4.2" - js-tokens: "npm:^4.0.0" - picocolors: "npm:^1.0.0" - checksum: 10/0d165283dd4eb312292cea8fec3ae0d376874b1885f476014f0136784ed5b564b2c2ba2d270587ed546ee92505056dab56493f7960c01c4e6394d71d1b2e7db6 + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-validator-option": "npm:^7.27.1" + "@babel/plugin-transform-react-display-name": "npm:^7.28.0" + "@babel/plugin-transform-react-jsx": "npm:^7.27.1" + "@babel/plugin-transform-react-jsx-development": "npm:^7.27.1" + "@babel/plugin-transform-react-pure-annotations": "npm:^7.27.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/c00d43b27790caddee7c4971b11b4bf479a761175433e2f168b3d7e1ac6ee36d4d929a76acc7f302e9bff3a5b26d02d37f0ad7ae6359e076e5baa862b00843b2 languageName: node linkType: hard -"@babel/parser@npm:^7.27.2, @babel/parser@npm:^7.27.4, @babel/parser@npm:^7.27.5": - version: 7.27.5 - resolution: "@babel/parser@npm:7.27.5" +"@babel/preset-typescript@npm:^7.18.6": + version: 7.28.5 + resolution: "@babel/preset-typescript@npm:7.28.5" dependencies: - "@babel/types": "npm:^7.29.0" - bin: - parser: ./bin/babel-parser.js - checksum: 10/0ad671be7994dba7d31ec771bd70ea5090aa34faf73e93b1b072e3c0a704ab69f4a7a68ebfb9d6a7fa455e0aa03dfa65619c4df6bae1cf327cba925b1d233fc4 + "@babel/helper-plugin-utils": "npm:^7.27.1" + "@babel/helper-validator-option": "npm:^7.27.1" + "@babel/plugin-syntax-jsx": "npm:^7.27.1" + "@babel/plugin-transform-modules-commonjs": "npm:^7.27.1" + "@babel/plugin-transform-typescript": "npm:^7.28.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/72c03e01c34906041b1813542761a283c52da1751e7ddf63191bc5fb2a0354eca30a00537c5a92951688bec3975bdc0e50ef4516b5e94cfd6d4cf947f2125bdc languageName: node linkType: hard @@ -1695,9 +2599,9 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.27.2": - version: 7.27.2 - resolution: "@babel/template@npm:7.27.2" +"@babel/template@npm:^7.28.6, @babel/template@npm:^7.3.3": + version: 7.28.6 + resolution: "@babel/template@npm:7.28.6" dependencies: "@babel/code-frame": "npm:^7.28.6" "@babel/parser": "npm:^7.28.6" @@ -1706,9 +2610,9 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.27.1": - version: 7.27.4 - resolution: "@babel/traverse@npm:7.27.4" +"@babel/traverse@npm:^7.27.1, @babel/traverse@npm:^7.28.5, @babel/traverse@npm:^7.28.6, @babel/traverse@npm:^7.29.0": + version: 7.29.0 + resolution: "@babel/traverse@npm:7.29.0" dependencies: "@babel/code-frame": "npm:^7.29.0" "@babel/generator": "npm:^7.29.0" @@ -1721,9 +2625,9 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3": - version: 7.27.6 - resolution: "@babel/types@npm:7.27.6" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.1, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.5, @babel/types@npm:^7.28.6, @babel/types@npm:^7.29.0, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4": + version: 7.29.0 + resolution: "@babel/types@npm:7.29.0" dependencies: "@babel/helper-string-parser": "npm:^7.27.1" "@babel/helper-validator-identifier": "npm:^7.28.5" @@ -1767,7 +2671,7 @@ __metadata: "@backstage/backend-plugin-api": "npm:^1.4.0" "@backstage/cli": "npm:^0.33.0" "@backstage/config": "npm:^1.3.0" - "@google/generative-ai": "npm:^0.24.1" + "@google/genai": "npm:^1.41.0" languageName: unknown linkType: soft @@ -1834,8 +2738,7 @@ __metadata: "@backstage/cli": "npm:^0.33.0" "@backstage/config": "npm:^1.3.0" "@backstage/errors": "npm:^1.2.7" - "@backstage/plugin-catalog-node": "npm:^2.0.0" - "@google/generative-ai": "npm:^0.24.1" + "@backstage/plugin-catalog-node": "npm:^2.1.0" "@modelcontextprotocol/sdk": "npm:^1.25.2" "@types/express": "npm:^4.17.6" "@types/supertest": "npm:^7.0.0" @@ -1844,7 +2747,7 @@ __metadata: express-promise-router: "npm:^4.1.0" knex: "npm:^3.1.0" supertest: "npm:^7.0.0" - uuid: "npm:^9.0.0" + uuid: "npm:^11.0.0" languageName: unknown linkType: soft @@ -1923,9 +2826,9 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-app-api@npm:^1.5.0": - version: 1.5.0 - resolution: "@backstage/backend-app-api@npm:1.5.0" +"@backstage/backend-app-api@npm:^1.2.5, @backstage/backend-app-api@npm:^1.6.0": + version: 1.6.0 + resolution: "@backstage/backend-app-api@npm:1.6.0" dependencies: "@backstage/backend-plugin-api": "npm:^1.8.0" "@backstage/config": "npm:^1.3.6" @@ -2105,16 +3008,16 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-dev-utils@npm:^0.1.7": +"@backstage/backend-dev-utils@npm:^0.1.5, @backstage/backend-dev-utils@npm:^0.1.7": version: 0.1.7 resolution: "@backstage/backend-dev-utils@npm:0.1.7" checksum: 10/c10ca3636d48dc5963f269f3b5c504bb48956ca5d90b54895b4e5c76e05c5813f1f498e58f0020f99d073abedc2b31c76083e720e01252a1726940249663d09b languageName: node linkType: hard -"@backstage/backend-plugin-api@npm:^1.7.0": - version: 1.7.0 - resolution: "@backstage/backend-plugin-api@npm:1.7.0" +"@backstage/backend-plugin-api@npm:^1.4.0, @backstage/backend-plugin-api@npm:^1.4.1, @backstage/backend-plugin-api@npm:^1.8.0": + version: 1.8.0 + resolution: "@backstage/backend-plugin-api@npm:1.8.0" dependencies: "@backstage/cli-common": "npm:^0.2.0" "@backstage/config": "npm:^1.3.6" @@ -2134,9 +3037,9 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-test-utils@npm:^1.11.0": - version: 1.11.0 - resolution: "@backstage/backend-test-utils@npm:1.11.0" +"@backstage/backend-test-utils@npm:^1.6.0": + version: 1.11.1 + resolution: "@backstage/backend-test-utils@npm:1.11.1" dependencies: "@backstage/backend-app-api": "npm:^1.6.0" "@backstage/backend-defaults": "npm:^0.16.0" @@ -2179,9 +3082,9 @@ __metadata: languageName: node linkType: hard -"@backstage/catalog-client@npm:^1.13.0": - version: 1.13.0 - resolution: "@backstage/catalog-client@npm:1.13.0" +"@backstage/catalog-client@npm:^1.14.0": + version: 1.14.0 + resolution: "@backstage/catalog-client@npm:1.14.0" dependencies: "@backstage/catalog-model": "npm:^1.7.7" "@backstage/errors": "npm:^1.2.7" @@ -2193,9 +3096,9 @@ __metadata: languageName: node linkType: hard -"@backstage/catalog-model@npm:^1.7.6": - version: 1.7.6 - resolution: "@backstage/catalog-model@npm:1.7.6" +"@backstage/catalog-model@npm:^1.7.5, @backstage/catalog-model@npm:^1.7.6, @backstage/catalog-model@npm:^1.7.7": + version: 1.7.7 + resolution: "@backstage/catalog-model@npm:1.7.7" dependencies: "@backstage/errors": "npm:^1.2.7" "@backstage/types": "npm:^1.2.2" @@ -2208,6 +3111,18 @@ __metadata: "@backstage/cli-common@npm:^0.1.15, @backstage/cli-common@npm:^0.1.18": version: 0.1.18 resolution: "@backstage/cli-common@npm:0.1.18" + dependencies: + "@backstage/errors": "npm:^1.2.7" + cross-spawn: "npm:^7.0.3" + global-agent: "npm:^3.0.0" + undici: "npm:^7.2.3" + checksum: 10/2ed0c51bfc7a24d09a2c5fdb0e9b715f654e1ec5b6f6d528c457dad96ad57dfc57840292712dac29a9af206bb4f9d3cefbe311200f5708f9587386b00897e5b0 + languageName: node + linkType: hard + +"@backstage/cli-common@npm:^0.2.0": + version: 0.2.0 + resolution: "@backstage/cli-common@npm:0.2.0" dependencies: "@backstage/errors": "npm:^1.2.7" cross-spawn: "npm:^7.0.3" @@ -2217,9 +3132,43 @@ __metadata: languageName: node linkType: hard -"@backstage/cli-node@npm:^0.2.18": - version: 0.2.18 - resolution: "@backstage/cli-node@npm:0.2.18" +"@backstage/cli-defaults@npm:^0.1.0": + version: 0.1.0 + resolution: "@backstage/cli-defaults@npm:0.1.0" + dependencies: + "@backstage/cli-module-actions": "npm:^0.0.1" + "@backstage/cli-module-auth": "npm:^0.1.0" + "@backstage/cli-module-build": "npm:^0.1.0" + "@backstage/cli-module-config": "npm:^0.1.0" + "@backstage/cli-module-github": "npm:^0.1.0" + "@backstage/cli-module-info": "npm:^0.1.0" + "@backstage/cli-module-lint": "npm:^0.1.0" + "@backstage/cli-module-maintenance": "npm:^0.1.0" + "@backstage/cli-module-migrate": "npm:^0.1.0" + "@backstage/cli-module-new": "npm:^0.1.0" + "@backstage/cli-module-test-jest": "npm:^0.1.0" + "@backstage/cli-module-translations": "npm:^0.1.0" + checksum: 10/e1db3b0e52485b5ddba43e070f79bb0a41eedc32475fdf59cff837df70324fe033043d699b0bf91c1224da10dcc043126fe9a0d57c556e63f8792822d5d9ddf4 + languageName: node + linkType: hard + +"@backstage/cli-module-actions@npm:^0.0.1": + version: 0.0.1 + resolution: "@backstage/cli-module-actions@npm:0.0.1" + dependencies: + "@backstage/cli-node": "npm:^0.3.0" + "@backstage/errors": "npm:^1.2.7" + cleye: "npm:^2.3.0" + zod: "npm:^3.25.76 || ^4.0.0" + bin: + cli-module-actions: bin/backstage-cli-module-actions + checksum: 10/d6fcf0d5aaadaf9f0314594851f2ce833f503035018947e3a30c5ae7d2b5378022f9e625a07e54d738e36dc359a809fa282f0aee332bd9a2266d216d7ab83ca1 + languageName: node + linkType: hard + +"@backstage/cli-module-auth@npm:^0.1.0": + version: 0.1.0 + resolution: "@backstage/cli-module-auth@npm:0.1.0" dependencies: "@backstage/cli-node": "npm:^0.3.0" "@backstage/errors": "npm:^1.2.7" @@ -2472,32 +3421,214 @@ __metadata: optional: true jest-environment-jsdom: optional: true - jsdom: + jsdom: + optional: true + bin: + cli-module-test-jest: bin/backstage-cli-module-test-jest + checksum: 10/23777a9a8d1e64fd7a8f61609d38fbbfe74b1292626089a05b711af8d816daae87706239b7dad0a9faee33958c2263d71d820f75d26d4df7d4b7b69b5dba773b + languageName: node + linkType: hard + +"@backstage/cli-module-translations@npm:^0.1.0": + version: 0.1.0 + resolution: "@backstage/cli-module-translations@npm:0.1.0" + dependencies: + "@backstage/cli-common": "npm:^0.2.0" + "@backstage/cli-node": "npm:^0.3.0" + cleye: "npm:^2.3.0" + fs-extra: "npm:^11.2.0" + ts-morph: "npm:^24.0.0" + bin: + cli-module-translations: bin/backstage-cli-module-translations + checksum: 10/2d4a06f4844b7b7ccf029e2304840ca4607c8cb0049a8a15d29f2022a44197b1c128d45e250f0df6cde0b14e177c5aed0e499a53535332bfcba58d7c871231f5 + languageName: node + linkType: hard + +"@backstage/cli-node@npm:^0.2.13": + version: 0.2.18 + resolution: "@backstage/cli-node@npm:0.2.18" + dependencies: + "@backstage/cli-common": "npm:^0.1.18" + "@backstage/errors": "npm:^1.2.7" + "@backstage/types": "npm:^1.2.2" + "@manypkg/get-packages": "npm:^1.1.3" + "@yarnpkg/parsers": "npm:^3.0.0" + fs-extra: "npm:^11.2.0" + semver: "npm:^7.5.3" + zod: "npm:^3.25.76" + checksum: 10/fafdacdf29e8aac9607c5dd2de3a4294f2d40acc5e610e6041841d678fb460b4fff74f39824f6f155fc5191f09ed6537e4e2c867bc2708855ce0a4d7ea62e3a3 + languageName: node + linkType: hard + +"@backstage/cli-node@npm:^0.3.0": + version: 0.3.0 + resolution: "@backstage/cli-node@npm:0.3.0" + dependencies: + "@backstage/cli-common": "npm:^0.2.0" + "@backstage/errors": "npm:^1.2.7" + "@backstage/types": "npm:^1.2.2" + "@manypkg/get-packages": "npm:^1.1.3" + "@yarnpkg/lockfile": "npm:^1.1.0" + "@yarnpkg/parsers": "npm:^3.0.0" + chalk: "npm:^4.0.0" + commander: "npm:^12.0.0" + fs-extra: "npm:^11.2.0" + keytar: "npm:^7.9.0" + pirates: "npm:^4.0.6" + proper-lockfile: "npm:^4.1.2" + semver: "npm:^7.5.3" + yaml: "npm:^2.0.0" + zod: "npm:^3.25.76 || ^4.0.0" + peerDependencies: + "@swc/core": ^1.15.6 + dependenciesMeta: + keytar: + optional: true + peerDependenciesMeta: + "@swc/core": + optional: true + checksum: 10/dcbbe2b143489917ce017c5a3c6da0654fab1344ccced7bd33618b1540de2dafd8b4493fcec6402aa4ae8cd5971038eac547b709c67dba00180b6b813b399f79 + languageName: node + linkType: hard + +"@backstage/cli@npm:^0.33.0": + version: 0.33.1 + resolution: "@backstage/cli@npm:0.33.1" + dependencies: + "@backstage/catalog-model": "npm:^1.7.5" + "@backstage/cli-common": "npm:^0.1.15" + "@backstage/cli-node": "npm:^0.2.13" + "@backstage/config": "npm:^1.3.3" + "@backstage/config-loader": "npm:^1.10.2" + "@backstage/errors": "npm:^1.2.7" + "@backstage/eslint-plugin": "npm:^0.1.11" + "@backstage/integration": "npm:^1.17.1" + "@backstage/release-manifests": "npm:^0.0.13" + "@backstage/types": "npm:^1.2.1" + "@manypkg/get-packages": "npm:^1.1.3" + "@module-federation/enhanced": "npm:^0.9.0" + "@octokit/graphql": "npm:^5.0.0" + "@octokit/graphql-schema": "npm:^13.7.0" + "@octokit/oauth-app": "npm:^4.2.0" + "@octokit/request": "npm:^8.0.0" + "@pmmmwh/react-refresh-webpack-plugin": "npm:^0.5.7" + "@rollup/plugin-commonjs": "npm:^26.0.0" + "@rollup/plugin-json": "npm:^6.0.0" + "@rollup/plugin-node-resolve": "npm:^15.0.0" + "@rollup/plugin-yaml": "npm:^4.0.0" + "@spotify/eslint-config-base": "npm:^15.0.0" + "@spotify/eslint-config-react": "npm:^15.0.0" + "@spotify/eslint-config-typescript": "npm:^15.0.0" + "@sucrase/webpack-loader": "npm:^2.0.0" + "@svgr/core": "npm:6.5.x" + "@svgr/plugin-jsx": "npm:6.5.x" + "@svgr/plugin-svgo": "npm:6.5.x" + "@svgr/rollup": "npm:6.5.x" + "@svgr/webpack": "npm:6.5.x" + "@swc/core": "npm:^1.3.46" + "@swc/helpers": "npm:^0.5.0" + "@swc/jest": "npm:^0.2.22" + "@types/jest": "npm:^29.5.11" + "@types/webpack-env": "npm:^1.15.2" + "@typescript-eslint/eslint-plugin": "npm:^8.17.0" + "@typescript-eslint/parser": "npm:^8.16.0" + "@yarnpkg/lockfile": "npm:^1.1.0" + "@yarnpkg/parsers": "npm:^3.0.0" + bfj: "npm:^8.0.0" + buffer: "npm:^6.0.3" + chalk: "npm:^4.0.0" + chokidar: "npm:^3.3.1" + commander: "npm:^12.0.0" + cross-fetch: "npm:^4.0.0" + cross-spawn: "npm:^7.0.3" + css-loader: "npm:^6.5.1" + ctrlc-windows: "npm:^2.1.0" + esbuild: "npm:^0.25.0" + esbuild-loader: "npm:^4.0.0" + eslint: "npm:^8.6.0" + eslint-config-prettier: "npm:^9.0.0" + eslint-formatter-friendly: "npm:^7.0.0" + eslint-plugin-deprecation: "npm:^3.0.0" + eslint-plugin-import: "npm:^2.31.0" + eslint-plugin-jest: "npm:^28.9.0" + eslint-plugin-jsx-a11y: "npm:^6.10.2" + eslint-plugin-react: "npm:^7.37.2" + eslint-plugin-react-hooks: "npm:^5.0.0" + eslint-plugin-unused-imports: "npm:^4.1.4" + eslint-webpack-plugin: "npm:^4.2.0" + express: "npm:^4.17.1" + fork-ts-checker-webpack-plugin: "npm:^9.0.0" + fs-extra: "npm:^11.2.0" + git-url-parse: "npm:^15.0.0" + glob: "npm:^7.1.7" + global-agent: "npm:^3.0.0" + globby: "npm:^11.1.0" + handlebars: "npm:^4.7.3" + html-webpack-plugin: "npm:^5.6.3" + inquirer: "npm:^8.2.0" + jest: "npm:^29.7.0" + jest-cli: "npm:^29.7.0" + jest-css-modules: "npm:^2.1.0" + jest-environment-jsdom: "npm:^29.0.2" + jest-runtime: "npm:^29.0.2" + json-schema: "npm:^0.4.0" + lodash: "npm:^4.17.21" + mini-css-extract-plugin: "npm:^2.4.2" + minimatch: "npm:^9.0.0" + node-stdlib-browser: "npm:^1.3.1" + npm-packlist: "npm:^5.0.0" + ora: "npm:^5.3.0" + p-queue: "npm:^6.6.2" + pirates: "npm:^4.0.6" + postcss: "npm:^8.1.0" + process: "npm:^0.11.10" + raw-loader: "npm:^4.0.2" + react-dev-utils: "npm:^12.0.0-next.60" + react-refresh: "npm:^0.17.0" + recursive-readdir: "npm:^2.2.2" + replace-in-file: "npm:^7.1.0" + rollup: "npm:^4.27.3" + rollup-plugin-dts: "npm:^6.1.0" + rollup-plugin-esbuild: "npm:^6.1.1" + rollup-plugin-postcss: "npm:^4.0.0" + rollup-pluginutils: "npm:^2.8.2" + semver: "npm:^7.5.3" + style-loader: "npm:^3.3.1" + sucrase: "npm:^3.20.2" + swc-loader: "npm:^0.2.3" + tar: "npm:^6.1.12" + terser-webpack-plugin: "npm:^5.1.3" + ts-morph: "npm:^24.0.0" + undici: "npm:^7.2.3" + util: "npm:^0.12.3" + webpack: "npm:^5.94.0" + webpack-dev-server: "npm:^5.0.0" + yaml: "npm:^2.0.0" + yargs: "npm:^16.2.0" + yml-loader: "npm:^2.1.0" + yn: "npm:^4.0.0" + zod: "npm:^3.22.4" + zod-validation-error: "npm:^3.4.0" + peerDependencies: + "@rspack/core": ^1.2.8 + "@rspack/dev-server": ^1.0.9 + "@rspack/plugin-react-refresh": ^1.0.0 + peerDependenciesMeta: + "@rspack/core": + optional: true + "@rspack/dev-server": + optional: true + "@rspack/plugin-react-refresh": optional: true bin: - cli-module-test-jest: bin/backstage-cli-module-test-jest - checksum: 10/23777a9a8d1e64fd7a8f61609d38fbbfe74b1292626089a05b711af8d816daae87706239b7dad0a9faee33958c2263d71d820f75d26d4df7d4b7b69b5dba773b - languageName: node - linkType: hard - -"@backstage/cli-module-translations@npm:^0.1.0": - version: 0.1.0 - resolution: "@backstage/cli-module-translations@npm:0.1.0" - dependencies: - "@backstage/cli-common": "npm:^0.2.0" - "@backstage/cli-node": "npm:^0.3.0" - cleye: "npm:^2.3.0" - fs-extra: "npm:^11.2.0" - ts-morph: "npm:^24.0.0" - bin: - cli-module-translations: bin/backstage-cli-module-translations - checksum: 10/2d4a06f4844b7b7ccf029e2304840ca4607c8cb0049a8a15d29f2022a44197b1c128d45e250f0df6cde0b14e177c5aed0e499a53535332bfcba58d7c871231f5 + backstage-cli: bin/backstage-cli + checksum: 10/46b28cb5398b2711d76bf4f64c7a0b64862ae9030253ad9c0fc1632f1d3bc65b19faa3eeb204be3a5210cc5e17a3e65a3eb80f44bfd718da763eb1b4a9149754 languageName: node linkType: hard -"@backstage/cli@npm:^0.35.4": - version: 0.35.4 - resolution: "@backstage/cli@npm:0.35.4" +"@backstage/cli@npm:^0.36.0": + version: 0.36.0 + resolution: "@backstage/cli@npm:0.36.0" dependencies: "@backstage/cli-common": "npm:^0.2.0" "@backstage/cli-defaults": "npm:^0.1.0" @@ -2552,9 +3683,9 @@ __metadata: languageName: node linkType: hard -"@backstage/config-loader@npm:^1.10.8": - version: 1.10.8 - resolution: "@backstage/config-loader@npm:1.10.8" +"@backstage/config-loader@npm:^1.10.2, @backstage/config-loader@npm:^1.10.9": + version: 1.10.9 + resolution: "@backstage/config-loader@npm:1.10.9" dependencies: "@backstage/cli-common": "npm:^0.2.0" "@backstage/config": "npm:^1.3.6" @@ -2785,7 +3916,7 @@ __metadata: languageName: node linkType: hard -"@backstage/eslint-plugin@npm:^0.2.1": +"@backstage/eslint-plugin@npm:^0.2.2": version: 0.2.2 resolution: "@backstage/eslint-plugin@npm:0.2.2" dependencies: @@ -2795,9 +3926,9 @@ __metadata: languageName: node linkType: hard -"@backstage/filter-predicates@npm:^0.1.0": - version: 0.1.0 - resolution: "@backstage/filter-predicates@npm:0.1.0" +"@backstage/filter-predicates@npm:^0.1.1": + version: 0.1.1 + resolution: "@backstage/filter-predicates@npm:0.1.1" dependencies: "@backstage/config": "npm:^1.3.6" "@backstage/errors": "npm:^1.2.7" @@ -2808,14 +3939,15 @@ __metadata: languageName: node linkType: hard -"@backstage/frontend-plugin-api@npm:^0.14.1": - version: 0.14.1 - resolution: "@backstage/frontend-plugin-api@npm:0.14.1" +"@backstage/frontend-plugin-api@npm:^0.15.0, @backstage/frontend-plugin-api@npm:^0.15.1": + version: 0.15.1 + resolution: "@backstage/frontend-plugin-api@npm:0.15.1" dependencies: "@backstage/errors": "npm:^1.2.7" + "@backstage/filter-predicates": "npm:^0.1.1" "@backstage/types": "npm:^1.2.2" "@backstage/version-bridge": "npm:^1.0.12" - zod: "npm:^3.25.76" + zod: "npm:^3.25.76 || ^4.0.0" zod-to-json-schema: "npm:^3.25.1" peerDependencies: "@types/react": ^17.0.0 || ^18.0.0 @@ -2825,11 +3957,11 @@ __metadata: peerDependenciesMeta: "@types/react": optional: true - checksum: 10/d54c3bee4c7f3708c1196aedec76a4edcc4d99e5856a2d7b404ad1f70ed6395ee32ac7de69290b37f3cc32c19507b8cdda566c04655c57e6ed364ee356434538 + checksum: 10/e40d2bbd8eb2b55eaced37e8f855cece9ed74092a89949a474e38ed6f06c20d289fef4595ee6267375effc9983ae6dfb8fc91d8d2d2b7d7a1642ced248ec1f01 languageName: node linkType: hard -"@backstage/integration-aws-node@npm:^0.1.20": +"@backstage/integration-aws-node@npm:^0.1.17, @backstage/integration-aws-node@npm:^0.1.20": version: 0.1.20 resolution: "@backstage/integration-aws-node@npm:0.1.20" dependencies: @@ -2865,7 +3997,7 @@ __metadata: languageName: node linkType: hard -"@backstage/integration@npm:^1.17.1, @backstage/integration@npm:^1.20.0": +"@backstage/integration@npm:^1.17.1": version: 1.20.1 resolution: "@backstage/integration@npm:1.20.1" dependencies: @@ -2946,9 +4078,9 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-auth-node@npm:^0.6.13": - version: 0.6.13 - resolution: "@backstage/plugin-auth-node@npm:0.6.13" +"@backstage/plugin-auth-node@npm:^0.6.14, @backstage/plugin-auth-node@npm:^0.6.5": + version: 0.6.14 + resolution: "@backstage/plugin-auth-node@npm:0.6.14" dependencies: "@backstage/backend-plugin-api": "npm:^1.8.0" "@backstage/catalog-client": "npm:^1.14.0" @@ -2969,7 +4101,7 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-catalog-common@npm:^1.1.7, @backstage/plugin-catalog-common@npm:^1.1.8": +"@backstage/plugin-catalog-common@npm:^1.1.8": version: 1.1.8 resolution: "@backstage/plugin-catalog-common@npm:1.1.8" dependencies: @@ -2980,27 +4112,27 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-catalog-node@npm:^2.0.0": - version: 2.0.0 - resolution: "@backstage/plugin-catalog-node@npm:2.0.0" +"@backstage/plugin-catalog-node@npm:^2.1.0": + version: 2.1.0 + resolution: "@backstage/plugin-catalog-node@npm:2.1.0" dependencies: - "@backstage/backend-plugin-api": "npm:^1.7.0" - "@backstage/catalog-client": "npm:^1.13.0" - "@backstage/catalog-model": "npm:^1.7.6" + "@backstage/backend-plugin-api": "npm:^1.8.0" + "@backstage/catalog-client": "npm:^1.14.0" + "@backstage/catalog-model": "npm:^1.7.7" "@backstage/errors": "npm:^1.2.7" "@backstage/plugin-catalog-common": "npm:^1.1.8" - "@backstage/plugin-permission-common": "npm:^0.9.6" - "@backstage/plugin-permission-node": "npm:^0.10.10" + "@backstage/plugin-permission-common": "npm:^0.9.7" + "@backstage/plugin-permission-node": "npm:^0.10.11" "@backstage/types": "npm:^1.2.2" "@opentelemetry/api": "npm:^1.9.0" lodash: "npm:^4.17.21" yaml: "npm:^2.0.0" peerDependencies: - "@backstage/backend-test-utils": ^1.11.0 + "@backstage/backend-test-utils": ^1.11.1 peerDependenciesMeta: "@backstage/backend-test-utils": optional: true - checksum: 10/fd7550a3f34b6b3a13159a21c4b3889f7f1a6af1164cb3e84b6b0d0cd6d678da83629c4e7f476f6bec8042b9186d5b47575d0333da9194d12b96ce71af603afa + checksum: 10/f47bdaf40de1f9b344f20ab8179557af845fef66b2a875f1c4427f4464bd06d453e21028ab1873c5da4e60bacd2dff13cace6cdd77c7fa6f8a166cd64e6060e2 languageName: node linkType: hard @@ -3049,9 +4181,9 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-events-node@npm:^0.4.19": - version: 0.4.19 - resolution: "@backstage/plugin-events-node@npm:0.4.19" +"@backstage/plugin-events-node@npm:^0.4.13, @backstage/plugin-events-node@npm:^0.4.20": + version: 0.4.20 + resolution: "@backstage/plugin-events-node@npm:0.4.20" dependencies: "@backstage/backend-plugin-api": "npm:^1.8.0" "@backstage/errors": "npm:^1.2.7" @@ -3066,9 +4198,9 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-permission-common@npm:^0.9.6": - version: 0.9.6 - resolution: "@backstage/plugin-permission-common@npm:0.9.6" +"@backstage/plugin-permission-common@npm:^0.9.6, @backstage/plugin-permission-common@npm:^0.9.7": + version: 0.9.7 + resolution: "@backstage/plugin-permission-common@npm:0.9.7" dependencies: "@backstage/config": "npm:^1.3.6" "@backstage/errors": "npm:^1.2.7" @@ -3081,9 +4213,9 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-permission-node@npm:^0.10.10": - version: 0.10.10 - resolution: "@backstage/plugin-permission-node@npm:0.10.10" +"@backstage/plugin-permission-node@npm:^0.10.11, @backstage/plugin-permission-node@npm:^0.10.2": + version: 0.10.11 + resolution: "@backstage/plugin-permission-node@npm:0.10.11" dependencies: "@backstage/backend-plugin-api": "npm:^1.8.0" "@backstage/config": "npm:^1.3.6" @@ -3307,9 +4439,23 @@ __metadata: languageName: node linkType: hard -"@changesets/apply-release-plan@npm:^7.0.12": - version: 7.0.12 - resolution: "@changesets/apply-release-plan@npm:7.0.12" +"@bcoe/v8-coverage@npm:^0.2.3": + version: 0.2.3 + resolution: "@bcoe/v8-coverage@npm:0.2.3" + checksum: 10/1a1f0e356a3bb30b5f1ced6f79c413e6ebacf130421f15fac5fcd8be5ddf98aedb4404d7f5624e3285b700e041f9ef938321f3ca4d359d5b716f96afa120d88d + languageName: node + linkType: hard + +"@borewit/text-codec@npm:^0.2.1": + version: 0.2.2 + resolution: "@borewit/text-codec@npm:0.2.2" + checksum: 10/c971790a72d9e766286db71f68613d1bac3b8bd9eaba52fbf18a8b17903c095968ed5369efdba378751926440aab93f3dd17c89242ef20525808ddced22d49b8 + languageName: node + linkType: hard + +"@changesets/apply-release-plan@npm:^7.1.0": + version: 7.1.0 + resolution: "@changesets/apply-release-plan@npm:7.1.0" dependencies: "@changesets/config": "npm:^3.1.3" "@changesets/get-version-range-type": "npm:^0.4.0" @@ -3796,184 +4942,366 @@ __metadata: languageName: node linkType: hard -"@esbuild/aix-ppc64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/aix-ppc64@npm:0.27.3" +"@esbuild/aix-ppc64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/aix-ppc64@npm:0.25.12" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/aix-ppc64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/aix-ppc64@npm:0.27.4" conditions: os=aix & cpu=ppc64 languageName: node linkType: hard -"@esbuild/android-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/android-arm64@npm:0.27.3" +"@esbuild/android-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/android-arm64@npm:0.25.12" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/android-arm64@npm:0.27.4" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@esbuild/android-arm@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/android-arm@npm:0.27.3" +"@esbuild/android-arm@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/android-arm@npm:0.25.12" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/android-arm@npm:0.27.4" conditions: os=android & cpu=arm languageName: node linkType: hard -"@esbuild/android-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/android-x64@npm:0.27.3" +"@esbuild/android-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/android-x64@npm:0.25.12" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/android-x64@npm:0.27.4" conditions: os=android & cpu=x64 languageName: node linkType: hard -"@esbuild/darwin-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/darwin-arm64@npm:0.27.3" +"@esbuild/darwin-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/darwin-arm64@npm:0.25.12" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/darwin-arm64@npm:0.27.4" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@esbuild/darwin-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/darwin-x64@npm:0.27.3" +"@esbuild/darwin-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/darwin-x64@npm:0.25.12" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/darwin-x64@npm:0.27.4" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@esbuild/freebsd-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/freebsd-arm64@npm:0.27.3" +"@esbuild/freebsd-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/freebsd-arm64@npm:0.25.12" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/freebsd-arm64@npm:0.27.4" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/freebsd-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/freebsd-x64@npm:0.27.3" +"@esbuild/freebsd-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/freebsd-x64@npm:0.25.12" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/freebsd-x64@npm:0.27.4" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@esbuild/linux-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-arm64@npm:0.27.3" +"@esbuild/linux-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-arm64@npm:0.25.12" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-arm64@npm:0.27.4" conditions: os=linux & cpu=arm64 languageName: node linkType: hard -"@esbuild/linux-arm@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-arm@npm:0.27.3" +"@esbuild/linux-arm@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-arm@npm:0.25.12" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-arm@npm:0.27.4" conditions: os=linux & cpu=arm languageName: node linkType: hard -"@esbuild/linux-ia32@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-ia32@npm:0.27.3" +"@esbuild/linux-ia32@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-ia32@npm:0.25.12" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-ia32@npm:0.27.4" conditions: os=linux & cpu=ia32 languageName: node linkType: hard -"@esbuild/linux-loong64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-loong64@npm:0.27.3" +"@esbuild/linux-loong64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-loong64@npm:0.25.12" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-loong64@npm:0.27.4" conditions: os=linux & cpu=loong64 languageName: node linkType: hard -"@esbuild/linux-mips64el@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-mips64el@npm:0.27.3" +"@esbuild/linux-mips64el@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-mips64el@npm:0.25.12" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-mips64el@npm:0.27.4" conditions: os=linux & cpu=mips64el languageName: node linkType: hard -"@esbuild/linux-ppc64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-ppc64@npm:0.27.3" +"@esbuild/linux-ppc64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-ppc64@npm:0.25.12" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-ppc64@npm:0.27.4" conditions: os=linux & cpu=ppc64 languageName: node linkType: hard -"@esbuild/linux-riscv64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-riscv64@npm:0.27.3" +"@esbuild/linux-riscv64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-riscv64@npm:0.25.12" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-riscv64@npm:0.27.4" conditions: os=linux & cpu=riscv64 languageName: node linkType: hard -"@esbuild/linux-s390x@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-s390x@npm:0.27.3" +"@esbuild/linux-s390x@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-s390x@npm:0.25.12" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-s390x@npm:0.27.4" conditions: os=linux & cpu=s390x languageName: node linkType: hard -"@esbuild/linux-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/linux-x64@npm:0.27.3" +"@esbuild/linux-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/linux-x64@npm:0.25.12" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/linux-x64@npm:0.27.4" conditions: os=linux & cpu=x64 languageName: node linkType: hard -"@esbuild/netbsd-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/netbsd-arm64@npm:0.27.3" +"@esbuild/netbsd-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/netbsd-arm64@npm:0.25.12" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/netbsd-arm64@npm:0.27.4" conditions: os=netbsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/netbsd-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/netbsd-x64@npm:0.27.3" +"@esbuild/netbsd-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/netbsd-x64@npm:0.25.12" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/netbsd-x64@npm:0.27.4" conditions: os=netbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openbsd-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/openbsd-arm64@npm:0.27.3" +"@esbuild/openbsd-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/openbsd-arm64@npm:0.25.12" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/openbsd-arm64@npm:0.27.4" conditions: os=openbsd & cpu=arm64 languageName: node linkType: hard -"@esbuild/openbsd-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/openbsd-x64@npm:0.27.3" +"@esbuild/openbsd-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/openbsd-x64@npm:0.25.12" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/openbsd-x64@npm:0.27.4" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@esbuild/openharmony-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/openharmony-arm64@npm:0.27.3" +"@esbuild/openharmony-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/openharmony-arm64@npm:0.25.12" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openharmony-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/openharmony-arm64@npm:0.27.4" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard -"@esbuild/sunos-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/sunos-x64@npm:0.27.3" +"@esbuild/sunos-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/sunos-x64@npm:0.25.12" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/sunos-x64@npm:0.27.4" conditions: os=sunos & cpu=x64 languageName: node linkType: hard -"@esbuild/win32-arm64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/win32-arm64@npm:0.27.3" +"@esbuild/win32-arm64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/win32-arm64@npm:0.25.12" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/win32-arm64@npm:0.27.4" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@esbuild/win32-ia32@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/win32-ia32@npm:0.27.3" +"@esbuild/win32-ia32@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/win32-ia32@npm:0.25.12" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/win32-ia32@npm:0.27.4" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@esbuild/win32-x64@npm:0.27.3": - version: 0.27.3 - resolution: "@esbuild/win32-x64@npm:0.27.3" +"@esbuild/win32-x64@npm:0.25.12": + version: 0.25.12 + resolution: "@esbuild/win32-x64@npm:0.25.12" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.27.4": + version: 0.27.4 + resolution: "@esbuild/win32-x64@npm:0.27.4" conditions: os=win32 & cpu=x64 languageName: node linkType: hard @@ -4710,9 +6038,9 @@ __metadata: languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25": - version: 0.3.25 - resolution: "@jridgewell/trace-mapping@npm:0.3.25" +"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.18, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28": + version: 0.3.31 + resolution: "@jridgewell/trace-mapping@npm:0.3.31" dependencies: "@jridgewell/resolve-uri": "npm:^3.1.0" "@jridgewell/sourcemap-codec": "npm:^1.4.14" @@ -5865,10 +7193,20 @@ __metadata: languageName: node linkType: hard -"@mui/core-downloads-tracker@npm:^5.17.1": - version: 5.17.1 - resolution: "@mui/core-downloads-tracker@npm:5.17.1" - checksum: 10/40a697aa031f089dde29812563320221efa1ec18840b0d0b744ba8846b558146d58910b5b4e67b7eb1942c6817ffc389b4b6b28456c762d39d250bc1e54423f7 +"@module-federation/webpack-bundler-runtime@npm:0.9.1": + version: 0.9.1 + resolution: "@module-federation/webpack-bundler-runtime@npm:0.9.1" + dependencies: + "@module-federation/runtime": "npm:0.9.1" + "@module-federation/sdk": "npm:0.9.1" + checksum: 10/430cac0a770b3c46bc195088eb4c1892e1e29a69238dbe72423d64b2b67050afeca2b5026b1a30659b4fe8d9faa038ff97cceba7e2ddf6193b93763f270d9df6 + languageName: node + linkType: hard + +"@mui/core-downloads-tracker@npm:^5.18.0": + version: 5.18.0 + resolution: "@mui/core-downloads-tracker@npm:5.18.0" + checksum: 10/065b46739d2bd84b880ad2f6a0a2062d60e3a296ce18ff380cad22ab5b2cb3de396755f322f4bea3a422ffffe1a9244536fc3c9623056ff3873c996e6664b1b9 languageName: node linkType: hard @@ -6112,13 +7450,6 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:1.4.0": - version: 1.4.0 - resolution: "@noble/hashes@npm:1.4.0" - checksum: 10/e156e65794c473794c52fa9d06baf1eb20903d0d96719530f523cc4450f6c721a957c544796e6efd0197b2296e7cd70efeb312f861465e17940a3e3c7e0febc6 - languageName: node - linkType: hard - "@noble/hashes@npm:^1.1.5": version: 1.8.0 resolution: "@noble/hashes@npm:1.8.0" @@ -6650,220 +7981,75 @@ __metadata: "@oxc-resolver/binding-linux-riscv64-musl@npm:11.19.1": version: 11.19.1 - resolution: "@oxc-resolver/binding-linux-riscv64-musl@npm:11.19.1" - conditions: os=linux & cpu=riscv64 & libc=musl - languageName: node - linkType: hard - -"@oxc-resolver/binding-linux-s390x-gnu@npm:11.19.1": - version: 11.19.1 - resolution: "@oxc-resolver/binding-linux-s390x-gnu@npm:11.19.1" - conditions: os=linux & cpu=s390x & libc=glibc - languageName: node - linkType: hard - -"@oxc-resolver/binding-linux-x64-gnu@npm:11.19.1": - version: 11.19.1 - resolution: "@oxc-resolver/binding-linux-x64-gnu@npm:11.19.1" - conditions: os=linux & cpu=x64 & libc=glibc - languageName: node - linkType: hard - -"@oxc-resolver/binding-linux-x64-musl@npm:11.19.1": - version: 11.19.1 - resolution: "@oxc-resolver/binding-linux-x64-musl@npm:11.19.1" - conditions: os=linux & cpu=x64 & libc=musl - languageName: node - linkType: hard - -"@oxc-resolver/binding-openharmony-arm64@npm:11.19.1": - version: 11.19.1 - resolution: "@oxc-resolver/binding-openharmony-arm64@npm:11.19.1" - conditions: os=openharmony & cpu=arm64 - languageName: node - linkType: hard - -"@oxc-resolver/binding-wasm32-wasi@npm:11.19.1": - version: 11.19.1 - resolution: "@oxc-resolver/binding-wasm32-wasi@npm:11.19.1" - dependencies: - "@napi-rs/wasm-runtime": "npm:^1.1.1" - conditions: cpu=wasm32 - languageName: node - linkType: hard - -"@oxc-resolver/binding-win32-arm64-msvc@npm:11.19.1": - version: 11.19.1 - resolution: "@oxc-resolver/binding-win32-arm64-msvc@npm:11.19.1" - conditions: os=win32 & cpu=arm64 - languageName: node - linkType: hard - -"@oxc-resolver/binding-win32-ia32-msvc@npm:11.19.1": - version: 11.19.1 - resolution: "@oxc-resolver/binding-win32-ia32-msvc@npm:11.19.1" - conditions: os=win32 & cpu=ia32 - languageName: node - linkType: hard - -"@oxc-resolver/binding-win32-x64-msvc@npm:11.19.1": - version: 11.19.1 - resolution: "@oxc-resolver/binding-win32-x64-msvc@npm:11.19.1" - conditions: os=win32 & cpu=x64 - languageName: node - linkType: hard - -"@paralleldrive/cuid2@npm:^2.2.2": - version: 2.3.1 - resolution: "@paralleldrive/cuid2@npm:2.3.1" - dependencies: - "@noble/hashes": "npm:^1.1.5" - checksum: 10/08687b891dfdad44f13a2c69232e95ca27efffc8b376587c2b89114b100a505808e7af5fbb51c3103053c637a6604f5987afa3ee8b4e1ba4c38742ebd47b4a84 - languageName: node - linkType: hard - -"@peculiar/asn1-cms@npm:^2.6.0, @peculiar/asn1-cms@npm:^2.6.1": - version: 2.6.1 - resolution: "@peculiar/asn1-cms@npm:2.6.1" - dependencies: - "@peculiar/asn1-schema": "npm:^2.6.0" - "@peculiar/asn1-x509": "npm:^2.6.1" - "@peculiar/asn1-x509-attr": "npm:^2.6.1" - asn1js: "npm:^3.0.6" - tslib: "npm:^2.8.1" - checksum: 10/e431f6229b98c63a929538d266488e8c2dddc895936117da8f9ec775558e08c20ded6a4adcca4bb88bfea282e7204d4f6bba7a46da2cced162c174e1e6964f36 - languageName: node - linkType: hard - -"@peculiar/asn1-csr@npm:^2.6.0": - version: 2.6.1 - resolution: "@peculiar/asn1-csr@npm:2.6.1" - dependencies: - "@peculiar/asn1-schema": "npm:^2.6.0" - "@peculiar/asn1-x509": "npm:^2.6.1" - asn1js: "npm:^3.0.6" - tslib: "npm:^2.8.1" - checksum: 10/4ac2f1c3a2cb392fcdd5aa602140abe90f849af0a9e8296aab9aaf1712ee2e0c4f5fa86b0fe83975e771b0aba91fc848670f9c2008ea1e850c849fae6e181179 + resolution: "@oxc-resolver/binding-linux-riscv64-musl@npm:11.19.1" + conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard -"@peculiar/asn1-ecc@npm:^2.6.0": - version: 2.6.1 - resolution: "@peculiar/asn1-ecc@npm:2.6.1" - dependencies: - "@peculiar/asn1-schema": "npm:^2.6.0" - "@peculiar/asn1-x509": "npm:^2.6.1" - asn1js: "npm:^3.0.6" - tslib: "npm:^2.8.1" - checksum: 10/baa646c1c86283d5876230b1cfbd80cf42f97b3bb8d8b23cd5830f6f8d6466e6a06887c6838f3c4c61c87df9ffd2abe905f555472e8e70d722ce964a8074d838 +"@oxc-resolver/binding-linux-s390x-gnu@npm:11.19.1": + version: 11.19.1 + resolution: "@oxc-resolver/binding-linux-s390x-gnu@npm:11.19.1" + conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@peculiar/asn1-pfx@npm:^2.6.1": - version: 2.6.1 - resolution: "@peculiar/asn1-pfx@npm:2.6.1" - dependencies: - "@peculiar/asn1-cms": "npm:^2.6.1" - "@peculiar/asn1-pkcs8": "npm:^2.6.1" - "@peculiar/asn1-rsa": "npm:^2.6.1" - "@peculiar/asn1-schema": "npm:^2.6.0" - asn1js: "npm:^3.0.6" - tslib: "npm:^2.8.1" - checksum: 10/50adc7db96928d98b85a1a2e6765ba1d4ec708f937b8172ea6a22e3b92137ea36d656aded64b3be661db39f924102c5a80da54ee647e2441af3bc19c55a183ef +"@oxc-resolver/binding-linux-x64-gnu@npm:11.19.1": + version: 11.19.1 + resolution: "@oxc-resolver/binding-linux-x64-gnu@npm:11.19.1" + conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@peculiar/asn1-pkcs8@npm:^2.6.1": - version: 2.6.1 - resolution: "@peculiar/asn1-pkcs8@npm:2.6.1" - dependencies: - "@peculiar/asn1-schema": "npm:^2.6.0" - "@peculiar/asn1-x509": "npm:^2.6.1" - asn1js: "npm:^3.0.6" - tslib: "npm:^2.8.1" - checksum: 10/99c4326da30e7ef17bb8e92d8a9525b78c101e4d743493000e220f3da6bbc4755371f1dbcc2a36951fb15769c2efead20d90a08918fd268c21bebcac26e71053 +"@oxc-resolver/binding-linux-x64-musl@npm:11.19.1": + version: 11.19.1 + resolution: "@oxc-resolver/binding-linux-x64-musl@npm:11.19.1" + conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@peculiar/asn1-pkcs9@npm:^2.6.0": - version: 2.6.1 - resolution: "@peculiar/asn1-pkcs9@npm:2.6.1" - dependencies: - "@peculiar/asn1-cms": "npm:^2.6.1" - "@peculiar/asn1-pfx": "npm:^2.6.1" - "@peculiar/asn1-pkcs8": "npm:^2.6.1" - "@peculiar/asn1-schema": "npm:^2.6.0" - "@peculiar/asn1-x509": "npm:^2.6.1" - "@peculiar/asn1-x509-attr": "npm:^2.6.1" - asn1js: "npm:^3.0.6" - tslib: "npm:^2.8.1" - checksum: 10/61759a50d6adf108a0376735b2e76cdfc9c41db39a7abed23ca332f7699d831aa6324534aa38153018a31e6ee5e8fef85534c92b68067f6afcb90787e953c449 +"@oxc-resolver/binding-openharmony-arm64@npm:11.19.1": + version: 11.19.1 + resolution: "@oxc-resolver/binding-openharmony-arm64@npm:11.19.1" + conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard -"@peculiar/asn1-rsa@npm:^2.6.0, @peculiar/asn1-rsa@npm:^2.6.1": - version: 2.6.1 - resolution: "@peculiar/asn1-rsa@npm:2.6.1" +"@oxc-resolver/binding-wasm32-wasi@npm:11.19.1": + version: 11.19.1 + resolution: "@oxc-resolver/binding-wasm32-wasi@npm:11.19.1" dependencies: - "@peculiar/asn1-schema": "npm:^2.6.0" - "@peculiar/asn1-x509": "npm:^2.6.1" - asn1js: "npm:^3.0.6" - tslib: "npm:^2.8.1" - checksum: 10/e91efe57017feac71c69ee5950e9c323b45aaf10baa32153fe88f237948f9d906ba04c645d085c4293c90440cad95392a91b3760251cd0ebc8e4c1a383fc331a + "@napi-rs/wasm-runtime": "npm:^1.1.1" + conditions: cpu=wasm32 languageName: node linkType: hard -"@peculiar/asn1-schema@npm:^2.6.0": - version: 2.6.0 - resolution: "@peculiar/asn1-schema@npm:2.6.0" - dependencies: - asn1js: "npm:^3.0.6" - pvtsutils: "npm:^1.3.6" - tslib: "npm:^2.8.1" - checksum: 10/af9b1094d0e020f0fd828777488578322d62a41f597ead7d80939dafcfe35b672fcb0ec7460ef66b2a155f9614d4340a98896d417a830aff1685cb4c21d5bbe4 +"@oxc-resolver/binding-win32-arm64-msvc@npm:11.19.1": + version: 11.19.1 + resolution: "@oxc-resolver/binding-win32-arm64-msvc@npm:11.19.1" + conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@peculiar/asn1-x509-attr@npm:^2.6.1": - version: 2.6.1 - resolution: "@peculiar/asn1-x509-attr@npm:2.6.1" - dependencies: - "@peculiar/asn1-schema": "npm:^2.6.0" - "@peculiar/asn1-x509": "npm:^2.6.1" - asn1js: "npm:^3.0.6" - tslib: "npm:^2.8.1" - checksum: 10/86f7d5495459dee81daadd830ebb7d26ec15a98f6479c88b90a915ac9f28105b0d5003ba0c382b4aa8f7fa42e399f7cc37e4fe73c26cbaacd47e63a50b132e25 +"@oxc-resolver/binding-win32-ia32-msvc@npm:11.19.1": + version: 11.19.1 + resolution: "@oxc-resolver/binding-win32-ia32-msvc@npm:11.19.1" + conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@peculiar/asn1-x509@npm:^2.6.0, @peculiar/asn1-x509@npm:^2.6.1": - version: 2.6.1 - resolution: "@peculiar/asn1-x509@npm:2.6.1" - dependencies: - "@peculiar/asn1-schema": "npm:^2.6.0" - asn1js: "npm:^3.0.6" - pvtsutils: "npm:^1.3.6" - tslib: "npm:^2.8.1" - checksum: 10/e3187ad04d397cdd6a946895a51202b67f57992dfef55e40acc7e7ea325e2854267ed2581c4b1ea729d7147e9e8e6f34af77f1ffb48e3e8b25b2216b213b4641 +"@oxc-resolver/binding-win32-x64-msvc@npm:11.19.1": + version: 11.19.1 + resolution: "@oxc-resolver/binding-win32-x64-msvc@npm:11.19.1" + conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@peculiar/x509@npm:^1.14.2": - version: 1.14.3 - resolution: "@peculiar/x509@npm:1.14.3" +"@paralleldrive/cuid2@npm:^2.2.2": + version: 2.3.1 + resolution: "@paralleldrive/cuid2@npm:2.3.1" dependencies: - "@peculiar/asn1-cms": "npm:^2.6.0" - "@peculiar/asn1-csr": "npm:^2.6.0" - "@peculiar/asn1-ecc": "npm:^2.6.0" - "@peculiar/asn1-pkcs9": "npm:^2.6.0" - "@peculiar/asn1-rsa": "npm:^2.6.0" - "@peculiar/asn1-schema": "npm:^2.6.0" - "@peculiar/asn1-x509": "npm:^2.6.0" - pvtsutils: "npm:^1.3.6" - reflect-metadata: "npm:^0.2.2" - tslib: "npm:^2.8.1" - tsyringe: "npm:^4.10.0" - checksum: 10/d37c56fa5f2c644141948d85010e14f0e4963089e3b0b81edd0bfe85bdfea0eb3f38ab6ff20d322db2bd6977117824cc498a77b2d35af111983b4d58b5e2ccd1 + "@noble/hashes": "npm:^1.1.5" + checksum: 10/08687b891dfdad44f13a2c69232e95ca27efffc8b376587c2b89114b100a505808e7af5fbb51c3103053c637a6604f5987afa3ee8b4e1ba4c38742ebd47b4a84 languageName: node linkType: hard @@ -7056,6 +8242,42 @@ __metadata: languageName: node linkType: hard +"@pmmmwh/react-refresh-webpack-plugin@npm:^0.6.0": + version: 0.6.2 + resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.6.2" + dependencies: + anser: "npm:^2.1.1" + core-js-pure: "npm:^3.23.3" + error-stack-parser: "npm:^2.0.6" + html-entities: "npm:^2.1.0" + schema-utils: "npm:^4.2.0" + source-map: "npm:^0.7.3" + peerDependencies: + "@types/webpack": 5.x + react-refresh: ">=0.10.0 <1.0.0" + sockjs-client: ^1.4.0 + type-fest: ">=0.17.0 <6.0.0" + webpack: ^5.0.0 + webpack-dev-server: ^4.8.0 || 5.x + webpack-hot-middleware: 2.x + webpack-plugin-serve: 1.x + peerDependenciesMeta: + "@types/webpack": + optional: true + sockjs-client: + optional: true + type-fest: + optional: true + webpack-dev-server: + optional: true + webpack-hot-middleware: + optional: true + webpack-plugin-serve: + optional: true + checksum: 10/157a20464b0bdca39b31e09450f6ce1d91cbe32bcce882a02df797482b0226247d13e5a2c750a3fb2e2758bffc25d49a468b33b66d8364aa4e1ed785596453c8 + languageName: node + linkType: hard + "@popperjs/core@npm:^2.11.8": version: 2.11.8 resolution: "@popperjs/core@npm:2.11.8" @@ -9435,7 +10657,25 @@ __metadata: languageName: node linkType: hard -"@smithy/abort-controller@npm:^4.0.4, @smithy/abort-controller@npm:^4.2.12": +"@sinonjs/commons@npm:^3.0.0": + version: 3.0.1 + resolution: "@sinonjs/commons@npm:3.0.1" + dependencies: + type-detect: "npm:4.0.8" + checksum: 10/a0af217ba7044426c78df52c23cedede6daf377586f3ac58857c565769358ab1f44ebf95ba04bbe38814fba6e316ca6f02870a009328294fc2c555d0f85a7117 + languageName: node + linkType: hard + +"@sinonjs/fake-timers@npm:^10.0.2": + version: 10.3.0 + resolution: "@sinonjs/fake-timers@npm:10.3.0" + dependencies: + "@sinonjs/commons": "npm:^3.0.0" + checksum: 10/78155c7bd866a85df85e22028e046b8d46cf3e840f72260954f5e3ed5bd97d66c595524305a6841ffb3f681a08f6e5cef572a2cce5442a8a232dc29fb409b83e + languageName: node + linkType: hard + +"@smithy/abort-controller@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/abort-controller@npm:4.2.12" dependencies: @@ -9464,7 +10704,7 @@ __metadata: languageName: node linkType: hard -"@smithy/config-resolver@npm:^4.1.4, @smithy/config-resolver@npm:^4.4.13": +"@smithy/config-resolver@npm:^4.4.13": version: 4.4.13 resolution: "@smithy/config-resolver@npm:4.4.13" dependencies: @@ -9478,7 +10718,7 @@ __metadata: languageName: node linkType: hard -"@smithy/core@npm:^3.23.12, @smithy/core@npm:^3.5.3": +"@smithy/core@npm:^3.23.12": version: 3.23.12 resolution: "@smithy/core@npm:3.23.12" dependencies: @@ -9496,7 +10736,7 @@ __metadata: languageName: node linkType: hard -"@smithy/credential-provider-imds@npm:^4.0.6, @smithy/credential-provider-imds@npm:^4.2.12": +"@smithy/credential-provider-imds@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/credential-provider-imds@npm:4.2.12" dependencies: @@ -9521,7 +10761,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-browser@npm:^4.0.4, @smithy/eventstream-serde-browser@npm:^4.2.12": +"@smithy/eventstream-serde-browser@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/eventstream-serde-browser@npm:4.2.12" dependencies: @@ -9532,7 +10772,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-config-resolver@npm:^4.1.2, @smithy/eventstream-serde-config-resolver@npm:^4.3.12": +"@smithy/eventstream-serde-config-resolver@npm:^4.3.12": version: 4.3.12 resolution: "@smithy/eventstream-serde-config-resolver@npm:4.3.12" dependencies: @@ -9542,7 +10782,7 @@ __metadata: languageName: node linkType: hard -"@smithy/eventstream-serde-node@npm:^4.0.4, @smithy/eventstream-serde-node@npm:^4.2.12": +"@smithy/eventstream-serde-node@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/eventstream-serde-node@npm:4.2.12" dependencies: @@ -9564,7 +10804,7 @@ __metadata: languageName: node linkType: hard -"@smithy/fetch-http-handler@npm:^5.0.4, @smithy/fetch-http-handler@npm:^5.3.15": +"@smithy/fetch-http-handler@npm:^5.3.15": version: 5.3.15 resolution: "@smithy/fetch-http-handler@npm:5.3.15" dependencies: @@ -9589,7 +10829,7 @@ __metadata: languageName: node linkType: hard -"@smithy/hash-node@npm:^4.0.4, @smithy/hash-node@npm:^4.2.12": +"@smithy/hash-node@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/hash-node@npm:4.2.12" dependencies: @@ -9612,7 +10852,7 @@ __metadata: languageName: node linkType: hard -"@smithy/invalid-dependency@npm:^4.0.4, @smithy/invalid-dependency@npm:^4.2.12": +"@smithy/invalid-dependency@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/invalid-dependency@npm:4.2.12" dependencies: @@ -9631,7 +10871,7 @@ __metadata: languageName: node linkType: hard -"@smithy/is-array-buffer@npm:^4.0.0, @smithy/is-array-buffer@npm:^4.2.2": +"@smithy/is-array-buffer@npm:^4.2.2": version: 4.2.2 resolution: "@smithy/is-array-buffer@npm:4.2.2" dependencies: @@ -9651,7 +10891,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-content-length@npm:^4.0.4, @smithy/middleware-content-length@npm:^4.2.12": +"@smithy/middleware-content-length@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/middleware-content-length@npm:4.2.12" dependencies: @@ -9662,7 +10902,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-endpoint@npm:^4.1.11, @smithy/middleware-endpoint@npm:^4.4.27": +"@smithy/middleware-endpoint@npm:^4.4.27": version: 4.4.27 resolution: "@smithy/middleware-endpoint@npm:4.4.27" dependencies: @@ -9678,7 +10918,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-retry@npm:^4.1.12, @smithy/middleware-retry@npm:^4.4.44": +"@smithy/middleware-retry@npm:^4.4.44": version: 4.4.44 resolution: "@smithy/middleware-retry@npm:4.4.44" dependencies: @@ -9695,7 +10935,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-serde@npm:^4.0.8, @smithy/middleware-serde@npm:^4.2.15": +"@smithy/middleware-serde@npm:^4.2.15": version: 4.2.15 resolution: "@smithy/middleware-serde@npm:4.2.15" dependencies: @@ -9707,7 +10947,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-stack@npm:^4.0.4, @smithy/middleware-stack@npm:^4.2.12": +"@smithy/middleware-stack@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/middleware-stack@npm:4.2.12" dependencies: @@ -9717,7 +10957,7 @@ __metadata: languageName: node linkType: hard -"@smithy/node-config-provider@npm:^4.1.3, @smithy/node-config-provider@npm:^4.3.12": +"@smithy/node-config-provider@npm:^4.3.12": version: 4.3.12 resolution: "@smithy/node-config-provider@npm:4.3.12" dependencies: @@ -9729,7 +10969,7 @@ __metadata: languageName: node linkType: hard -"@smithy/node-http-handler@npm:^4.0.6, @smithy/node-http-handler@npm:^4.5.0": +"@smithy/node-http-handler@npm:^4.5.0": version: 4.5.0 resolution: "@smithy/node-http-handler@npm:4.5.0" dependencies: @@ -9742,7 +10982,7 @@ __metadata: languageName: node linkType: hard -"@smithy/property-provider@npm:^4.0.4, @smithy/property-provider@npm:^4.2.12": +"@smithy/property-provider@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/property-provider@npm:4.2.12" dependencies: @@ -9752,7 +10992,7 @@ __metadata: languageName: node linkType: hard -"@smithy/protocol-http@npm:^5.1.2, @smithy/protocol-http@npm:^5.3.12": +"@smithy/protocol-http@npm:^5.3.12": version: 5.3.12 resolution: "@smithy/protocol-http@npm:5.3.12" dependencies: @@ -9792,7 +11032,7 @@ __metadata: languageName: node linkType: hard -"@smithy/shared-ini-file-loader@npm:^4.0.4, @smithy/shared-ini-file-loader@npm:^4.4.7": +"@smithy/shared-ini-file-loader@npm:^4.4.7": version: 4.4.7 resolution: "@smithy/shared-ini-file-loader@npm:4.4.7" dependencies: @@ -9802,7 +11042,7 @@ __metadata: languageName: node linkType: hard -"@smithy/signature-v4@npm:^5.1.2, @smithy/signature-v4@npm:^5.3.12": +"@smithy/signature-v4@npm:^5.3.12": version: 5.3.12 resolution: "@smithy/signature-v4@npm:5.3.12" dependencies: @@ -9818,7 +11058,7 @@ __metadata: languageName: node linkType: hard -"@smithy/smithy-client@npm:^4.12.7, @smithy/smithy-client@npm:^4.4.3": +"@smithy/smithy-client@npm:^4.12.7": version: 4.12.7 resolution: "@smithy/smithy-client@npm:4.12.7" dependencies: @@ -9842,7 +11082,7 @@ __metadata: languageName: node linkType: hard -"@smithy/types@npm:^4.13.1, @smithy/types@npm:^4.3.1": +"@smithy/types@npm:^4.13.1": version: 4.13.1 resolution: "@smithy/types@npm:4.13.1" dependencies: @@ -9851,7 +11091,7 @@ __metadata: languageName: node linkType: hard -"@smithy/url-parser@npm:^4.0.4, @smithy/url-parser@npm:^4.2.12": +"@smithy/url-parser@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/url-parser@npm:4.2.12" dependencies: @@ -9862,7 +11102,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-base64@npm:^4.0.0, @smithy/util-base64@npm:^4.3.2": +"@smithy/util-base64@npm:^4.3.2": version: 4.3.2 resolution: "@smithy/util-base64@npm:4.3.2" dependencies: @@ -9873,7 +11113,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-body-length-browser@npm:^4.0.0, @smithy/util-body-length-browser@npm:^4.2.2": +"@smithy/util-body-length-browser@npm:^4.2.2": version: 4.2.2 resolution: "@smithy/util-body-length-browser@npm:4.2.2" dependencies: @@ -9882,7 +11122,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-body-length-node@npm:^4.0.0, @smithy/util-body-length-node@npm:^4.2.3": +"@smithy/util-body-length-node@npm:^4.2.3": version: 4.2.3 resolution: "@smithy/util-body-length-node@npm:4.2.3" dependencies: @@ -9911,7 +11151,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-config-provider@npm:^4.0.0, @smithy/util-config-provider@npm:^4.2.2": +"@smithy/util-config-provider@npm:^4.2.2": version: 4.2.2 resolution: "@smithy/util-config-provider@npm:4.2.2" dependencies: @@ -9920,7 +11160,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-browser@npm:^4.0.19, @smithy/util-defaults-mode-browser@npm:^4.3.43": +"@smithy/util-defaults-mode-browser@npm:^4.3.43": version: 4.3.43 resolution: "@smithy/util-defaults-mode-browser@npm:4.3.43" dependencies: @@ -9932,7 +11172,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-defaults-mode-node@npm:^4.0.19, @smithy/util-defaults-mode-node@npm:^4.2.47": +"@smithy/util-defaults-mode-node@npm:^4.2.47": version: 4.2.47 resolution: "@smithy/util-defaults-mode-node@npm:4.2.47" dependencies: @@ -9947,7 +11187,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-endpoints@npm:^3.0.6, @smithy/util-endpoints@npm:^3.3.3": +"@smithy/util-endpoints@npm:^3.3.3": version: 3.3.3 resolution: "@smithy/util-endpoints@npm:3.3.3" dependencies: @@ -9967,7 +11207,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-middleware@npm:^4.0.4, @smithy/util-middleware@npm:^4.2.12": +"@smithy/util-middleware@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/util-middleware@npm:4.2.12" dependencies: @@ -9977,7 +11217,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-retry@npm:^4.0.5, @smithy/util-retry@npm:^4.2.12": +"@smithy/util-retry@npm:^4.2.12": version: 4.2.12 resolution: "@smithy/util-retry@npm:4.2.12" dependencies: @@ -9988,7 +11228,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-stream@npm:^4.2.2, @smithy/util-stream@npm:^4.5.20": +"@smithy/util-stream@npm:^4.5.20": version: 4.5.20 resolution: "@smithy/util-stream@npm:4.5.20" dependencies: @@ -10023,7 +11263,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-utf8@npm:^4.0.0, @smithy/util-utf8@npm:^4.2.2": +"@smithy/util-utf8@npm:^4.2.2": version: 4.2.2 resolution: "@smithy/util-utf8@npm:4.2.2" dependencies: @@ -10063,15 +11303,6 @@ __metadata: languageName: node linkType: hard -"@smithy/uuid@npm:^1.1.2": - version: 1.1.2 - resolution: "@smithy/uuid@npm:1.1.2" - dependencies: - tslib: "npm:^2.6.2" - checksum: 10/35b77a2483a37755c2be1faf66036f5e0b7939a7c608b93982fce9d4f137f1778784f101a2874a6756d9fd25092c6a95dd07314df12dcb9a0a03244b4cc4d8c4 - languageName: node - linkType: hard - "@spotify/eslint-config-base@npm:^15.0.0": version: 15.0.0 resolution: "@spotify/eslint-config-base@npm:15.0.0" @@ -10357,17 +11588,201 @@ __metadata: version: 4.3.0 resolution: "@stoplight/yaml@npm:4.3.0" dependencies: - "@stoplight/ordered-object-literal": "npm:^1.0.5" - "@stoplight/types": "npm:^14.1.1" - "@stoplight/yaml-ast-parser": "npm:0.0.50" - tslib: "npm:^2.2.0" - checksum: 10/4a3eacfb5fb8936cb4b229f69542224e5905f71a6e2baeb70f73a67de6ce3b20178079a79d7744a437db901f67740dcdfd9b53dafb918ce75cbbb498ec548fd7 + "@stoplight/ordered-object-literal": "npm:^1.0.5" + "@stoplight/types": "npm:^14.1.1" + "@stoplight/yaml-ast-parser": "npm:0.0.50" + tslib: "npm:^2.2.0" + checksum: 10/4a3eacfb5fb8936cb4b229f69542224e5905f71a6e2baeb70f73a67de6ce3b20178079a79d7744a437db901f67740dcdfd9b53dafb918ce75cbbb498ec548fd7 + languageName: node + linkType: hard + +"@sucrase/webpack-loader@npm:^2.0.0": + version: 2.0.0 + resolution: "@sucrase/webpack-loader@npm:2.0.0" + dependencies: + loader-utils: "npm:^1.1.0" + peerDependencies: + sucrase: ^3 + checksum: 10/16578991b1b888ac5bec5628bd24db9e21651bbbe30de076aece8787f115d8971ac87a20bc75446187c73c3185851ec2233d5b6f18c4a2dd53fbbb1ed4e488b4 + languageName: node + linkType: hard + +"@svgr/babel-plugin-add-jsx-attribute@npm:^6.5.1": + version: 6.5.1 + resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:6.5.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/cab83832830a57735329ed68f67c03b57ca21fa037b0134847b0c5c0ef4beca89956d7dacfbf7b2a10fd901e7009e877512086db2ee918b8c69aee7742ae32c0 + languageName: node + linkType: hard + +"@svgr/babel-plugin-remove-jsx-attribute@npm:*": + version: 8.0.0 + resolution: "@svgr/babel-plugin-remove-jsx-attribute@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/ff992893c6c4ac802713ba3a97c13be34e62e6d981c813af40daabcd676df68a72a61bd1e692bb1eda3587f1b1d700ea462222ae2153bb0f46886632d4f88d08 + languageName: node + linkType: hard + +"@svgr/babel-plugin-remove-jsx-empty-expression@npm:*": + version: 8.0.0 + resolution: "@svgr/babel-plugin-remove-jsx-empty-expression@npm:8.0.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/0fb691b63a21bac00da3aa2dccec50d0d5a5b347ff408d60803b84410d8af168f2656e4ba1ee1f24dab0ae4e4af77901f2928752bb0434c1f6788133ec599ec8 + languageName: node + linkType: hard + +"@svgr/babel-plugin-replace-jsx-attribute-value@npm:^6.5.1": + version: 6.5.1 + resolution: "@svgr/babel-plugin-replace-jsx-attribute-value@npm:6.5.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/b7d2125758e766e1ebd14b92216b800bdc976959bc696dbfa1e28682919147c1df4bb8b1b5fd037d7a83026e27e681fea3b8d3741af8d3cf4c9dfa3d412125df + languageName: node + linkType: hard + +"@svgr/babel-plugin-svg-dynamic-title@npm:^6.5.1": + version: 6.5.1 + resolution: "@svgr/babel-plugin-svg-dynamic-title@npm:6.5.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/0fd42ebf127ae9163ef341e84972daa99bdcb9e6ed3f83aabd95ee173fddc43e40e02fa847fbc0a1058cf5549f72b7960a2c5e22c3e4ac18f7e3ac81277852ae + languageName: node + linkType: hard + +"@svgr/babel-plugin-svg-em-dimensions@npm:^6.5.1": + version: 6.5.1 + resolution: "@svgr/babel-plugin-svg-em-dimensions@npm:6.5.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/c1550ee9f548526fa66fd171e3ffb5696bfc4e4cd108a631d39db492c7410dc10bba4eb5a190e9df824bf806130ccc586ae7d2e43c547e6a4f93bbb29a18f344 + languageName: node + linkType: hard + +"@svgr/babel-plugin-transform-react-native-svg@npm:^6.5.1": + version: 6.5.1 + resolution: "@svgr/babel-plugin-transform-react-native-svg@npm:6.5.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/4c924af22b948b812629e80efb90ad1ec8faae26a232d8ca8a06b46b53e966a2c415a57806a3ff0ea806a622612e546422719b69ec6839717a7755dac19171d9 + languageName: node + linkType: hard + +"@svgr/babel-plugin-transform-svg-component@npm:^6.5.1": + version: 6.5.1 + resolution: "@svgr/babel-plugin-transform-svg-component@npm:6.5.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/a4ddd3cf8b1a7a0542ff2c6a3eb7a75d6f79a86a62210306d94fb05e59699bb5da4ddde9ce98ef477b9cd528007fb728dc4d388d413b3aa25f48ed92b1f0a1c1 + languageName: node + linkType: hard + +"@svgr/babel-preset@npm:^6.5.1": + version: 6.5.1 + resolution: "@svgr/babel-preset@npm:6.5.1" + dependencies: + "@svgr/babel-plugin-add-jsx-attribute": "npm:^6.5.1" + "@svgr/babel-plugin-remove-jsx-attribute": "npm:*" + "@svgr/babel-plugin-remove-jsx-empty-expression": "npm:*" + "@svgr/babel-plugin-replace-jsx-attribute-value": "npm:^6.5.1" + "@svgr/babel-plugin-svg-dynamic-title": "npm:^6.5.1" + "@svgr/babel-plugin-svg-em-dimensions": "npm:^6.5.1" + "@svgr/babel-plugin-transform-react-native-svg": "npm:^6.5.1" + "@svgr/babel-plugin-transform-svg-component": "npm:^6.5.1" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10/9f124be39a8e64f909162f925b3a63ddaa5a342a5e24fc0b7f7d9d4d7f7e3b916596c754fb557dc259928399cad5366a27cb231627a0d2dcc4b13ac521cf05af + languageName: node + linkType: hard + +"@svgr/core@npm:6.5.x, @svgr/core@npm:^6.5.1": + version: 6.5.1 + resolution: "@svgr/core@npm:6.5.1" + dependencies: + "@babel/core": "npm:^7.19.6" + "@svgr/babel-preset": "npm:^6.5.1" + "@svgr/plugin-jsx": "npm:^6.5.1" + camelcase: "npm:^6.2.0" + cosmiconfig: "npm:^7.0.1" + checksum: 10/0aa3078eefb969d93fb5639c2d64c8868cf65134f0e36a1733dc595acc990081cbad62295e34b860150ce6baa21516d71410c5527579a1a0950cdc35a765873a + languageName: node + linkType: hard + +"@svgr/hast-util-to-babel-ast@npm:^6.5.1": + version: 6.5.1 + resolution: "@svgr/hast-util-to-babel-ast@npm:6.5.1" + dependencies: + "@babel/types": "npm:^7.20.0" + entities: "npm:^4.4.0" + checksum: 10/0410c6e5bf98fe31729ab1785642b915e7645e65c7ee5b2dd292a4603f8a1377402b95237c550b10dbdcc0bf084df1546ac7e98004d1fe5982cb8508147b47bb + languageName: node + linkType: hard + +"@svgr/plugin-jsx@npm:6.5.x, @svgr/plugin-jsx@npm:^6.5.1": + version: 6.5.1 + resolution: "@svgr/plugin-jsx@npm:6.5.1" + dependencies: + "@babel/core": "npm:^7.19.6" + "@svgr/babel-preset": "npm:^6.5.1" + "@svgr/hast-util-to-babel-ast": "npm:^6.5.1" + svg-parser: "npm:^2.0.4" + peerDependencies: + "@svgr/core": ^6.0.0 + checksum: 10/42f22847a6bdf930514d7bedd3c5e1fd8d53eb3594779f9db16cb94c762425907c375cd8ec789114e100a4d38068aca6c7ab5efea4c612fba63f0630c44cc859 + languageName: node + linkType: hard + +"@svgr/plugin-svgo@npm:6.5.x, @svgr/plugin-svgo@npm:^6.5.1": + version: 6.5.1 + resolution: "@svgr/plugin-svgo@npm:6.5.1" + dependencies: + cosmiconfig: "npm:^7.0.1" + deepmerge: "npm:^4.2.2" + svgo: "npm:^2.8.0" + peerDependencies: + "@svgr/core": "*" + checksum: 10/cd2833530ac0485221adc2146fd992ab20d79f4b12eebcd45fa859721dd779483158e11dfd9a534858fe468416b9412416e25cbe07ac7932c44ed5fa2021c72e + languageName: node + linkType: hard + +"@svgr/rollup@npm:6.5.x": + version: 6.5.1 + resolution: "@svgr/rollup@npm:6.5.1" + dependencies: + "@babel/core": "npm:^7.19.6" + "@babel/plugin-transform-react-constant-elements": "npm:^7.18.12" + "@babel/preset-env": "npm:^7.19.4" + "@babel/preset-react": "npm:^7.18.6" + "@babel/preset-typescript": "npm:^7.18.6" + "@rollup/pluginutils": "npm:^4.2.1" + "@svgr/core": "npm:^6.5.1" + "@svgr/plugin-jsx": "npm:^6.5.1" + "@svgr/plugin-svgo": "npm:^6.5.1" + checksum: 10/809198a655c280b434d762829aeab0c48e545daaa7a520ac87d5e7cfe96402eb4d0c01f8b25959fcc37a2ce4aa1a53c9e1c4ccb1206cd5833883a34db5799dd4 + languageName: node + linkType: hard + +"@svgr/webpack@npm:6.5.x": + version: 6.5.1 + resolution: "@svgr/webpack@npm:6.5.1" + dependencies: + "@babel/core": "npm:^7.19.6" + "@babel/plugin-transform-react-constant-elements": "npm:^7.18.12" + "@babel/preset-env": "npm:^7.19.4" + "@babel/preset-react": "npm:^7.18.6" + "@babel/preset-typescript": "npm:^7.18.6" + "@svgr/core": "npm:^6.5.1" + "@svgr/plugin-jsx": "npm:^6.5.1" + "@svgr/plugin-svgo": "npm:^6.5.1" + checksum: 10/2748acc94839a2da09d73fe23bd9df85e08d52d823425591c960e8a25b83861ca2f49dbb1d66ea318da8160f16ce6248c8854229bd6316565517356c74c3440f languageName: node linkType: hard -"@swc/core-darwin-arm64@npm:1.15.18": - version: 1.15.18 - resolution: "@swc/core-darwin-arm64@npm:1.15.18" +"@swc/core-darwin-arm64@npm:1.15.21": + version: 1.15.21 + resolution: "@swc/core-darwin-arm64@npm:1.15.21" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard @@ -10449,9 +11864,9 @@ __metadata: languageName: node linkType: hard -"@swc/core@npm:^1.15.6": - version: 1.15.18 - resolution: "@swc/core@npm:1.15.18" +"@swc/core@npm:^1.15.6, @swc/core@npm:^1.3.46": + version: 1.15.21 + resolution: "@swc/core@npm:1.15.21" dependencies: "@swc/core-darwin-arm64": "npm:1.15.21" "@swc/core-darwin-x64": "npm:1.15.21" @@ -10883,26 +12298,6 @@ __metadata: languageName: node linkType: hard -"@types/eslint-scope@npm:^3.7.7": - version: 3.7.7 - resolution: "@types/eslint-scope@npm:3.7.7" - dependencies: - "@types/eslint": "npm:*" - "@types/estree": "npm:*" - checksum: 10/e2889a124aaab0b89af1bab5959847c5bec09809209255de0e63b9f54c629a94781daa04adb66bffcdd742f5e25a17614fb933965093c0eea64aacda4309380e - languageName: node - linkType: hard - -"@types/eslint@npm:*": - version: 9.6.1 - resolution: "@types/eslint@npm:9.6.1" - dependencies: - "@types/estree": "npm:*" - "@types/json-schema": "npm:*" - checksum: 10/719fcd255760168a43d0e306ef87548e1e15bffe361d5f4022b0f266575637acc0ecb85604ac97879ee8ae83c6a6d0613b0ed31d0209ddf22a0fe6d608fc56fe - languageName: node - linkType: hard - "@types/eslint@npm:^8.56.10": version: 8.56.12 resolution: "@types/eslint@npm:8.56.12" @@ -10922,7 +12317,6 @@ __metadata: languageName: node linkType: hard -"@types/estree@npm:*, @types/estree@npm:1.0.8, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.8": "@types/estree@npm:*, @types/estree@npm:1.0.8, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.8": version: 1.0.8 resolution: "@types/estree@npm:1.0.8" @@ -11982,157 +13376,6 @@ __metadata: languageName: node linkType: hard -"@webassemblyjs/ast@npm:1.14.1, @webassemblyjs/ast@npm:^1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/ast@npm:1.14.1" - dependencies: - "@webassemblyjs/helper-numbers": "npm:1.13.2" - "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" - checksum: 10/f83e6abe38057f5d87c1fb356513a371a8b43c9b87657f2790741a66b1ef8ecf958d1391bc42f27c5fb33f58ab8286a38ea849fdd21f433cd4df1307424bab45 - languageName: node - linkType: hard - -"@webassemblyjs/floating-point-hex-parser@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.13.2" - checksum: 10/e866ec8433f4a70baa511df5e8f2ebcd6c24f4e2cc6274c7c5aabe2bcce3459ea4680e0f35d450e1f3602acf3913b6b8e4f15069c8cfd34ae8609fb9a7d01795 - languageName: node - linkType: hard - -"@webassemblyjs/helper-api-error@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/helper-api-error@npm:1.13.2" - checksum: 10/48b5df7fd3095bb252f59a139fe2cbd999a62ac9b488123e9a0da3906ad8a2f2da7b2eb21d328c01a90da987380928706395c2897d1f3ed9e2125b6d75a920d0 - languageName: node - linkType: hard - -"@webassemblyjs/helper-buffer@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/helper-buffer@npm:1.14.1" - checksum: 10/9690afeafa5e765a34620aa6216e9d40f9126d4e37e9726a2594bf60cab6b211ef20ab6670fd3c4449dd4a3497e69e49b2b725c8da0fb213208c7f45f15f5d5b - languageName: node - linkType: hard - -"@webassemblyjs/helper-numbers@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/helper-numbers@npm:1.13.2" - dependencies: - "@webassemblyjs/floating-point-hex-parser": "npm:1.13.2" - "@webassemblyjs/helper-api-error": "npm:1.13.2" - "@xtuc/long": "npm:4.2.2" - checksum: 10/e4c7d0b09811e1cda8eec644a022b560b28f4e974f50195375ccd007df5ee48a922a6dcff5ac40b6a8ec850d56d0ea6419318eee49fec7819ede14e90417a6a4 - languageName: node - linkType: hard - -"@webassemblyjs/helper-wasm-bytecode@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.13.2" - checksum: 10/3edd191fff7296df1ef3b023bdbe6cb5ea668f6386fd197ccfce46015c6f2a8cc9763cfb86503a0b94973ad27996645afff2252ee39a236513833259a47af6ed - languageName: node - linkType: hard - -"@webassemblyjs/helper-wasm-section@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/helper-wasm-section@npm:1.14.1" - dependencies: - "@webassemblyjs/ast": "npm:1.14.1" - "@webassemblyjs/helper-buffer": "npm:1.14.1" - "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" - "@webassemblyjs/wasm-gen": "npm:1.14.1" - checksum: 10/6b73874f906532512371181d7088460f767966f26309e836060c5a8e4e4bfe6d523fb5f4c034b34aa22ebb1192815f95f0e264298769485c1f0980fdd63ae0ce - languageName: node - linkType: hard - -"@webassemblyjs/ieee754@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/ieee754@npm:1.13.2" - dependencies: - "@xtuc/ieee754": "npm:^1.2.0" - checksum: 10/d7e3520baa37a7309fa7db4d73d69fb869878853b1ebd4b168821bd03fcc4c0e1669c06231315b0039035d9a7a462e53de3ad982da4a426a4b0743b5888e8673 - languageName: node - linkType: hard - -"@webassemblyjs/leb128@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/leb128@npm:1.13.2" - dependencies: - "@xtuc/long": "npm:4.2.2" - checksum: 10/3a10542c86807061ec3230bac8ee732289c852b6bceb4b88ebd521a12fbcecec7c432848284b298154f28619e2746efbed19d6904aef06c49ef20a0b85f650cf - languageName: node - linkType: hard - -"@webassemblyjs/utf8@npm:1.13.2": - version: 1.13.2 - resolution: "@webassemblyjs/utf8@npm:1.13.2" - checksum: 10/27885e5d19f339501feb210867d69613f281eda695ac508f04d69fa3398133d05b6870969c0242b054dc05420ed1cc49a64dea4fe0588c18d211cddb0117cc54 - languageName: node - linkType: hard - -"@webassemblyjs/wasm-edit@npm:^1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wasm-edit@npm:1.14.1" - dependencies: - "@webassemblyjs/ast": "npm:1.14.1" - "@webassemblyjs/helper-buffer": "npm:1.14.1" - "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" - "@webassemblyjs/helper-wasm-section": "npm:1.14.1" - "@webassemblyjs/wasm-gen": "npm:1.14.1" - "@webassemblyjs/wasm-opt": "npm:1.14.1" - "@webassemblyjs/wasm-parser": "npm:1.14.1" - "@webassemblyjs/wast-printer": "npm:1.14.1" - checksum: 10/c62c50eadcf80876713f8c9f24106b18cf208160ab842fcb92060fd78c37bf37e7fcf0b7cbf1afc05d230277c2ce0f3f728432082c472dd1293e184a95f9dbdd - languageName: node - linkType: hard - -"@webassemblyjs/wasm-gen@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wasm-gen@npm:1.14.1" - dependencies: - "@webassemblyjs/ast": "npm:1.14.1" - "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" - "@webassemblyjs/ieee754": "npm:1.13.2" - "@webassemblyjs/leb128": "npm:1.13.2" - "@webassemblyjs/utf8": "npm:1.13.2" - checksum: 10/6085166b0987d3031355fe17a4f9ef0f412e08098d95454059aced2bd72a4c3df2bc099fa4d32d640551fc3eca1ac1a997b44432e46dc9d84642688e42c17ed4 - languageName: node - linkType: hard - -"@webassemblyjs/wasm-opt@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wasm-opt@npm:1.14.1" - dependencies: - "@webassemblyjs/ast": "npm:1.14.1" - "@webassemblyjs/helper-buffer": "npm:1.14.1" - "@webassemblyjs/wasm-gen": "npm:1.14.1" - "@webassemblyjs/wasm-parser": "npm:1.14.1" - checksum: 10/fa5d1ef8d2156e7390927f938f513b7fb4440dd6804b3d6c8622b7b1cf25a3abf1a5809f615896d4918e04b27b52bc3cbcf18faf2d563cb563ae0a9204a492db - languageName: node - linkType: hard - -"@webassemblyjs/wasm-parser@npm:1.14.1, @webassemblyjs/wasm-parser@npm:^1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wasm-parser@npm:1.14.1" - dependencies: - "@webassemblyjs/ast": "npm:1.14.1" - "@webassemblyjs/helper-api-error": "npm:1.13.2" - "@webassemblyjs/helper-wasm-bytecode": "npm:1.13.2" - "@webassemblyjs/ieee754": "npm:1.13.2" - "@webassemblyjs/leb128": "npm:1.13.2" - "@webassemblyjs/utf8": "npm:1.13.2" - checksum: 10/07d9805fda88a893c984ed93d5a772d20d671e9731358ab61c6c1af8e0e58d1c42fc230c18974dfddebc9d2dd7775d514ba4d445e70080b16478b4b16c39c7d9 - languageName: node - linkType: hard - -"@webassemblyjs/wast-printer@npm:1.14.1": - version: 1.14.1 - resolution: "@webassemblyjs/wast-printer@npm:1.14.1" - dependencies: - "@webassemblyjs/ast": "npm:1.14.1" - "@xtuc/long": "npm:4.2.2" - checksum: 10/cef09aad2fcd291bfcf9efdae2ea1e961a1ba0f925d1d9dcdd8c746d32fbaf431b6d26a0241699c0e39f82139018aa720b4ceb84ac6f4c78f13072747480db69 - languageName: node - linkType: hard - "@xobotyi/scrollbar-width@npm:^1.9.5": version: 1.9.5 resolution: "@xobotyi/scrollbar-width@npm:1.9.5" @@ -12154,20 +13397,6 @@ __metadata: languageName: node linkType: hard -"@xtuc/ieee754@npm:^1.2.0": - version: 1.2.0 - resolution: "@xtuc/ieee754@npm:1.2.0" - checksum: 10/ab033b032927d77e2f9fa67accdf31b1ca7440974c21c9cfabc8349e10ca2817646171c4f23be98d0e31896d6c2c3462a074fe37752e523abc3e45c79254259c - languageName: node - linkType: hard - -"@xtuc/long@npm:4.2.2": - version: 4.2.2 - resolution: "@xtuc/long@npm:4.2.2" - checksum: 10/7217bae9fe240e0d804969e7b2af11cb04ec608837c78b56ca88831991b287e232a0b7fce8d548beaff42aaf0197ffa471d81be6ac4c4e53b0148025a2c076ec - languageName: node - linkType: hard - "@yarnpkg/lockfile@npm:^1.1.0": version: 1.1.0 resolution: "@yarnpkg/lockfile@npm:1.1.0" @@ -12215,7 +13444,7 @@ __metadata: languageName: node linkType: hard -"accepts@npm:^1.3.8, accepts@npm:~1.3.4, accepts@npm:~1.3.8": +"accepts@npm:^1.3.5, accepts@npm:^1.3.8, accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" dependencies: @@ -12272,7 +13501,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.11.0, acorn@npm:^8.14.0, acorn@npm:^8.15.0, acorn@npm:^8.4.1, acorn@npm:^8.9.0": +"acorn@npm:^8.1.0, acorn@npm:^8.11.0, acorn@npm:^8.15.0, acorn@npm:^8.16.0, acorn@npm:^8.4.1, acorn@npm:^8.8.1, acorn@npm:^8.9.0": version: 8.16.0 resolution: "acorn@npm:8.16.0" bin: @@ -12760,17 +13989,6 @@ __metadata: languageName: node linkType: hard -"asn1js@npm:^3.0.6": - version: 3.0.7 - resolution: "asn1js@npm:3.0.7" - dependencies: - pvtsutils: "npm:^1.3.6" - pvutils: "npm:^1.1.3" - tslib: "npm:^2.8.1" - checksum: 10/1ae92cc6825ff002aed5b2a800e89db1fccd0775b42278431332fe3ee6839711e80e1ca504c72a35a03d94d417c3b315fb03bc6a6f4518c309b1dcb5385a1a93 - languageName: node - linkType: hard - "assert@npm:^2.0.0": version: 2.1.0 resolution: "assert@npm:2.1.0" @@ -12883,20 +14101,9 @@ __metadata: languageName: node linkType: hard -"axios@npm:1.9.0": - version: 1.9.0 - resolution: "axios@npm:1.9.0" - dependencies: - follow-redirects: "npm:^1.15.6" - form-data: "npm:^4.0.0" - proxy-from-env: "npm:^1.1.0" - checksum: 10/a2f90bba56820883879f32a237e2b9ff25c250365dcafd41cec41b3406a3df334a148f90010182dfdadb4b41dc59f6f0b3e8898ff41b666d1157b5f3f4523497 - languageName: node - linkType: hard - -"axios@npm:^1.12.0": - version: 1.13.6 - resolution: "axios@npm:1.13.6" +"axios@npm:^1.12.0, axios@npm:^1.13.6, axios@npm:^1.7.4": + version: 1.14.0 + resolution: "axios@npm:1.14.0" dependencies: follow-redirects: "npm:^1.15.11" form-data: "npm:^4.0.5" @@ -13161,6 +14368,15 @@ __metadata: languageName: node linkType: hard +"baseline-browser-mapping@npm:^2.9.0": + version: 2.10.12 + resolution: "baseline-browser-mapping@npm:2.10.12" + bin: + baseline-browser-mapping: dist/cli.cjs + checksum: 10/ec3ecf8885a8aaf0c8294ac7414aa6948d1a0d2bdc68be238f7403b5a8b9bc52bbbb0ba9e230b487128047154565552c98cdf5489d31cc8ae49607b4ff5e1064 + languageName: node + linkType: hard + "basic-ftp@npm:^5.0.2": version: 5.2.0 resolution: "basic-ftp@npm:5.2.0" @@ -13222,6 +14438,19 @@ __metadata: languageName: node linkType: hard +"bfj@npm:^8.0.0": + version: 8.0.0 + resolution: "bfj@npm:8.0.0" + dependencies: + bluebird: "npm:^3.7.2" + check-types: "npm:^11.2.3" + hoopy: "npm:^0.1.4" + jsonpath: "npm:^1.1.1" + tryer: "npm:^1.0.1" + checksum: 10/3e79233e2ba30681a494470d664c654351d2f4fcba7c2972f7e8b6248e374a77a164141164ea32d23f805f0a235aa87dbf480ad0a5939c36f5efbf922de8beb4 + languageName: node + linkType: hard + "bfj@npm:^9.0.2": version: 9.1.3 resolution: "bfj@npm:9.1.3" @@ -13274,6 +14503,13 @@ __metadata: languageName: node linkType: hard +"bluebird@npm:^3.7.2": + version: 3.7.2 + resolution: "bluebird@npm:3.7.2" + checksum: 10/007c7bad22c5d799c8dd49c85b47d012a1fe3045be57447721e6afbd1d5be43237af1db62e26cb9b0d9ba812d2e4ca3bac82f6d7e016b6b88de06ee25ceb96e7 + languageName: node + linkType: hard + "bn.js@npm:^4.0.0, bn.js@npm:^4.1.0, bn.js@npm:^4.11.9": version: 4.12.3 resolution: "bn.js@npm:4.12.3" @@ -13483,9 +14719,9 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.21.4": - version: 4.25.0 - resolution: "browserslist@npm:4.25.0" +"browserslist@npm:^4.0.0, browserslist@npm:^4.18.1, browserslist@npm:^4.21.4, browserslist@npm:^4.24.0, browserslist@npm:^4.28.1": + version: 4.28.1 + resolution: "browserslist@npm:4.28.1" dependencies: baseline-browser-mapping: "npm:^2.9.0" caniuse-lite: "npm:^1.0.30001759" @@ -13494,7 +14730,16 @@ __metadata: update-browserslist-db: "npm:^1.2.0" bin: browserslist: cli.js - checksum: 10/4a5442b1a0d09c4c64454f184b8fed17d8c3e202034bf39de28f74497d7bd28dddee121b2bab4e34825fe0ed4c166d84e32a39f576c76fce73c1f8f05e4b6ee6 + checksum: 10/64f2a97de4bce8473c0e5ae0af8d76d1ead07a5b05fc6bc87b848678bb9c3a91ae787b27aa98cdd33fc00779607e6c156000bed58fefb9cf8e4c5a183b994cdb + languageName: node + linkType: hard + +"bser@npm:2.1.1": + version: 2.1.1 + resolution: "bser@npm:2.1.1" + dependencies: + node-int64: "npm:^0.4.0" + checksum: 10/edba1b65bae682450be4117b695997972bd9a3c4dfee029cab5bcb72ae5393a79a8f909b8bc77957eb0deec1c7168670f18f4d5c556f46cdd3bca5f3b3a8d020 languageName: node linkType: hard @@ -13622,13 +14867,6 @@ __metadata: languageName: node linkType: hard -"bytestreamjs@npm:^2.0.1": - version: 2.0.1 - resolution: "bytestreamjs@npm:2.0.1" - checksum: 10/523b1024e3f887cdc0b3db7c4fc14b8563aaeb75e6642a41991b3208277fd0ae9cd66003c73473fe706c42797bf0c3f1f498fb9880b431d75b332e5709d56a0c - languageName: node - linkType: hard - "cacache@npm:^18.0.0": version: 18.0.4 resolution: "cacache@npm:18.0.4" @@ -13902,15 +15140,6 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^4.0.1": - version: 4.0.3 - resolution: "chokidar@npm:4.0.3" - dependencies: - readdirp: "npm:^4.0.1" - checksum: 10/bf2a575ea5596000e88f5db95461a9d59ad2047e939d5a4aac59dd472d126be8f1c1ff3c7654b477cf532d18f42a97279ef80ee847972fd2a25410bf00b80b59 - languageName: node - linkType: hard - "chownr@npm:^1.1.1": version: 1.1.4 resolution: "chownr@npm:1.1.4" @@ -13932,7 +15161,14 @@ __metadata: languageName: node linkType: hard -"ci-info@npm:^3.2.0, ci-info@npm:^3.7.0": +"chrome-trace-event@npm:^1.0.2": + version: 1.0.4 + resolution: "chrome-trace-event@npm:1.0.4" + checksum: 10/1762bed739774903bf5915fe3045c3120fc3c7f7d929d88e566447ea38944937a6370ccb687278318c43c24f837ad22dac780bed67c066336815557b8cf558c6 + languageName: node + linkType: hard + +"ci-info@npm:^3.2.0": version: 3.9.0 resolution: "ci-info@npm:3.9.0" checksum: 10/75bc67902b4d1c7b435497adeb91598f6d52a3389398e44294f6601b20cfef32cf2176f7be0eb961d9e085bb333a8a5cae121cb22f81cf238ae7f58eb80e9397 @@ -14103,7 +15339,14 @@ __metadata: languageName: node linkType: hard -"color-convert@npm:^1.9.0, color-convert@npm:^1.9.3": +"collect-v8-coverage@npm:^1.0.0": + version: 1.0.3 + resolution: "collect-v8-coverage@npm:1.0.3" + checksum: 10/656443261fb7b79cf79e89cba4b55622b07c1d4976c630829d7c5c585c73cda1c2ff101f316bfb19bb9e2c58d724c7db1f70a21e213dcd14099227c5e6019860 + languageName: node + linkType: hard + +"color-convert@npm:^1.9.0": version: 1.9.3 resolution: "color-convert@npm:1.9.3" dependencies: @@ -14477,7 +15720,14 @@ __metadata: languageName: node linkType: hard -"cookie-signature@npm:^1.2.1": +"convert-source-map@npm:^2.0.0": + version: 2.0.0 + resolution: "convert-source-map@npm:2.0.0" + checksum: 10/c987be3ec061348cdb3c2bfb924bec86dea1eacad10550a85ca23edb0fe3556c3a61c7399114f3331ccb3499d7fd0285ab24566e5745929412983494c3926e15 + languageName: node + linkType: hard + +"cookie-signature@npm:^1.2.1, cookie-signature@npm:^1.2.2": version: 1.2.2 resolution: "cookie-signature@npm:1.2.2" checksum: 10/be44a3c9a56f3771aea3a8bd8ad8f0a8e2679bcb967478267f41a510b4eb5ec55085386ba79c706c4ac21605ca76f4251973444b90283e0eb3eeafe8a92c7708 @@ -14600,23 +15850,6 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^8.2.0": - version: 8.3.6 - resolution: "cosmiconfig@npm:8.3.6" - dependencies: - import-fresh: "npm:^3.3.0" - js-yaml: "npm:^4.1.0" - parse-json: "npm:^5.2.0" - path-type: "npm:^4.0.0" - peerDependencies: - typescript: ">=4.9.5" - peerDependenciesMeta: - typescript: - optional: true - checksum: 10/91d082baca0f33b1c085bf010f9ded4af43cbedacba8821da0fb5667184d0a848addc52c31fadd080007f904a555319c238cf5f4c03e6d58ece2e4876b2e73d6 - languageName: node - linkType: hard - "cpu-features@npm:~0.0.10": version: 0.0.10 resolution: "cpu-features@npm:0.0.10" @@ -15783,10 +17016,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.160": - version: 1.5.171 - resolution: "electron-to-chromium@npm:1.5.171" - checksum: 10/6d58ff50407107d7e86e7beb8d0361358f90dbc10c7d92a2ff9cdfbaf27a65165c00ae05a345ab32fa6e371ff9c7d1fef1441d57adfa8f59701c56734745c0a1 +"electron-to-chromium@npm:^1.5.263": + version: 1.5.328 + resolution: "electron-to-chromium@npm:1.5.328" + checksum: 10/bec0f12759edb8ee10a8856c7f8343a69e92d7626c443dec66a7718a3e54b0114397238ecc8320cb8502cab050a890988550da126843d2216b1a3e745914c512 languageName: node linkType: hard @@ -15882,16 +17115,6 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^5.20.0": - version: 5.20.1 - resolution: "enhanced-resolve@npm:5.20.1" - dependencies: - graceful-fs: "npm:^4.2.4" - tapable: "npm:^2.3.0" - checksum: 10/588afc56de97334e5742faebcf8177a504da08ea817d399f9901f35d8e9e5e6fa86b4c2ce95a99081f947764e09c9991cc0fc0ba5751bae455c329643a709187 - languageName: node - linkType: hard - "enquirer@npm:^2.4.1": version: 2.4.1 resolution: "enquirer@npm:2.4.1" @@ -16086,13 +17309,6 @@ __metadata: languageName: node linkType: hard -"es-module-lexer@npm:^2.0.0": - version: 2.0.0 - resolution: "es-module-lexer@npm:2.0.0" - checksum: 10/b075855289b5f40ee496f3d7525c5c501d029c3da15c22298a0030d625bf36d1da0768b26278f7f4bada2a602459b505888e20b77c414fba5da5619b0e84dbd1 - languageName: node - linkType: hard - "es-object-atoms@npm:^1.0.0, es-object-atoms@npm:^1.1.1": version: 1.1.1 resolution: "es-object-atoms@npm:1.1.1" @@ -16141,36 +17357,139 @@ __metadata: languageName: node linkType: hard -"esbuild@npm:^0.27.0": - version: 0.27.3 - resolution: "esbuild@npm:0.27.3" - dependencies: - "@esbuild/aix-ppc64": "npm:0.27.3" - "@esbuild/android-arm": "npm:0.27.3" - "@esbuild/android-arm64": "npm:0.27.3" - "@esbuild/android-x64": "npm:0.27.3" - "@esbuild/darwin-arm64": "npm:0.27.3" - "@esbuild/darwin-x64": "npm:0.27.3" - "@esbuild/freebsd-arm64": "npm:0.27.3" - "@esbuild/freebsd-x64": "npm:0.27.3" - "@esbuild/linux-arm": "npm:0.27.3" - "@esbuild/linux-arm64": "npm:0.27.3" - "@esbuild/linux-ia32": "npm:0.27.3" - "@esbuild/linux-loong64": "npm:0.27.3" - "@esbuild/linux-mips64el": "npm:0.27.3" - "@esbuild/linux-ppc64": "npm:0.27.3" - "@esbuild/linux-riscv64": "npm:0.27.3" - "@esbuild/linux-s390x": "npm:0.27.3" - "@esbuild/linux-x64": "npm:0.27.3" - "@esbuild/netbsd-arm64": "npm:0.27.3" - "@esbuild/netbsd-x64": "npm:0.27.3" - "@esbuild/openbsd-arm64": "npm:0.27.3" - "@esbuild/openbsd-x64": "npm:0.27.3" - "@esbuild/openharmony-arm64": "npm:0.27.3" - "@esbuild/sunos-x64": "npm:0.27.3" - "@esbuild/win32-arm64": "npm:0.27.3" - "@esbuild/win32-ia32": "npm:0.27.3" - "@esbuild/win32-x64": "npm:0.27.3" +"esbuild-loader@npm:^4.0.0": + version: 4.4.2 + resolution: "esbuild-loader@npm:4.4.2" + dependencies: + esbuild: "npm:^0.27.1" + get-tsconfig: "npm:^4.10.1" + loader-utils: "npm:^2.0.4" + webpack-sources: "npm:^1.4.3" + peerDependencies: + webpack: ^4.40.0 || ^5.0.0 + checksum: 10/d4c2f5a53f0e204bf9dc87f6767e59080fed016a3f54d8878a519a06fc82918bdb598f8eaab3bd47489566f4112f4737f1e00a5611f012e88d8d1f92eb8ccec6 + languageName: node + linkType: hard + +"esbuild@npm:^0.25.0": + version: 0.25.12 + resolution: "esbuild@npm:0.25.12" + dependencies: + "@esbuild/aix-ppc64": "npm:0.25.12" + "@esbuild/android-arm": "npm:0.25.12" + "@esbuild/android-arm64": "npm:0.25.12" + "@esbuild/android-x64": "npm:0.25.12" + "@esbuild/darwin-arm64": "npm:0.25.12" + "@esbuild/darwin-x64": "npm:0.25.12" + "@esbuild/freebsd-arm64": "npm:0.25.12" + "@esbuild/freebsd-x64": "npm:0.25.12" + "@esbuild/linux-arm": "npm:0.25.12" + "@esbuild/linux-arm64": "npm:0.25.12" + "@esbuild/linux-ia32": "npm:0.25.12" + "@esbuild/linux-loong64": "npm:0.25.12" + "@esbuild/linux-mips64el": "npm:0.25.12" + "@esbuild/linux-ppc64": "npm:0.25.12" + "@esbuild/linux-riscv64": "npm:0.25.12" + "@esbuild/linux-s390x": "npm:0.25.12" + "@esbuild/linux-x64": "npm:0.25.12" + "@esbuild/netbsd-arm64": "npm:0.25.12" + "@esbuild/netbsd-x64": "npm:0.25.12" + "@esbuild/openbsd-arm64": "npm:0.25.12" + "@esbuild/openbsd-x64": "npm:0.25.12" + "@esbuild/openharmony-arm64": "npm:0.25.12" + "@esbuild/sunos-x64": "npm:0.25.12" + "@esbuild/win32-arm64": "npm:0.25.12" + "@esbuild/win32-ia32": "npm:0.25.12" + "@esbuild/win32-x64": "npm:0.25.12" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10/bc9c03d64e96a0632a926662c9d29decafb13a40e5c91790f632f02939bc568edc9abe0ee5d8055085a2819a00139eb12e223cfb8126dbf89bbc569f125d91fd + languageName: node + linkType: hard + +"esbuild@npm:^0.27.1": + version: 0.27.4 + resolution: "esbuild@npm:0.27.4" + dependencies: + "@esbuild/aix-ppc64": "npm:0.27.4" + "@esbuild/android-arm": "npm:0.27.4" + "@esbuild/android-arm64": "npm:0.27.4" + "@esbuild/android-x64": "npm:0.27.4" + "@esbuild/darwin-arm64": "npm:0.27.4" + "@esbuild/darwin-x64": "npm:0.27.4" + "@esbuild/freebsd-arm64": "npm:0.27.4" + "@esbuild/freebsd-x64": "npm:0.27.4" + "@esbuild/linux-arm": "npm:0.27.4" + "@esbuild/linux-arm64": "npm:0.27.4" + "@esbuild/linux-ia32": "npm:0.27.4" + "@esbuild/linux-loong64": "npm:0.27.4" + "@esbuild/linux-mips64el": "npm:0.27.4" + "@esbuild/linux-ppc64": "npm:0.27.4" + "@esbuild/linux-riscv64": "npm:0.27.4" + "@esbuild/linux-s390x": "npm:0.27.4" + "@esbuild/linux-x64": "npm:0.27.4" + "@esbuild/netbsd-arm64": "npm:0.27.4" + "@esbuild/netbsd-x64": "npm:0.27.4" + "@esbuild/openbsd-arm64": "npm:0.27.4" + "@esbuild/openbsd-x64": "npm:0.27.4" + "@esbuild/openharmony-arm64": "npm:0.27.4" + "@esbuild/sunos-x64": "npm:0.27.4" + "@esbuild/win32-arm64": "npm:0.27.4" + "@esbuild/win32-ia32": "npm:0.27.4" + "@esbuild/win32-x64": "npm:0.27.4" dependenciesMeta: "@esbuild/aix-ppc64": optional: true @@ -16226,7 +17545,7 @@ __metadata: optional: true bin: esbuild: bin/esbuild - checksum: 10/aa74b8d8a3ed8e2eea4d8421737b322f4d21215244e8fa2156c6402d49b5bda01343c220196f1e3f830a7ce92b54ef653c6c723a8cc2e912bb4d17b7398b51ae + checksum: 10/32b46ec22ef78bae6cc141145022a4c0209852c07151f037fbefccc2033ca54e7f33705f8fca198eb7026f400142f64c2dbc9f0d0ce9c0a638ebc472a04abc4a languageName: node linkType: hard @@ -16272,26 +17591,7 @@ __metadata: languageName: node linkType: hard -"escodegen@npm:^1.8.1": - version: 1.14.3 - resolution: "escodegen@npm:1.14.3" - dependencies: - esprima: "npm:^4.0.1" - estraverse: "npm:^4.2.0" - esutils: "npm:^2.0.2" - optionator: "npm:^0.8.1" - source-map: "npm:~0.6.1" - dependenciesMeta: - source-map: - optional: true - bin: - escodegen: bin/escodegen.js - esgenerate: bin/esgenerate.js - checksum: 10/70f095ca9393535f9f1c145ef99dc0b3ff14cca6bc4a79d90ff3352f90c3f2e07f75af6d6c05174ea67c45271f75e80dd440dd7d04ed2cf44c9452c3042fa84a - languageName: node - linkType: hard - -"escodegen@npm:^2.1.0": +"escodegen@npm:^2.0.0, escodegen@npm:^2.1.0": version: 2.1.0 resolution: "escodegen@npm:2.1.0" dependencies: @@ -16517,16 +17817,6 @@ __metadata: languageName: node linkType: hard -"eslint-scope@npm:5.1.1": - version: 5.1.1 - resolution: "eslint-scope@npm:5.1.1" - dependencies: - esrecurse: "npm:^4.3.0" - estraverse: "npm:^4.1.1" - checksum: 10/c541ef384c92eb5c999b7d3443d80195fcafb3da335500946f6db76539b87d5826c8f2e1d23bf6afc3154ba8cd7c8e566f8dc00f1eea25fdf3afc8fb9c87b238 - languageName: node - linkType: hard - "eslint-scope@npm:^7.2.2": version: 7.2.2 resolution: "eslint-scope@npm:7.2.2" @@ -16567,22 +17857,6 @@ __metadata: languageName: node linkType: hard -"eslint-webpack-plugin@npm:^4.2.0": - version: 4.2.0 - resolution: "eslint-webpack-plugin@npm:4.2.0" - dependencies: - "@types/eslint": "npm:^8.56.10" - jest-worker: "npm:^29.7.0" - micromatch: "npm:^4.0.5" - normalize-path: "npm:^3.0.0" - schema-utils: "npm:^4.2.0" - peerDependencies: - eslint: ^8.0.0 || ^9.0.0 - webpack: ^5.0.0 - checksum: 10/061d11a93832b82bd0362d6c546f51fe5e3a0eb811374b86536a2929ff46fea7e5ef30e32f0d3194b9da146a7c0ae43f13b2ec5ce0f65a9ca9c4d961d9e446b3 - languageName: node - linkType: hard - "eslint@npm:^8.6.0": version: 8.57.1 resolution: "eslint@npm:8.57.1" @@ -16649,6 +17923,16 @@ __metadata: languageName: node linkType: hard +"esprima@npm:1.2.5": + version: 1.2.5 + resolution: "esprima@npm:1.2.5" + bin: + esparse: ./bin/esparse.js + esvalidate: ./bin/esvalidate.js + checksum: 10/839aad5916d05d3a82ccf3adaf67c2b5df69278fd7168347346e7af298dc7fbfbfd7bc5e27e38031a584d50d28e37da35d711b2f5d5376794f84b1bd8e559665 + languageName: node + linkType: hard + "esprima@npm:^4.0.0, esprima@npm:^4.0.1": version: 4.0.1 resolution: "esprima@npm:4.0.1" @@ -16677,7 +17961,7 @@ __metadata: languageName: node linkType: hard -"estraverse@npm:^4.2.0": +"estraverse@npm:^4.1.1": version: 4.3.0 resolution: "estraverse@npm:4.3.0" checksum: 10/3f67ad02b6dbfaddd9ea459cf2b6ef4ecff9a6082a7af9d22e445b9abc082ad9ca47e1825557b293fcdae477f4714e561123e30bb6a5b2f184fb2bad4a9497eb @@ -16740,7 +18024,16 @@ __metadata: languageName: node linkType: hard -"events@npm:^3.0.0, events@npm:^3.3.0": +"events-universal@npm:^1.0.0": + version: 1.0.1 + resolution: "events-universal@npm:1.0.1" + dependencies: + bare-events: "npm:^2.7.0" + checksum: 10/71b2e6079b4dc030c613ef73d99f1acb369dd3ddb6034f49fd98b3e2c6632cde9f61c15fb1351004339d7c79672252a4694ecc46a6124dc794b558be50a83867 + languageName: node + linkType: hard + +"events@npm:^3.0.0, events@npm:^3.2.0, events@npm:^3.3.0": version: 3.3.0 resolution: "events@npm:3.3.0" checksum: 10/a3d47e285e28d324d7180f1e493961a2bbb4cad6412090e4dec114f4db1f5b560c7696ee8e758f55e23913ede856e3689cd3aa9ae13c56b5d8314cd3b3ddd1be @@ -16851,6 +18144,15 @@ __metadata: languageName: node linkType: hard +"express-rate-limit@npm:^7.5.0": + version: 7.5.1 + resolution: "express-rate-limit@npm:7.5.1" + peerDependencies: + express: ">= 4.11" + checksum: 10/357c3398450144ab7bbce2841d0bf4f93a0f3fd9d1d5ed9a0ee331b557af969cc790941dc37b47f8d9b5672964aa0e31666f770e1f48b334dc7d1e69f6433040 + languageName: node + linkType: hard + "express-rate-limit@npm:^8.2.1, express-rate-limit@npm:^8.2.2": version: 8.3.1 resolution: "express-rate-limit@npm:8.3.1" @@ -17036,16 +18338,7 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:4.4.1": - version: 4.4.1 - resolution: "fast-xml-parser@npm:4.4.1" - dependencies: - path-expression-matcher: "npm:^1.1.3" - checksum: 10/32937866aaf5a90e69d1f4ee6e15e875248d5b5d2afd70277e9e8323074de4980cef24575a591b8e43c29f405d5f12377b3bad3842dc412b0c5c17a3eaee4b6b - languageName: node - linkType: hard - -"fast-xml-parser@npm:5.5.8, fast-xml-parser@npm:^5.0.7": +"fast-xml-parser@npm:5.5.8": version: 5.5.8 resolution: "fast-xml-parser@npm:5.5.8" dependencies: @@ -17058,16 +18351,16 @@ __metadata: languageName: node linkType: hard -"fast-xml-parser@npm:^4.4.1": - version: 4.5.3 - resolution: "fast-xml-parser@npm:4.5.3" +"fast-xml-parser@npm:^5.0.7, fast-xml-parser@npm:^5.3.4": + version: 5.5.9 + resolution: "fast-xml-parser@npm:5.5.9" dependencies: fast-xml-builder: "npm:^1.1.4" path-expression-matcher: "npm:^1.2.0" - strnum: "npm:^2.2.0" + strnum: "npm:^2.2.2" bin: fxparser: src/cli/cli.js - checksum: 10/888f9a5d345e65e34b70d394798a1542603a216f06c140a9671d031b80b42c01ef2e68f2a0ceea45e7703fa80549f0e06da710f5a2faafdc910d1b6b354f0fa0 + checksum: 10/5f1a1a8b524406af21e9adb24f846b0da6b629c86b1eeedb54757cc293c24ed4f79ff9570b82206265b6951d68acd2dc93e74687ea5d7da0beafa09536cee73f languageName: node linkType: hard @@ -17396,29 +18689,6 @@ __metadata: languageName: node linkType: hard -"fork-ts-checker-webpack-plugin@npm:^9.0.0": - version: 9.1.0 - resolution: "fork-ts-checker-webpack-plugin@npm:9.1.0" - dependencies: - "@babel/code-frame": "npm:^7.16.7" - chalk: "npm:^4.1.2" - chokidar: "npm:^4.0.1" - cosmiconfig: "npm:^8.2.0" - deepmerge: "npm:^4.2.2" - fs-extra: "npm:^10.0.0" - memfs: "npm:^3.4.1" - minimatch: "npm:^3.0.4" - node-abort-controller: "npm:^3.0.1" - schema-utils: "npm:^3.1.1" - semver: "npm:^7.3.5" - tapable: "npm:^2.2.1" - peerDependencies: - typescript: ">3.6.0" - webpack: ^5.11.0 - checksum: 10/1d24387224f7d49a17f7e44c9150971172f34ae30c4b1f581b8af967e73e8f36a434ed56f78aa45fd8cf0833c73a1b020102cc61070d7dc630b70c21c9770a1b - languageName: node - linkType: hard - "form-data-encoder@npm:^1.7.2": version: 1.9.0 resolution: "form-data-encoder@npm:1.9.0" @@ -17845,9 +19115,9 @@ __metadata: languageName: node linkType: hard -"get-tsconfig@npm:^4.10.0": - version: 4.10.1 - resolution: "get-tsconfig@npm:4.10.1" +"get-tsconfig@npm:^4.10.0, get-tsconfig@npm:^4.10.1": + version: 4.13.7 + resolution: "get-tsconfig@npm:4.13.7" dependencies: resolve-pkg-maps: "npm:^1.0.0" checksum: 10/e23622bd3c5766a2fe43a28cb7a490ebb175eb7f429e4ec53688e3b7a40882fb0ec6f3b753f237757d63861ccd8033232d1d76f8960a683af8e09099e7c897fe @@ -17925,9 +19195,16 @@ __metadata: languageName: node linkType: hard -"glob@npm:9.3.5": - version: 9.3.5 - resolution: "glob@npm:9.3.5" +"glob-to-regexp@npm:^0.4.1": + version: 0.4.1 + resolution: "glob-to-regexp@npm:0.4.1" + checksum: 10/9009529195a955c40d7b9690794aeff5ba665cc38f1519e111c58bb54366fd0c106bde80acf97ba4e533208eb53422c83b136611a54c5fefb1edd8dc267cb62e + languageName: node + linkType: hard + +"glob@npm:13.0.6, glob@npm:^13.0.0": + version: 13.0.6 + resolution: "glob@npm:13.0.6" dependencies: minimatch: "npm:^10.2.2" minipass: "npm:^7.1.3" @@ -18119,7 +19396,6 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.5, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": "graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.5, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" @@ -18146,9 +19422,9 @@ __metadata: linkType: hard "graphql@npm:^16.0.0": - version: 16.13.1 - resolution: "graphql@npm:16.13.1" - checksum: 10/a42f857f60351e1f4665aa5bc5524796d3f45bf81793e6db932f902aff769b0488dafaa1d9c07bddda7122a1f6d0b0105fab12d38992f6b6fb81fc3d7ced1afc + version: 16.13.2 + resolution: "graphql@npm:16.13.2" + checksum: 10/9ede86f0a7227d47a41e2076e0132839f66fbd14899abfd818d7de2ab81076ee249c8788ad42243367d68a027a8763cc4c7be2e441ccfb03a8549490c7b66c2f languageName: node linkType: hard @@ -18649,32 +19925,7 @@ __metadata: languageName: node linkType: hard -"http-errors@npm:^2.0.0, http-errors@npm:~2.0.0, http-errors@npm:~2.0.1": - version: 2.0.1 - resolution: "http-errors@npm:2.0.1" - dependencies: - depd: "npm:~2.0.0" - inherits: "npm:~2.0.4" - setprototypeof: "npm:~1.2.0" - statuses: "npm:~2.0.2" - toidentifier: "npm:~1.0.1" - checksum: 10/9fe31bc0edf36566c87048aed1d3d0cbe03552564adc3541626a0613f542d753fbcb13bdfcec0a3a530dbe1714bb566c89d46244616b66bddd26ac413b06a207 - languageName: node - linkType: hard - -"http-errors@npm:~1.6.2": - version: 1.6.3 - resolution: "http-errors@npm:1.6.3" - dependencies: - depd: "npm:~1.1.2" - inherits: "npm:2.0.3" - setprototypeof: "npm:1.1.0" - statuses: "npm:>= 1.4.0 < 2" - checksum: 10/e48732657ea0b4a09853d2696a584fa59fa2a8c1ba692af7af3137b5491a997d7f9723f824e7e08eb6a87098532c09ce066966ddf0f9f3dd30905e52301acadb - languageName: node - linkType: hard - -"http-errors@npm:~1.8.0": +"http-errors@npm:^1.6.3, http-errors@npm:~1.8.0": version: 1.8.1 resolution: "http-errors@npm:1.8.1" dependencies: @@ -18687,6 +19938,19 @@ __metadata: languageName: node linkType: hard +"http-errors@npm:^2.0.0, http-errors@npm:^2.0.1, http-errors@npm:~2.0.0, http-errors@npm:~2.0.1": + version: 2.0.1 + resolution: "http-errors@npm:2.0.1" + dependencies: + depd: "npm:~2.0.0" + inherits: "npm:~2.0.4" + setprototypeof: "npm:~1.2.0" + statuses: "npm:~2.0.2" + toidentifier: "npm:~1.0.1" + checksum: 10/9fe31bc0edf36566c87048aed1d3d0cbe03552564adc3541626a0613f542d753fbcb13bdfcec0a3a530dbe1714bb566c89d46244616b66bddd26ac413b06a207 + languageName: node + linkType: hard + "http-parser-js@npm:>=0.5.1": version: 0.5.10 resolution: "http-parser-js@npm:0.5.10" @@ -18810,16 +20074,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:^0.4.24, iconv-lite@npm:~0.4.24": - version: 0.4.24 - resolution: "iconv-lite@npm:0.4.24" - dependencies: - safer-buffer: "npm:>= 2.1.2 < 3" - checksum: 10/6d3a2dac6e5d1fb126d25645c25c3a1209f70cceecc68b8ef51ae0da3cdc078c151fade7524a30b12a3094926336831fca09c666ef55b37e2c69638b5d6bd2e3 - languageName: node - linkType: hard - -"iconv-lite@npm:^0.6.2, iconv-lite@npm:^0.6.3": +"iconv-lite@npm:0.6.3, iconv-lite@npm:^0.6.2": version: 0.6.3 resolution: "iconv-lite@npm:0.6.3" dependencies: @@ -18828,7 +20083,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:^0.7.0, iconv-lite@npm:~0.7.0": +"iconv-lite@npm:^0.7.0, iconv-lite@npm:^0.7.2, iconv-lite@npm:~0.7.0": version: 0.7.2 resolution: "iconv-lite@npm:0.7.2" dependencies: @@ -18917,7 +20172,6 @@ __metadata: languageName: node linkType: hard -"import-fresh@npm:^3.1.0, import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": "import-fresh@npm:^3.1.0, import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": version: 3.3.1 resolution: "import-fresh@npm:3.3.1" @@ -19100,20 +20354,10 @@ __metadata: languageName: node linkType: hard -"ip-address@npm:10.0.1": - version: 10.0.1 - resolution: "ip-address@npm:10.0.1" - checksum: 10/09731acda32cd8e14c46830c137e7e5940f47b36d63ffb87c737331270287d631cf25aa95570907a67d3f919fdb25f4470c404eda21e62f22e0a55927f4dd0fb - languageName: node - linkType: hard - -"ip-address@npm:^9.0.5": - version: 9.0.5 - resolution: "ip-address@npm:9.0.5" - dependencies: - jsbn: "npm:1.1.0" - sprintf-js: "npm:^1.1.3" - checksum: 10/1ed81e06721af012306329b31f532b5e24e00cb537be18ddc905a84f19fe8f83a09a1699862bf3a1ec4b9dea93c55a3fa5faf8b5ea380431469df540f38b092c +"ip-address@npm:10.1.0, ip-address@npm:^10.0.1": + version: 10.1.0 + resolution: "ip-address@npm:10.1.0" + checksum: 10/a6979629d1ad9c1fb424bc25182203fad739b40225aebc55ec6243bbff5035faf7b9ed6efab3a097de6e713acbbfde944baacfa73e11852bb43989c45a68d79e languageName: node linkType: hard @@ -20294,7 +21538,26 @@ __metadata: languageName: node linkType: hard -"jiti@npm:2.4.2, jiti@npm:^2.4.2": +"jest@npm:^29.7.0": + version: 29.7.0 + resolution: "jest@npm:29.7.0" + dependencies: + "@jest/core": "npm:^29.7.0" + "@jest/types": "npm:^29.6.3" + import-local: "npm:^3.0.2" + jest-cli: "npm:^29.7.0" + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + bin: + jest: bin/jest.js + checksum: 10/97023d78446098c586faaa467fbf2c6b07ff06e2c85a19e3926adb5b0effe9ac60c4913ae03e2719f9c01ae8ffd8d92f6b262cedb9555ceeb5d19263d8c6362a + languageName: node + linkType: hard + +"jiti@npm:2.4.2": version: 2.4.2 resolution: "jiti@npm:2.4.2" bin: @@ -20347,7 +21610,7 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:^3.10.0, js-yaml@npm:^3.6.1, js-yaml@npm:^3.8.3": +"js-yaml@npm:^3.10.0, js-yaml@npm:^3.13.1, js-yaml@npm:^3.6.1, js-yaml@npm:^3.8.3": version: 3.14.2 resolution: "js-yaml@npm:3.14.2" dependencies: @@ -20370,10 +21633,42 @@ __metadata: languageName: node linkType: hard -"jsbn@npm:1.1.0": - version: 1.1.0 - resolution: "jsbn@npm:1.1.0" - checksum: 10/bebe7ae829bbd586ce8cbe83501dd8cb8c282c8902a8aeeed0a073a89dc37e8103b1244f3c6acd60278bcbfe12d93a3f83c9ac396868a3b3bbc3c5e5e3b648ef +"jsdom@npm:^20.0.0": + version: 20.0.3 + resolution: "jsdom@npm:20.0.3" + dependencies: + abab: "npm:^2.0.6" + acorn: "npm:^8.8.1" + acorn-globals: "npm:^7.0.0" + cssom: "npm:^0.5.0" + cssstyle: "npm:^2.3.0" + data-urls: "npm:^3.0.2" + decimal.js: "npm:^10.4.2" + domexception: "npm:^4.0.0" + escodegen: "npm:^2.0.0" + form-data: "npm:^4.0.0" + html-encoding-sniffer: "npm:^3.0.0" + http-proxy-agent: "npm:^5.0.0" + https-proxy-agent: "npm:^5.0.1" + is-potential-custom-element-name: "npm:^1.0.1" + nwsapi: "npm:^2.2.2" + parse5: "npm:^7.1.1" + saxes: "npm:^6.0.0" + symbol-tree: "npm:^3.2.4" + tough-cookie: "npm:^4.1.2" + w3c-xmlserializer: "npm:^4.0.0" + webidl-conversions: "npm:^7.0.0" + whatwg-encoding: "npm:^2.0.0" + whatwg-mimetype: "npm:^3.0.0" + whatwg-url: "npm:^11.0.0" + ws: "npm:^8.11.0" + xml-name-validator: "npm:^4.0.0" + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + checksum: 10/a4cdcff5b07eed87da90b146b82936321533b5efe8124492acf7160ebd5b9cf2b3c2435683592bf1cffb479615245756efb6c173effc1906f845a86ed22af985 languageName: node linkType: hard @@ -20409,7 +21704,6 @@ __metadata: languageName: node linkType: hard -"json-parse-even-better-errors@npm:^2.3.0, json-parse-even-better-errors@npm:^2.3.1": "json-parse-even-better-errors@npm:^2.3.0, json-parse-even-better-errors@npm:^2.3.1": version: 2.3.1 resolution: "json-parse-even-better-errors@npm:2.3.1" @@ -20572,6 +21866,17 @@ __metadata: languageName: node linkType: hard +"jsonpath@npm:^1.1.1": + version: 1.3.0 + resolution: "jsonpath@npm:1.3.0" + dependencies: + esprima: "npm:1.2.5" + static-eval: "npm:2.1.1" + underscore: "npm:1.13.6" + checksum: 10/291740ea4112023f3baaeebc67904daf98f6e099f741a1224a6f31e6c0ea4dc0b36df3fb37f65936c6bdde86b751b43154c8d06583be811c5df9c37e23c5611d + languageName: node + linkType: hard + "jsonpointer@npm:^5.0.0, jsonpointer@npm:^5.0.1": version: 5.0.1 resolution: "jsonpointer@npm:5.0.1" @@ -21079,13 +22384,6 @@ __metadata: languageName: node linkType: hard -"loader-runner@npm:^4.3.1": - version: 4.3.1 - resolution: "loader-runner@npm:4.3.1" - checksum: 10/d77127497c3f91fdba351e3e91156034e6e590e9f050b40df6c38ac16c54b5c903f7e2e141e09fefd046ee96b26fb50773c695ebc0aa205a4918683b124b04ba - languageName: node - linkType: hard - "loader-utils@npm:^1.1.0": version: 1.4.2 resolution: "loader-utils@npm:1.4.2" @@ -21097,7 +22395,6 @@ __metadata: languageName: node linkType: hard -"loader-utils@npm:^2.0.0, loader-utils@npm:^2.0.4": "loader-utils@npm:^2.0.0, loader-utils@npm:^2.0.4": version: 2.0.4 resolution: "loader-utils@npm:2.0.4" @@ -21393,6 +22690,22 @@ __metadata: languageName: node linkType: hard +"lru-cache@npm:^11.0.0, lru-cache@npm:^11.1.0, lru-cache@npm:^11.2.1": + version: 11.2.7 + resolution: "lru-cache@npm:11.2.7" + checksum: 10/fbff4b8dee8189dde9b52cdfb3ea89b4c9cec094c1538cd30d1f47299477ff312efdb35f7994477ec72328f8e754e232b26a143feda1bd1f79ff22da6664d2c5 + languageName: node + linkType: hard + +"lru-cache@npm:^5.1.1": + version: 5.1.1 + resolution: "lru-cache@npm:5.1.1" + dependencies: + yallist: "npm:^3.0.2" + checksum: 10/951d2673dcc64a7fb888bf3d13bc2fdf923faca97d89cdb405ba3dfff77e2b26e5798d405e78fcd7094c9e7b8b4dab2ddc5a4f8a11928af24a207b7c738ca3f8 + languageName: node + linkType: hard + "lru-cache@npm:^6.0.0": version: 6.0.0 resolution: "lru-cache@npm:6.0.0" @@ -21893,7 +23206,6 @@ __metadata: languageName: node linkType: hard -"memfs@npm:^3.1.2, memfs@npm:^3.4.1": "memfs@npm:^3.1.2, memfs@npm:^3.4.1": version: 3.5.3 resolution: "memfs@npm:3.5.3" @@ -22577,7 +23889,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:^2.1.31, mime-types@npm:^2.1.35, mime-types@npm:~2.1.17, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:^2.1.12, mime-types@npm:^2.1.18, mime-types@npm:^2.1.27, mime-types@npm:^2.1.35, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34, mime-types@npm:~2.1.35": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -22644,26 +23956,14 @@ __metadata: linkType: hard "mini-css-extract-plugin@npm:^2.4.2": - version: 2.10.1 - resolution: "mini-css-extract-plugin@npm:2.10.1" - dependencies: - schema-utils: "npm:^4.0.0" - tapable: "npm:^2.2.1" - peerDependencies: - webpack: ^5.0.0 - checksum: 10/2d0cecc3bea85cd7f9b1ce0974f1672976d610a9267e2988ff19f5d03b017bff12b32151a412de0f519a70be7d3b050b499b20101445fb21728cc2d35dd4041a - languageName: node - linkType: hard - -"mini-css-extract-plugin@npm:^2.4.2": - version: 2.10.1 - resolution: "mini-css-extract-plugin@npm:2.10.1" + version: 2.10.2 + resolution: "mini-css-extract-plugin@npm:2.10.2" dependencies: schema-utils: "npm:^4.0.0" tapable: "npm:^2.2.1" peerDependencies: webpack: ^5.0.0 - checksum: 10/2d0cecc3bea85cd7f9b1ce0974f1672976d610a9267e2988ff19f5d03b017bff12b32151a412de0f519a70be7d3b050b499b20101445fb21728cc2d35dd4041a + checksum: 10/d2b01f25e229d04263274fceccfcb3ec0937a448859e4cb65e32652e26dde46ae6ecf7d15a52a4bb700bea6e47675db88691d3abc418901ec8542e1cfdc62b85 languageName: node linkType: hard @@ -22708,9 +24008,9 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^5.0.1, minimatch@npm:^5.1.0": - version: 5.1.6 - resolution: "minimatch@npm:5.1.6" +"minimatch@npm:^10.2.1, minimatch@npm:^10.2.2": + version: 10.2.4 + resolution: "minimatch@npm:10.2.4" dependencies: brace-expansion: "npm:^5.0.2" checksum: 10/aea4874e521c55bb60744685bbffe3d152e5460f84efac3ea936e6bbe2ceba7deb93345fec3f9bb17f7b6946776073a64d40ae32bf5f298ad690308121068a1f @@ -22735,7 +24035,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.4": +"minimatch@npm:^9.0.0, minimatch@npm:^9.0.4": version: 9.0.9 resolution: "minimatch@npm:9.0.9" dependencies: @@ -23109,7 +24409,23 @@ __metadata: languageName: node linkType: hard -"node-domexception@npm:1.0.0": +"node-abort-controller@npm:^3.0.1": + version: 3.1.1 + resolution: "node-abort-controller@npm:3.1.1" + checksum: 10/0a2cdb7ec0aeaf3cb31e1ca0e192f5add48f1c5c9c9ed822129f9dddbd9432f69b7425982f94ce803c56a2104884530aa67cd57696e5774b2e5b8ec2f58de042 + languageName: node + linkType: hard + +"node-addon-api@npm:^4.3.0": + version: 4.3.0 + resolution: "node-addon-api@npm:4.3.0" + dependencies: + node-gyp: "npm:latest" + checksum: 10/d3b38d16cb9ad0714d965331d0e38cef1c27750c2c3343cd3464a9ed8158501a2910ccbf2fd9fdc476e806a19dbc9e0524ff9d66a7c779d42a9752a63ba30b80 + languageName: node + linkType: hard + +"node-domexception@npm:1.0.0, node-domexception@npm:^1.0.0": version: 1.0.0 resolution: "node-domexception@npm:1.0.0" checksum: 10/e332522f242348c511640c25a6fc7da4f30e09e580c70c6b13cb0be83c78c3e71c8d4665af2527e869fc96848924a4316ae7ec9014c091e2156f41739d4fa233 @@ -23142,10 +24458,21 @@ __metadata: languageName: node linkType: hard -"node-forge@npm:^1, node-forge@npm:^1.3.2": - version: 1.3.3 - resolution: "node-forge@npm:1.3.3" - checksum: 10/f41c31b9296771a4b8c955d58417471712f54f324603a35f8e6cbac19d5e6eaaf5fd5fd14584dfedecbf46a05438ded6eee60a5f2f0822fc5061aaa073cfc75d +"node-fetch@npm:^3.3.2": + version: 3.3.2 + resolution: "node-fetch@npm:3.3.2" + dependencies: + data-uri-to-buffer: "npm:^4.0.0" + fetch-blob: "npm:^3.1.4" + formdata-polyfill: "npm:^4.0.10" + checksum: 10/24207ca8c81231c7c59151840e3fded461d67a31cf3e3b3968e12201a42f89ce4a0b5fb7079b1fa0a4655957b1ca9257553200f03a9f668b45ebad265ca5593d + languageName: node + linkType: hard + +"node-forge@npm:^1, node-forge@npm:^1.3.1, node-forge@npm:^1.3.2": + version: 1.4.0 + resolution: "node-forge@npm:1.4.0" + checksum: 10/d70fd769768e646eda73343d4d4105ccb6869315d975905a22117431c04ae5b6df6c488e34ed275b1a66b50195a09b84b5c8aeca3b8605c20605fcb8e9f109d9 languageName: node linkType: hard @@ -23957,7 +25284,6 @@ __metadata: languageName: node linkType: hard -"parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": "parse-json@npm:^5.0.0, parse-json@npm:^5.2.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" @@ -24002,7 +25328,16 @@ __metadata: languageName: node linkType: hard -"parseurl@npm:^1.3.3, parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": +"parse5@npm:^7.0.0, parse5@npm:^7.1.1": + version: 7.3.0 + resolution: "parse5@npm:7.3.0" + dependencies: + entities: "npm:^6.0.0" + checksum: 10/b0e48be20b820c655b138b86fa6fb3a790de6c891aa2aba536524f8027b4dca4fe538f11a0e5cf2f6f847d120dbb9e4822dcaeb933ff1e10850a2ef0154d1d88 + languageName: node + linkType: hard + +"parseurl@npm:^1.3.2, parseurl@npm:^1.3.3, parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" checksum: 10/407cee8e0a3a4c5cd472559bca8b6a45b82c124e9a4703302326e9ab60fc1081442ada4e02628efef1eb16197ddc7f8822f5a91fd7d7c86b51f530aedb17dfa2 @@ -24294,10 +25629,10 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": - version: 2.3.1 - resolution: "picomatch@npm:2.3.1" - checksum: 10/60c2595003b05e4535394d1da94850f5372c9427ca4413b71210f437f7b2ca091dbd611c45e8b37d10036fa8eade25c1b8951654f9d3973bfa66a2ff4d3b08bc +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.2, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": + version: 2.3.2 + resolution: "picomatch@npm:2.3.2" + checksum: 10/b788ef8148a2415b9dec12f0bb350ae6a5830f8f1950e472abc2f5225494debf7d1b75eb031df0ceaea9e8ec3e7bad599e8dbf3c60d61b42be429ba41bff4426 languageName: node linkType: hard @@ -24384,20 +25719,6 @@ __metadata: languageName: node linkType: hard -"pkijs@npm:^3.3.3": - version: 3.4.0 - resolution: "pkijs@npm:3.4.0" - dependencies: - "@noble/hashes": "npm:1.4.0" - asn1js: "npm:^3.0.6" - bytestreamjs: "npm:^2.0.1" - pvtsutils: "npm:^1.3.6" - pvutils: "npm:^1.1.3" - tslib: "npm:^2.8.1" - checksum: 10/a937347584b27012919f69e4b3865b2fd09dced85a344f9a22bbf1376dd9e1534ccbe0bbdb997807b4990b07865c1ea028447d78b2c8a64436d4d393193a0777 - languageName: node - linkType: hard - "pluralize@npm:^8.0.0": version: 8.0.0 resolution: "pluralize@npm:8.0.0" @@ -24961,7 +26282,18 @@ __metadata: languageName: node linkType: hard -"prismjs@npm:^1.27.0": +"pretty-format@npm:^29.0.0, pretty-format@npm:^29.7.0": + version: 29.7.0 + resolution: "pretty-format@npm:29.7.0" + dependencies: + "@jest/schemas": "npm:^29.6.3" + ansi-styles: "npm:^5.0.0" + react-is: "npm:^18.0.0" + checksum: 10/dea96bc83c83cd91b2bfc55757b6b2747edcaac45b568e46de29deee80742f17bc76fe8898135a70d904f4928eafd8bb693cd1da4896e8bdd3c5e82cadf1d2bb + languageName: node + linkType: hard + +"prismjs@npm:^1.30.0": version: 1.30.0 resolution: "prismjs@npm:1.30.0" checksum: 10/6b48a2439a82e5c6882f48ebc1564c3890e16463ba17ac10c3ad4f62d98dea5b5c915b172b63b83023a70ad4f5d7be3e8a60304420db34a161fae69dd4e3e2da @@ -25145,6 +26477,22 @@ __metadata: languageName: node linkType: hard +"proxy-from-env@npm:^2.1.0": + version: 2.1.0 + resolution: "proxy-from-env@npm:2.1.0" + checksum: 10/fbbaf4dab2a6231dc9e394903a5f66f20475e36b734335790b46feb9da07c37d6b32e2c02e3e2ea4d4b23774c53d8562e5b7cc73282cb43f4a597b7eacaee2ee + languageName: node + linkType: hard + +"psl@npm:^1.1.33": + version: 1.15.0 + resolution: "psl@npm:1.15.0" + dependencies: + punycode: "npm:^2.3.1" + checksum: 10/5e7467eb5196eb7900d156783d12907d445c0122f76c73203ce96b148a6ccf8c5450cc805887ffada38ff92d634afcf33720c24053cb01d5b6598d1c913c5caf + languageName: node + linkType: hard + "public-encrypt@npm:^4.0.3": version: 4.0.3 resolution: "public-encrypt@npm:4.0.3" @@ -25183,9 +26531,32 @@ __metadata: languageName: node linkType: hard -"qs@npm:^6.11.2, qs@npm:^6.12.3, qs@npm:^6.14.0, qs@npm:^6.14.1, qs@npm:^6.9.4, qs@npm:~6.14.0": - version: 6.14.1 - resolution: "qs@npm:6.14.1" +"pure-rand@npm:^6.0.0": + version: 6.1.0 + resolution: "pure-rand@npm:6.1.0" + checksum: 10/256aa4bcaf9297256f552914e03cbdb0039c8fe1db11fa1e6d3f80790e16e563eb0a859a1e61082a95e224fc0c608661839439f8ecc6a3db4e48d46d99216ee4 + languageName: node + linkType: hard + +"pvtsutils@npm:^1.3.6": + version: 1.3.6 + resolution: "pvtsutils@npm:1.3.6" + dependencies: + tslib: "npm:^2.8.1" + checksum: 10/d45b12f8526e13ecf15fe09b30cde65501f3300fd2a07c11b28a966d434d1f767c8a61597ecba2e19c7eb19ca0c740341a6babc67a4f741e08b1ef1095c71663 + languageName: node + linkType: hard + +"pvutils@npm:^1.1.3": + version: 1.1.5 + resolution: "pvutils@npm:1.1.5" + checksum: 10/9a5a71603c72bf9ea3a4501e8251e3f7a56026ed059bf63a18bd9a30cac6c35cc8250b39eb6291c1cb204cdeb6660663ab9bb2c74e85a512919bb2d614e340ea + languageName: node + linkType: hard + +"qs@npm:^6.11.2, qs@npm:^6.12.3, qs@npm:^6.14.0, qs@npm:^6.14.1, qs@npm:^6.9.4": + version: 6.15.0 + resolution: "qs@npm:6.15.0" dependencies: side-channel: "npm:^1.1.0" checksum: 10/a3458f2f389285c3512e0ebc55522ee370ac7cb720ba9f0eff3e30fb2bb07631caf556c08e2a3d4481a371ac14faa9ceb7442a0610c5a7e55b23a5bdee7b701c @@ -25674,6 +27045,13 @@ __metadata: languageName: node linkType: hard +"react-refresh@npm:^0.17.0": + version: 0.17.0 + resolution: "react-refresh@npm:0.17.0" + checksum: 10/5e94f07d43bb1cfdc9b0c6e0c8c73e754005489950dcff1edb53aa8451d1d69a47b740b195c7c80fb4eb511c56a3585dc55eddd83f0097fb5e015116a1460467 + languageName: node + linkType: hard + "react-refresh@npm:^0.18.0": version: 0.18.0 resolution: "react-refresh@npm:0.18.0" @@ -25936,13 +27314,6 @@ __metadata: languageName: node linkType: hard -"readdirp@npm:^4.0.1": - version: 4.1.2 - resolution: "readdirp@npm:4.1.2" - checksum: 10/7b817c265940dba90bb9c94d82920d76c3a35ea2d67f9f9d8bd936adcfe02d50c802b14be3dd2e725e002dddbe2cc1c7a0edfb1bc3a365c9dfd5a61e612eea1e - languageName: node - linkType: hard - "readdirp@npm:~3.6.0": version: 3.6.0 resolution: "readdirp@npm:3.6.0" @@ -26005,7 +27376,6 @@ __metadata: languageName: node linkType: hard -"reflect-metadata@npm:0.2.2, reflect-metadata@npm:^0.2.2": "reflect-metadata@npm:0.2.2, reflect-metadata@npm:^0.2.2": version: 0.2.2 resolution: "reflect-metadata@npm:0.2.2" @@ -26773,6 +28143,22 @@ __metadata: languageName: node linkType: hard +"sax@npm:^1.5.0": + version: 1.6.0 + resolution: "sax@npm:1.6.0" + checksum: 10/0909cedcd9f011ceeac80c0240a92d64ef712cf6c04e0f6ee236a8d812f86a59f61bee6bb5da28d75306db050b99e0593051ea77351795822253b984af6cf044 + languageName: node + linkType: hard + +"saxes@npm:^6.0.0": + version: 6.0.0 + resolution: "saxes@npm:6.0.0" + dependencies: + xmlchars: "npm:^2.2.0" + checksum: 10/97b50daf6ca3a153e89842efa18a862e446248296622b7473c169c84c823ee8a16e4a43bac2f73f11fc8cb9168c73fbb0d73340f26552bac17970e9052367aa9 + languageName: node + linkType: hard + "scheduler@npm:^0.23.2": version: 0.23.2 resolution: "scheduler@npm:0.23.2" @@ -26793,7 +28179,6 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1": "schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1": version: 3.3.0 resolution: "schema-utils@npm:3.3.0" @@ -26805,9 +28190,9 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^4.0.0, schema-utils@npm:^4.2.0, schema-utils@npm:^4.3.0": - version: 4.3.2 - resolution: "schema-utils@npm:4.3.2" +"schema-utils@npm:^4.0.0, schema-utils@npm:^4.2.0, schema-utils@npm:^4.3.0, schema-utils@npm:^4.3.3": + version: 4.3.3 + resolution: "schema-utils@npm:4.3.3" dependencies: "@types/json-schema": "npm:^7.0.9" ajv: "npm:^8.9.0" @@ -26851,16 +28236,6 @@ __metadata: languageName: node linkType: hard -"selfsigned@npm:^5.5.0": - version: 5.5.0 - resolution: "selfsigned@npm:5.5.0" - dependencies: - "@peculiar/x509": "npm:^1.14.2" - pkijs: "npm:^3.3.3" - checksum: 10/fe9be2647507c3ee21dcaf5cab20e1ae4b8b84eac83d2fe4d82f9a3b6c70636f9aaeeba0089e3343dcb13fbb31ef70c2e72c41f2e2dcf38368040b49830c670e - languageName: node - linkType: hard - "semver-compare@npm:^1.0.0": version: 1.0.0 resolution: "semver-compare@npm:1.0.0" @@ -27269,13 +28644,6 @@ __metadata: languageName: node linkType: hard -"source-list-map@npm:^2.0.0": - version: 2.0.1 - resolution: "source-list-map@npm:2.0.1" - checksum: 10/3918ffba5fe8447bc816800026fe707aab233d9d05a3487225d880e23b7e37ed455b4e1b844e05644f6ecc7c9b837c0cc32da54dd37f77c993370ebcdb049246 - languageName: node - linkType: hard - "source-map-js@npm:^1.2.1": version: 1.2.1 resolution: "source-map-js@npm:1.2.1" @@ -27331,13 +28699,6 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.7.3": - version: 0.7.6 - resolution: "source-map@npm:0.7.6" - checksum: 10/c8d2da7c57c14f3fd7568f764b39ad49bbf9dd7632b86df3542b31fed117d4af2fb74a4f886fc06baf7a510fee68e37998efc3080aacdac951c36211dc29a7a3 - languageName: node - linkType: hard - "space-separated-tokens@npm:^1.0.0": version: 1.1.5 resolution: "space-separated-tokens@npm:1.1.5" @@ -27545,7 +28906,7 @@ __metadata: languageName: node linkType: hard -"statuses@npm:>= 1.4.0 < 2, statuses@npm:>= 1.5.0 < 2": +"statuses@npm:>= 1.5.0 < 2, statuses@npm:^1.5.0": version: 1.5.0 resolution: "statuses@npm:1.5.0" checksum: 10/c469b9519de16a4bb19600205cffb39ee471a5f17b82589757ca7bd40a8d92ebb6ed9f98b5a540c5d302ccbc78f15dc03cc0280dd6e00df1335568a5d5758a5c @@ -27868,16 +29229,9 @@ __metadata: languageName: node linkType: hard -"strnum@npm:^2.2.0": - version: 2.2.2 - resolution: "strnum@npm:2.2.2" - checksum: 10/c55813cfded750dc84556b4881ffc7cee91382ff15a48f1fba0ff7a678e1640ed96ca40806fbd55724940fd7d51cf752469b2d862e196e4adefb6c7d5d9cd73b - languageName: node - linkType: hard - -"strtok3@npm:^10.2.0": - version: 10.3.1 - resolution: "strtok3@npm:10.3.1" +"strtok3@npm:^10.3.4": + version: 10.3.5 + resolution: "strtok3@npm:10.3.5" dependencies: "@tokenizer/token": "npm:^0.3.0" checksum: 10/7279dc97a7207a5664ea07cf5304b94968db4f02d64d2732be8e7a3a31a876375126749cd36a00d0bd54c891875f3e47175f8194d40c64118f3265dbc241aaca @@ -28040,9 +29394,16 @@ __metadata: languageName: node linkType: hard -"svgo@npm:^2.7.0": - version: 2.8.0 - resolution: "svgo@npm:2.8.0" +"svg-parser@npm:^2.0.4": + version: 2.0.4 + resolution: "svg-parser@npm:2.0.4" + checksum: 10/ec196da6ea21481868ab26911970e35488361c39ead1c6cdd977ba16c885c21a91ddcbfd113bfb01f79a822e2a751ef85b2f7f95e2cb9245558ebce12c34af1f + languageName: node + linkType: hard + +"svgo@npm:^2.7.0, svgo@npm:^2.8.0": + version: 2.8.2 + resolution: "svgo@npm:2.8.2" dependencies: commander: "npm:^7.2.0" css-select: "npm:^4.1.3" @@ -28095,10 +29456,10 @@ __metadata: languageName: node linkType: hard -"tapable@npm:^2.0.0": - version: 2.2.2 - resolution: "tapable@npm:2.2.2" - checksum: 10/065a0dc44aba1b32020faa1c27c719e8f76e5345347515d8494bf158524f36e9f22ad9eaa5b5494f9d5d67bf0640afdd5698505948c46d720b6b7e69d19349a6 +"tapable@npm:^2.0.0, tapable@npm:^2.2.1, tapable@npm:^2.3.0": + version: 2.3.2 + resolution: "tapable@npm:2.3.2" + checksum: 10/fd3affe2e34efb3970883f934b1828f10b48dffb1eb71a52b7f955bfdd88bf80e94ec388704d95334f72ddf77e34d813b19e1f4bf56897d20252fa025d44bede languageName: node linkType: hard @@ -28219,9 +29580,37 @@ __metadata: languageName: node linkType: hard -"terser@npm:^5.10.0": - version: 5.43.1 - resolution: "terser@npm:5.43.1" +"terminal-columns@npm:^2.0.0": + version: 2.0.0 + resolution: "terminal-columns@npm:2.0.0" + checksum: 10/f958993886e09d7c0780f47833316532a0c7dd7db2fb43da9d34a88c821633408a6e7084af59f99c20b045776814748f14a8e33573886186be7a30174092964f + languageName: node + linkType: hard + +"terser-webpack-plugin@npm:^5.1.3, terser-webpack-plugin@npm:^5.3.17": + version: 5.4.0 + resolution: "terser-webpack-plugin@npm:5.4.0" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.25" + jest-worker: "npm:^27.4.5" + schema-utils: "npm:^4.3.0" + terser: "npm:^5.31.1" + peerDependencies: + webpack: ^5.1.0 + peerDependenciesMeta: + "@swc/core": + optional: true + esbuild: + optional: true + uglify-js: + optional: true + checksum: 10/f4618b18cec5dd41fca4a53f621ea06df04ff7bb2b09d3766559284e171a91df2884083e5c143aaacee2000870b046eb7157e39d1d2d8024577395165a070094 + languageName: node + linkType: hard + +"terser@npm:^5.10.0, terser@npm:^5.31.1": + version: 5.46.1 + resolution: "terser@npm:5.46.1" dependencies: "@jridgewell/source-map": "npm:^0.3.3" acorn: "npm:^8.15.0" @@ -28229,7 +29618,18 @@ __metadata: source-map-support: "npm:~0.5.20" bin: terser: bin/terser - checksum: 10/c0a0fd62319e0ce66e800f57ae12ef4ca45f12e9422dac160b866f0d890d01f8b547c96de2557b8443d96953db36be5d900e8006436ef9f628dbd38082e8fe5d + checksum: 10/16d21179905e549dae2560e107d069ba0fdb801c637bf5f07c2f30431e53b1641151d5e35915ca6578ac1d9763984095723034bf1a26740b183093f200293f86 + languageName: node + linkType: hard + +"test-exclude@npm:^6.0.0": + version: 6.0.0 + resolution: "test-exclude@npm:6.0.0" + dependencies: + "@istanbuljs/schema": "npm:^0.1.2" + glob: "npm:^7.1.4" + minimatch: "npm:^3.0.4" + checksum: 10/8fccb2cb6c8fcb6bb4115394feb833f8b6cf4b9503ec2485c2c90febf435cac62abe882a0c5c51a37b9bbe70640cdd05acf5f45e486ac4583389f4b0855f69e5 languageName: node linkType: hard @@ -28381,9 +29781,16 @@ __metadata: languageName: node linkType: hard -"to-buffer@npm:^1.2.0": - version: 1.2.1 - resolution: "to-buffer@npm:1.2.1" +"tmpl@npm:1.0.5": + version: 1.0.5 + resolution: "tmpl@npm:1.0.5" + checksum: 10/cd922d9b853c00fe414c5a774817be65b058d54a2d01ebb415840960406c669a0fc632f66df885e24cb022ec812739199ccbdb8d1164c3e513f85bfca5ab2873 + languageName: node + linkType: hard + +"to-buffer@npm:^1.2.0, to-buffer@npm:^1.2.1, to-buffer@npm:^1.2.2": + version: 1.2.2 + resolution: "to-buffer@npm:1.2.2" dependencies: isarray: "npm:^2.0.5" safe-buffer: "npm:^5.2.1" @@ -28633,7 +30040,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.14.1, tslib@npm:^1.9.0": +"tslib@npm:^1.14.1, tslib@npm:^1.9.3": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: 10/7dbf34e6f55c6492637adb81b555af5e3b4f9cc6b998fb440dac82d3b42bdc91560a35a5fb75e20e24a076c651438234da6743d139e4feabf0783f3cdfe1dddb @@ -28656,15 +30063,6 @@ __metadata: languageName: node linkType: hard -"tsyringe@npm:^4.10.0": - version: 4.10.0 - resolution: "tsyringe@npm:4.10.0" - dependencies: - tslib: "npm:^1.9.3" - checksum: 10/b42660dc112cee2db02b3d69f2ef6a6a9d185afd96b18d8f88e47c1e62be94b69a9f5a58fcfdb2a3fbb7c6c175b8162ea00f7db6499bf333ce945e570e31615c - languageName: node - linkType: hard - "tty-browserify@npm:0.0.1": version: 0.0.1 resolution: "tty-browserify@npm:0.0.1" @@ -28697,12 +30095,10 @@ __metadata: languageName: node linkType: hard -"type-check@npm:~0.3.2": - version: 0.3.2 - resolution: "type-check@npm:0.3.2" - dependencies: - prelude-ls: "npm:~1.1.2" - checksum: 10/11dec0b50d7c3fd2e630b4b074ba36918ed2b1efbc87dfbd40ba9429d49c58d12dad5c415ece69fcf358fa083f33466fc370f23ab91aa63295c45d38b3a60dda +"type-detect@npm:4.0.8": + version: 4.0.8 + resolution: "type-detect@npm:4.0.8" + checksum: 10/5179e3b8ebc51fce1b13efb75fdea4595484433f9683bbc2dca6d99789dba4e602ab7922d2656f2ce8383987467f7770131d4a7f06a26287db0615d2f4c4ce7d languageName: node linkType: hard @@ -28734,6 +30130,13 @@ __metadata: languageName: node linkType: hard +"type-flag@npm:^4.1.0": + version: 4.1.0 + resolution: "type-flag@npm:4.1.0" + checksum: 10/d3af106dab651751426f778095b3963791d15482b2154f92f4f98e5d6b72d593ae9873120d2de24f34191ab42c0d71c0259743162e543aee8d55b528ed1c6e78 + languageName: node + linkType: hard + "type-is@npm:^1.6.16, type-is@npm:~1.6.18": version: 1.6.18 resolution: "type-is@npm:1.6.18" @@ -28938,6 +30341,13 @@ __metadata: languageName: node linkType: hard +"underscore@npm:1.13.6": + version: 1.13.6 + resolution: "underscore@npm:1.13.6" + checksum: 10/58cf5dc42cb0ac99c146ae4064792c0a2cc84f3a3c4ad88f5082e79057dfdff3371d896d1ec20379e9ece2450d94fa78f2ef5bfefc199ba320653e32c009bd66 + languageName: node + linkType: hard + "underscore@npm:^1.13.3": version: 1.13.8 resolution: "underscore@npm:1.13.8" @@ -29743,7 +31153,7 @@ __metadata: languageName: node linkType: hard -"webpack@npm:^5.94.0": +"webpack@npm:^5.94.0, webpack@npm:~5.105.0": version: 5.105.4 resolution: "webpack@npm:5.105.4" dependencies: @@ -30065,9 +31475,9 @@ __metadata: languageName: node linkType: hard -"ws@npm:^8.18.0": - version: 8.18.2 - resolution: "ws@npm:8.18.2" +"ws@npm:^8.11.0, ws@npm:^8.18.0": + version: 8.20.0 + resolution: "ws@npm:8.20.0" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -30076,7 +31486,30 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 10/018e04ec95561d88248d53a2eaf094b4ae131e9b062f2679e6e8a62f04649bc543448f1e038125225ac6bbb25f54c1e65d7a2cc9dbc1e28b43e5e6b7162ad88e + checksum: 10/b7ab934b21ffdea9f25a5af5097e8c1ec7625db553bca026c5a23e35b7c236f3fb89782f2b57fab9da553864512f9aa7d245827ef998d26ffa1b2187a19a6d10 + languageName: node + linkType: hard + +"wsl-utils@npm:^0.1.0": + version: 0.1.0 + resolution: "wsl-utils@npm:0.1.0" + dependencies: + is-wsl: "npm:^3.1.0" + checksum: 10/de4c92187e04c3c27b4478f410a02e81c351dc85efa3447bf1666f34fc80baacd890a6698ec91995631714086992036013286aea3d77e6974020d40a08e00aec + languageName: node + linkType: hard + +"xml-name-validator@npm:^4.0.0": + version: 4.0.0 + resolution: "xml-name-validator@npm:4.0.0" + checksum: 10/f9582a3f281f790344a471c207516e29e293c6041b2c20d84dd6e58832cd7c19796c47e108fd4fd4b164a5e72ad94f2268f8ace8231cde4a2c6428d6aa220f92 + languageName: node + linkType: hard + +"xmlchars@npm:^2.2.0": + version: 2.2.0 + resolution: "xmlchars@npm:2.2.0" + checksum: 10/4ad5924974efd004a47cce6acf5c0269aee0e62f9a805a426db3337af7bcbd331099df174b024ace4fb18971b8a56de386d2e73a1c4b020e3abd63a4a9b917f1 languageName: node linkType: hard @@ -30167,7 +31600,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:17.7.2, yargs@npm:^17.1.1, yargs@npm:^17.7.2": +"yargs@npm:17.7.2, yargs@npm:^17.1.1, yargs@npm:^17.3.1, yargs@npm:^17.7.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: @@ -30182,9 +31615,9 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.1.1, yargs@npm:^17.7.2": - version: 17.7.2 - resolution: "yargs@npm:17.7.2" +"yargs@npm:^16.2.0": + version: 16.2.0 + resolution: "yargs@npm:16.2.0" dependencies: cliui: "npm:^7.0.2" escalade: "npm:^3.1.1" @@ -30197,7 +31630,7 @@ __metadata: languageName: node linkType: hard -"yauzl@npm:^3.2.1": +"yauzl@npm:^3.0.0, yauzl@npm:^3.2.1": version: 3.2.1 resolution: "yauzl@npm:3.2.1" dependencies: @@ -30263,21 +31696,21 @@ __metadata: languageName: node linkType: hard -"zod-to-json-schema@npm:^3.25.1": - version: 3.25.1 - resolution: "zod-to-json-schema@npm:3.25.1" +"zod-to-json-schema@npm:^3.20.4, zod-to-json-schema@npm:^3.25.1": + version: 3.25.2 + resolution: "zod-to-json-schema@npm:3.25.2" peerDependencies: - zod: ^3.25 || ^4 - checksum: 10/744dd370f4452c8db120de1475ea4d484a11df884c4636111d630e5e1351b8a7590d99cf14a2b9f21e7906f8b78721d958663a7973a40994e7d28770876674cc + zod: ^3.25.28 || ^4 + checksum: 10/7035328654113f1a0b8e4c2d34a06f918c93650ef8a50d4fb30ad8f22e47d5762c163af9c82494756b34776bae3c41c26cfc6945105b0eee7dceb528cc07e665 languageName: node linkType: hard -"zod-validation-error@npm:^3.0.3": - version: 3.5.2 - resolution: "zod-validation-error@npm:3.5.2" +"zod-validation-error@npm:^3.4.0": + version: 3.5.4 + resolution: "zod-validation-error@npm:3.5.4" peerDependencies: - zod: ^3.25.0 - checksum: 10/ca084429d32b6e084088a2d384fd12c2839929fbf0f31e383ae1606c60a85ac0a0cf7a9c1a61f8053690c50a39e9d6ee4d1286edc19305532f20de1b369109e6 + zod: ^3.24.4 + checksum: 10/eb85392e6fd7af255fb233713b1f038134e66cbaff20d1a52d46bd4210fe7b776d48d7dd2170095fbd2b375f6c41d629109bd5eac245c576083c9cf6e131a20b languageName: node linkType: hard @@ -30290,24 +31723,17 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.25 || ^4.0, zod@npm:^3.25.76 || ^4.0.0, zod@npm:^4.1.11": - version: 4.3.6 - resolution: "zod@npm:4.3.6" - checksum: 10/25fc0f62e01b557b4644bf0b393bbaf47542ab30877c37837ea8caf314a8713d220c7d7fe51f68ffa72f0e1018ddfa34d96f1973d23033f5a2a5a9b6b9d9da01 - languageName: node - linkType: hard - -"zod@npm:^3.25.76": +"zod@npm:^3.22.4, zod@npm:^3.25.76": version: 3.25.76 resolution: "zod@npm:3.25.76" checksum: 10/f0c963ec40cd96858451d1690404d603d36507c1fc9682f2dae59ab38b578687d542708a7fdbf645f77926f78c9ed558f57c3d3aa226c285f798df0c4da16995 languageName: node linkType: hard -"zod@npm:^3.25 || ^4.0": - version: 4.2.1 - resolution: "zod@npm:4.2.1" - checksum: 10/f21d106ce31e0f24040aa13b13fdd1300fcc8119622b28ca1b1b726ff70b75190dbcfeb927d34f19174683afa298e5df4d806f622abe9b037a0aadb9cdef6443 +"zod@npm:^3.25 || ^4.0, zod@npm:^3.25.76 || ^4.0.0, zod@npm:^4.1.11": + version: 4.3.6 + resolution: "zod@npm:4.3.6" + checksum: 10/25fc0f62e01b557b4644bf0b393bbaf47542ab30877c37837ea8caf314a8713d220c7d7fe51f68ffa72f0e1018ddfa34d96f1973d23033f5a2a5a9b6b9d9da01 languageName: node linkType: hard From 678e80b5af8a7a555b88a783eef3acc052720c08 Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Sun, 29 Mar 2026 19:09:17 -0400 Subject: [PATCH 12/17] feat(mcp-chat): updated api reports Signed-off-by: Florian JUDITH --- .../mcp-chat-backend-module-amazon-bedrock/report.api.md | 9 +-------- workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md | 2 +- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md index 0b9ab0b247c..9c47a191d14 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md @@ -3,7 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import type { AwsCredentialIdentityProvider } from '@aws-sdk/types'; import { BackendFeature } from '@backstage/backend-plugin-api'; import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; @@ -13,7 +12,7 @@ import { Tool } from '@backstage-community/plugin-mcp-chat-common'; // @public export class BedrockProvider extends LLMProvider { - constructor(config: ProviderConfig, options: BedrockProviderOptions); + constructor(config: ProviderConfig); // (undocumented) protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; // (undocumented) @@ -30,12 +29,6 @@ export class BedrockProvider extends LLMProvider { }>; } -// @public -export interface BedrockProviderOptions { - credentialProvider: AwsCredentialIdentityProvider; - region: string; -} - // @public const _default: BackendFeature; export default _default; diff --git a/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md b/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md index 0709ef07b40..14d183b1565 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md @@ -77,6 +77,7 @@ const mcpChatPlugin: OverridableFrontendPlugin< path?: string | undefined; }; output: + | ExtensionDataRef | ExtensionDataRef | ExtensionDataRef< RouteRef_2, @@ -85,7 +86,6 @@ const mcpChatPlugin: OverridableFrontendPlugin< optional: true; } > - | ExtensionDataRef | ExtensionDataRef< string, 'core.title', From dbd195a8c7ac63be414e9b33e561c6d718531b91 Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Sun, 29 Mar 2026 19:35:05 -0400 Subject: [PATCH 13/17] feat(mcp-chat): moved base provider to node shared library Signed-off-by: Florian JUDITH --- .../plugins/mcp-chat-node/package.json | 4 +- .../mcp-chat-node/src/base-provider.test.ts | 256 ++++++++++++++++++ .../src/base-provider.ts | 70 ++--- .../plugins/mcp-chat-node/src/extensions.ts | 2 +- .../plugins/mcp-chat-node/src/index.ts | 2 + workspaces/mcp-chat/yarn.lock | 2 + 6 files changed, 302 insertions(+), 34 deletions(-) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.test.ts rename workspaces/mcp-chat/plugins/{mcp-chat-common => mcp-chat-node}/src/base-provider.ts (55%) diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/package.json b/workspaces/mcp-chat/plugins/mcp-chat-node/package.json index 418b6b722e0..dcbf50d8c02 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-node/package.json +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/package.json @@ -30,9 +30,11 @@ }, "dependencies": { "@backstage-community/plugin-mcp-chat-common": "workspace:^", - "@backstage/backend-plugin-api": "^1.4.0" + "@backstage/backend-plugin-api": "^1.4.0", + "@backstage/errors": "^1.2.7" }, "devDependencies": { + "@backstage/backend-test-utils": "^1.6.0", "@backstage/cli": "^0.33.0" }, "files": [ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.test.ts new file mode 100644 index 00000000000..a49f99e0d2c --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.test.ts @@ -0,0 +1,256 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { mockServices } from '@backstage/backend-test-utils'; +import { LLMProvider } from './base-provider'; +import { + ChatMessage, + Tool, + ChatResponse, + ProviderConfig, +} from '@backstage-community/plugin-mcp-chat-common'; + +global.fetch = jest.fn(); + +class TestProvider extends LLMProvider { + public exposeTruncateForLogging(data: string, maxLength?: number): string { + return this.truncateForLogging(data, maxLength); + } + + public exposeMakeRequest(endpoint: string, body: any): Promise { + return this.makeRequest(endpoint, body); + } + + async sendMessage( + _messages: ChatMessage[], + _tools?: Tool[], + ): Promise { + return { choices: [{ message: { role: 'assistant', content: '' } }] }; + } + + async testConnection() { + return { connected: true }; + } + + protected getHeaders(): Record { + return { 'Content-Type': 'application/json' }; + } + + protected formatRequest(_messages: ChatMessage[], _tools?: Tool[]): any { + return {}; + } + + protected parseResponse(response: any): ChatResponse { + return response; + } +} + +describe('LLMProvider', () => { + const mockLogger = mockServices.logger.mock(); + + const config: ProviderConfig = { + type: 'test-provider', + apiKey: 'test-key', + baseUrl: 'http://localhost:1234', + model: 'test-model', + logger: mockLogger, + }; + + let provider: TestProvider; + + beforeEach(() => { + jest.clearAllMocks(); + (global.fetch as jest.Mock).mockReset(); + provider = new TestProvider(config); + }); + + describe('truncateForLogging', () => { + it('should return data unchanged when under default limit', () => { + const short = 'a'.repeat(4096); + expect(provider.exposeTruncateForLogging(short)).toBe(short); + }); + + it('should return data unchanged when exactly at default limit', () => { + const exact = 'x'.repeat(4096); + expect(provider.exposeTruncateForLogging(exact)).toBe(exact); + }); + + it('should truncate data exceeding default 4096 char limit', () => { + const long = 'b'.repeat(5000); + const result = provider.exposeTruncateForLogging(long); + expect(result).toHaveLength(4096 + '... [truncated 904 chars]'.length); + expect(result).toContain('... [truncated 904 chars]'); + expect(result.startsWith('b'.repeat(4096))).toBe(true); + }); + + it('should respect a custom maxLength parameter', () => { + const data = 'c'.repeat(200); + const result = provider.exposeTruncateForLogging(data, 100); + expect(result).toContain('... [truncated 100 chars]'); + expect(result.startsWith('c'.repeat(100))).toBe(true); + }); + + it('should return unchanged for empty string', () => { + expect(provider.exposeTruncateForLogging('')).toBe(''); + }); + }); + + describe('makeRequest logging', () => { + it('should log debug on successful request with request body and response data', async () => { + const responseBody = { + choices: [{ message: { role: 'assistant', content: 'hello' } }], + }; + + (global.fetch as jest.Mock).mockResolvedValueOnce({ + ok: true, + json: async () => responseBody, + }); + + await provider.exposeMakeRequest('/chat/completions', { + model: 'test', + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + expect.stringContaining( + '[test-provider] Request to http://localhost:1234/chat/completions', + ), + expect.objectContaining({ body: expect.any(String) }), + ); + + expect(mockLogger.debug).toHaveBeenCalledWith( + expect.stringContaining('[test-provider] Response received in'), + expect.objectContaining({ data: expect.any(String) }), + ); + }); + + it('should log error on HTTP failure with response data', async () => { + (global.fetch as jest.Mock).mockResolvedValueOnce({ + ok: false, + status: 500, + statusText: 'Internal Server Error', + text: async () => 'server error details', + headers: new Headers({ 'Content-Type': 'text/plain' }), + json: async () => ({ error: 'server error' }), + }); + + await expect( + provider.exposeMakeRequest('/chat/completions', {}), + ).rejects.toThrow(); + + expect(mockLogger.error).toHaveBeenCalledWith( + expect.stringContaining('[test-provider] Request failed (500)'), + expect.objectContaining({ responseData: 'server error details' }), + ); + }); + + it('should log warn when finish_reason is length', async () => { + const responseBody = { + choices: [ + { + message: { role: 'assistant', content: 'truncated...' }, + finish_reason: 'length', + }, + ], + }; + + (global.fetch as jest.Mock).mockResolvedValueOnce({ + ok: true, + json: async () => responseBody, + }); + + await provider.exposeMakeRequest('/chat/completions', {}); + + expect(mockLogger.warn).toHaveBeenCalledWith( + expect.stringContaining('truncated due to token limit'), + ); + }); + + it('should log warn when finish_reason is max_tokens', async () => { + const responseBody = { + choices: [ + { + message: { role: 'assistant', content: 'truncated...' }, + finish_reason: 'max_tokens', + }, + ], + }; + + (global.fetch as jest.Mock).mockResolvedValueOnce({ + ok: true, + json: async () => responseBody, + }); + + await provider.exposeMakeRequest('/chat/completions', {}); + + expect(mockLogger.warn).toHaveBeenCalledWith( + expect.stringContaining('finish_reason: max_tokens'), + ); + }); + + it('should not log warn when finish_reason is stop', async () => { + const responseBody = { + choices: [ + { + message: { role: 'assistant', content: 'done' }, + finish_reason: 'stop', + }, + ], + }; + + (global.fetch as jest.Mock).mockResolvedValueOnce({ + ok: true, + json: async () => responseBody, + }); + + await provider.exposeMakeRequest('/chat/completions', {}); + + expect(mockLogger.warn).not.toHaveBeenCalled(); + }); + + it('should work without a logger configured', async () => { + const noLoggerProvider = new TestProvider({ + ...config, + logger: undefined, + }); + + (global.fetch as jest.Mock).mockResolvedValueOnce({ + ok: true, + json: async () => ({ choices: [{ message: { content: 'ok' } }] }), + }); + + const result = await noLoggerProvider.exposeMakeRequest( + '/chat/completions', + {}, + ); + expect(result).toBeDefined(); + }); + + it('should truncate large request bodies in debug logs', async () => { + const largeBody = { data: 'x'.repeat(5000) }; + + (global.fetch as jest.Mock).mockResolvedValueOnce({ + ok: true, + json: async () => ({ choices: [] }), + }); + + await provider.exposeMakeRequest('/chat/completions', largeBody); + + const debugCall = mockLogger.debug.mock.calls[0]; + const metadata = debugCall[1] as Record; + expect(metadata.body).toContain('... [truncated'); + }); + }); +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/src/base-provider.ts b/workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.ts similarity index 55% rename from workspaces/mcp-chat/plugins/mcp-chat-common/src/base-provider.ts rename to workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.ts index 954996bf649..631c693849a 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-common/src/base-provider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.ts @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { LoggerService } from '@backstage/backend-plugin-api'; import { ResponseError } from '@backstage/errors'; import { ChatMessage, Tool, ChatResponse, ProviderConfig, - MCPServerFullConfig, -} from './types'; +} from '@backstage-community/plugin-mcp-chat-common'; /** * Abstract base class for all LLM providers. @@ -33,27 +33,14 @@ export abstract class LLMProvider { protected baseUrl: string; protected model: string; protected type: string; + protected logger?: LoggerService; constructor(config: ProviderConfig) { this.apiKey = config.apiKey; this.baseUrl = config.baseUrl; this.model = config.model; this.type = config.type; - } - - /** Returns the provider type identifier. */ - getType(): string { - return this.type; - } - - /** Returns the model identifier. */ - getModel(): string { - return this.model; - } - - /** Returns the base URL for the provider's API. */ - getBaseUrl(): string { - return this.baseUrl; + this.logger = config.logger; } abstract sendMessage( @@ -74,32 +61,51 @@ export abstract class LLMProvider { ): any; protected abstract parseResponse(response: any): ChatResponse; - /** Override to return `true` in providers that handle MCP natively. */ - supportsNativeMcp(): boolean { - return false; - } - - /** Set MCP server configs for native MCP providers. No-op by default. */ - setMcpServerConfigs(_configs: MCPServerFullConfig[]): void { - // no-op - } - - /** Get last response output for native MCP providers. Returns `null` by default. */ - getLastResponseOutput(): any { - return null; + protected truncateForLogging(data: string, maxLength = 4096): string { + if (data.length <= maxLength) return data; + return `${data.substring(0, maxLength)}... [truncated ${ + data.length - maxLength + } chars]`; } protected async makeRequest(endpoint: string, body: any): Promise { - const response = await fetch(`${this.baseUrl}${endpoint}`, { + const url = `${this.baseUrl}${endpoint}`; + + this.logger?.debug(`[${this.type}] Request to ${url}`, { + body: this.truncateForLogging(JSON.stringify(body)), + }); + const startTime = Date.now(); + const response = await fetch(url, { method: 'POST', headers: this.getHeaders(), body: JSON.stringify(body), }); + const duration = Date.now() - startTime; if (!response.ok) { + const errorText = await response.text(); + this.logger?.error( + `[${this.type}] Request failed (${response.status}) after ${duration}ms`, + { responseData: errorText }, + ); throw await ResponseError.fromResponse(response); } - return response.json(); + const responseData = await response.json(); + + this.logger?.debug(`[${this.type}] Response received in ${duration}ms`, { + data: this.truncateForLogging(JSON.stringify(responseData)), + }); + + // Warn if response was truncated due to token limits + const finishReason = responseData.choices?.[0]?.finish_reason; + if (finishReason === 'length' || finishReason === 'max_tokens') { + this.logger?.warn( + `[${this.type}] Response was truncated due to token limit (finish_reason: ${finishReason}). ` + + `Consider increasing max_tokens in your provider configuration.`, + ); + } + + return responseData; } } diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/src/extensions.ts b/workspaces/mcp-chat/plugins/mcp-chat-node/src/extensions.ts index fd8890a670b..db39996496e 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-node/src/extensions.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/src/extensions.ts @@ -15,7 +15,7 @@ */ import { createExtensionPoint } from '@backstage/backend-plugin-api'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; +import { LLMProvider } from './base-provider'; /** * Extension point for registering LLM provider implementations diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-node/src/index.ts index 95786cfe4a2..71a7e7ddd15 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-node/src/index.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/src/index.ts @@ -24,3 +24,5 @@ export { llmProviderExtensionPoint, type LlmProviderExtensionPoint, } from './extensions'; + +export { LLMProvider } from './base-provider'; diff --git a/workspaces/mcp-chat/yarn.lock b/workspaces/mcp-chat/yarn.lock index f962faa0585..1b4a809cec1 100644 --- a/workspaces/mcp-chat/yarn.lock +++ b/workspaces/mcp-chat/yarn.lock @@ -2766,7 +2766,9 @@ __metadata: dependencies: "@backstage-community/plugin-mcp-chat-common": "workspace:^" "@backstage/backend-plugin-api": "npm:^1.4.0" + "@backstage/backend-test-utils": "npm:^1.6.0" "@backstage/cli": "npm:^0.33.0" + "@backstage/errors": "npm:^1.2.7" languageName: unknown linkType: soft From 1cd26641b07bbbcc05ba185a9aa4f97aab6e8c7a Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Sun, 29 Mar 2026 20:31:19 -0400 Subject: [PATCH 14/17] feat(mcp-chat): restored backend integrated providers see: comments https://github.com/backstage/community-plugins/pull/8196 Signed-off-by: Florian JUDITH --- .../.eslintrc.js | 1 - .../README.md | 64 -- .../config.d.ts | 52 -- .../knip-report.md | 2 - .../package.json | 65 -- .../report.api.md | 35 - .../src/BedrockProvider.test.ts | 238 ------ .../src/BedrockProvider.ts | 290 ------- .../src/index.ts | 27 - .../src/module.ts | 91 -- .../tsconfig.json | 9 - .../.eslintrc.js | 1 - .../README.md | 5 - .../config.d.ts | 52 -- .../knip-report.md | 2 - .../package.json | 61 -- .../report.api.md | 33 - .../src/ClaudeProvider.test.ts | 187 ----- .../src/index.ts | 24 - .../src/module.ts | 79 -- .../tsconfig.json | 9 - .../.eslintrc.js | 1 - .../mcp-chat-backend-module-gemini/README.md | 5 - .../config.d.ts | 52 -- .../knip-report.md | 2 - .../package.json | 62 -- .../report.api.md | 36 - .../src/index.ts | 24 - .../src/module.ts | 79 -- .../tsconfig.json | 9 - .../.eslintrc.js | 1 - .../mcp-chat-backend-module-litellm/README.md | 5 - .../config.d.ts | 52 -- .../knip-report.md | 2 - .../package.json | 60 -- .../report.api.md | 33 - .../src/LiteLLMProvider.test.ts | 223 ----- .../src/index.ts | 24 - .../src/module.ts | 78 -- .../tsconfig.json | 9 - .../.eslintrc.js | 1 - .../mcp-chat-backend-module-ollama/README.md | 5 - .../config.d.ts | 52 -- .../knip-report.md | 2 - .../package.json | 61 -- .../report.api.md | 35 - .../src/OllamaProvider.test.ts | 195 ----- .../src/index.ts | 24 - .../src/module.ts | 78 -- .../tsconfig.json | 9 - .../.eslintrc.js | 1 - .../README.md | 10 - .../config.d.ts | 52 -- .../knip-report.md | 2 - .../package.json | 61 -- .../report.api.md | 40 - .../src/OpenAIResponsesProvider.test.ts | 193 ----- .../src/index.ts | 24 - .../src/module.ts | 80 -- .../tsconfig.json | 9 - .../.eslintrc.js | 1 - .../mcp-chat-backend-module-openai/README.md | 10 - .../config.d.ts | 52 -- .../knip-report.md | 2 - .../package.json | 60 -- .../report.api.md | 33 - .../src/OpenAIProvider.test.ts | 214 ----- .../src/index.ts | 24 - .../src/module.ts | 78 -- .../tsconfig.json | 9 - .../plugins/mcp-chat-backend/dev/index.ts | 6 - .../plugins/mcp-chat-backend/package.json | 10 +- .../plugins/mcp-chat-backend/src/index.ts | 5 - .../mcp-chat-backend/src/plugin.test.ts | 28 - .../plugins/mcp-chat-backend/src/plugin.ts | 41 +- .../src/providers/base-provider.test.ts | 251 ------ .../src/providers/base-provider.ts | 21 - .../src/providers/claude-provider.ts} | 13 +- .../src/providers/gemini-provider.test.ts} | 13 +- .../src/providers/gemini-provider.ts} | 11 +- .../mcp-chat-backend/src/providers/index.ts | 19 +- .../src/providers/litellm-provider.test.ts | 340 ++++++++ .../src/providers/litellm-provider.ts} | 32 +- .../src/providers/ollama-provider.test.ts | 710 ++++++++++++++++ .../src/providers/ollama-provider.ts} | 16 +- .../src/providers/openai-provider.ts} | 11 +- .../openai-responses-provider.test.ts | 782 ++++++++++++++++++ .../providers/openai-responses-provider.ts} | 52 +- .../src/providers/provider-factory.test.ts | 372 +++++++++ .../src/providers/provider-factory.ts | 189 +++++ .../src/services/MCPClientServiceImpl.test.ts | 62 +- .../src/services/MCPClientServiceImpl.ts | 85 +- .../plugins/mcp-chat-common/src/index.ts | 6 - .../plugins/mcp-chat-common/src/types.ts | 32 - .../mcp-chat-node/src/base-provider.test.ts | 2 +- .../mcp-chat-node/src/base-provider.ts | 2 +- .../plugins/mcp-chat-node/src/index.ts | 1 + .../plugins/mcp-chat-node/src/types.ts | 55 ++ workspaces/mcp-chat/yarn.lock | 337 +------- 99 files changed, 2679 insertions(+), 4326 deletions(-) delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/.eslintrc.js delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/README.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/config.d.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/knip-report.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/package.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.test.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/index.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/module.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/.eslintrc.js delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/README.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/config.d.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/knip-report.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/package.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/report.api.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.test.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/index.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/module.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/tsconfig.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/.eslintrc.js delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/README.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/config.d.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/knip-report.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/package.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/report.api.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/index.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/module.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/tsconfig.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/.eslintrc.js delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/README.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/config.d.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/knip-report.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/package.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/report.api.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.test.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/index.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/module.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/tsconfig.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/.eslintrc.js delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/README.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/config.d.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/knip-report.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/package.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/report.api.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.test.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/index.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/module.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/tsconfig.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/.eslintrc.js delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/README.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/config.d.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/knip-report.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/package.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/report.api.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.test.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/index.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/module.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/tsconfig.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/.eslintrc.js delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/README.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/config.d.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/knip-report.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/package.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/report.api.md delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.test.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/index.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/module.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/tsconfig.json delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/base-provider.test.ts delete mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/base-provider.ts rename workspaces/mcp-chat/plugins/{mcp-chat-backend-module-anthropic/src/ClaudeProvider.ts => mcp-chat-backend/src/providers/claude-provider.ts} (96%) rename workspaces/mcp-chat/plugins/{mcp-chat-backend-module-gemini/src/GeminiProvider.test.ts => mcp-chat-backend/src/providers/gemini-provider.test.ts} (98%) rename workspaces/mcp-chat/plugins/{mcp-chat-backend-module-gemini/src/GeminiProvider.ts => mcp-chat-backend/src/providers/gemini-provider.ts} (98%) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.test.ts rename workspaces/mcp-chat/plugins/{mcp-chat-backend-module-litellm/src/LiteLLMProvider.ts => mcp-chat-backend/src/providers/litellm-provider.ts} (85%) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.test.ts rename workspaces/mcp-chat/plugins/{mcp-chat-backend-module-ollama/src/OllamaProvider.ts => mcp-chat-backend/src/providers/ollama-provider.ts} (93%) rename workspaces/mcp-chat/plugins/{mcp-chat-backend-module-openai/src/OpenAIProvider.ts => mcp-chat-backend/src/providers/openai-provider.ts} (93%) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.test.ts rename workspaces/mcp-chat/plugins/{mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.ts => mcp-chat-backend/src/providers/openai-responses-provider.ts} (91%) create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.test.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.ts create mode 100644 workspaces/mcp-chat/plugins/mcp-chat-node/src/types.ts diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/.eslintrc.js deleted file mode 100644 index e2a53a6ad28..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/README.md deleted file mode 100644 index 1deb16faf12..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/README.md +++ /dev/null @@ -1,64 +0,0 @@ -# @backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock - -This plugin is a submodule for the `@backstage-community/plugin-mcp-chat-backend` module, which provides the chat interface with Amazon Bedrock. - -## Configuration - -Two configuration sections requires the following configuraiton sections: - -1. [AWS integration](#aws-integration) section to manage AWS credentials -2. [Amazon Bedrock integration](#amazon-bedrock-integration) to manage the model configuration - -### AWS Integration - -The module depends on the [@backstage/integration-aws-node](https://backstage.io/api/next/modules/_backstage_integration-aws-node.html) package to fetch AWS account credentials for the AWS SDK client included in this submodule. IAM user credentail, IAM roles, AWS CLI profile name and [IRSA](#iam-role-for-service-account) is supported. - -```yaml -aws: - mainAccount: - accessKeyId: ${MY_ACCESS_KEY_ID} - secretAccessKey: ${MY_SECRET_ACCESS_KEY} - accounts: - - accountId: '111111111111' - roleName: 'my-iam-role-name' - externalId: 'my-external-id' - - accountId: '222222222222' - partition: 'aws-other' - roleName: 'my-iam-role-name' - region: 'not-us-east-1' - accessKeyId: ${MY_ACCESS_KEY_ID_FOR_ANOTHER_PARTITION} - secretAccessKey: ${MY_SECRET_ACCESS_KEY_FOR_ANOTHER_PARTITION} - - accountId: '333333333333' - accessKeyId: ${MY_OTHER_ACCESS_KEY_ID} - secretAccessKey: ${MY_OTHER_SECRET_ACCESS_KEY} - - accountId: '444444444444' - profile: my-profile-name - - accountId: '555555555555' - accountDefaults: - roleName: 'my-backstage-role' - externalId: 'my-id' -``` - -#### IAM Role for Service Account - -When Backstage is deployed in a Amazon EKS cluster, [IRSA](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) is typically enabled to support the injection of AWS credential at pod startup. In this specific case the app-config should only contain the account id where bedrock will be accessed - -```yaml -aws: - accounts: - - accountId: '123456789012' -``` - -### Amazon Bedrock integration - -The ID of the model have to be `amazon-bedrock` and expects a model ID or an inference profile ID. -If not interrested by Amazon Bedrock in `us-east-1`, you should **always configure the region** as the model ID can varies depending on target AWS region. - -```yaml -mcpChat: - providers: - - id: amazon-bedrock - model: ca.amazon.nova-lite-v1:0 - auth: - region: ca-central-1 -``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/config.d.ts deleted file mode 100644 index 65d61e8b043..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/config.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface Config { - /** Configuration options for the MCP Chat plugin */ - mcpChat?: { - /** - * AI/LLM providers configuration - * @visibility backend - */ - providers?: Array<{ - /** - * Unique identifier for the provider - * @visibility backend - */ - id: string; - /** - * API token for the provider - * @visibility secret - */ - token?: string; - /** - * Model name to use for this provider - * @visibility backend - */ - model: string; - /** - * Base URL for the provider's API - * @visibility backend - */ - baseUrl?: string; - /** - * Provider-specific authentication parameters (IAM, session tokens, etc.) - * @visibility secret - */ - auth?: { [key: string]: string }; - }>; - }; -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/knip-report.md deleted file mode 100644 index 2661c353270..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/package.json deleted file mode 100644 index 3088e300686..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock", - "version": "0.1.0", - "license": "Apache-2.0", - "main": "src/index.ts", - "types": "src/index.ts", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin-module", - "pluginId": "mcp-chat", - "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", - "pluginPackages": [ - "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock", - "@backstage-community/plugin-mcp-chat-backend" - ] - }, - "dependencies": { - "@aws-sdk/client-bedrock-runtime": "^3.0.0", - "@aws-sdk/types": "^3.0.0", - "@backstage-community/plugin-mcp-chat-common": "workspace:^", - "@backstage-community/plugin-mcp-chat-node": "workspace:^", - "@backstage/backend-plugin-api": "^1.4.0", - "@backstage/config": "^1.3.0", - "@backstage/integration-aws-node": "^0.1.20" - }, - "devDependencies": { - "@backstage/cli": "^0.33.0" - }, - "scripts": { - "start": "backstage-cli package start", - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/backstage/community-plugins", - "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock" - }, - "keywords": [ - "backstage", - "backstage-plugin", - "backstage-backend-module", - "amazon-bedrock", - "aws", - "bedrock", - "llm", - "mcp", - "mcp-chat" - ], - "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock", - "bugs": "https://github.com/backstage/community-plugins/issues" -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md deleted file mode 100644 index 9c47a191d14..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/report.api.md +++ /dev/null @@ -1,35 +0,0 @@ -## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; -import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; -import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; -import { ProviderConfig } from '@backstage-community/plugin-mcp-chat-common'; -import { Tool } from '@backstage-community/plugin-mcp-chat-common'; - -// @public -export class BedrockProvider extends LLMProvider { - constructor(config: ProviderConfig); - // (undocumented) - protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; - // (undocumented) - protected getHeaders(): Record; - // (undocumented) - protected parseResponse(response: any): ChatResponse; - // (undocumented) - sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; - // (undocumented) - testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; -} - -// @public -const _default: BackendFeature; -export default _default; -``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.test.ts deleted file mode 100644 index 63064f9d009..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.test.ts +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { BedrockProvider } from './BedrockProvider'; -import type { - ChatMessage, - Tool, - ProviderConfig, -} from '@backstage-community/plugin-mcp-chat-common'; -import type { BedrockProviderOptions } from './BedrockProvider'; - -// Mock the AWS SDK -const mockSend = jest.fn(); -jest.mock('@aws-sdk/client-bedrock-runtime', () => { - const actual = jest.requireActual('@aws-sdk/client-bedrock-runtime'); - return { - ...actual, - BedrockRuntimeClient: jest.fn().mockImplementation(() => ({ - send: mockSend, - })), - ConverseCommand: jest.fn().mockImplementation(input => ({ input })), - }; -}); - -const mockCredentialProvider = jest.fn().mockResolvedValue({ - accessKeyId: 'AKIAV3RY1N53CUR3MOCK', - secretAccessKey: 's4kv3rY1ns3CUR353cr3t4cC355k3y+mocked', -}); - -function createProvider( - configOverrides?: Partial, - optionOverrides?: Partial, -): BedrockProvider { - const config: ProviderConfig = { - type: 'amazon-bedrock', - baseUrl: '', - model: 'us.anthropic.claude-sonnet-4-20250514-v1:0', - ...configOverrides, - }; - const options: BedrockProviderOptions = { - region: 'us-east-1', - credentialProvider: mockCredentialProvider, - ...optionOverrides, - }; - return new BedrockProvider(config, options); -} - -function makeConverseResponse( - content: any[], - usage?: { inputTokens: number; outputTokens: number }, -) { - return { - output: { message: { role: 'assistant', content } }, - usage, - }; -} - -const sampleTool: Tool = { - type: 'function', - function: { - name: 'get_weather', - description: 'Get the weather', - parameters: { type: 'object', properties: { city: { type: 'string' } } }, - }, -}; - -describe('BedrockProvider', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('sends a basic user message and returns parsed response', async () => { - const provider = createProvider(); - mockSend.mockResolvedValueOnce( - makeConverseResponse([{ text: 'Hello there!' }], { - inputTokens: 10, - outputTokens: 5, - }), - ); - - const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; - const result = await provider.sendMessage(messages); - - expect(result.choices[0].message.role).toBe('assistant'); - expect(result.choices[0].message.content).toBe('Hello there!'); - expect(result.usage).toEqual({ - prompt_tokens: 10, - completion_tokens: 5, - total_tokens: 15, - }); - }); - - it('extracts system prompts into the system field', async () => { - const provider = createProvider(); - const { ConverseCommand } = require('@aws-sdk/client-bedrock-runtime'); - mockSend.mockResolvedValueOnce(makeConverseResponse([{ text: 'OK' }])); - - const messages: ChatMessage[] = [ - { role: 'system', content: 'You are helpful.' }, - { role: 'user', content: 'Hi' }, - ]; - await provider.sendMessage(messages); - - const commandInput = ConverseCommand.mock.calls[0][0]; - expect(commandInput.system).toEqual([{ text: 'You are helpful.' }]); - expect(commandInput.messages.every((m: any) => m.role !== 'system')).toBe( - true, - ); - }); - - it('parses tool use response blocks into tool_calls', async () => { - const provider = createProvider(); - mockSend.mockResolvedValueOnce( - makeConverseResponse([ - { - toolUse: { - toolUseId: 'call_123', - name: 'get_weather', - input: { city: 'Seattle' }, - }, - }, - ]), - ); - - const result = await provider.sendMessage( - [{ role: 'user', content: 'Weather in Seattle?' }], - [sampleTool], - ); - - expect(result.choices[0].message.tool_calls).toHaveLength(1); - expect(result.choices[0].message.tool_calls![0]).toEqual({ - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"Seattle"}', - }, - }); - }); - - it('converts tool_calls round-trip and re-attaches toolConfig on follow-up', async () => { - const provider = createProvider(); - const { ConverseCommand } = require('@aws-sdk/client-bedrock-runtime'); - - // First call — model requests a tool call - mockSend.mockResolvedValueOnce( - makeConverseResponse([ - { - toolUse: { - toolUseId: 'call_1', - name: 'get_weather', - input: { city: 'NYC' }, - }, - }, - ]), - ); - await provider.sendMessage( - [{ role: 'user', content: 'Weather?' }], - [sampleTool], - ); - - // Follow-up with tool result in history (no tools param) - mockSend.mockResolvedValueOnce( - makeConverseResponse([{ text: 'It is sunny in NYC.' }]), - ); - - const followUpMessages: ChatMessage[] = [ - { role: 'user', content: 'Weather?' }, - { - role: 'assistant', - content: null, - tool_calls: [ - { - id: 'call_1', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"NYC"}', - }, - }, - ], - }, - { role: 'tool', content: 'Sunny, 75°F', tool_call_id: 'call_1' }, - ]; - await provider.sendMessage(followUpMessages); - - const commandInput = ConverseCommand.mock.calls[1][0]; - - // Assistant tool_calls converted to Bedrock toolUse blocks - const assistantMsg = commandInput.messages.find( - (m: any) => m.role === 'assistant', - ); - expect(assistantMsg.content).toEqual( - expect.arrayContaining([ - expect.objectContaining({ - toolUse: expect.objectContaining({ - toolUseId: 'call_1', - name: 'get_weather', - }), - }), - ]), - ); - - // Tool result converted to Bedrock toolResult block - const toolMsg = commandInput.messages.find( - (m: any) => m.role === 'user' && m.content.some((c: any) => c.toolResult), - ); - expect(toolMsg).toBeDefined(); - expect(toolMsg.content[0].toolResult.toolUseId).toBe('call_1'); - - // toolConfig re-attached from cached tools - expect(commandInput.toolConfig).toBeDefined(); - expect(commandInput.toolConfig.tools[0].toolSpec.name).toBe('get_weather'); - }); - - it('returns error on failed testConnection', async () => { - const provider = createProvider(); - mockSend.mockRejectedValueOnce(new Error('Access denied')); - - const result = await provider.testConnection(); - - expect(result.connected).toBe(false); - expect(result.error).toBe('Access denied'); - }); -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.ts deleted file mode 100644 index 3b7031fac67..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/BedrockProvider.ts +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - BedrockRuntimeClient, - ConverseCommand, - type ConverseCommandInput, - type Message, - type ContentBlock, -} from '@aws-sdk/client-bedrock-runtime'; -import type { AwsCredentialIdentityProvider } from '@aws-sdk/types'; -import { - LLMProvider, - type ChatMessage, - type Tool, - type ChatResponse, - type ProviderConfig, - type ToolCall, -} from '@backstage-community/plugin-mcp-chat-common'; - -/** - * Options for constructing a BedrockProvider with AWS credentials - * resolved via `@backstage/integration-aws-node`. - * - * @public - */ -export interface BedrockProviderOptions { - /** AWS region for the Bedrock Runtime client. */ - region: string; - /** Credential provider resolved from DefaultAwsCredentialsManager. */ - credentialProvider: AwsCredentialIdentityProvider; -} - -/** - * Amazon Bedrock Converse API provider. - * - * Uses the AWS SDK Bedrock Runtime client with the Converse API, - * which provides a unified interface across all Bedrock foundation models. - * - * Authentication is handled via `@backstage/integration-aws-node`, - * which resolves credentials from the Backstage `aws` app-config section - * (IAM roles, profiles, static keys, or the default SDK credential chain). - * - * @public - */ -export class BedrockProvider extends LLMProvider { - private client: BedrockRuntimeClient; - private lastTools?: Tool[]; - - constructor(config: ProviderConfig, options: BedrockProviderOptions) { - super(config); - - const clientConfig: ConstructorParameters[0] = - { - region: options.region, - credentialDefaultProvider: () => options.credentialProvider, - }; - - if (config.baseUrl) { - clientConfig.endpoint = config.baseUrl; - } - - this.client = new BedrockRuntimeClient(clientConfig); - } - - async sendMessage( - messages: ChatMessage[], - tools?: Tool[], - ): Promise { - const bedrockMessages = this.convertToBedrockFormat(messages); - const systemPrompts = this.extractSystemPrompts(messages); - - const input: ConverseCommandInput = { - modelId: this.model, - messages: bedrockMessages, - }; - - if (systemPrompts.length > 0) { - input.system = systemPrompts; - } - - if (tools && tools.length > 0) { - // Store tools so we can re-attach toolConfig on follow-up calls - this.lastTools = tools; - input.toolConfig = this.convertToBedrockTools(tools); - } else if (this.hasToolBlocks(messages) && this.lastTools?.length) { - // Bedrock requires toolConfig whenever the conversation contains - // toolUse / toolResult blocks (e.g. the follow-up call after tool - // execution in processQuery which doesn't pass tools). - input.toolConfig = this.convertToBedrockTools(this.lastTools); - } - - const command = new ConverseCommand(input); - const response = await this.client.send(command); - - return this.parseConverseResponse(response); - } - - async testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }> { - try { - const command = new ConverseCommand({ - modelId: this.model, - messages: [ - { - role: 'user', - content: [{ text: 'Hello' }], - }, - ], - inferenceConfig: { maxTokens: 1 }, - }); - - await this.client.send(command); - - return { - connected: true, - models: [this.model], - }; - } catch (error: unknown) { - const message = error instanceof Error ? error.message : 'Unknown error'; - return { - connected: false, - error: message, - }; - } - } - - protected getHeaders(): Record { - // Not used — Bedrock auth is handled by the AWS SDK - return {}; - } - - protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any { - // Not used — sendMessage calls the SDK directly - return { messages, tools }; - } - - protected parseResponse(response: any): ChatResponse { - return this.parseConverseResponse(response); - } - - private hasToolBlocks(messages: ChatMessage[]): boolean { - return messages.some( - msg => - msg.role === 'tool' || - (msg.role === 'assistant' && msg.tool_calls?.length), - ); - } - - private extractSystemPrompts( - messages: ChatMessage[], - ): Array<{ text: string }> { - return messages - .filter(msg => msg.role === 'system' && msg.content) - .map(msg => ({ text: msg.content as string })); - } - - private convertToBedrockFormat(messages: ChatMessage[]): Message[] { - return messages - .filter(msg => msg.role !== 'system') - .map(msg => { - if (msg.role === 'tool') { - return { - role: 'user' as const, - content: [ - { - toolResult: { - toolUseId: msg.tool_call_id || 'unknown', - content: [{ text: msg.content || '' }], - }, - }, - ] as ContentBlock[], - }; - } - - if (msg.role === 'assistant' && msg.tool_calls?.length) { - const blocks: ContentBlock[] = []; - - if (msg.content) { - blocks.push({ text: msg.content }); - } - - for (const tc of msg.tool_calls) { - let input: Record = {}; - try { - input = JSON.parse(tc.function.arguments); - } catch { - // keep empty input if parsing fails - } - blocks.push({ - toolUse: { - toolUseId: tc.id, - name: tc.function.name, - input, - }, - } as ContentBlock); - } - - return { - role: 'assistant' as const, - content: blocks, - }; - } - - return { - role: - msg.role === 'assistant' - ? ('assistant' as const) - : ('user' as const), - content: [{ text: msg.content || ' ' }] as ContentBlock[], - }; - }); - } - - private convertToBedrockTools( - tools: Tool[], - ): ConverseCommandInput['toolConfig'] { - return { - tools: tools.map(tool => ({ - toolSpec: { - name: tool.function.name, - description: tool.function.description, - inputSchema: { - json: tool.function.parameters as Record, - }, - }, - })) as ConverseCommandInput['toolConfig'] extends { tools?: infer T } - ? T - : never, - }; - } - - private parseConverseResponse(response: any): ChatResponse { - const output = response.output; - const content: ContentBlock[] = output?.message?.content || []; - - const textParts = content - .filter((block: any) => block.text) - .map((block: any) => block.text); - const textContent = textParts.join(''); - - const toolCalls: ToolCall[] = content - .filter((block: any) => block.toolUse) - .map((block: any) => ({ - id: block.toolUse.toolUseId, - type: 'function' as const, - function: { - name: block.toolUse.name, - arguments: JSON.stringify(block.toolUse.input), - }, - })); - - return { - choices: [ - { - message: { - role: 'assistant', - content: textContent, - tool_calls: toolCalls.length > 0 ? toolCalls : undefined, - }, - }, - ], - usage: response.usage - ? { - prompt_tokens: response.usage.inputTokens || 0, - completion_tokens: response.usage.outputTokens || 0, - total_tokens: - (response.usage.inputTokens || 0) + - (response.usage.outputTokens || 0), - } - : undefined, - }; - } -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/index.ts deleted file mode 100644 index 0c492f675b3..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/index.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Backend module for the mcp-chat plugin that provides the Amazon Bedrock LLM provider. - * - * @packageDocumentation - */ - -export { default } from './module'; -export { - BedrockProvider, - type BedrockProviderOptions, -} from './BedrockProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/module.ts deleted file mode 100644 index aa18542f1f7..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/src/module.ts +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - createBackendModule, - coreServices, -} from '@backstage/backend-plugin-api'; -import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; -import { DefaultAwsCredentialsManager } from '@backstage/integration-aws-node'; -import type { Config } from '@backstage/config'; -import { BedrockProvider } from './BedrockProvider'; - -/** - * Reads the optional `auth` record from a provider config entry. - * @param entry - The config entry to read auth from - * @returns A record of string key-value pairs, or undefined if no auth config - */ -function readAuthRecord(entry: Config): Record | undefined { - const authConfig = entry.getOptionalConfig('auth'); - if (!authConfig) return undefined; - const result: Record = {}; - for (const key of authConfig.keys()) { - result[key] = authConfig.getString(key); - } - return result; -} - -/** - * Backend module that registers the Amazon Bedrock LLM provider - * with the mcp-chat backend plugin. - * - * @public - */ -export default createBackendModule({ - pluginId: 'mcp-chat', - moduleId: 'amazon-bedrock', - register(reg) { - reg.registerInit({ - deps: { - config: coreServices.rootConfig, - llmProviders: llmProviderExtensionPoint, - }, - async init({ config, llmProviders }) { - const providers = - config.getOptionalConfigArray('mcpChat.providers') || []; - const entry = providers.find( - p => p.getString('id') === 'amazon-bedrock', - ); - - if (!entry) return; // Skip registration if not configured - - const auth = readAuthRecord(entry); - const region = auth?.region || 'us-east-1'; - - const credsManager = DefaultAwsCredentialsManager.fromConfig(config); - const credProvider = await credsManager.getCredentialProvider({ - accountId: auth?.accountId, - }); - - const providerConfig = { - type: 'amazon-bedrock', - apiKey: entry.getOptionalString('token'), - baseUrl: entry.getOptionalString('baseUrl') || '', - model: entry.getString('model'), - auth, - }; - - llmProviders.registerProvider( - 'amazon-bedrock', - new BedrockProvider(providerConfig, { - region, - credentialProvider: credProvider.sdkCredentialProvider, - }), - ); - }, - }); - }, -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.json deleted file mode 100644 index 6364965a1a3..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-amazon-bedrock/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@backstage/cli/config/tsconfig.json", - "include": ["src"], - "exclude": ["node_modules"], - "compilerOptions": { - "outDir": "dist", - "rootDir": "src" - } -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/.eslintrc.js deleted file mode 100644 index e2a53a6ad28..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/README.md deleted file mode 100644 index a79b0a7ed34..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# @backstage-community/plugin-mcp-chat-backend-module-anthropic - -The anthropic backend module for the mcp-chat plugin. - -_This plugin was created through the Backstage CLI_ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/config.d.ts deleted file mode 100644 index 65d61e8b043..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/config.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface Config { - /** Configuration options for the MCP Chat plugin */ - mcpChat?: { - /** - * AI/LLM providers configuration - * @visibility backend - */ - providers?: Array<{ - /** - * Unique identifier for the provider - * @visibility backend - */ - id: string; - /** - * API token for the provider - * @visibility secret - */ - token?: string; - /** - * Model name to use for this provider - * @visibility backend - */ - model: string; - /** - * Base URL for the provider's API - * @visibility backend - */ - baseUrl?: string; - /** - * Provider-specific authentication parameters (IAM, session tokens, etc.) - * @visibility secret - */ - auth?: { [key: string]: string }; - }>; - }; -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/knip-report.md deleted file mode 100644 index 2661c353270..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/package.json deleted file mode 100644 index ab02cc2e276..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/package.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "@backstage-community/plugin-mcp-chat-backend-module-anthropic", - "version": "0.1.0", - "license": "Apache-2.0", - "main": "src/index.ts", - "types": "src/index.ts", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin-module", - "pluginId": "mcp-chat", - "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", - "pluginPackages": [ - "@backstage-community/plugin-mcp-chat-backend-module-anthropic", - "@backstage-community/plugin-mcp-chat-backend" - ] - }, - "dependencies": { - "@backstage-community/plugin-mcp-chat-common": "workspace:^", - "@backstage-community/plugin-mcp-chat-node": "workspace:^", - "@backstage/backend-plugin-api": "^1.4.0", - "@backstage/config": "^1.3.0" - }, - "devDependencies": { - "@backstage/cli": "^0.33.0" - }, - "scripts": { - "start": "backstage-cli package start", - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/backstage/community-plugins", - "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic" - }, - "keywords": [ - "backstage", - "backstage-plugin", - "backstage-backend-module", - "anthropic", - "claude", - "llm", - "mcp", - "mcp-chat" - ], - "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic", - "bugs": "https://github.com/backstage/community-plugins/issues" -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/report.api.md deleted file mode 100644 index 63b634eaf3d..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/report.api.md +++ /dev/null @@ -1,33 +0,0 @@ -## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-anthropic" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; -import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; -import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; -import { Tool } from '@backstage-community/plugin-mcp-chat-common'; - -// @public -export class ClaudeProvider extends LLMProvider { - // (undocumented) - protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; - // (undocumented) - protected getHeaders(): Record; - // (undocumented) - protected parseResponse(response: any): ChatResponse; - // (undocumented) - sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; - // (undocumented) - testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; -} - -// @public -const _default: BackendFeature; -export default _default; -``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.test.ts deleted file mode 100644 index 0a4d84c3a83..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.test.ts +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { ClaudeProvider } from './ClaudeProvider'; -import type { - ChatMessage, - Tool, - ProviderConfig, -} from '@backstage-community/plugin-mcp-chat-common'; - -// Mock global.fetch for makeRequest and testConnection -const mockFetch = jest.fn() as jest.Mock; -global.fetch = mockFetch; - -function createProvider( - configOverrides?: Partial, -): ClaudeProvider { - const config: ProviderConfig = { - type: 'anthropic', - baseUrl: 'https://api.anthropic.com/v1', - model: 'claude-sonnet-4-20250514', - apiKey: 'test-api-key', - ...configOverrides, - }; - return new ClaudeProvider(config); -} - -const sampleTool: Tool = { - type: 'function', - function: { - name: 'get_weather', - description: 'Get the weather', - parameters: { type: 'object', properties: { city: { type: 'string' } } }, - }, -}; - -describe('ClaudeProvider', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('sends a basic user message and returns parsed response', async () => { - const provider = createProvider(); - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ - content: [{ type: 'text', text: 'Hello there!' }], - usage: { input_tokens: 10, output_tokens: 5 }, - }), - }); - - const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; - const result = await provider.sendMessage(messages); - - expect(result.choices[0].message.role).toBe('assistant'); - expect(result.choices[0].message.content).toBe('Hello there!'); - expect(result.usage).toEqual({ - prompt_tokens: 10, - completion_tokens: 5, - total_tokens: 15, - }); - }); - - it('filters system messages from the array sent to the API', async () => { - const provider = createProvider(); - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ - content: [{ type: 'text', text: 'OK' }], - }), - }); - - const messages: ChatMessage[] = [ - { role: 'system', content: 'You are helpful.' }, - { role: 'user', content: 'Hi' }, - ]; - await provider.sendMessage(messages); - - const fetchCall = mockFetch.mock.calls[0]; - const body = JSON.parse(fetchCall[1].body); - expect(body.messages.every((m: any) => m.role !== 'system')).toBe(true); - expect(body.messages).toHaveLength(1); - expect(body.messages[0]).toEqual({ role: 'user', content: 'Hi' }); - }); - - it('parses tool_use blocks into ToolCall objects', async () => { - const provider = createProvider(); - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ - content: [ - { - type: 'tool_use', - id: 'call_123', - name: 'get_weather', - input: { city: 'Seattle' }, - }, - ], - }), - }); - - const result = await provider.sendMessage( - [{ role: 'user', content: 'Weather in Seattle?' }], - [sampleTool], - ); - - expect(result.choices[0].message.tool_calls).toHaveLength(1); - expect(result.choices[0].message.tool_calls![0]).toEqual({ - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"Seattle"}', - }, - }); - }); - - it('converts tool messages to user format with Tool result prefix and includes assistant tool_calls in history', async () => { - const provider = createProvider(); - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ - content: [{ type: 'text', text: 'It is sunny in NYC.' }], - }), - }); - - const messages: ChatMessage[] = [ - { role: 'user', content: 'Weather?' }, - { - role: 'assistant', - content: null, - tool_calls: [ - { - id: 'call_1', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"NYC"}', - }, - }, - ], - }, - { role: 'tool', content: 'Sunny, 75°F', tool_call_id: 'call_1' }, - ]; - await provider.sendMessage(messages); - - const fetchCall = mockFetch.mock.calls[0]; - const body = JSON.parse(fetchCall[1].body); - - // Tool message converted to user with "Tool result:" prefix - const toolMsg = body.messages.find( - (m: any) => - m.role === 'user' && - typeof m.content === 'string' && - m.content.startsWith('Tool result:'), - ); - expect(toolMsg).toBeDefined(); - expect(toolMsg.content).toBe('Tool result: Sunny, 75°F'); - - // Assistant message is included in history - const assistantMsg = body.messages.find((m: any) => m.role === 'assistant'); - expect(assistantMsg).toBeDefined(); - }); - - it('returns error on failed testConnection', async () => { - const provider = createProvider(); - mockFetch.mockRejectedValueOnce(new Error('Network error')); - - const result = await provider.testConnection(); - - expect(result.connected).toBe(false); - expect(result.error).toBe('Network error'); - }); -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/index.ts deleted file mode 100644 index 5fe4a572a7c..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Backend module for the mcp-chat plugin that provides the Anthropic Claude LLM provider. - * - * @packageDocumentation - */ - -export { default } from './module'; -export { ClaudeProvider } from './ClaudeProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/module.ts deleted file mode 100644 index afa4cd025f3..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/module.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - createBackendModule, - coreServices, -} from '@backstage/backend-plugin-api'; -import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; -import type { Config } from '@backstage/config'; -import { ClaudeProvider } from './ClaudeProvider'; - -/** - * Reads the optional `auth` record from a provider config entry. - * @param entry - The config entry to read auth from - * @returns A record of string key-value pairs, or undefined if no auth config - */ -function readAuthRecord(entry: Config): Record | undefined { - const authConfig = entry.getOptionalConfig('auth'); - if (!authConfig) return undefined; - const result: Record = {}; - for (const key of authConfig.keys()) { - result[key] = authConfig.getString(key); - } - return result; -} - -/** - * Backend module that registers the Anthropic Claude LLM provider - * with the mcp-chat backend plugin. - * - * @public - */ -export default createBackendModule({ - pluginId: 'mcp-chat', - moduleId: 'anthropic', - register(reg) { - reg.registerInit({ - deps: { - config: coreServices.rootConfig, - llmProviders: llmProviderExtensionPoint, - }, - async init({ config, llmProviders }) { - const providers = - config.getOptionalConfigArray('mcpChat.providers') || []; - const entry = providers.find(p => p.getString('id') === 'claude'); - - if (!entry) return; // Skip registration if not configured - - const providerConfig = { - type: 'claude', - apiKey: entry.getOptionalString('token'), - baseUrl: - entry.getOptionalString('baseUrl') || - 'https://api.anthropic.com/v1', - model: entry.getString('model'), - auth: readAuthRecord(entry), - }; - - llmProviders.registerProvider( - 'claude', - new ClaudeProvider(providerConfig), - ); - }, - }); - }, -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/tsconfig.json deleted file mode 100644 index 6364965a1a3..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@backstage/cli/config/tsconfig.json", - "include": ["src"], - "exclude": ["node_modules"], - "compilerOptions": { - "outDir": "dist", - "rootDir": "src" - } -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/.eslintrc.js deleted file mode 100644 index e2a53a6ad28..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/README.md deleted file mode 100644 index 54e5bc73a45..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# @backstage-community/plugin-mcp-chat-backend-module-gemini - -The gemini backend module for the mcp-chat plugin. - -_This plugin was created through the Backstage CLI_ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/config.d.ts deleted file mode 100644 index 65d61e8b043..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/config.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface Config { - /** Configuration options for the MCP Chat plugin */ - mcpChat?: { - /** - * AI/LLM providers configuration - * @visibility backend - */ - providers?: Array<{ - /** - * Unique identifier for the provider - * @visibility backend - */ - id: string; - /** - * API token for the provider - * @visibility secret - */ - token?: string; - /** - * Model name to use for this provider - * @visibility backend - */ - model: string; - /** - * Base URL for the provider's API - * @visibility backend - */ - baseUrl?: string; - /** - * Provider-specific authentication parameters (IAM, session tokens, etc.) - * @visibility secret - */ - auth?: { [key: string]: string }; - }>; - }; -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/knip-report.md deleted file mode 100644 index 2661c353270..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/package.json deleted file mode 100644 index fa503ddb8d7..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/package.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "name": "@backstage-community/plugin-mcp-chat-backend-module-gemini", - "version": "0.1.0", - "license": "Apache-2.0", - "main": "src/index.ts", - "types": "src/index.ts", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin-module", - "pluginId": "mcp-chat", - "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", - "pluginPackages": [ - "@backstage-community/plugin-mcp-chat-backend-module-gemini", - "@backstage-community/plugin-mcp-chat-backend" - ] - }, - "dependencies": { - "@backstage-community/plugin-mcp-chat-common": "workspace:^", - "@backstage-community/plugin-mcp-chat-node": "workspace:^", - "@backstage/backend-plugin-api": "^1.4.0", - "@backstage/config": "^1.3.0", - "@google/genai": "^1.41.0" - }, - "devDependencies": { - "@backstage/cli": "^0.33.0" - }, - "scripts": { - "start": "backstage-cli package start", - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/backstage/community-plugins", - "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini" - }, - "keywords": [ - "backstage", - "backstage-plugin", - "backstage-backend-module", - "gemini", - "google", - "llm", - "mcp", - "mcp-chat" - ], - "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini", - "bugs": "https://github.com/backstage/community-plugins/issues" -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/report.api.md deleted file mode 100644 index d72a8acab0d..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/report.api.md +++ /dev/null @@ -1,36 +0,0 @@ -## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-gemini" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; -import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; -import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; -import { GenerateContentResult } from '@google/generative-ai'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; -import { ProviderConfig } from '@backstage-community/plugin-mcp-chat-common'; -import { Tool } from '@backstage-community/plugin-mcp-chat-common'; - -// @public -const _default: BackendFeature; -export default _default; - -// @public -export class GeminiProvider extends LLMProvider { - constructor(config: ProviderConfig); - // (undocumented) - protected formatRequest(_messages: ChatMessage[], _tools?: Tool[]): any; - // (undocumented) - protected getHeaders(): Record; - // (undocumented) - protected parseResponse(result: GenerateContentResult): ChatResponse; - // (undocumented) - sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; - // (undocumented) - testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; -} -``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/index.ts deleted file mode 100644 index a3738a61591..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Backend module for the mcp-chat plugin that provides the Google Gemini LLM provider. - * - * @packageDocumentation - */ - -export { default } from './module'; -export { GeminiProvider } from './GeminiProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/module.ts deleted file mode 100644 index 340e43c240f..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/module.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - createBackendModule, - coreServices, -} from '@backstage/backend-plugin-api'; -import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; -import type { Config } from '@backstage/config'; -import { GeminiProvider } from './GeminiProvider'; - -/** - * Reads the optional `auth` record from a provider config entry. - * @param entry - The config entry to read auth from - * @returns A record of string key-value pairs, or undefined if no auth config - */ -function readAuthRecord(entry: Config): Record | undefined { - const authConfig = entry.getOptionalConfig('auth'); - if (!authConfig) return undefined; - const result: Record = {}; - for (const key of authConfig.keys()) { - result[key] = authConfig.getString(key); - } - return result; -} - -/** - * Backend module that registers the Google Gemini LLM provider - * with the mcp-chat backend plugin. - * - * @public - */ -export default createBackendModule({ - pluginId: 'mcp-chat', - moduleId: 'gemini', - register(reg) { - reg.registerInit({ - deps: { - config: coreServices.rootConfig, - llmProviders: llmProviderExtensionPoint, - }, - async init({ config, llmProviders }) { - const providers = - config.getOptionalConfigArray('mcpChat.providers') || []; - const entry = providers.find(p => p.getString('id') === 'gemini'); - - if (!entry) return; // Skip registration if not configured - - const providerConfig = { - type: 'gemini', - apiKey: entry.getOptionalString('token'), - baseUrl: - entry.getOptionalString('baseUrl') || - 'https://generativelanguage.googleapis.com', - model: entry.getString('model'), - auth: readAuthRecord(entry), - }; - - llmProviders.registerProvider( - 'gemini', - new GeminiProvider(providerConfig), - ); - }, - }); - }, -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/tsconfig.json deleted file mode 100644 index 6364965a1a3..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@backstage/cli/config/tsconfig.json", - "include": ["src"], - "exclude": ["node_modules"], - "compilerOptions": { - "outDir": "dist", - "rootDir": "src" - } -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/.eslintrc.js deleted file mode 100644 index e2a53a6ad28..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/README.md deleted file mode 100644 index 58a4f313c5d..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# @backstage-community/plugin-mcp-chat-backend-module-litellm - -The litellm backend module for the mcp-chat plugin. - -_This plugin was created through the Backstage CLI_ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/config.d.ts deleted file mode 100644 index 65d61e8b043..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/config.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface Config { - /** Configuration options for the MCP Chat plugin */ - mcpChat?: { - /** - * AI/LLM providers configuration - * @visibility backend - */ - providers?: Array<{ - /** - * Unique identifier for the provider - * @visibility backend - */ - id: string; - /** - * API token for the provider - * @visibility secret - */ - token?: string; - /** - * Model name to use for this provider - * @visibility backend - */ - model: string; - /** - * Base URL for the provider's API - * @visibility backend - */ - baseUrl?: string; - /** - * Provider-specific authentication parameters (IAM, session tokens, etc.) - * @visibility secret - */ - auth?: { [key: string]: string }; - }>; - }; -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/knip-report.md deleted file mode 100644 index 2661c353270..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/package.json deleted file mode 100644 index b5648c581d5..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/package.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "@backstage-community/plugin-mcp-chat-backend-module-litellm", - "version": "0.1.0", - "license": "Apache-2.0", - "main": "src/index.ts", - "types": "src/index.ts", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin-module", - "pluginId": "mcp-chat", - "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", - "pluginPackages": [ - "@backstage-community/plugin-mcp-chat-backend-module-litellm", - "@backstage-community/plugin-mcp-chat-backend" - ] - }, - "dependencies": { - "@backstage-community/plugin-mcp-chat-common": "workspace:^", - "@backstage-community/plugin-mcp-chat-node": "workspace:^", - "@backstage/backend-plugin-api": "^1.4.0", - "@backstage/config": "^1.3.0" - }, - "devDependencies": { - "@backstage/cli": "^0.33.0" - }, - "scripts": { - "start": "backstage-cli package start", - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/backstage/community-plugins", - "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm" - }, - "keywords": [ - "backstage", - "backstage-plugin", - "backstage-backend-module", - "litellm", - "llm", - "mcp", - "mcp-chat" - ], - "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm", - "bugs": "https://github.com/backstage/community-plugins/issues" -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/report.api.md deleted file mode 100644 index 7c09a3b7ef9..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/report.api.md +++ /dev/null @@ -1,33 +0,0 @@ -## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-litellm" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; -import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; -import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; -import { Tool } from '@backstage-community/plugin-mcp-chat-common'; - -// @public -const _default: BackendFeature; -export default _default; - -// @public -export class LiteLLMProvider extends LLMProvider { - // (undocumented) - protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; - // (undocumented) - protected getHeaders(): Record; - // (undocumented) - protected parseResponse(response: any): ChatResponse; - // (undocumented) - sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; - // (undocumented) - testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; -} -``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.test.ts deleted file mode 100644 index a2e239210e9..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.test.ts +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { LiteLLMProvider } from './LiteLLMProvider'; -import type { - ChatMessage, - Tool, - ProviderConfig, -} from '@backstage-community/plugin-mcp-chat-common'; - -// Mock global.fetch for makeRequest and testConnection -const mockFetch = jest.fn() as jest.Mock; -global.fetch = mockFetch; - -function createProvider( - configOverrides?: Partial, -): LiteLLMProvider { - const config: ProviderConfig = { - type: 'litellm', - baseUrl: 'http://localhost:4000', - model: 'gpt-4o', - apiKey: 'test-api-key', - ...configOverrides, - }; - return new LiteLLMProvider(config); -} - -const sampleTool: Tool = { - type: 'function', - function: { - name: 'get_weather', - description: 'Get the weather', - parameters: { type: 'object', properties: { city: { type: 'string' } } }, - }, -}; - -describe('LiteLLMProvider', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('sends a basic user message and returns the response as-is (passthrough)', async () => { - const provider = createProvider(); - const apiResponse = { - choices: [ - { - message: { - role: 'assistant', - content: 'Hello there!', - }, - }, - ], - usage: { - prompt_tokens: 10, - completion_tokens: 5, - total_tokens: 15, - }, - }; - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => apiResponse, - }); - - const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; - const result = await provider.sendMessage(messages); - - expect(result.choices[0].message.role).toBe('assistant'); - expect(result.choices[0].message.content).toBe('Hello there!'); - expect(result.usage).toEqual({ - prompt_tokens: 10, - completion_tokens: 5, - total_tokens: 15, - }); - }); - - it('includes system messages as-is in the formatted request', async () => { - const provider = createProvider(); - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ - choices: [{ message: { role: 'assistant', content: 'OK' } }], - }), - }); - - const messages: ChatMessage[] = [ - { role: 'system', content: 'You are helpful.' }, - { role: 'user', content: 'Hi' }, - ]; - await provider.sendMessage(messages); - - const fetchCall = mockFetch.mock.calls[0]; - const body = JSON.parse(fetchCall[1].body); - expect(body.messages).toHaveLength(2); - expect(body.messages[0]).toEqual({ - role: 'system', - content: 'You are helpful.', - }); - expect(body.messages[1]).toEqual({ role: 'user', content: 'Hi' }); - }); - - it('returns native tool_calls directly and includes parallel_tool_calls in the request', async () => { - const provider = createProvider(); - const apiResponse = { - choices: [ - { - message: { - role: 'assistant', - content: null, - tool_calls: [ - { - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"Seattle"}', - }, - }, - ], - }, - }, - ], - }; - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => apiResponse, - }); - - const result = await provider.sendMessage( - [{ role: 'user', content: 'Weather in Seattle?' }], - [sampleTool], - ); - - // Verify tool_calls are returned directly - expect(result.choices[0].message.tool_calls).toHaveLength(1); - expect(result.choices[0].message.tool_calls![0]).toEqual({ - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"Seattle"}', - }, - }); - - // Verify parallel_tool_calls: true is in the request - const fetchCall = mockFetch.mock.calls[0]; - const body = JSON.parse(fetchCall[1].body); - expect(body.parallel_tool_calls).toBe(true); - }); - - it('passes tool messages with tool_call_id as-is in the request', async () => { - const provider = createProvider(); - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ - choices: [ - { - message: { role: 'assistant', content: 'It is sunny in NYC.' }, - }, - ], - }), - }); - - const messages: ChatMessage[] = [ - { role: 'user', content: 'Weather?' }, - { - role: 'assistant', - content: null, - tool_calls: [ - { - id: 'call_1', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"NYC"}', - }, - }, - ], - }, - { role: 'tool', content: 'Sunny, 75°F', tool_call_id: 'call_1' }, - ]; - await provider.sendMessage(messages); - - const fetchCall = mockFetch.mock.calls[0]; - const body = JSON.parse(fetchCall[1].body); - - // Tool message passed as-is with tool_call_id - const toolMsg = body.messages.find((m: any) => m.role === 'tool'); - expect(toolMsg).toBeDefined(); - expect(toolMsg.content).toBe('Sunny, 75°F'); - expect(toolMsg.tool_call_id).toBe('call_1'); - - // Assistant message with tool_calls is included in history - const assistantMsg = body.messages.find((m: any) => m.role === 'assistant'); - expect(assistantMsg).toBeDefined(); - expect(assistantMsg.tool_calls).toHaveLength(1); - }); - - it('returns error on failed testConnection when both /models and /health fail', async () => { - const provider = createProvider(); - // First call to /models fails - mockFetch.mockRejectedValueOnce(new Error('Network error')); - // Fallback call to /health also fails - mockFetch.mockRejectedValueOnce(new Error('Network error')); - - const result = await provider.testConnection(); - - expect(result.connected).toBe(false); - expect(result.error).toBe('Network error'); - }); -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/index.ts deleted file mode 100644 index 8dcd10d0b90..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Backend module for the mcp-chat plugin that provides the LiteLLM provider. - * - * @packageDocumentation - */ - -export { default } from './module'; -export { LiteLLMProvider } from './LiteLLMProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/module.ts deleted file mode 100644 index 9f49588137a..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/module.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - createBackendModule, - coreServices, -} from '@backstage/backend-plugin-api'; -import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; -import type { Config } from '@backstage/config'; -import { LiteLLMProvider } from './LiteLLMProvider'; - -/** - * Reads the optional `auth` record from a provider config entry. - * @param entry - The config entry to read auth from - * @returns A record of string key-value pairs, or undefined if no auth config - */ -function readAuthRecord(entry: Config): Record | undefined { - const authConfig = entry.getOptionalConfig('auth'); - if (!authConfig) return undefined; - const result: Record = {}; - for (const key of authConfig.keys()) { - result[key] = authConfig.getString(key); - } - return result; -} - -/** - * Backend module that registers the LiteLLM provider - * with the mcp-chat backend plugin. - * - * @public - */ -export default createBackendModule({ - pluginId: 'mcp-chat', - moduleId: 'litellm', - register(reg) { - reg.registerInit({ - deps: { - config: coreServices.rootConfig, - llmProviders: llmProviderExtensionPoint, - }, - async init({ config, llmProviders }) { - const providers = - config.getOptionalConfigArray('mcpChat.providers') || []; - const entry = providers.find(p => p.getString('id') === 'litellm'); - - if (!entry) return; // Skip registration if not configured - - const providerConfig = { - type: 'litellm', - apiKey: entry.getOptionalString('token'), - baseUrl: - entry.getOptionalString('baseUrl') || 'http://localhost:4000', - model: entry.getString('model'), - auth: readAuthRecord(entry), - }; - - llmProviders.registerProvider( - 'litellm', - new LiteLLMProvider(providerConfig), - ); - }, - }); - }, -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/tsconfig.json deleted file mode 100644 index 6364965a1a3..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@backstage/cli/config/tsconfig.json", - "include": ["src"], - "exclude": ["node_modules"], - "compilerOptions": { - "outDir": "dist", - "rootDir": "src" - } -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/.eslintrc.js deleted file mode 100644 index e2a53a6ad28..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/README.md deleted file mode 100644 index df5b1e958d7..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# @backstage-community/plugin-mcp-chat-backend-module-ollama - -The ollama backend module for the mcp-chat plugin. - -_This plugin was created through the Backstage CLI_ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/config.d.ts deleted file mode 100644 index 65d61e8b043..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/config.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface Config { - /** Configuration options for the MCP Chat plugin */ - mcpChat?: { - /** - * AI/LLM providers configuration - * @visibility backend - */ - providers?: Array<{ - /** - * Unique identifier for the provider - * @visibility backend - */ - id: string; - /** - * API token for the provider - * @visibility secret - */ - token?: string; - /** - * Model name to use for this provider - * @visibility backend - */ - model: string; - /** - * Base URL for the provider's API - * @visibility backend - */ - baseUrl?: string; - /** - * Provider-specific authentication parameters (IAM, session tokens, etc.) - * @visibility secret - */ - auth?: { [key: string]: string }; - }>; - }; -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/knip-report.md deleted file mode 100644 index 2661c353270..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/package.json deleted file mode 100644 index 4d3e62e88f4..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/package.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "@backstage-community/plugin-mcp-chat-backend-module-ollama", - "version": "0.1.0", - "license": "Apache-2.0", - "main": "src/index.ts", - "types": "src/index.ts", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin-module", - "pluginId": "mcp-chat", - "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", - "pluginPackages": [ - "@backstage-community/plugin-mcp-chat-backend-module-ollama", - "@backstage-community/plugin-mcp-chat-backend" - ] - }, - "dependencies": { - "@backstage-community/plugin-mcp-chat-common": "workspace:^", - "@backstage-community/plugin-mcp-chat-node": "workspace:^", - "@backstage/backend-plugin-api": "^1.4.0", - "@backstage/config": "^1.3.0", - "ollama": "^0.6.0" - }, - "devDependencies": { - "@backstage/cli": "^0.33.0" - }, - "scripts": { - "start": "backstage-cli package start", - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/backstage/community-plugins", - "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama" - }, - "keywords": [ - "backstage", - "backstage-plugin", - "backstage-backend-module", - "ollama", - "llm", - "mcp", - "mcp-chat" - ], - "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama", - "bugs": "https://github.com/backstage/community-plugins/issues" -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/report.api.md deleted file mode 100644 index c395304b52b..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/report.api.md +++ /dev/null @@ -1,35 +0,0 @@ -## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-ollama" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; -import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; -import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; -import { ProviderConfig } from '@backstage-community/plugin-mcp-chat-common'; -import { Tool } from '@backstage-community/plugin-mcp-chat-common'; - -// @public -const _default: BackendFeature; -export default _default; - -// @public -export class OllamaProvider extends LLMProvider { - constructor(config: ProviderConfig); - // (undocumented) - protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; - // (undocumented) - protected getHeaders(): Record; - // (undocumented) - protected parseResponse(response: any): ChatResponse; - // (undocumented) - sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; - // (undocumented) - testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; -} -``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.test.ts deleted file mode 100644 index c7e6b078de1..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.test.ts +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { OllamaProvider } from './OllamaProvider'; -import type { - ChatMessage, - Tool, - ProviderConfig, -} from '@backstage-community/plugin-mcp-chat-common'; - -// Mock the ollama SDK module -const mockChat = jest.fn(); -const mockList = jest.fn(); -jest.mock('ollama', () => ({ - Ollama: jest.fn().mockImplementation(() => ({ - chat: mockChat, - list: mockList, - })), -})); - -function createProvider( - configOverrides?: Partial, -): OllamaProvider { - const config: ProviderConfig = { - type: 'ollama', - baseUrl: 'http://localhost:11434/v1', - model: 'llama3', - ...configOverrides, - }; - return new OllamaProvider(config); -} - -const sampleTool: Tool = { - type: 'function', - function: { - name: 'get_weather', - description: 'Get the weather', - parameters: { type: 'object', properties: { city: { type: 'string' } } }, - }, -}; - -describe('OllamaProvider', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('sends a basic user message and returns parsed response', async () => { - const provider = createProvider(); - mockChat.mockResolvedValueOnce({ - message: { role: 'assistant', content: 'Hello there!' }, - prompt_eval_count: 10, - eval_count: 5, - }); - - const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; - const result = await provider.sendMessage(messages); - - expect(result.choices[0].message.role).toBe('assistant'); - expect(result.choices[0].message.content).toBe('Hello there!'); - expect(result.usage).toEqual({ - prompt_tokens: 10, - completion_tokens: 5, - total_tokens: 15, - }); - }); - - it('passes system messages as-is to the SDK in the messages array', async () => { - const provider = createProvider(); - mockChat.mockResolvedValueOnce({ - message: { role: 'assistant', content: 'OK' }, - }); - - const messages: ChatMessage[] = [ - { role: 'system', content: 'You are helpful.' }, - { role: 'user', content: 'Hi' }, - ]; - await provider.sendMessage(messages); - - const chatCall = mockChat.mock.calls[0][0]; - expect(chatCall.messages).toHaveLength(2); - expect(chatCall.messages[0]).toEqual( - expect.objectContaining({ role: 'system', content: 'You are helpful.' }), - ); - expect(chatCall.messages[1]).toEqual( - expect.objectContaining({ role: 'user', content: 'Hi' }), - ); - }); - - it('parses tool_calls with object arguments serialized to JSON string and assigns id', async () => { - const provider = createProvider(); - mockChat.mockResolvedValueOnce({ - message: { - role: 'assistant', - content: '', - tool_calls: [ - { - function: { - name: 'get_weather', - arguments: { city: 'Seattle' }, - }, - }, - ], - }, - }); - - const result = await provider.sendMessage( - [{ role: 'user', content: 'Weather in Seattle?' }], - [sampleTool], - ); - - expect(result.choices[0].message.tool_calls).toHaveLength(1); - expect(result.choices[0].message.tool_calls![0]).toEqual({ - id: 'call_0', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"Seattle"}', - }, - }); - }); - - it('handles tool messages round-trip with tool_call_id and parses follow-up response', async () => { - const provider = createProvider(); - mockChat.mockResolvedValueOnce({ - message: { role: 'assistant', content: 'It is sunny in NYC.' }, - }); - - const messages: ChatMessage[] = [ - { role: 'user', content: 'Weather?' }, - { - role: 'assistant', - content: null, - tool_calls: [ - { - id: 'call_1', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"NYC"}', - }, - }, - ], - }, - { role: 'tool', content: 'Sunny, 75°F', tool_call_id: 'call_1' }, - ]; - const result = await provider.sendMessage(messages); - - const chatCall = mockChat.mock.calls[0][0]; - - // Tool message with tool_call_id is passed to the SDK - const toolMsg = chatCall.messages.find((m: any) => m.role === 'tool'); - expect(toolMsg).toBeDefined(); - expect(toolMsg.tool_call_id).toBe('call_1'); - expect(toolMsg.content).toBe('Sunny, 75°F'); - - // Assistant message with tool_calls is included in history - const assistantMsg = chatCall.messages.find( - (m: any) => m.role === 'assistant', - ); - expect(assistantMsg).toBeDefined(); - expect(assistantMsg.tool_calls).toBeDefined(); - expect(assistantMsg.tool_calls[0].function.name).toBe('get_weather'); - // Arguments are deserialized back to object for Ollama SDK - expect(assistantMsg.tool_calls[0].function.arguments).toEqual({ - city: 'NYC', - }); - - // Follow-up response is parsed correctly - expect(result.choices[0].message.role).toBe('assistant'); - expect(result.choices[0].message.content).toBe('It is sunny in NYC.'); - }); - - it('returns error on failed testConnection', async () => { - const provider = createProvider(); - mockList.mockRejectedValueOnce(new Error('Connection refused')); - - const result = await provider.testConnection(); - - expect(result.connected).toBe(false); - expect(result.error).toBe('Connection refused'); - }); -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/index.ts deleted file mode 100644 index b55c8ad4d4a..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Backend module for the mcp-chat plugin that provides the Ollama LLM provider. - * - * @packageDocumentation - */ - -export { default } from './module'; -export { OllamaProvider } from './OllamaProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/module.ts deleted file mode 100644 index 4bb8ea5b99e..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/module.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - createBackendModule, - coreServices, -} from '@backstage/backend-plugin-api'; -import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; -import type { Config } from '@backstage/config'; -import { OllamaProvider } from './OllamaProvider'; - -/** - * Reads the optional `auth` record from a provider config entry. - * @param entry - The config entry to read auth from - * @returns A record of string key-value pairs, or undefined if no auth config - */ -function readAuthRecord(entry: Config): Record | undefined { - const authConfig = entry.getOptionalConfig('auth'); - if (!authConfig) return undefined; - const result: Record = {}; - for (const key of authConfig.keys()) { - result[key] = authConfig.getString(key); - } - return result; -} - -/** - * Backend module that registers the Ollama LLM provider - * with the mcp-chat backend plugin. - * - * @public - */ -export default createBackendModule({ - pluginId: 'mcp-chat', - moduleId: 'ollama', - register(reg) { - reg.registerInit({ - deps: { - config: coreServices.rootConfig, - llmProviders: llmProviderExtensionPoint, - }, - async init({ config, llmProviders }) { - const providers = - config.getOptionalConfigArray('mcpChat.providers') || []; - const entry = providers.find(p => p.getString('id') === 'ollama'); - - if (!entry) return; // Skip registration if not configured - - const providerConfig = { - type: 'ollama', - apiKey: entry.getOptionalString('token'), - baseUrl: - entry.getOptionalString('baseUrl') || 'http://localhost:11434', - model: entry.getString('model'), - auth: readAuthRecord(entry), - }; - - llmProviders.registerProvider( - 'ollama', - new OllamaProvider(providerConfig), - ); - }, - }); - }, -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/tsconfig.json deleted file mode 100644 index 6364965a1a3..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@backstage/cli/config/tsconfig.json", - "include": ["src"], - "exclude": ["node_modules"], - "compilerOptions": { - "outDir": "dist", - "rootDir": "src" - } -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/.eslintrc.js deleted file mode 100644 index e2a53a6ad28..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/README.md deleted file mode 100644 index 03c3159b7a5..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# @backstage-community/plugin-mcp-chat-backend-module-openai-responses - -The openai-responses backend module for the mcp-chat plugin. - -_This plugin was created through the Backstage CLI_ - -## Reponses API - -`openai-responses` backend module uses the newer Responses API (`/v1/responses`) which supports native MCP. -OpenAI's servers connect directly to MCP servers and execute tool calls themselves diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/config.d.ts deleted file mode 100644 index 65d61e8b043..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/config.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface Config { - /** Configuration options for the MCP Chat plugin */ - mcpChat?: { - /** - * AI/LLM providers configuration - * @visibility backend - */ - providers?: Array<{ - /** - * Unique identifier for the provider - * @visibility backend - */ - id: string; - /** - * API token for the provider - * @visibility secret - */ - token?: string; - /** - * Model name to use for this provider - * @visibility backend - */ - model: string; - /** - * Base URL for the provider's API - * @visibility backend - */ - baseUrl?: string; - /** - * Provider-specific authentication parameters (IAM, session tokens, etc.) - * @visibility secret - */ - auth?: { [key: string]: string }; - }>; - }; -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/knip-report.md deleted file mode 100644 index 2661c353270..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/package.json deleted file mode 100644 index f6ee577a793..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/package.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "name": "@backstage-community/plugin-mcp-chat-backend-module-openai-responses", - "version": "0.1.0", - "license": "Apache-2.0", - "main": "src/index.ts", - "types": "src/index.ts", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin-module", - "pluginId": "mcp-chat", - "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", - "pluginPackages": [ - "@backstage-community/plugin-mcp-chat-backend-module-openai-responses", - "@backstage-community/plugin-mcp-chat-backend" - ] - }, - "dependencies": { - "@backstage-community/plugin-mcp-chat-common": "workspace:^", - "@backstage-community/plugin-mcp-chat-node": "workspace:^", - "@backstage/backend-plugin-api": "^1.4.0", - "@backstage/config": "^1.3.0" - }, - "devDependencies": { - "@backstage/cli": "^0.33.0" - }, - "scripts": { - "start": "backstage-cli package start", - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/backstage/community-plugins", - "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses" - }, - "keywords": [ - "backstage", - "backstage-plugin", - "backstage-backend-module", - "openai", - "openai-responses", - "llm", - "mcp", - "mcp-chat" - ], - "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses", - "bugs": "https://github.com/backstage/community-plugins/issues" -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/report.api.md deleted file mode 100644 index 1ff5cf06177..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/report.api.md +++ /dev/null @@ -1,40 +0,0 @@ -## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-openai-responses" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; -import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; -import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; -import { MCPServerFullConfig } from '@backstage-community/plugin-mcp-chat-common'; -import { ResponsesApiResponse } from '@backstage-community/plugin-mcp-chat-common'; -import { Tool } from '@backstage-community/plugin-mcp-chat-common'; - -// @public -const _default: BackendFeature; -export default _default; - -// @public -export class OpenAIResponsesProvider extends LLMProvider { - // (undocumented) - protected formatRequest(messages: ChatMessage[], _tools?: Tool[]): any; - // (undocumented) - protected getHeaders(): Record; - getLastResponseOutput(): ResponsesApiResponse['output'] | null; - // (undocumented) - protected makeRequest(endpoint: string, body: any): Promise; - // (undocumented) - protected parseResponse(response: ResponsesApiResponse): ChatResponse; - // (undocumented) - sendMessage(messages: ChatMessage[], _tools?: Tool[]): Promise; - setMcpServerConfigs(configs: MCPServerFullConfig[]): void; - supportsNativeMcp(): boolean; - // (undocumented) - testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; -} -``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.test.ts deleted file mode 100644 index 5795a7912de..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.test.ts +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { OpenAIResponsesProvider } from './OpenAIResponsesProvider'; -import type { - ChatMessage, - Tool, - ProviderConfig, -} from '@backstage-community/plugin-mcp-chat-common'; - -// Mock global.fetch — OpenAIResponsesProvider overrides makeRequest and uses fetch directly -const mockFetch = jest.fn() as jest.Mock; -global.fetch = mockFetch; - -function createProvider( - configOverrides?: Partial, -): OpenAIResponsesProvider { - const config: ProviderConfig = { - type: 'openai-responses', - baseUrl: 'https://api.openai.com/v1', - model: 'gpt-4o', - apiKey: 'test-api-key', - ...configOverrides, - }; - return new OpenAIResponsesProvider(config); -} - -const sampleTool: Tool = { - type: 'function', - function: { - name: 'get_weather', - description: 'Get the weather', - parameters: { type: 'object', properties: { city: { type: 'string' } } }, - }, -}; - -describe('OpenAIResponsesProvider', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('sends a basic user message and returns parsed response with usage', async () => { - const provider = createProvider(); - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ - output: [ - { - type: 'message', - id: 'msg_1', - role: 'assistant', - status: 'completed', - content: [{ type: 'output_text', text: 'Hello there!' }], - }, - ], - usage: { - input_tokens: 10, - output_tokens: 5, - total_tokens: 15, - }, - }), - }); - - const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; - const result = await provider.sendMessage(messages); - - expect(result.choices[0].message.role).toBe('assistant'); - expect(result.choices[0].message.content).toBe('Hello there!'); - expect(result.usage).toEqual({ - prompt_tokens: 10, - completion_tokens: 5, - total_tokens: 15, - }); - }); - - it('places system message content in instructions and last message in input', async () => { - const provider = createProvider(); - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ - output: [ - { - type: 'message', - id: 'msg_1', - role: 'assistant', - status: 'completed', - content: [{ type: 'output_text', text: 'OK' }], - }, - ], - }), - }); - - const messages: ChatMessage[] = [ - { role: 'system', content: 'You are helpful.' }, - { role: 'user', content: 'Hi' }, - ]; - await provider.sendMessage(messages); - - const fetchCall = mockFetch.mock.calls[0]; - const body = JSON.parse(fetchCall[1].body); - expect(body.instructions).toBe('You are helpful.'); - expect(body.input).toBe('Hi'); - }); - - it('parses mcp_call events into ToolCall objects', async () => { - const provider = createProvider(); - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ - output: [ - { - type: 'mcp_call', - id: 'call_123', - name: 'get_weather', - arguments: '{"city":"Seattle"}', - server_label: 'weather-server', - error: null, - output: '{"temp":72}', - }, - ], - }), - }); - - const result = await provider.sendMessage( - [{ role: 'user', content: 'Weather in Seattle?' }], - [sampleTool], - ); - - expect(result.choices[0].message.tool_calls).toHaveLength(1); - expect(result.choices[0].message.tool_calls![0]).toEqual({ - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"Seattle"}', - }, - }); - }); - - it('correctly extracts instructions and input when history contains system + user', async () => { - const provider = createProvider(); - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ - output: [ - { - type: 'message', - id: 'msg_1', - role: 'assistant', - status: 'completed', - content: [{ type: 'output_text', text: 'It is sunny in NYC.' }], - }, - ], - }), - }); - - const messages: ChatMessage[] = [ - { role: 'system', content: 'You are a weather assistant.' }, - { role: 'user', content: 'What is the weather in NYC?' }, - ]; - await provider.sendMessage(messages); - - const fetchCall = mockFetch.mock.calls[0]; - const body = JSON.parse(fetchCall[1].body); - - expect(body.instructions).toBe('You are a weather assistant.'); - expect(body.input).toBe('What is the weather in NYC?'); - expect(body.model).toBe('gpt-4o'); - }); - - it('returns error on failed testConnection', async () => { - const provider = createProvider(); - mockFetch.mockRejectedValueOnce(new Error('Network error')); - - const result = await provider.testConnection(); - - expect(result.connected).toBe(false); - expect(result.error).toBe('Network error'); - }); -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/index.ts deleted file mode 100644 index 926ada24e30..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Backend module for the mcp-chat plugin that provides the OpenAI Responses API LLM provider. - * - * @packageDocumentation - */ - -export { default } from './module'; -export { OpenAIResponsesProvider } from './OpenAIResponsesProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/module.ts deleted file mode 100644 index 2e42b959c8e..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/module.ts +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - createBackendModule, - coreServices, -} from '@backstage/backend-plugin-api'; -import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; -import type { Config } from '@backstage/config'; -import { OpenAIResponsesProvider } from './OpenAIResponsesProvider'; - -/** - * Reads the optional `auth` record from a provider config entry. - * @param entry - The config entry to read auth from - * @returns A record of string key-value pairs, or undefined if no auth config - */ -function readAuthRecord(entry: Config): Record | undefined { - const authConfig = entry.getOptionalConfig('auth'); - if (!authConfig) return undefined; - const result: Record = {}; - for (const key of authConfig.keys()) { - result[key] = authConfig.getString(key); - } - return result; -} - -/** - * Backend module that registers the OpenAI Responses API LLM provider - * with the mcp-chat backend plugin. - * - * @public - */ -export default createBackendModule({ - pluginId: 'mcp-chat', - moduleId: 'openai-responses', - register(reg) { - reg.registerInit({ - deps: { - config: coreServices.rootConfig, - llmProviders: llmProviderExtensionPoint, - }, - async init({ config, llmProviders }) { - const providers = - config.getOptionalConfigArray('mcpChat.providers') || []; - const entry = providers.find( - p => p.getString('id') === 'openai-responses', - ); - - if (!entry) return; // Skip registration if not configured - - const providerConfig = { - type: 'openai-responses', - apiKey: entry.getOptionalString('token'), - baseUrl: - entry.getOptionalString('baseUrl') || 'https://api.openai.com/v1', - model: entry.getString('model'), - auth: readAuthRecord(entry), - }; - - llmProviders.registerProvider( - 'openai-responses', - new OpenAIResponsesProvider(providerConfig), - ); - }, - }); - }, -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/tsconfig.json deleted file mode 100644 index 6364965a1a3..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@backstage/cli/config/tsconfig.json", - "include": ["src"], - "exclude": ["node_modules"], - "compilerOptions": { - "outDir": "dist", - "rootDir": "src" - } -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/.eslintrc.js b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/.eslintrc.js deleted file mode 100644 index e2a53a6ad28..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/.eslintrc.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/README.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/README.md deleted file mode 100644 index dc9e4db89df..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# @backstage-community/plugin-mcp-chat-backend-module-openai - -The openai backend module for the mcp-chat plugin. - -_This plugin was created through the Backstage CLI_ - -## Chat Completions API - -`openai` backend module uses the standard Chat Completions API (`/v1/chat/completions`). -The classic request/response flow where MCP tool calls are handled by the Backstage backend (it receives tool call requests, executes them locally, sends results back). diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/config.d.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/config.d.ts deleted file mode 100644 index 65d61e8b043..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/config.d.ts +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export interface Config { - /** Configuration options for the MCP Chat plugin */ - mcpChat?: { - /** - * AI/LLM providers configuration - * @visibility backend - */ - providers?: Array<{ - /** - * Unique identifier for the provider - * @visibility backend - */ - id: string; - /** - * API token for the provider - * @visibility secret - */ - token?: string; - /** - * Model name to use for this provider - * @visibility backend - */ - model: string; - /** - * Base URL for the provider's API - * @visibility backend - */ - baseUrl?: string; - /** - * Provider-specific authentication parameters (IAM, session tokens, etc.) - * @visibility secret - */ - auth?: { [key: string]: string }; - }>; - }; -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/knip-report.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/knip-report.md deleted file mode 100644 index 2661c353270..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/knip-report.md +++ /dev/null @@ -1,2 +0,0 @@ -# Knip report - diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/package.json deleted file mode 100644 index 12b05dc9fe7..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/package.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "@backstage-community/plugin-mcp-chat-backend-module-openai", - "version": "0.1.0", - "license": "Apache-2.0", - "main": "src/index.ts", - "types": "src/index.ts", - "publishConfig": { - "access": "public", - "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" - }, - "backstage": { - "role": "backend-plugin-module", - "pluginId": "mcp-chat", - "pluginPackage": "@backstage-community/plugin-mcp-chat-backend", - "pluginPackages": [ - "@backstage-community/plugin-mcp-chat-backend-module-openai", - "@backstage-community/plugin-mcp-chat-backend" - ] - }, - "dependencies": { - "@backstage-community/plugin-mcp-chat-common": "workspace:^", - "@backstage-community/plugin-mcp-chat-node": "workspace:^", - "@backstage/backend-plugin-api": "^1.4.0", - "@backstage/config": "^1.3.0" - }, - "devDependencies": { - "@backstage/cli": "^0.33.0" - }, - "scripts": { - "start": "backstage-cli package start", - "build": "backstage-cli package build", - "lint": "backstage-cli package lint", - "test": "backstage-cli package test", - "clean": "backstage-cli package clean", - "prepack": "backstage-cli package prepack", - "postpack": "backstage-cli package postpack" - }, - "files": [ - "dist", - "config.d.ts" - ], - "configSchema": "config.d.ts", - "repository": { - "type": "git", - "url": "https://github.com/backstage/community-plugins", - "directory": "workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai" - }, - "keywords": [ - "backstage", - "backstage-plugin", - "backstage-backend-module", - "openai", - "llm", - "mcp", - "mcp-chat" - ], - "homepage": "https://github.com/backstage/community-plugins/tree/main/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai", - "bugs": "https://github.com/backstage/community-plugins/issues" -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/report.api.md deleted file mode 100644 index 0353c17dec7..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/report.api.md +++ /dev/null @@ -1,33 +0,0 @@ -## API Report File for "@backstage-community/plugin-mcp-chat-backend-module-openai" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts -import { BackendFeature } from '@backstage/backend-plugin-api'; -import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; -import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; -import { Tool } from '@backstage-community/plugin-mcp-chat-common'; - -// @public -const _default: BackendFeature; -export default _default; - -// @public -export class OpenAIProvider extends LLMProvider { - // (undocumented) - protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any; - // (undocumented) - protected getHeaders(): Record; - // (undocumented) - protected parseResponse(response: any): ChatResponse; - // (undocumented) - sendMessage(messages: ChatMessage[], tools?: Tool[]): Promise; - // (undocumented) - testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; -} -``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.test.ts deleted file mode 100644 index ac73bdd56e0..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.test.ts +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { OpenAIProvider } from './OpenAIProvider'; -import type { - ChatMessage, - Tool, - ProviderConfig, -} from '@backstage-community/plugin-mcp-chat-common'; - -// Mock global.fetch for makeRequest and testConnection -const mockFetch = jest.fn() as jest.Mock; -global.fetch = mockFetch; - -function createProvider( - configOverrides?: Partial, -): OpenAIProvider { - const config: ProviderConfig = { - type: 'openai', - baseUrl: 'https://api.openai.com/v1', - model: 'gpt-4o', - apiKey: 'test-api-key', - ...configOverrides, - }; - return new OpenAIProvider(config); -} - -const sampleTool: Tool = { - type: 'function', - function: { - name: 'get_weather', - description: 'Get the weather', - parameters: { type: 'object', properties: { city: { type: 'string' } } }, - }, -}; - -describe('OpenAIProvider', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('sends a basic user message and returns the response as-is (passthrough)', async () => { - const provider = createProvider(); - const apiResponse = { - choices: [ - { - message: { - role: 'assistant', - content: 'Hello there!', - }, - }, - ], - usage: { - prompt_tokens: 10, - completion_tokens: 5, - total_tokens: 15, - }, - }; - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => apiResponse, - }); - - const messages: ChatMessage[] = [{ role: 'user', content: 'Hi' }]; - const result = await provider.sendMessage(messages); - - expect(result.choices[0].message.role).toBe('assistant'); - expect(result.choices[0].message.content).toBe('Hello there!'); - expect(result.usage).toEqual({ - prompt_tokens: 10, - completion_tokens: 5, - total_tokens: 15, - }); - }); - - it('includes system messages as-is in the formatted request', async () => { - const provider = createProvider(); - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ - choices: [{ message: { role: 'assistant', content: 'OK' } }], - }), - }); - - const messages: ChatMessage[] = [ - { role: 'system', content: 'You are helpful.' }, - { role: 'user', content: 'Hi' }, - ]; - await provider.sendMessage(messages); - - const fetchCall = mockFetch.mock.calls[0]; - const body = JSON.parse(fetchCall[1].body); - expect(body.messages).toHaveLength(2); - expect(body.messages[0]).toEqual({ - role: 'system', - content: 'You are helpful.', - }); - expect(body.messages[1]).toEqual({ role: 'user', content: 'Hi' }); - }); - - it('returns native OpenAI tool_calls directly in the response', async () => { - const provider = createProvider(); - const apiResponse = { - choices: [ - { - message: { - role: 'assistant', - content: null, - tool_calls: [ - { - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"Seattle"}', - }, - }, - ], - }, - }, - ], - }; - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => apiResponse, - }); - - const result = await provider.sendMessage( - [{ role: 'user', content: 'Weather in Seattle?' }], - [sampleTool], - ); - - expect(result.choices[0].message.tool_calls).toHaveLength(1); - expect(result.choices[0].message.tool_calls![0]).toEqual({ - id: 'call_123', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"Seattle"}', - }, - }); - }); - - it('passes tool messages with tool_call_id as-is in the request', async () => { - const provider = createProvider(); - mockFetch.mockResolvedValueOnce({ - ok: true, - json: async () => ({ - choices: [ - { - message: { role: 'assistant', content: 'It is sunny in NYC.' }, - }, - ], - }), - }); - - const messages: ChatMessage[] = [ - { role: 'user', content: 'Weather?' }, - { - role: 'assistant', - content: null, - tool_calls: [ - { - id: 'call_1', - type: 'function', - function: { - name: 'get_weather', - arguments: '{"city":"NYC"}', - }, - }, - ], - }, - { role: 'tool', content: 'Sunny, 75°F', tool_call_id: 'call_1' }, - ]; - await provider.sendMessage(messages); - - const fetchCall = mockFetch.mock.calls[0]; - const body = JSON.parse(fetchCall[1].body); - - // Tool message passed as-is with tool_call_id - const toolMsg = body.messages.find((m: any) => m.role === 'tool'); - expect(toolMsg).toBeDefined(); - expect(toolMsg.content).toBe('Sunny, 75°F'); - expect(toolMsg.tool_call_id).toBe('call_1'); - - // Assistant message with tool_calls is included in history - const assistantMsg = body.messages.find((m: any) => m.role === 'assistant'); - expect(assistantMsg).toBeDefined(); - expect(assistantMsg.tool_calls).toHaveLength(1); - }); - - it('returns error on failed testConnection', async () => { - const provider = createProvider(); - mockFetch.mockRejectedValueOnce(new Error('Network error')); - - const result = await provider.testConnection(); - - expect(result.connected).toBe(false); - expect(result.error).toBe('Network error'); - }); -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/index.ts deleted file mode 100644 index 2d75f3a63e9..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Backend module for the mcp-chat plugin that provides the OpenAI LLM provider. - * - * @packageDocumentation - */ - -export { default } from './module'; -export { OpenAIProvider } from './OpenAIProvider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/module.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/module.ts deleted file mode 100644 index 62cbbf9b618..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/module.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { - createBackendModule, - coreServices, -} from '@backstage/backend-plugin-api'; -import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; -import type { Config } from '@backstage/config'; -import { OpenAIProvider } from './OpenAIProvider'; - -/** - * Reads the optional `auth` record from a provider config entry. - * @param entry - The config entry to read auth from - * @returns A record of string key-value pairs, or undefined if no auth config - */ -function readAuthRecord(entry: Config): Record | undefined { - const authConfig = entry.getOptionalConfig('auth'); - if (!authConfig) return undefined; - const result: Record = {}; - for (const key of authConfig.keys()) { - result[key] = authConfig.getString(key); - } - return result; -} - -/** - * Backend module that registers the OpenAI LLM provider - * with the mcp-chat backend plugin. - * - * @public - */ -export default createBackendModule({ - pluginId: 'mcp-chat', - moduleId: 'openai', - register(reg) { - reg.registerInit({ - deps: { - config: coreServices.rootConfig, - llmProviders: llmProviderExtensionPoint, - }, - async init({ config, llmProviders }) { - const providers = - config.getOptionalConfigArray('mcpChat.providers') || []; - const entry = providers.find(p => p.getString('id') === 'openai'); - - if (!entry) return; // Skip registration if not configured - - const providerConfig = { - type: 'openai', - apiKey: entry.getOptionalString('token'), - baseUrl: - entry.getOptionalString('baseUrl') || 'https://api.openai.com/v1', - model: entry.getString('model'), - auth: readAuthRecord(entry), - }; - - llmProviders.registerProvider( - 'openai', - new OpenAIProvider(providerConfig), - ); - }, - }); - }, -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/tsconfig.json b/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/tsconfig.json deleted file mode 100644 index 6364965a1a3..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "@backstage/cli/config/tsconfig.json", - "include": ["src"], - "exclude": ["node_modules"], - "compilerOptions": { - "outDir": "dist", - "rootDir": "src" - } -} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/dev/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/dev/index.ts index 57733100b2f..fb2920444fe 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/dev/index.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/dev/index.ts @@ -41,10 +41,4 @@ backend.add( ); backend.add(import('../src')); -backend.add( - import('@backstage-community/plugin-mcp-chat-backend-module-openai'), -); -backend.add( - import('@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock'), -); backend.start(); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json b/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json index 36225815dba..d03566949ce 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/package.json @@ -30,20 +30,20 @@ "dependencies": { "@backstage-community/plugin-mcp-chat-common": "workspace:^", "@backstage-community/plugin-mcp-chat-node": "workspace:^", - "@backstage/backend-defaults": "^0.11.0", - "@backstage/backend-plugin-api": "^1.4.0", - "@backstage/config": "^1.3.0", + "@backstage/backend-defaults": "^0.16.0", + "@backstage/backend-plugin-api": "^1.8.0", + "@backstage/config": "^1.3.6", "@backstage/errors": "^1.2.7", "@backstage/plugin-catalog-node": "^2.1.0", + "@google/genai": "^1.41.0", "@modelcontextprotocol/sdk": "^1.25.2", "express": "^4.22.0", "express-promise-router": "^4.1.0", "knex": "^3.1.0", + "ollama": "^0.6.0", "uuid": "^11.0.0" }, "devDependencies": { - "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock": "workspace:^", - "@backstage-community/plugin-mcp-chat-backend-module-openai": "workspace:^", "@backstage/backend-test-utils": "^1.6.0", "@backstage/cli": "^0.33.0", "@types/express": "^4.17.6", diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/index.ts index d9e6f696fa1..79660c9f18c 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/index.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/index.ts @@ -27,11 +27,6 @@ export { type LlmProviderExtensionPoint, } from './extensions'; -// ============================================================================= -// LLM Providers -// ============================================================================= -export { LLMProvider } from './providers'; - // ============================================================================= // Services // ============================================================================= diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.test.ts index 9deb69a2cbb..00666f998b6 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.test.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.test.ts @@ -15,11 +15,9 @@ */ import { startTestBackend, mockServices } from '@backstage/backend-test-utils'; import { mcpChatPlugin } from './plugin'; -import { llmProviderExtensionPoint } from './extensions'; import request from 'supertest'; import { TestBackend } from '@backstage/backend-test-utils'; import { MCPServerType } from '@backstage-community/plugin-mcp-chat-common'; -import { createBackendModule } from '@backstage/backend-plugin-api'; jest.mock('./services/MCPClientServiceImpl', () => ({ MCPClientServiceImpl: jest.fn().mockImplementation(() => ({ @@ -113,36 +111,10 @@ describe('mcpChatPlugin', () => { let backend: TestBackend; const { validateMessages } = require('./utils'); - // Create a test module that registers a mock provider via the extension point - const mockProviderModule = createBackendModule({ - pluginId: 'mcp-chat', - moduleId: 'test-openai', - register(reg) { - reg.registerInit({ - deps: { - llmProviders: llmProviderExtensionPoint, - }, - async init({ llmProviders }) { - llmProviders.registerProvider('openai', { - sendMessage: jest.fn(), - testConnection: jest.fn(), - getType: () => 'openai', - getModel: () => 'gpt-4o-mini', - getBaseUrl: () => 'https://api.openai.com/v1', - supportsNativeMcp: () => false, - setMcpServerConfigs: jest.fn(), - getLastResponseOutput: () => null, - } as any); - }, - }); - }, - }); - beforeEach(async () => { backend = await startTestBackend({ features: [ mcpChatPlugin, - mockProviderModule, mockServices.rootConfig.factory({ data: mockConfig, }), diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.ts index 78c5dfa7a8d..46046393bbd 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/plugin.ts @@ -24,8 +24,6 @@ import { SummarizationService, } from './services'; import { validateConfig } from './utils'; -import { llmProviderExtensionPoint } from './extensions'; -import { LLMProvider } from './providers/base-provider'; /** * mcpChatPlugin backend plugin @@ -35,15 +33,6 @@ import { LLMProvider } from './providers/base-provider'; export const mcpChatPlugin = createBackendPlugin({ pluginId: 'mcp-chat', register(env) { - const providers = new Map(); - - env.registerExtensionPoint(llmProviderExtensionPoint, { - registerProvider(type: string, provider: LLMProvider) { - // Last-write-wins on duplicate registration (Req 1.4) - providers.set(type, provider); - }, - }); - env.registerInit({ deps: { logger: coreServices.logger, @@ -55,38 +44,10 @@ export const mcpChatPlugin = createBackendPlugin({ async init({ logger, httpRouter, config, database, httpAuth }) { validateConfig(config); - // Resolve active provider from extension point registry (Req 6.3, 8.2) - const configuredProviders = - config.getOptionalConfigArray('mcpChat.providers') ?? []; - const activeId = configuredProviders[0]?.getString('id'); - - if (!activeId) { - throw new Error('No provider configured in mcpChat.providers[0].id'); - } - - const activeProvider = providers.get(activeId); - if (!activeProvider) { - const available = Array.from(providers.keys()).join(', '); - throw new Error( - `No provider module registered for type '${activeId}'. ` + - `Available registered types: [${available}]. ` + - `Install the corresponding module package.`, - ); - } - - if (providers.size > 0) { - for (const [type] of providers) { - if (type === activeId) { - logger.info(`Active LLM provider: '${type}'`); - } - } - } - - // Inject resolved provider into MCPClientServiceImpl (Req 8.2) + // Initialize core services const mcpClientService = new MCPClientServiceImpl({ logger, config, - provider: activeProvider, }); const conversationStore = await ChatConversationStore.create({ diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/base-provider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/base-provider.test.ts deleted file mode 100644 index 2723332f3ea..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/base-provider.test.ts +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { mockServices } from '@backstage/backend-test-utils'; -import { LLMProvider } from './base-provider'; -import { ChatMessage, Tool, ChatResponse, ProviderConfig } from '../types'; - -global.fetch = jest.fn(); - -class TestProvider extends LLMProvider { - public exposeTruncateForLogging(data: string, maxLength?: number): string { - return this.truncateForLogging(data, maxLength); - } - - public exposeMakeRequest(endpoint: string, body: any): Promise { - return this.makeRequest(endpoint, body); - } - - async sendMessage( - _messages: ChatMessage[], - _tools?: Tool[], - ): Promise { - return { choices: [{ message: { role: 'assistant', content: '' } }] }; - } - - async testConnection() { - return { connected: true }; - } - - protected getHeaders(): Record { - return { 'Content-Type': 'application/json' }; - } - - protected formatRequest(_messages: ChatMessage[], _tools?: Tool[]): any { - return {}; - } - - protected parseResponse(response: any): ChatResponse { - return response; - } -} - -describe('LLMProvider', () => { - const mockLogger = mockServices.logger.mock(); - - const config: ProviderConfig = { - type: 'test-provider', - apiKey: 'test-key', - baseUrl: 'http://localhost:1234', - model: 'test-model', - logger: mockLogger, - }; - - let provider: TestProvider; - - beforeEach(() => { - jest.clearAllMocks(); - (global.fetch as jest.Mock).mockReset(); - provider = new TestProvider(config); - }); - - describe('truncateForLogging', () => { - it('should return data unchanged when under default limit', () => { - const short = 'a'.repeat(4096); - expect(provider.exposeTruncateForLogging(short)).toBe(short); - }); - - it('should return data unchanged when exactly at default limit', () => { - const exact = 'x'.repeat(4096); - expect(provider.exposeTruncateForLogging(exact)).toBe(exact); - }); - - it('should truncate data exceeding default 4096 char limit', () => { - const long = 'b'.repeat(5000); - const result = provider.exposeTruncateForLogging(long); - expect(result).toHaveLength(4096 + '... [truncated 904 chars]'.length); - expect(result).toContain('... [truncated 904 chars]'); - expect(result.startsWith('b'.repeat(4096))).toBe(true); - }); - - it('should respect a custom maxLength parameter', () => { - const data = 'c'.repeat(200); - const result = provider.exposeTruncateForLogging(data, 100); - expect(result).toContain('... [truncated 100 chars]'); - expect(result.startsWith('c'.repeat(100))).toBe(true); - }); - - it('should return unchanged for empty string', () => { - expect(provider.exposeTruncateForLogging('')).toBe(''); - }); - }); - - describe('makeRequest logging', () => { - it('should log debug on successful request with request body and response data', async () => { - const responseBody = { - choices: [{ message: { role: 'assistant', content: 'hello' } }], - }; - - (global.fetch as jest.Mock).mockResolvedValueOnce({ - ok: true, - json: async () => responseBody, - }); - - await provider.exposeMakeRequest('/chat/completions', { - model: 'test', - }); - - expect(mockLogger.debug).toHaveBeenCalledWith( - expect.stringContaining( - '[test-provider] Request to http://localhost:1234/chat/completions', - ), - expect.objectContaining({ body: expect.any(String) }), - ); - - expect(mockLogger.debug).toHaveBeenCalledWith( - expect.stringContaining('[test-provider] Response received in'), - expect.objectContaining({ data: expect.any(String) }), - ); - }); - - it('should log error on HTTP failure with response data', async () => { - (global.fetch as jest.Mock).mockResolvedValueOnce({ - ok: false, - status: 500, - statusText: 'Internal Server Error', - text: async () => 'server error details', - headers: new Headers({ 'Content-Type': 'text/plain' }), - json: async () => ({ error: 'server error' }), - }); - - await expect( - provider.exposeMakeRequest('/chat/completions', {}), - ).rejects.toThrow(); - - expect(mockLogger.error).toHaveBeenCalledWith( - expect.stringContaining('[test-provider] Request failed (500)'), - expect.objectContaining({ responseData: 'server error details' }), - ); - }); - - it('should log warn when finish_reason is length', async () => { - const responseBody = { - choices: [ - { - message: { role: 'assistant', content: 'truncated...' }, - finish_reason: 'length', - }, - ], - }; - - (global.fetch as jest.Mock).mockResolvedValueOnce({ - ok: true, - json: async () => responseBody, - }); - - await provider.exposeMakeRequest('/chat/completions', {}); - - expect(mockLogger.warn).toHaveBeenCalledWith( - expect.stringContaining('truncated due to token limit'), - ); - }); - - it('should log warn when finish_reason is max_tokens', async () => { - const responseBody = { - choices: [ - { - message: { role: 'assistant', content: 'truncated...' }, - finish_reason: 'max_tokens', - }, - ], - }; - - (global.fetch as jest.Mock).mockResolvedValueOnce({ - ok: true, - json: async () => responseBody, - }); - - await provider.exposeMakeRequest('/chat/completions', {}); - - expect(mockLogger.warn).toHaveBeenCalledWith( - expect.stringContaining('finish_reason: max_tokens'), - ); - }); - - it('should not log warn when finish_reason is stop', async () => { - const responseBody = { - choices: [ - { - message: { role: 'assistant', content: 'done' }, - finish_reason: 'stop', - }, - ], - }; - - (global.fetch as jest.Mock).mockResolvedValueOnce({ - ok: true, - json: async () => responseBody, - }); - - await provider.exposeMakeRequest('/chat/completions', {}); - - expect(mockLogger.warn).not.toHaveBeenCalled(); - }); - - it('should work without a logger configured', async () => { - const noLoggerProvider = new TestProvider({ - ...config, - logger: undefined, - }); - - (global.fetch as jest.Mock).mockResolvedValueOnce({ - ok: true, - json: async () => ({ choices: [{ message: { content: 'ok' } }] }), - }); - - const result = await noLoggerProvider.exposeMakeRequest( - '/chat/completions', - {}, - ); - expect(result).toBeDefined(); - }); - - it('should truncate large request bodies in debug logs', async () => { - const largeBody = { data: 'x'.repeat(5000) }; - - (global.fetch as jest.Mock).mockResolvedValueOnce({ - ok: true, - json: async () => ({ choices: [] }), - }); - - await provider.exposeMakeRequest('/chat/completions', largeBody); - - const debugCall = mockLogger.debug.mock.calls[0]; - const metadata = debugCall[1] as Record; - expect(metadata.body).toContain('... [truncated'); - }); - }); -}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/base-provider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/base-provider.ts deleted file mode 100644 index 2601e87125e..00000000000 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/base-provider.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2025 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Re-exports LLMProvider from the common package for backward compatibility. - * New consumers should import directly from `@backstage-community/plugin-mcp-chat-common`. - */ -export { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/claude-provider.ts similarity index 96% rename from workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.ts rename to workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/claude-provider.ts index 05a1312ae9f..3cdcc46c663 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-anthropic/src/ClaudeProvider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/claude-provider.ts @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-node'; import { - LLMProvider, - type ChatMessage, - type Tool, - type ChatResponse, - type ToolCall, + ChatMessage, + Tool, + ChatResponse, + ToolCall, } from '@backstage-community/plugin-mcp-chat-common'; /** @@ -43,7 +42,7 @@ export class ClaudeProvider extends LLMProvider { error?: string; }> { try { - // Claude doesn't have a models endpoint, so we make a simple test request + // Claude doesn't have a models endpoint, so we'll make a simple test request const testMessages = [{ role: 'user' as const, content: 'Hello' }]; const requestBody = { model: this.model, diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/gemini-provider.test.ts similarity index 98% rename from workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.test.ts rename to workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/gemini-provider.test.ts index 442d670d4d7..2290c70bcef 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.test.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/gemini-provider.test.ts @@ -14,13 +14,11 @@ * limitations under the License. */ +import { mockServices } from '@backstage/backend-test-utils'; import { GoogleGenAI } from '@google/genai'; -import { GeminiProvider } from './GeminiProvider'; -import type { - ChatMessage, - Tool, - ProviderConfig, -} from '@backstage-community/plugin-mcp-chat-common'; +import { GeminiProvider } from './gemini-provider'; +import { ChatMessage, Tool } from '@backstage-community/plugin-mcp-chat-common'; +import { type ProviderConfig } from '@backstage-community/plugin-mcp-chat-node'; jest.mock('@google/genai'); @@ -30,11 +28,14 @@ describe('GeminiProvider', () => { let provider: GeminiProvider; let mockGenerateContent: jest.Mock; + const mockLogger = mockServices.logger.mock(); + const config: ProviderConfig = { type: 'gemini', apiKey: 'test-api-key', baseUrl: 'https://generativelanguage.googleapis.com', model: 'gemini-pro', + logger: mockLogger, }; beforeEach(() => { diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/gemini-provider.ts similarity index 98% rename from workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.ts rename to workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/gemini-provider.ts index a51d6692a16..3b72ab88986 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-gemini/src/GeminiProvider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/gemini-provider.ts @@ -13,14 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - import { LLMProvider, - type ChatMessage, - type Tool, - type ChatResponse, - type ToolCall, type ProviderConfig, +} from '@backstage-community/plugin-mcp-chat-node'; +import { + ChatMessage, + Tool, + ChatResponse, + ToolCall, } from '@backstage-community/plugin-mcp-chat-common'; import { GenerateContentConfig, diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/index.ts index 37f99351972..e9574d8448c 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/index.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/index.ts @@ -14,4 +14,21 @@ * limitations under the License. */ -export { LLMProvider } from './base-provider'; +// ============================================================================= +// Provider Base Class and Factory +// ============================================================================= +export { + ProviderFactory, + getProviderConfig, + getProviderInfo, +} from './provider-factory'; + +// ============================================================================= +// Provider Implementations +// ============================================================================= +export { OpenAIProvider } from './openai-provider'; +export { OpenAIResponsesProvider } from './openai-responses-provider'; +export { ClaudeProvider } from './claude-provider'; +export { GeminiProvider } from './gemini-provider'; +export { OllamaProvider } from './ollama-provider'; +export { LiteLLMProvider } from './litellm-provider'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.test.ts new file mode 100644 index 00000000000..d1196e3ef2c --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.test.ts @@ -0,0 +1,340 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { mockServices } from '@backstage/backend-test-utils'; +import { LiteLLMProvider } from './litellm-provider'; +import { ChatMessage, Tool } from '@backstage-community/plugin-mcp-chat-common'; +import { type ProviderConfig } from '@backstage-community/plugin-mcp-chat-node'; + +// Mock fetch globally +global.fetch = jest.fn(); + +describe('LiteLLMProvider', () => { + let provider: LiteLLMProvider; + + const mockLogger = mockServices.logger.mock(); + + const config: ProviderConfig = { + type: 'litellm', + apiKey: 'test-api-key', + baseUrl: 'http://localhost:4000', + model: 'gpt-4', + logger: mockLogger, + }; + + beforeEach(() => { + jest.clearAllMocks(); + (global.fetch as jest.Mock).mockReset(); + provider = new LiteLLMProvider(config); + }); + + describe('constructor', () => { + it('should initialize with provided config', () => { + expect(provider).toBeDefined(); + }); + + it('should work without API key', () => { + const configWithoutKey = { + ...config, + apiKey: undefined, + }; + const testProvider = new LiteLLMProvider(configWithoutKey); + expect(testProvider).toBeDefined(); + }); + }); + + describe('sendMessage', () => { + it('should send simple message without tools', async () => { + const messages: ChatMessage[] = [ + { role: 'user', content: 'Hello, how are you?' }, + ]; + + const mockResponse = { + choices: [ + { + message: { + role: 'assistant', + content: 'I am doing well, thank you!', + }, + }, + ], + usage: { + prompt_tokens: 10, + completion_tokens: 15, + total_tokens: 25, + }, + }; + + (global.fetch as jest.Mock).mockResolvedValueOnce({ + ok: true, + json: async () => mockResponse, + }); + + const response = await provider.sendMessage(messages); + + expect(global.fetch).toHaveBeenCalledWith( + 'http://localhost:4000/chat/completions', + expect.objectContaining({ + method: 'POST', + headers: expect.objectContaining({ + 'Content-Type': 'application/json', + Authorization: 'Bearer test-api-key', + }), + body: expect.stringContaining('"model":"gpt-4"'), + }), + ); + + expect(response).toEqual(mockResponse); + }); + + it('should send message with tools', async () => { + const messages: ChatMessage[] = [ + { role: 'user', content: 'What is the weather?' }, + ]; + + const tools: Tool[] = [ + { + type: 'function', + function: { + name: 'get_weather', + description: 'Get current weather', + parameters: { + type: 'object', + properties: { + location: { type: 'string' }, + }, + }, + }, + }, + ]; + + const mockResponse = { + choices: [ + { + message: { + role: 'assistant', + content: null, + tool_calls: [ + { + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"location":"San Francisco"}', + }, + }, + ], + }, + }, + ], + }; + + (global.fetch as jest.Mock).mockResolvedValueOnce({ + ok: true, + json: async () => mockResponse, + }); + + const response = await provider.sendMessage(messages, tools); + + expect(global.fetch).toHaveBeenCalledWith( + 'http://localhost:4000/chat/completions', + expect.objectContaining({ + method: 'POST', + body: expect.stringContaining('"tools"'), + }), + ); + + expect(response.choices[0].message.tool_calls).toHaveLength(1); + expect(response.choices[0].message.tool_calls?.[0].function.name).toBe( + 'get_weather', + ); + }); + + it('should handle API errors', async () => { + const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; + + (global.fetch as jest.Mock).mockResolvedValueOnce({ + ok: false, + status: 500, + text: async () => 'Internal Server Error', + }); + + await expect(provider.sendMessage(messages)).rejects.toThrow(); + }); + }); + + describe('testConnection', () => { + it('should successfully test connection with models endpoint', async () => { + const mockModelsResponse = { + data: [ + { id: 'gpt-4' }, + { id: 'gpt-3.5-turbo' }, + { id: 'claude-3-opus' }, + ], + }; + + (global.fetch as jest.Mock).mockResolvedValueOnce({ + ok: true, + json: async () => mockModelsResponse, + }); + + const result = await provider.testConnection(); + + expect(result.connected).toBe(true); + expect(result.models).toEqual([ + 'gpt-4', + 'gpt-3.5-turbo', + 'claude-3-opus', + ]); + expect(result.error).toBeUndefined(); + }); + + it('should fallback to health endpoint if models endpoint fails', async () => { + (global.fetch as jest.Mock) + .mockRejectedValueOnce(new Error('Models endpoint failed')) + .mockResolvedValueOnce({ + ok: true, + json: async () => ({ status: 'healthy' }), + }); + + const result = await provider.testConnection(); + + expect(result.connected).toBe(true); + expect(result.models).toEqual(['gpt-4']); + }); + + it('should handle 401 authentication error', async () => { + (global.fetch as jest.Mock) + .mockResolvedValueOnce({ + ok: false, + status: 401, + text: async () => + JSON.stringify({ error: { message: 'Unauthorized' } }), + }) + .mockRejectedValueOnce(new Error('Health check failed')); + + const result = await provider.testConnection(); + + expect(result.connected).toBe(false); + expect(result.error).toContain('Invalid API key'); + }); + + it('should handle 404 endpoint not found error', async () => { + (global.fetch as jest.Mock) + .mockResolvedValueOnce({ + ok: false, + status: 404, + text: async () => 'Not Found', + }) + .mockRejectedValueOnce(new Error('Connection refused')); + + const result = await provider.testConnection(); + + expect(result.connected).toBe(false); + expect(result.error).toBeDefined(); + }); + + it('should handle network errors', async () => { + (global.fetch as jest.Mock) + .mockRejectedValueOnce(new Error('Network error')) + .mockRejectedValueOnce(new Error('Network error')); // Health check also fails with same error + + const result = await provider.testConnection(); + + expect(result.connected).toBe(false); + expect(result.error).toBe('Network error'); + }); + }); + + describe('getHeaders', () => { + it('should include Authorization header when API key is provided', () => { + const headers = (provider as any).getHeaders(); + + expect(headers).toEqual({ + 'Content-Type': 'application/json', + Authorization: 'Bearer test-api-key', + }); + }); + + it('should not include Authorization header when API key is missing', () => { + const configWithoutKey = { + ...config, + apiKey: undefined, + }; + const testProvider = new LiteLLMProvider(configWithoutKey); + const headers = (testProvider as any).getHeaders(); + + expect(headers).toEqual({ + 'Content-Type': 'application/json', + }); + expect(headers.Authorization).toBeUndefined(); + }); + }); + + describe('formatRequest', () => { + it('should format request with default parameters', () => { + const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; + + const request = (provider as any).formatRequest(messages); + + expect(request).toEqual({ + model: 'gpt-4', + messages, + max_tokens: 1000, + temperature: 0.7, + }); + }); + + it('should include tools when provided', () => { + const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; + + const tools: Tool[] = [ + { + type: 'function', + function: { + name: 'test_tool', + description: 'A test tool', + parameters: {}, + }, + }, + ]; + + const request = (provider as any).formatRequest(messages, tools); + + expect(request.tools).toEqual(tools); + expect(request.parallel_tool_calls).toBe(true); + }); + }); + + describe('parseResponse', () => { + it('should return response as-is for OpenAI-compatible format', () => { + const mockResponse = { + choices: [ + { + message: { + role: 'assistant', + content: 'Test response', + }, + }, + ], + }; + + const parsed = (provider as any).parseResponse(mockResponse); + + expect(parsed).toEqual(mockResponse); + }); + }); +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.ts similarity index 85% rename from workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.ts rename to workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.ts index 372378b1104..7828b4a27ed 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-litellm/src/LiteLLMProvider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/litellm-provider.ts @@ -13,14 +13,36 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-node'; import { - LLMProvider, - type ChatMessage, - type Tool, - type ChatResponse, + ChatMessage, + Tool, + ChatResponse, } from '@backstage-community/plugin-mcp-chat-common'; +/** + * LiteLLM Provider + * + * LiteLLM is a unified interface to 100+ LLM APIs including: + * - OpenAI, Azure OpenAI + * - Anthropic (Claude) + * - Google (Gemini, VertexAI) + * - AWS Bedrock + * - Cohere, Replicate, Huggingface + * - And many more... + * + * It uses the OpenAI-compatible format, making it easy to integrate. + * + * Configuration example in app-config.yaml: + * ```yaml + * mcpChat: + * providers: + * - id: litellm + * token: ${LITELLM_API_KEY} # Optional, depends on your LiteLLM setup + * baseUrl: 'http://localhost:4000' # Your LiteLLM proxy URL + * model: gpt-4 # Any model supported by your LiteLLM instance + * ``` + */ /** * LiteLLM proxy provider. * Provides unified access to 100+ LLM APIs through LiteLLM. diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.test.ts new file mode 100644 index 00000000000..5c624785df2 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.test.ts @@ -0,0 +1,710 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { mockServices } from '@backstage/backend-test-utils'; +import { OllamaProvider } from './ollama-provider'; +import { ChatMessage, Tool } from '@backstage-community/plugin-mcp-chat-common'; +import { type ProviderConfig } from '@backstage-community/plugin-mcp-chat-node'; +import { Ollama } from 'ollama'; + +// Mock the Ollama library +jest.mock('ollama'); + +const MockOllama = Ollama as jest.MockedClass; + +describe('OllamaProvider', () => { + let provider: OllamaProvider; + let mockOllama: jest.Mocked; + + const mockLogger = mockServices.logger.mock(); + + const config: ProviderConfig = { + type: 'ollama', + baseUrl: 'http://localhost:11434', + model: 'llama2', + logger: mockLogger, + }; + + beforeEach(() => { + jest.clearAllMocks(); + + mockOllama = { + chat: jest.fn(), + list: jest.fn(), + } as any; + + MockOllama.mockImplementation(() => mockOllama); + + provider = new OllamaProvider(config); + }); + + describe('constructor', () => { + it('should initialize with default baseUrl', () => { + expect(MockOllama).toHaveBeenCalledWith({ + host: 'http://localhost:11434', + }); + }); + + it('should remove /v1 suffix from baseUrl', () => { + const configWithV1 = { + ...config, + baseUrl: 'http://localhost:11434/v1', + }; + + const testProvider = new OllamaProvider(configWithV1); + expect(testProvider).toBeDefined(); + + expect(MockOllama).toHaveBeenCalledWith({ + host: 'http://localhost:11434', + }); + }); + + it('should handle custom baseUrl', () => { + const customConfig = { + ...config, + baseUrl: 'http://custom-ollama:8080', + }; + + const testProvider = new OllamaProvider(customConfig); + expect(testProvider).toBeDefined(); + + expect(MockOllama).toHaveBeenCalledWith({ + host: 'http://custom-ollama:8080', + }); + }); + }); + + describe('sendMessage', () => { + it('should send simple message without tools', async () => { + const messages: ChatMessage[] = [ + { role: 'user', content: 'Hello, how are you?' }, + ]; + + const mockResponse = { + message: { + role: 'assistant', + content: 'I am doing well, thank you!', + }, + usage: { + prompt_tokens: 10, + completion_tokens: 15, + total_tokens: 25, + }, + } as any; + + mockOllama.chat.mockResolvedValue(mockResponse); + + const result = await provider.sendMessage(messages); + + expect(mockOllama.chat).toHaveBeenCalledWith({ + model: 'llama2', + messages: [ + { + role: 'user', + content: 'Hello, how are you?', + tool_call_id: undefined, + }, + ], + tools: undefined, + }); + + expect(result).toEqual({ + choices: [ + { + message: { + role: 'assistant', + content: 'I am doing well, thank you!', + tool_calls: undefined, + }, + }, + ], + usage: { + prompt_tokens: 10, + completion_tokens: 15, + total_tokens: 25, + }, + }); + }); + + it('should handle null content by converting to empty string', async () => { + const messages: ChatMessage[] = [{ role: 'user', content: null }]; + + const mockResponse = { + message: { + role: 'assistant', + content: 'Hello!', + }, + } as any; + + mockOllama.chat.mockResolvedValue(mockResponse); + + await provider.sendMessage(messages); + + expect(mockOllama.chat).toHaveBeenCalledWith({ + model: 'llama2', + messages: [ + { + role: 'user', + content: '', + tool_call_id: undefined, + }, + ], + tools: undefined, + }); + }); + + it('should handle tools correctly', async () => { + const messages: ChatMessage[] = [ + { role: 'user', content: 'What is the weather like?' }, + ]; + + const tools: Tool[] = [ + { + type: 'function', + function: { + name: 'get_weather', + description: 'Get current weather information', + parameters: { + type: 'object', + properties: { + location: { + type: 'string', + description: 'The city and state', + }, + }, + required: ['location'], + }, + }, + }, + ]; + + const mockResponse = { + message: { + role: 'assistant', + content: 'I can help you get weather information.', + tool_calls: [ + { + id: 'call_123', + function: { + name: 'get_weather', + arguments: { location: 'New York' }, + }, + }, + ], + }, + } as any; + + mockOllama.chat.mockResolvedValue(mockResponse); + + const result = await provider.sendMessage(messages, tools); + + expect(mockOllama.chat).toHaveBeenCalledWith({ + model: 'llama2', + messages: [ + { + role: 'user', + content: 'What is the weather like?', + tool_call_id: undefined, + }, + ], + tools: tools, + }); + + expect(result.choices[0].message.tool_calls).toHaveLength(1); + expect(result.choices[0].message.tool_calls![0]).toEqual({ + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"location":"New York"}', + }, + }); + }); + + it('should convert string tool call arguments to objects', async () => { + const messages: ChatMessage[] = [ + { + role: 'assistant', + content: 'Let me check that for you.', + tool_calls: [ + { + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: '{"location":"New York"}', // String arguments + }, + }, + ], + }, + ]; + + const mockResponse = { + message: { + role: 'assistant', + content: 'Done!', + }, + } as any; + + mockOllama.chat.mockResolvedValue(mockResponse); + + await provider.sendMessage(messages); + + expect(mockOllama.chat).toHaveBeenCalledWith({ + model: 'llama2', + messages: [ + { + role: 'assistant', + content: 'Let me check that for you.', + tool_call_id: undefined, + tool_calls: [ + { + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: { location: 'New York' }, // Converted to object + }, + }, + ], + }, + ], + tools: undefined, + }); + }); + + it('should handle tool call arguments that are already objects', async () => { + const messages: ChatMessage[] = [ + { + role: 'assistant', + content: 'Let me check that for you.', + tool_calls: [ + { + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: JSON.stringify({ location: 'New York' }), + }, + }, + ], + }, + ]; + + const mockResponse = { + message: { + role: 'assistant', + content: 'Done!', + }, + } as any; + + mockOllama.chat.mockResolvedValue(mockResponse); + + await provider.sendMessage(messages); + + expect(mockOllama.chat).toHaveBeenCalledWith({ + model: 'llama2', + messages: [ + { + role: 'assistant', + content: 'Let me check that for you.', + tool_call_id: undefined, + tool_calls: [ + { + id: 'call_123', + type: 'function', + function: { + name: 'get_weather', + arguments: { location: 'New York' }, + }, + }, + ], + }, + ], + tools: undefined, + }); + }); + + it('should handle tool messages', async () => { + const messages: ChatMessage[] = [ + { + role: 'tool', + content: '{"temperature": "72°F", "condition": "sunny"}', + tool_call_id: 'call_123', + }, + ]; + + const mockResponse = { + message: { + role: 'assistant', + content: 'The weather is sunny and 72°F.', + }, + } as any; + + mockOllama.chat.mockResolvedValue(mockResponse); + + await provider.sendMessage(messages); + + expect(mockOllama.chat).toHaveBeenCalledWith({ + model: 'llama2', + messages: [ + { + role: 'tool', + content: '{"temperature": "72°F", "condition": "sunny"}', + tool_call_id: 'call_123', + }, + ], + tools: undefined, + }); + }); + + it('should handle response with alternative tool call format', async () => { + const messages: ChatMessage[] = [ + { role: 'user', content: 'Test message' }, + ]; + + const mockResponse = { + message: { + role: 'assistant', + content: 'I can help with that.', + tool_calls: [ + { + // Alternative format without nested function + name: 'get_info', + arguments: { query: 'test' }, + }, + ], + }, + } as any; + + mockOllama.chat.mockResolvedValue(mockResponse); + + const result = await provider.sendMessage(messages); + + expect(result.choices[0].message.tool_calls).toHaveLength(1); + expect(result.choices[0].message.tool_calls![0]).toEqual({ + id: 'call_0', + type: 'function', + function: { + name: 'get_info', + arguments: '{"query":"test"}', + }, + }); + }); + + it('should handle response without usage metadata', async () => { + const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; + + const mockResponse = { + message: { + role: 'assistant', + content: 'Hi there!', + }, + // No usage field + prompt_eval_count: 5, + eval_count: 8, + } as any; + + mockOllama.chat.mockResolvedValue(mockResponse); + + const result = await provider.sendMessage(messages); + + expect(result.usage).toEqual({ + prompt_tokens: 5, + completion_tokens: 8, + total_tokens: 13, + }); + }); + + it('should handle response with null content', async () => { + const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; + + const mockResponse = { + message: { + role: 'assistant', + content: null, + }, + } as any; + + mockOllama.chat.mockResolvedValue(mockResponse); + + const result = await provider.sendMessage(messages); + + expect(result.choices[0].message.content).toBeNull(); + }); + }); + + describe('testConnection', () => { + it('should return connected when model is available', async () => { + const mockModelList = { + models: [ + { name: 'llama2' }, + { name: 'codellama' }, + { name: 'mistral' }, + ], + } as any; + + mockOllama.list.mockResolvedValue(mockModelList); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: true, + models: ['llama2', 'codellama', 'mistral'], + }); + + expect(mockOllama.list).toHaveBeenCalled(); + }); + + it('should return error when configured model is not available', async () => { + const mockModelList = { + models: [{ name: 'codellama' }, { name: 'mistral' }], + } as any; + + mockOllama.list.mockResolvedValue(mockModelList); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: false, + models: ['codellama', 'mistral'], + error: + "Model 'llama2' is not available on this Ollama server. Available models: codellama, mistral. Please ensure the model is installed by running 'ollama pull llama2' or update your configuration to use an available model.", + }); + }); + + it('should handle empty model list', async () => { + const mockModelList = { + models: [], + }; + + mockOllama.list.mockResolvedValue(mockModelList); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: false, + models: [], + error: + "Model 'llama2' is not available on this Ollama server. Available models: none. Please ensure the model is installed by running 'ollama pull llama2' or update your configuration to use an available model.", + }); + }); + + it('should handle undefined models array', async () => { + const mockModelList = { + models: undefined, + }; + + mockOllama.list.mockResolvedValue(mockModelList as any); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: false, + models: [], + error: + "Model 'llama2' is not available on this Ollama server. Available models: none. Please ensure the model is installed by running 'ollama pull llama2' or update your configuration to use an available model.", + }); + }); + + it('should return error when connection fails', async () => { + const error = new Error('Connection refused'); + mockOllama.list.mockRejectedValue(error); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: false, + error: 'Connection refused', + }); + }); + + it('should handle non-Error exceptions', async () => { + mockOllama.list.mockRejectedValue('String error'); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: false, + error: 'Failed to connect to Ollama server', + }); + }); + }); + + describe('getHeaders', () => { + it('should return correct headers', () => { + const headers = (provider as any).getHeaders(); + + expect(headers).toEqual({ + 'Content-Type': 'application/json', + }); + }); + }); + + describe('formatRequest', () => { + it('should format request correctly without tools', () => { + const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; + + const request = (provider as any).formatRequest(messages); + + expect(request).toEqual({ + model: 'llama2', + messages: messages, + max_tokens: 1000, + temperature: 0.7, + }); + }); + + it('should format request correctly with tools', () => { + const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; + + const tools: Tool[] = [ + { + type: 'function', + function: { + name: 'test_function', + description: 'A test function', + parameters: { type: 'object' }, + }, + }, + ]; + + const request = (provider as any).formatRequest(messages, tools); + + expect(request).toEqual({ + model: 'llama2', + messages: messages, + max_tokens: 1000, + temperature: 0.7, + tools: tools, + }); + }); + + it('should not include tools when empty array', () => { + const messages: ChatMessage[] = [{ role: 'user', content: 'Hello' }]; + + const request = (provider as any).formatRequest(messages, []); + + expect(request).toEqual({ + model: 'llama2', + messages: messages, + max_tokens: 1000, + temperature: 0.7, + }); + }); + }); + + describe('parseResponse', () => { + it('should parse response correctly', () => { + const response = { + message: { + role: 'assistant', + content: 'Hello world', + }, + usage: { + prompt_tokens: 10, + completion_tokens: 15, + total_tokens: 25, + }, + }; + + const result = (provider as any).parseResponse(response); + + expect(result).toEqual({ + choices: [ + { + message: { + role: 'assistant', + content: 'Hello world', + tool_calls: undefined, + }, + }, + ], + usage: { + prompt_tokens: 10, + completion_tokens: 15, + total_tokens: 25, + }, + }); + }); + + it('should handle response with eval counts when no usage', () => { + const response = { + message: { + role: 'assistant', + content: 'Hello world', + }, + prompt_eval_count: 10, + eval_count: 15, + }; + + const result = (provider as any).parseResponse(response); + + expect(result.usage).toEqual({ + prompt_tokens: 10, + completion_tokens: 15, + total_tokens: 25, + }); + }); + + it('should handle response with missing eval counts', () => { + const response = { + message: { + role: 'assistant', + content: 'Hello world', + }, + }; + + const result = (provider as any).parseResponse(response); + + expect(result.usage).toEqual({ + prompt_tokens: 0, + completion_tokens: 0, + total_tokens: 0, + }); + }); + + it('should generate IDs for tool calls without IDs', () => { + const response = { + message: { + role: 'assistant', + content: 'Let me help with that.', + tool_calls: [ + { + function: { + name: 'test_function', + arguments: { test: 'value' }, + }, + }, + { + id: 'existing_id', + function: { + name: 'another_function', + arguments: { test: 'value2' }, + }, + }, + ], + }, + }; + + const result = (provider as any).parseResponse(response); + + expect(result.choices[0].message.tool_calls).toHaveLength(2); + expect(result.choices[0].message.tool_calls![0].id).toBe('call_0'); + expect(result.choices[0].message.tool_calls![1].id).toBe('existing_id'); + }); + }); +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.ts similarity index 93% rename from workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.ts rename to workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.ts index ed6cc405c1f..fa798bfc795 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-ollama/src/OllamaProvider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/ollama-provider.ts @@ -13,13 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-node'; import { - LLMProvider, - type ChatMessage, - type Tool, - type ChatResponse, - type ProviderConfig, + ChatMessage, + Tool, + ChatResponse, } from '@backstage-community/plugin-mcp-chat-common'; import { Ollama } from 'ollama'; @@ -31,7 +29,7 @@ import { Ollama } from 'ollama'; export class OllamaProvider extends LLMProvider { private ollama: Ollama; - constructor(config: ProviderConfig) { + constructor(config: any) { super(config); // Initialize Ollama client with the base URL this.ollama = new Ollama({ @@ -143,7 +141,7 @@ export class OllamaProvider extends LLMProvider { } protected formatRequest(messages: ChatMessage[], tools?: Tool[]): any { - // This method is not used since we use the Ollama SDK directly + // This method is not used anymore since we're using the Ollama library directly const request: any = { model: this.model, messages, @@ -159,6 +157,8 @@ export class OllamaProvider extends LLMProvider { } protected parseResponse(response: any): ChatResponse { + // The Ollama library returns a response that should be compatible with OpenAI format + // But let's ensure it matches our expected ChatResponse format let toolCalls; if (response.message?.tool_calls) { // Convert Ollama tool calls to the expected format diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-provider.ts similarity index 93% rename from workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.ts rename to workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-provider.ts index 9951e27b628..59c176008e1 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai/src/OpenAIProvider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-provider.ts @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-node'; import { - LLMProvider, - type ChatMessage, - type Tool, - type ChatResponse, + ChatMessage, + Tool, + ChatResponse, } from '@backstage-community/plugin-mcp-chat-common'; /** @@ -57,12 +56,14 @@ export class OpenAIProvider extends LLMProvider { errorMessage = errorData.error.message; } } catch { + // If parsing fails, use the raw error text but truncate if too long errorMessage = errorText.length > 100 ? `${errorText.substring(0, 100)}...` : errorText; } + // Provide user-friendly messages for common errors if (response.status === 401) { errorMessage = 'Invalid API key. Please check your OpenAI API key configuration.'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.test.ts new file mode 100644 index 00000000000..d16b0312985 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.test.ts @@ -0,0 +1,782 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { mockServices } from '@backstage/backend-test-utils'; +import { OpenAIResponsesProvider } from './openai-responses-provider'; +import { + ChatMessage, + MCPServerFullConfig, + MCPServerType, + ResponsesApiResponse, +} from '@backstage-community/plugin-mcp-chat-common'; +import { type ProviderConfig } from '@backstage-community/plugin-mcp-chat-node'; + +// Mock fetch globally +global.fetch = jest.fn(); + +describe('OpenAIResponsesProvider', () => { + let provider: OpenAIResponsesProvider; + const mockFetch = global.fetch as jest.MockedFunction; + + const mockLogger = mockServices.logger.mock(); + + const config: ProviderConfig = { + type: 'openai-responses', + apiKey: 'test-api-key', + baseUrl: 'http://test-api.com/v1', + model: 'gemini/models/gemini-2.5-flash', + logger: mockLogger, + }; + + const mockMCPServerFullConfigs: MCPServerFullConfig[] = [ + { + id: 'k8s', + name: 'Kubernetes Server', + type: MCPServerType.STREAMABLE_HTTP, + url: 'https://kubernetes-mcp-server.example.com/mcp', + }, + { + id: 'brave-search', + name: 'Brave Search', + type: MCPServerType.STREAMABLE_HTTP, + url: 'https://brave-search-mcp.example.com/mcp', + }, + ]; + + beforeEach(() => { + jest.clearAllMocks(); + provider = new OpenAIResponsesProvider(config); + provider.setMcpServerConfigs(mockMCPServerFullConfigs); + }); + + describe('constructor', () => { + it('should initialize with valid config', () => { + expect(provider).toBeDefined(); + }); + }); + + describe('setMcpServerConfigs', () => { + it('should store MCP server configurations', () => { + const newConfigs: MCPServerFullConfig[] = [ + { + id: 'test-server', + name: 'Test Server', + type: MCPServerType.STREAMABLE_HTTP, + url: 'https://test.com/mcp', + }, + ]; + provider.setMcpServerConfigs(newConfigs); + // Configuration is stored internally for use in formatRequest + expect(provider).toBeDefined(); + }); + }); + + describe('sendMessage', () => { + it('should send message with MCP tools to Responses API', async () => { + const messages: ChatMessage[] = [ + { + role: 'user', + content: 'How many pods in the mcp-servers namespace?', + }, + ]; + + const mockResponse: ResponsesApiResponse = { + id: 'resp_test_123', + object: 'response', + created_at: Date.now(), + model: 'gemini/models/gemini-2.5-flash', + status: 'completed', + output: [ + { + id: 'mcp_list_1', + type: 'mcp_list_tools', + server_label: 'k8s', + tools: [ + { + name: 'pods_list_in_namespace', + description: 'List all pods in a namespace', + input_schema: {}, + }, + ], + }, + { + id: 'mcp_call_1', + type: 'mcp_call', + name: 'pods_list_in_namespace', + arguments: '{"namespace":"mcp-servers"}', + server_label: 'k8s', + error: null, + output: 'Found 12 pods in mcp-servers namespace', + }, + { + id: 'msg_1', + type: 'message', + role: 'assistant', + status: 'completed', + content: [ + { + type: 'output_text', + text: 'There are 12 pods in the mcp-servers namespace.', + }, + ], + }, + ], + usage: { + input_tokens: 100, + output_tokens: 50, + total_tokens: 150, + }, + }; + + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => mockResponse, + } as Response); + + const result = await provider.sendMessage(messages); + + expect(mockFetch).toHaveBeenCalledWith( + 'http://test-api.com/v1/responses', + expect.objectContaining({ + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer test-api-key', + }, + body: JSON.stringify({ + input: 'How many pods in the mcp-servers namespace?', + model: 'gemini/models/gemini-2.5-flash', + tools: [ + { + type: 'mcp', + server_url: 'https://kubernetes-mcp-server.example.com/mcp', + server_label: 'k8s', + require_approval: 'never', + }, + { + type: 'mcp', + server_url: 'https://brave-search-mcp.example.com/mcp', + server_label: 'brave-search', + require_approval: 'never', + }, + ], + }), + }), + ); + + expect(result).toEqual({ + choices: [ + { + message: { + role: 'assistant', + content: 'There are 12 pods in the mcp-servers namespace.', + tool_calls: [ + { + id: 'mcp_call_1', + type: 'function', + function: { + name: 'pods_list_in_namespace', + arguments: '{"namespace":"mcp-servers"}', + }, + }, + ], + }, + }, + ], + usage: { + prompt_tokens: 100, + completion_tokens: 50, + total_tokens: 150, + }, + }); + }); + + it('should handle response without tool calls', async () => { + const messages: ChatMessage[] = [ + { role: 'user', content: 'Hello, how are you?' }, + ]; + + const mockResponse: ResponsesApiResponse = { + id: 'resp_test_456', + object: 'response', + created_at: Date.now(), + model: 'gemini/models/gemini-2.5-flash', + status: 'completed', + output: [ + { + id: 'msg_1', + type: 'message', + role: 'assistant', + status: 'completed', + content: [ + { + type: 'output_text', + text: 'I am doing well, thank you for asking!', + }, + ], + }, + ], + }; + + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => mockResponse, + } as Response); + + const result = await provider.sendMessage(messages); + + expect(result).toEqual({ + choices: [ + { + message: { + role: 'assistant', + content: 'I am doing well, thank you for asking!', + tool_calls: undefined, + }, + }, + ], + usage: undefined, + }); + }); + + it('should include system prompt as instructions', async () => { + const messages: ChatMessage[] = [ + { role: 'system', content: 'You are a helpful assistant.' }, + { role: 'user', content: 'Help me' }, + ]; + + const mockResponse: ResponsesApiResponse = { + id: 'resp_test_789', + object: 'response', + created_at: Date.now(), + model: 'gemini/models/gemini-2.5-flash', + status: 'completed', + output: [ + { + id: 'msg_1', + type: 'message', + role: 'assistant', + status: 'completed', + content: [ + { + type: 'output_text', + text: 'How can I help you?', + }, + ], + }, + ], + }; + + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => mockResponse, + } as Response); + + await provider.sendMessage(messages); + + expect(mockFetch).toHaveBeenCalledWith( + 'http://test-api.com/v1/responses', + expect.objectContaining({ + body: expect.stringContaining( + '"instructions":"You are a helpful assistant."', + ), + }), + ); + }); + + it('should filter out non-URL servers', async () => { + const mixedConfigs: MCPServerFullConfig[] = [ + { + id: 'url-server', + name: 'URL Server', + type: MCPServerType.STREAMABLE_HTTP, + url: 'https://example.com/mcp', + }, + { + id: 'stdio-server', + name: 'STDIO Server', + type: MCPServerType.STDIO, + npxCommand: 'some-mcp-server', + }, + ]; + + provider.setMcpServerConfigs(mixedConfigs); + + const messages: ChatMessage[] = [{ role: 'user', content: 'Test' }]; + + const mockResponse: ResponsesApiResponse = { + id: 'resp_test', + object: 'response', + created_at: Date.now(), + model: 'gemini/models/gemini-2.5-flash', + status: 'completed', + output: [ + { + id: 'msg_1', + type: 'message', + role: 'assistant', + status: 'completed', + content: [{ type: 'output_text', text: 'Test response' }], + }, + ], + }; + + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => mockResponse, + } as Response); + + await provider.sendMessage(messages); + + const fetchCall = mockFetch.mock.calls[0]; + const requestBody = JSON.parse(fetchCall[1]?.body as string); + + // Should only include the URL server + expect(requestBody.tools).toHaveLength(1); + expect(requestBody.tools[0].server_label).toBe('url-server'); + }); + + it('should handle API errors', async () => { + const messages: ChatMessage[] = [{ role: 'user', content: 'Test' }]; + + mockFetch.mockResolvedValueOnce({ + ok: false, + status: 500, + text: async () => 'Internal Server Error', + } as Response); + + await expect(provider.sendMessage(messages)).rejects.toThrow( + 'HTTP 500: Internal Server Error', + ); + }); + + it('should handle multiple tool calls', async () => { + const messages: ChatMessage[] = [ + { role: 'user', content: 'Check pods and search' }, + ]; + + const mockResponse: ResponsesApiResponse = { + id: 'resp_multi', + object: 'response', + created_at: Date.now(), + model: 'gemini/models/gemini-2.5-flash', + status: 'completed', + output: [ + { + id: 'mcp_call_1', + type: 'mcp_call', + name: 'pods_list', + arguments: '{}', + server_label: 'k8s', + error: null, + output: 'Found 10 pods', + }, + { + id: 'mcp_call_2', + type: 'mcp_call', + name: 'search', + arguments: '{"query":"kubernetes"}', + server_label: 'brave-search', + error: null, + output: 'Search results...', + }, + { + id: 'msg_1', + type: 'message', + role: 'assistant', + status: 'completed', + content: [ + { + type: 'output_text', + text: 'Found 10 pods and search results.', + }, + ], + }, + ], + }; + + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => mockResponse, + } as Response); + + const result = await provider.sendMessage(messages); + + expect(result.choices[0].message.tool_calls).toHaveLength(2); + expect(result.choices[0].message.tool_calls![0].function.name).toBe( + 'pods_list', + ); + expect(result.choices[0].message.tool_calls![1].function.name).toBe( + 'search', + ); + }); + + it('should include headers in tools when server has headers', async () => { + const serverWithHeaders: MCPServerFullConfig[] = [ + { + id: 'github-server', + name: 'GitHub Server', + type: MCPServerType.STREAMABLE_HTTP, + url: 'https://api.githubcopilot.com/mcp', + headers: { + Authorization: 'Bearer ghp_test_token_123', + }, + }, + ]; + + provider.setMcpServerConfigs(serverWithHeaders); + + const messages: ChatMessage[] = [ + { role: 'user', content: 'Test with headers' }, + ]; + + const mockResponse: ResponsesApiResponse = { + id: 'resp_headers', + object: 'response', + created_at: Date.now(), + model: 'gemini/models/gemini-2.5-flash', + status: 'completed', + output: [ + { + id: 'msg_1', + type: 'message', + role: 'assistant', + status: 'completed', + content: [{ type: 'output_text', text: 'Response' }], + }, + ], + }; + + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => mockResponse, + } as Response); + + await provider.sendMessage(messages); + + expect(mockFetch).toHaveBeenCalledWith( + 'http://test-api.com/v1/responses', + expect.objectContaining({ + method: 'POST', + headers: expect.objectContaining({ + 'Content-Type': 'application/json', + }), + }), + ); + + const callArgs = mockFetch.mock.calls[0]; + const bodyStr = callArgs[1]?.body as string; + const bodyObj = JSON.parse(bodyStr); + + expect(bodyObj.tools).toHaveLength(1); + expect(bodyObj.tools[0]).toEqual({ + type: 'mcp', + server_url: 'https://api.githubcopilot.com/mcp', + server_label: 'github-server', + require_approval: 'never', + headers: { + Authorization: 'Bearer ghp_test_token_123', + }, + }); + }); + + it('should not include headers field when server has no headers', async () => { + const serverWithoutHeaders: MCPServerFullConfig[] = [ + { + id: 'k8s-server', + name: 'Kubernetes Server', + type: MCPServerType.STREAMABLE_HTTP, + url: 'https://k8s.example.com/mcp', + }, + ]; + + provider.setMcpServerConfigs(serverWithoutHeaders); + + const messages: ChatMessage[] = [ + { role: 'user', content: 'Test without headers' }, + ]; + + const mockResponse: ResponsesApiResponse = { + id: 'resp_no_headers', + object: 'response', + created_at: Date.now(), + model: 'gemini/models/gemini-2.5-flash', + status: 'completed', + output: [ + { + id: 'msg_1', + type: 'message', + role: 'assistant', + status: 'completed', + content: [{ type: 'output_text', text: 'Response' }], + }, + ], + }; + + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => mockResponse, + } as Response); + + await provider.sendMessage(messages); + + const callArgs = mockFetch.mock.calls[0]; + const bodyStr = callArgs[1]?.body as string; + const bodyObj = JSON.parse(bodyStr); + + expect(bodyObj.tools).toHaveLength(1); + expect(bodyObj.tools[0]).toEqual({ + type: 'mcp', + server_url: 'https://k8s.example.com/mcp', + server_label: 'k8s-server', + require_approval: 'never', + }); + expect(bodyObj.tools[0].headers).toBeUndefined(); + }); + + it('should handle multiple servers with mixed header configurations', async () => { + const mixedServers: MCPServerFullConfig[] = [ + { + id: 'github-server', + name: 'GitHub Server', + type: MCPServerType.STREAMABLE_HTTP, + url: 'https://api.githubcopilot.com/mcp', + headers: { + Authorization: 'Bearer ghp_token', + 'X-Custom-Header': 'custom-value', + }, + }, + { + id: 'k8s-server', + name: 'Kubernetes Server', + type: MCPServerType.STREAMABLE_HTTP, + url: 'https://k8s.example.com/mcp', + }, + { + id: 'backstage-server', + name: 'Backstage Server', + type: MCPServerType.STREAMABLE_HTTP, + url: 'http://localhost:7008/api/mcp', + headers: { + Authorization: 'Bearer backstage_token', + }, + }, + ]; + + provider.setMcpServerConfigs(mixedServers); + + const messages: ChatMessage[] = [ + { role: 'user', content: 'Test mixed servers' }, + ]; + + const mockResponse: ResponsesApiResponse = { + id: 'resp_mixed', + object: 'response', + created_at: Date.now(), + model: 'gemini/models/gemini-2.5-flash', + status: 'completed', + output: [ + { + id: 'msg_1', + type: 'message', + role: 'assistant', + status: 'completed', + content: [{ type: 'output_text', text: 'Response' }], + }, + ], + }; + + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => mockResponse, + } as Response); + + await provider.sendMessage(messages); + + const callArgs = mockFetch.mock.calls[0]; + const bodyStr = callArgs[1]?.body as string; + const bodyObj = JSON.parse(bodyStr); + + expect(bodyObj.tools).toHaveLength(3); + + // First server with headers + expect(bodyObj.tools[0]).toEqual({ + type: 'mcp', + server_url: 'https://api.githubcopilot.com/mcp', + server_label: 'github-server', + require_approval: 'never', + headers: { + Authorization: 'Bearer ghp_token', + 'X-Custom-Header': 'custom-value', + }, + }); + + // Second server without headers + expect(bodyObj.tools[1]).toEqual({ + type: 'mcp', + server_url: 'https://k8s.example.com/mcp', + server_label: 'k8s-server', + require_approval: 'never', + }); + expect(bodyObj.tools[1].headers).toBeUndefined(); + + // Third server with headers + expect(bodyObj.tools[2]).toEqual({ + type: 'mcp', + server_url: 'http://localhost:7008/api/mcp', + server_label: 'backstage-server', + require_approval: 'never', + headers: { + Authorization: 'Bearer backstage_token', + }, + }); + }); + }); + + describe('testConnection', () => { + it('should return connected when API is reachable', async () => { + const mockResponse: ResponsesApiResponse = { + id: 'resp_test', + object: 'response', + created_at: Date.now(), + model: 'gemini/models/gemini-2.5-flash', + status: 'completed', + output: [ + { + id: 'msg_1', + type: 'message', + role: 'assistant', + status: 'completed', + content: [{ type: 'output_text', text: 'test' }], + }, + ], + }; + + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => mockResponse, + } as Response); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: true, + models: ['gemini/models/gemini-2.5-flash'], + }); + }); + + it('should return not connected on 401 error', async () => { + mockFetch.mockResolvedValueOnce({ + ok: false, + status: 401, + text: async () => 'Unauthorized', + } as Response); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: false, + error: 'Invalid API key. Please check your API key configuration.', + }); + }); + + it('should return not connected on network error', async () => { + mockFetch.mockRejectedValueOnce(new Error('Network error')); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: false, + error: 'Network error', + }); + }); + + it('should handle 429 rate limit error', async () => { + mockFetch.mockResolvedValueOnce({ + ok: false, + status: 429, + text: async () => 'Too Many Requests', + } as Response); + + const result = await provider.testConnection(); + + expect(result).toEqual({ + connected: false, + error: 'Rate limit exceeded. Please try again later.', + }); + }); + }); + + describe('getLastResponseOutput', () => { + it('should return the last response output', async () => { + const messages: ChatMessage[] = [{ role: 'user', content: 'Test' }]; + + const mockResponse: ResponsesApiResponse = { + id: 'resp_test', + object: 'response', + created_at: Date.now(), + model: 'gemini/models/gemini-2.5-flash', + status: 'completed', + output: [ + { + id: 'msg_1', + type: 'message', + role: 'assistant', + status: 'completed', + content: [{ type: 'output_text', text: 'Test' }], + }, + ], + }; + + mockFetch.mockResolvedValueOnce({ + ok: true, + json: async () => mockResponse, + } as Response); + + await provider.sendMessage(messages); + const output = provider.getLastResponseOutput(); + + expect(output).toEqual(mockResponse.output); + }); + + it('should return null before any message is sent', () => { + const output = provider.getLastResponseOutput(); + expect(output).toBeNull(); + }); + }); + + describe('getHeaders', () => { + it('should include authorization header when API key is provided', () => { + const headers = (provider as any).getHeaders(); + expect(headers).toEqual({ + 'Content-Type': 'application/json', + Authorization: 'Bearer test-api-key', + }); + }); + + it('should not include authorization header when API key is not provided', () => { + const configWithoutKey: ProviderConfig = { + ...config, + apiKey: undefined, + }; + const providerWithoutKey = new OpenAIResponsesProvider(configWithoutKey); + const headers = (providerWithoutKey as any).getHeaders(); + expect(headers).toEqual({ + 'Content-Type': 'application/json', + }); + }); + }); +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.ts similarity index 91% rename from workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.ts rename to workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.ts index 0efa50992b9..10737ec8954 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend-module-openai-responses/src/OpenAIResponsesProvider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/openai-responses-provider.ts @@ -13,18 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-node'; import { - LLMProvider, - type ChatMessage, - type Tool, - type ChatResponse, - type MCPServerFullConfig, - type ResponsesApiResponse, - type ResponsesApiMcpTool, - type ResponsesApiMcpCall, - type ResponsesApiMessage, - type ToolCall, + ChatMessage, + Tool, + ChatResponse, + MCPServerFullConfig, + ResponsesApiResponse, + ResponsesApiMcpTool, + ResponsesApiMcpCall, + ResponsesApiMessage, + ToolCall, } from '@backstage-community/plugin-mcp-chat-common'; /** @@ -35,29 +34,17 @@ import { */ export class OpenAIResponsesProvider extends LLMProvider { private mcpServerConfigs: MCPServerFullConfig[] = []; - private lastResponseOutput: ResponsesApiResponse['output'] | null = null; - - /** Override to indicate this provider handles MCP natively. */ - supportsNativeMcp(): boolean { - return true; - } /** * Sets the MCP server configurations for native tool support. * These servers will be passed to the OpenAI Responses API. + * + * @param configs - Array of MCP server configurations */ setMcpServerConfigs(configs: MCPServerFullConfig[]): void { this.mcpServerConfigs = configs; } - /** - * Get the raw Responses API output for detailed tool execution information. - * Used by MCPClientServiceImpl to construct toolResponses. - */ - getLastResponseOutput(): ResponsesApiResponse['output'] | null { - return this.lastResponseOutput; - } - async sendMessage( messages: ChatMessage[], _tools?: Tool[], @@ -73,6 +60,8 @@ export class OpenAIResponsesProvider extends LLMProvider { error?: string; }> { try { + // For Responses API, we can test with a simple request + // Or we could check if the endpoint is reachable const response = await fetch(`${this.baseUrl}/responses`, { method: 'POST', headers: this.getHeaders(), @@ -187,6 +176,7 @@ export class OpenAIResponsesProvider extends LLMProvider { for (const event of response.output) { if (event.type === 'mcp_call') { const mcpCall = event as ResponsesApiMcpCall; + // Create a tool call in the standard format toolCalls.push({ id: mcpCall.id, type: 'function', @@ -197,6 +187,7 @@ export class OpenAIResponsesProvider extends LLMProvider { }); } else if (event.type === 'message') { const message = event as ResponsesApiMessage; + // Extract the final text content if (message.content && message.content.length > 0) { finalContent = message.content .map(part => part.text) @@ -206,6 +197,7 @@ export class OpenAIResponsesProvider extends LLMProvider { } } + // Return in standard ChatResponse format return { choices: [ { @@ -226,6 +218,16 @@ export class OpenAIResponsesProvider extends LLMProvider { }; } + /** + * Get the raw Responses API output for detailed tool execution information + * This is used by MCPClientServiceImpl to construct toolResponses + */ + getLastResponseOutput(): ResponsesApiResponse['output'] | null { + return this.lastResponseOutput; + } + + private lastResponseOutput: ResponsesApiResponse['output'] | null = null; + protected async makeRequest(endpoint: string, body: any): Promise { const url = `${this.baseUrl}${endpoint}`; this.logger?.debug(`[${this.type}] Request to ${url}`, { diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.test.ts new file mode 100644 index 00000000000..89ad7ddcd34 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.test.ts @@ -0,0 +1,372 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { mockServices } from '@backstage/backend-test-utils'; +import { + ProviderFactory, + getProviderConfig, + getProviderInfo, +} from './provider-factory'; +import { OpenAIProvider } from './openai-provider'; +import { ClaudeProvider } from './claude-provider'; +import { GeminiProvider } from './gemini-provider'; +import { OllamaProvider } from './ollama-provider'; +import { LiteLLMProvider } from './litellm-provider'; +import { type ProviderConfig } from '@backstage-community/plugin-mcp-chat-node'; + +describe('ProviderFactory', () => { + describe('createProvider', () => { + it('should create correct provider instances for supported types', () => { + const testCases = [ + { type: 'openai', expectedClass: OpenAIProvider }, + { type: 'claude', expectedClass: ClaudeProvider }, + { type: 'gemini', expectedClass: GeminiProvider }, + { type: 'ollama', expectedClass: OllamaProvider }, + { type: 'litellm', expectedClass: LiteLLMProvider }, + ]; + + testCases.forEach(({ type, expectedClass }) => { + const config: ProviderConfig = { + type, + apiKey: 'test-key', + baseUrl: 'https://example.com', + model: 'test-model', + logger: mockServices.logger.mock(), + }; + + const provider = ProviderFactory.createProvider(config); + expect(provider).toBeInstanceOf(expectedClass); + }); + }); + + it('should throw error for unsupported provider type', () => { + const config: ProviderConfig = { + type: 'unsupported', + apiKey: 'test-key', + baseUrl: 'https://example.com', + model: 'test-model', + logger: mockServices.logger.mock(), + }; + + expect(() => ProviderFactory.createProvider(config)).toThrow( + 'Unsupported provider: unsupported', + ); + }); + }); +}); + +describe('getProviderConfig', () => { + let mockConfig: ReturnType; + + beforeEach(() => { + mockConfig = mockServices.rootConfig.mock(); + }); + + it('should throw error when no providers are configured', () => { + mockConfig.getOptionalConfigArray.mockReturnValue([]); + + expect(() => getProviderConfig(mockConfig)).toThrow(); + }); + + it('should throw error for unsupported provider id', () => { + const mockProviderConfig = { + getString: jest.fn().mockImplementation((key: string) => { + if (key === 'id') return 'unsupported'; + if (key === 'model') return 'test-model'; + throw new Error(`Unexpected key: ${key}`); + }), + getOptionalString: jest.fn().mockImplementation((key: string) => { + if (key === 'baseUrl') return undefined; + return 'test-key'; + }), + } as any; + + mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); + + expect(() => getProviderConfig(mockConfig)).toThrow( + 'Unsupported provider id: unsupported. Allowed values are: openai, openai-responses, claude, gemini, ollama, litellm', + ); + }); + + it('should configure providers with correct default base URLs', () => { + const testCases = [ + { id: 'openai', expectedBaseUrl: 'https://api.openai.com/v1' }, + { id: 'claude', expectedBaseUrl: 'https://api.anthropic.com/v1' }, + { + id: 'gemini', + expectedBaseUrl: 'https://generativelanguage.googleapis.com', + }, + ]; + + testCases.forEach(({ id, expectedBaseUrl }) => { + const mockProviderConfig = { + getString: jest.fn().mockImplementation((key: string) => { + if (key === 'id') return id; + if (key === 'model') return 'test-model'; + throw new Error(`Unexpected key: ${key}`); + }), + getOptionalString: jest.fn().mockImplementation((key: string) => { + if (key === 'baseUrl') return undefined; + return 'test-key'; + }), + } as any; + + mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); + + const result = getProviderConfig(mockConfig); + expect(result.baseUrl).toBe(expectedBaseUrl); + expect(result.type).toBe(id); + expect(result.apiKey).toBe('test-key'); + expect(result.model).toBe('test-model'); + }); + }); + + it('should configure OpenAI provider with default and custom base URLs', () => { + const testCases = [ + { + customBaseUrl: undefined, + expectedBaseUrl: 'https://api.openai.com/v1', + }, + { + customBaseUrl: 'https://custom-openai.com/v1', + expectedBaseUrl: 'https://custom-openai.com/v1', + }, + ]; + + testCases.forEach(({ customBaseUrl, expectedBaseUrl }) => { + const mockProviderConfig = { + getString: jest.fn().mockImplementation((key: string) => { + if (key === 'id') return 'openai'; + if (key === 'model') return 'test-model'; + throw new Error(`Unexpected key: ${key}`); + }), + getOptionalString: jest.fn().mockImplementation((key: string) => { + if (key === 'token') return 'test-token'; + if (key === 'baseUrl') return customBaseUrl; + return undefined; + }), + } as any; + + mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); + + const result = getProviderConfig(mockConfig); + expect(result.baseUrl).toBe(expectedBaseUrl); + expect(result.type).toBe('openai'); + expect(result.apiKey).toBe('test-token'); + }); + }); + + it('should configure Ollama provider with default and custom base URLs', () => { + const testCases = [ + { customBaseUrl: undefined, expectedBaseUrl: 'http://localhost:11434' }, + { + customBaseUrl: 'http://custom:11434', + expectedBaseUrl: 'http://custom:11434', + }, + ]; + + testCases.forEach(({ customBaseUrl, expectedBaseUrl }) => { + const mockProviderConfig = { + getString: jest.fn().mockImplementation((key: string) => { + if (key === 'id') return 'ollama'; + if (key === 'model') return 'llama2'; + throw new Error(`Unexpected key: ${key}`); + }), + getOptionalString: jest.fn().mockImplementation((key: string) => { + if (key === 'token') return undefined; + if (key === 'baseUrl') return customBaseUrl; + return undefined; + }), + } as any; + + mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); + + const result = getProviderConfig(mockConfig); + expect(result.baseUrl).toBe(expectedBaseUrl); + expect(result.type).toBe('ollama'); + expect(result.apiKey).toBeUndefined(); + }); + }); + + it('should configure LiteLLM provider with default and custom base URLs', () => { + const testCases = [ + { customBaseUrl: undefined, expectedBaseUrl: 'http://localhost:4000' }, + { + customBaseUrl: 'http://custom:4000', + expectedBaseUrl: 'http://custom:4000', + }, + ]; + + testCases.forEach(({ customBaseUrl, expectedBaseUrl }) => { + const mockProviderConfig = { + getString: jest.fn().mockImplementation((key: string) => { + if (key === 'id') return 'litellm'; + if (key === 'model') return 'gpt-4o-mini'; + throw new Error(`Unexpected key: ${key}`); + }), + getOptionalString: jest.fn().mockImplementation((key: string) => { + if (key === 'token') return 'test-key'; + if (key === 'baseUrl') return customBaseUrl; + return undefined; + }), + } as any; + + mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); + + const result = getProviderConfig(mockConfig); + expect(result.baseUrl).toBe(expectedBaseUrl); + expect(result.type).toBe('litellm'); + expect(result.apiKey).toBe('test-key'); + }); + }); + + it('should allow LiteLLM provider without API key', () => { + const mockProviderConfig = { + getString: jest.fn().mockImplementation((key: string) => { + if (key === 'id') return 'litellm'; + if (key === 'model') return 'gpt-4o-mini'; + throw new Error(`Unexpected key: ${key}`); + }), + getOptionalString: jest.fn().mockImplementation((key: string) => { + if (key === 'token') return undefined; + if (key === 'baseUrl') return 'http://localhost:4000'; + return undefined; + }), + } as any; + + mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); + + const result = getProviderConfig(mockConfig); + expect(result.baseUrl).toBe('http://localhost:4000'); + expect(result.type).toBe('litellm'); + expect(result.apiKey).toBeUndefined(); + }); + + it('should throw error when API key is missing for non-Ollama/LiteLLM providers', () => { + const mockProviderConfig = { + getString: jest.fn().mockImplementation((key: string) => { + if (key === 'id') return 'openai'; + if (key === 'model') return 'gpt-4'; + throw new Error(`Unexpected key: ${key}`); + }), + getOptionalString: jest.fn().mockReturnValue(undefined), + } as any; + + mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); + + expect(() => getProviderConfig(mockConfig)).toThrow( + 'API key is required for provider: openai', + ); + }); + + it('should use first provider when multiple are configured', () => { + const mockProviderConfig1 = { + getString: jest.fn().mockImplementation((key: string) => { + if (key === 'id') return 'openai'; + if (key === 'model') return 'gpt-4'; + throw new Error(`Unexpected key: ${key}`); + }), + getOptionalString: jest.fn().mockImplementation((key: string) => { + if (key === 'baseUrl') return undefined; + return 'first-key'; + }), + } as any; + + const mockProviderConfig2 = { + getString: jest.fn().mockImplementation((key: string) => { + if (key === 'id') return 'claude'; + if (key === 'model') return 'claude-3-sonnet-20240229'; + throw new Error(`Unexpected key: ${key}`); + }), + getOptionalString: jest.fn().mockImplementation((key: string) => { + if (key === 'baseUrl') return undefined; + return 'second-key'; + }), + } as any; + + mockConfig.getOptionalConfigArray.mockReturnValue([ + mockProviderConfig1, + mockProviderConfig2, + ]); + + const result = getProviderConfig(mockConfig); + + expect(result).toEqual({ + type: 'openai', + apiKey: 'first-key', + baseUrl: 'https://api.openai.com/v1', + model: 'gpt-4', + }); + }); + + it('should throw error when model is missing', () => { + const mockProviderConfig = { + getString: jest.fn().mockImplementation((key: string) => { + if (key === 'id') return 'openai'; + if (key === 'model') return ''; + throw new Error(`Unexpected key: ${key}`); + }), + getOptionalString: jest.fn().mockImplementation((key: string) => { + if (key === 'baseUrl') return undefined; + return 'test-key'; + }), + } as any; + + mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); + + expect(() => getProviderConfig(mockConfig)).toThrow( + 'Model is required for provider: openai', + ); + }); +}); + +describe('getProviderInfo', () => { + let mockConfig: ReturnType; + + beforeEach(() => { + mockConfig = mockServices.rootConfig.mock(); + }); + + it('should return provider info from config', () => { + const mockProviderConfig = { + getString: jest.fn().mockImplementation((key: string) => { + if (key === 'id') return 'openai'; + if (key === 'model') return 'gpt-4'; + throw new Error(`Unexpected key: ${key}`); + }), + getOptionalString: jest.fn().mockImplementation((key: string) => { + if (key === 'baseUrl') return 'https://api.openai.com/v1'; + return 'test-key'; + }), + } as any; + + mockConfig.getOptionalConfigArray.mockReturnValue([mockProviderConfig]); + + const result = getProviderInfo(mockConfig); + + expect(result).toEqual({ + provider: 'openai', + model: 'gpt-4', + baseURL: 'https://api.openai.com/v1', + }); + }); + + it('should propagate errors from getProviderConfig', () => { + mockConfig.getOptionalConfigArray.mockReturnValue([]); + + expect(() => getProviderInfo(mockConfig)).toThrow(); + }); +}); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.ts new file mode 100644 index 00000000000..e7336cde1f4 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/providers/provider-factory.ts @@ -0,0 +1,189 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-node'; +import { type ProviderConfig } from '@backstage-community/plugin-mcp-chat-node'; +import { OpenAIProvider } from './openai-provider'; +import { OpenAIResponsesProvider } from './openai-responses-provider'; +import { ClaudeProvider } from './claude-provider'; +import { GeminiProvider } from './gemini-provider'; +import { OllamaProvider } from './ollama-provider'; +import { LiteLLMProvider } from './litellm-provider'; +import { + RootConfigService, + LoggerService, +} from '@backstage/backend-plugin-api'; + +/** + * Factory class for creating LLM provider instances. + * Supports OpenAI, Claude, Gemini, Ollama, LiteLLM, and OpenAI Responses API. + * + * @public + */ +export class ProviderFactory { + /** + * Creates an LLM provider instance based on the configuration. + * + * @param config - The provider configuration + * @param logger - Optional logger service for debug logging + * @returns An LLM provider instance + */ + static createProvider( + config: ProviderConfig, + logger?: LoggerService, + ): LLMProvider { + const configWithLogger = { ...config, logger }; + switch (config.type) { + case 'openai': + return new OpenAIProvider(configWithLogger); + + case 'openai-responses': + return new OpenAIResponsesProvider(configWithLogger); + + case 'claude': + return new ClaudeProvider(configWithLogger); + + case 'gemini': + return new GeminiProvider(configWithLogger); + + case 'ollama': + return new OllamaProvider(configWithLogger); + + case 'litellm': + return new LiteLLMProvider(configWithLogger); + + default: + throw new Error(`Unsupported provider: ${config.type}`); + } + } +} + +/** + * Parses and returns the LLM provider configuration from Backstage config. + * Reads from mcpChat.providers configuration section. + * + * @param config - The Backstage root config service + * @returns The provider configuration + * @public + */ +export function getProviderConfig(config: RootConfigService): ProviderConfig { + const providers = config.getOptionalConfigArray('mcpChat.providers') || []; + + // For now, use the first provider. In the future, you might want to support multiple providers + const providerConfig = providers[0]; + const providerId = providerConfig.getString('id'); + const token = providerConfig.getOptionalString('token'); + const model = providerConfig.getString('model'); + + const allowedProviders = [ + 'openai', + 'openai-responses', + 'claude', + 'gemini', + 'ollama', + 'litellm', + ]; + if (!allowedProviders.includes(providerId)) { + throw new Error( + `Unsupported provider id: ${providerId}. Allowed values are: ${allowedProviders.join( + ', ', + )}`, + ); + } + + const configs: Record> = { + openai: { + type: 'openai', + apiKey: token, + baseUrl: + providerConfig.getOptionalString('baseUrl') || + 'https://api.openai.com/v1', + model: model, + }, + + 'openai-responses': { + type: 'openai-responses', + apiKey: token, + baseUrl: providerConfig.getOptionalString('baseUrl') || '', + model: model, + }, + + claude: { + type: 'claude', + apiKey: token, + baseUrl: 'https://api.anthropic.com/v1', + model: model, + }, + + gemini: { + type: 'gemini', + apiKey: token, + baseUrl: 'https://generativelanguage.googleapis.com', + model: model, + }, + + ollama: { + type: 'ollama', + // No API key needed for Ollama + baseUrl: + providerConfig.getOptionalString('baseUrl') || 'http://localhost:11434', + model: model, + }, + + litellm: { + type: 'litellm', + apiKey: token, // Optional, depends on LiteLLM configuration + baseUrl: + providerConfig.getOptionalString('baseUrl') || 'http://localhost:4000', + model: model, + }, + }; + + const configTemplate = configs[providerId]; + if (!configTemplate) { + throw new Error(`Unknown provider: ${providerId}`); + } + + // Validate required fields + // Ollama, LiteLLM, and OpenAI Responses can work without API keys depending on configuration + const noApiKeyRequired = ['ollama', 'litellm', 'openai-responses']; + if (!noApiKeyRequired.includes(providerId) && !configTemplate.apiKey) { + throw new Error(`API key is required for provider: ${providerId}`); + } + if (!configTemplate.baseUrl) { + throw new Error(`Base URL is required for provider: ${providerId}`); + } + if (!configTemplate.model) { + throw new Error(`Model is required for provider: ${providerId}`); + } + + return configTemplate as ProviderConfig; +} + +/** + * Returns provider information for status display purposes. + * + * @param config - The Backstage root config service + * @returns Provider info including type, model, and base URL + * @public + */ +export function getProviderInfo(config: RootConfigService) { + const providerConfig = getProviderConfig(config); + return { + provider: providerConfig.type, + model: providerConfig.model, + baseURL: providerConfig.baseUrl, + }; +} diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.test.ts index 7bc955a61b7..fa80edff173 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.test.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.test.ts @@ -26,6 +26,7 @@ jest.mock('@modelcontextprotocol/sdk/client/index.js'); jest.mock('@modelcontextprotocol/sdk/client/streamableHttp.js'); jest.mock('@modelcontextprotocol/sdk/client/stdio.js'); jest.mock('@modelcontextprotocol/sdk/client/sse.js'); +jest.mock('../providers/provider-factory'); jest.mock('../utils'); const { Client } = require('@modelcontextprotocol/sdk/client/index.js'); @@ -35,6 +36,7 @@ const { const { StdioClientTransport, } = require('@modelcontextprotocol/sdk/client/stdio.js'); +const providerFactory = require('../providers/provider-factory'); const utils = require('../utils'); describe('MCPClientServiceImpl', () => { @@ -53,12 +55,6 @@ describe('MCPClientServiceImpl', () => { mockLLMProvider = { sendMessage: jest.fn(), testConnection: jest.fn(), - getType: jest.fn().mockReturnValue('openai'), - getModel: jest.fn().mockReturnValue('gpt-4'), - getBaseUrl: jest.fn().mockReturnValue('https://api.openai.com/v1'), - supportsNativeMcp: jest.fn().mockReturnValue(false), - setMcpServerConfigs: jest.fn(), - getLastResponseOutput: jest.fn().mockReturnValue(null), }; mockClient = { @@ -67,6 +63,23 @@ describe('MCPClientServiceImpl', () => { callTool: jest.fn(), }; + providerFactory.getProviderConfig.mockReturnValue({ + type: 'openai', + apiKey: 'test-key', + baseUrl: 'https://api.openai.com/v1', + model: 'gpt-4', + }); + + providerFactory.ProviderFactory.createProvider.mockReturnValue( + mockLLMProvider, + ); + + providerFactory.getProviderInfo.mockReturnValue({ + provider: 'openai', + model: 'gpt-4', + baseURL: 'https://api.openai.com/v1', + }); + utils.loadServerConfigs.mockReturnValue([]); utils.findNpxPath.mockResolvedValue('/usr/local/bin/npx'); utils.executeToolCall.mockResolvedValue({ @@ -85,10 +98,27 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, - provider: mockLLMProvider, }); expect(service).toBeDefined(); + expect(providerFactory.getProviderConfig).toHaveBeenCalledWith( + mockConfig, + ); + expect(providerFactory.ProviderFactory.createProvider).toHaveBeenCalled(); + }); + + it('should throw error when LLM provider configuration is invalid', () => { + providerFactory.getProviderConfig.mockImplementation(() => { + throw new Error('Invalid provider configuration'); + }); + + expect( + () => + new MCPClientServiceImpl({ + logger: mockLogger, + config: mockConfig, + }), + ).toThrow('Invalid provider configuration'); }); }); @@ -97,7 +127,6 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, - provider: mockLLMProvider, }); }); @@ -243,7 +272,6 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, - provider: mockLLMProvider, }); }); @@ -270,15 +298,15 @@ describe('MCPClientServiceImpl', () => { }); it('should handle provider status errors', async () => { - mockLLMProvider.testConnection.mockRejectedValue( - new Error('Provider connection failed'), - ); + providerFactory.getProviderInfo.mockImplementation(() => { + throw new Error('Provider info failed'); + }); const status = await service.getProviderStatus(); expect(status.providers).toHaveLength(0); expect(status.summary.totalProviders).toBe(0); - expect(status.summary.error).toBe('Provider connection failed'); + expect(status.summary.error).toBe('Provider info failed'); expect(status.timestamp).toBeDefined(); }); @@ -317,7 +345,6 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, - provider: mockLLMProvider, }); const servers = await service.initializeMCPServers(); @@ -343,7 +370,6 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, - provider: mockLLMProvider, }); const servers = await service.initializeMCPServers(); @@ -375,7 +401,6 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, - provider: mockLLMProvider, }); await service.initializeMCPServers(); @@ -406,7 +431,6 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, - provider: mockLLMProvider, }); const servers = await service.initializeMCPServers(); @@ -422,7 +446,6 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, - provider: mockLLMProvider, }); const tools = service.getAvailableTools(); @@ -456,7 +479,6 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, - provider: mockLLMProvider, }); await service.processQuery([{ role: 'user', content: 'Hello' }], []); @@ -496,7 +518,6 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, - provider: mockLLMProvider, }); await service.processQuery([{ role: 'user', content: 'Hello' }], []); @@ -542,7 +563,6 @@ describe('MCPClientServiceImpl', () => { service = new MCPClientServiceImpl({ logger: mockLogger, config: mockConfig, - provider: mockLLMProvider, }); await service.processQuery( diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.ts b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.ts index ac3fff064d6..9c17af31a96 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/src/services/MCPClientServiceImpl.ts @@ -21,8 +21,14 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js'; import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'; import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; import * as path from 'path'; +import { + ProviderFactory, + getProviderConfig as getConfig, + getProviderInfo, +} from '../providers/provider-factory'; import { executeToolCall, findNpxPath, loadServerConfigs } from '../utils'; -import { LLMProvider } from '../providers/base-provider'; +import { LLMProvider } from '@backstage-community/plugin-mcp-chat-node'; +import { OpenAIResponsesProvider } from '../providers/openai-responses-provider'; import { MCPClientService } from './MCPClientService'; import { ChatMessage, @@ -45,7 +51,6 @@ import { export type Options = { logger: LoggerService; config: RootConfigService; - provider: LLMProvider; }; /** @@ -68,13 +73,34 @@ export class MCPClientServiceImpl implements MCPClientService { constructor(options: Options) { this.logger = options.logger; this.config = options.config; - this.llmProvider = options.provider; + this.llmProvider = this.initializeLLMProvider(); this.mcpServers = this.initializeMCPServers(); this.systemPrompt = this.config.getOptionalString('mcpChat.systemPrompt') || "You are a helpful assistant. When using tools, provide a clear, readable summary of the results rather than showing raw data. Focus on answering the user's question with the information gathered."; } + private initializeLLMProvider(): LLMProvider { + try { + const providerConfig = getConfig(this.config); + const llmProvider = ProviderFactory.createProvider( + providerConfig, + this.logger, + ); + this.logger.info( + `Using LLM Provider: ${providerConfig.type}, Model: ${providerConfig.model}`, + ); + return llmProvider; + } catch (error) { + this.logger.error( + `Failed to initialize LLM provider: ${ + error instanceof Error ? error.message : String(error) + }`, + ); + throw error; + } + } + async initializeMCPServers(): Promise { // If initialization is already in progress or completed, return the same promise if (this.mcpServers) { @@ -98,8 +124,9 @@ export class MCPClientServiceImpl implements MCPClientService { // Store server configs for Responses API provider this.serverConfigs = serverConfigs; - // Check if using native MCP provider - initialize local MCP for tool discovery - if (this.llmProvider.supportsNativeMcp()) { + // Check if using Responses API provider - initialize local MCP for tool discovery + const providerConfig = getConfig(this.config); + if (providerConfig.type === 'openai-responses') { this.logger.info( 'Using OpenAI Responses API - initializing local MCP for tool discovery', ); @@ -401,8 +428,9 @@ export class MCPClientServiceImpl implements MCPClientService { }); } - // Check if using native MCP provider - if (this.llmProvider.supportsNativeMcp()) { + // Check if using Responses API provider + const providerConfig = getConfig(this.config); + if (providerConfig.type === 'openai-responses') { return this.processQueryWithResponsesApi(messages, enabledTools); } @@ -516,7 +544,9 @@ export class MCPClientServiceImpl implements MCPClientService { : this.serverConfigs; // Set the filtered configs on the provider - this.llmProvider.setMcpServerConfigs(enabledServerConfigs); + if (this.llmProvider instanceof OpenAIResponsesProvider) { + this.llmProvider.setMcpServerConfigs(enabledServerConfigs); + } // Send message - the provider handles MCP tool configuration internally const response = await this.llmProvider.sendMessage(messages); @@ -527,20 +557,22 @@ export class MCPClientServiceImpl implements MCPClientService { const toolResponses: any[] = []; // Get the raw output from the provider to extract tool execution details - const output = this.llmProvider.getLastResponseOutput(); - if (output) { - for (const event of output) { - if (event.type === 'mcp_call') { - const mcpCall = event as ResponsesApiMcpCall; - // Build tool response in the format expected by the UI - toolResponses.push({ - id: mcpCall.id, - name: mcpCall.name, - arguments: JSON.parse(mcpCall.arguments || '{}'), - result: mcpCall.error || mcpCall.output, - serverId: mcpCall.server_label, - error: mcpCall.error, - }); + if (this.llmProvider instanceof OpenAIResponsesProvider) { + const output = this.llmProvider.getLastResponseOutput(); + if (output) { + for (const event of output) { + if (event.type === 'mcp_call') { + const mcpCall = event as ResponsesApiMcpCall; + // Build tool response in the format expected by the UI + toolResponses.push({ + id: mcpCall.id, + name: mcpCall.name, + arguments: JSON.parse(mcpCall.arguments || '{}'), + result: mcpCall.error || mcpCall.output, + serverId: mcpCall.server_label, + error: mcpCall.error, + }); + } } } } @@ -562,14 +594,15 @@ export class MCPClientServiceImpl implements MCPClientService { async getProviderStatus(): Promise { try { + const info = getProviderInfo(this.config); const status = await this.llmProvider.testConnection(); - // Derive provider info from the injected provider instance + // Structure for future multi-provider support const providers = [ { - id: this.llmProvider.getType(), - model: this.llmProvider.getModel(), - baseUrl: this.llmProvider.getBaseUrl(), + id: info.provider, + model: info.model, + baseUrl: info.baseURL, connection: { connected: status.connected, models: status.models || [], diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-common/src/index.ts index 5b7618a42c1..0b7c9c3c5f0 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-common/src/index.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/src/index.ts @@ -20,17 +20,11 @@ * @packageDocumentation */ -// ============================================================================= -// LLM Provider Base Class -// ============================================================================= -export { LLMProvider } from './base-provider'; - // ============================================================================= // Types // ============================================================================= export type { // Provider types - ProviderConfig, ProviderStatusData, ProviderInfo, ProviderConnectionStatus, diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts b/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts index a5cfd1a7ec5..51f7839f998 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/src/types.ts @@ -159,38 +159,6 @@ export interface MCPServerStatusData { // LLM Provider Configuration Types // ============================================================================= -/** - * Configuration for an LLM provider. - * - * @example - * ```typescript - * const openaiConfig: ProviderConfig = { - * type: 'openai', - * apiKey: 'sk-...', - * baseUrl: 'https://api.openai.com/v1', - * model: 'gpt-4' - * }; - * - * const ollamaConfig: ProviderConfig = { - * type: 'ollama', - * baseUrl: 'http://localhost:11434', - * model: 'llama2' - * }; - * ``` - * - * @public - */ -export interface ProviderConfig { - /** Provider type identifier */ - type: string; - /** API key for authentication (optional for local providers like Ollama) */ - apiKey?: string; - /** Base URL for the provider's API */ - baseUrl: string; - /** Model identifier to use */ - model: string; -} - /** * Runtime information about an active LLM provider. * Used for status display and monitoring. diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.test.ts b/workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.test.ts index a49f99e0d2c..2af3b06a37a 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.test.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.test.ts @@ -16,11 +16,11 @@ import { mockServices } from '@backstage/backend-test-utils'; import { LLMProvider } from './base-provider'; +import { type ProviderConfig } from './types'; import { ChatMessage, Tool, ChatResponse, - ProviderConfig, } from '@backstage-community/plugin-mcp-chat-common'; global.fetch = jest.fn(); diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.ts b/workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.ts index 631c693849a..c4284b3bccf 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/src/base-provider.ts @@ -19,8 +19,8 @@ import { ChatMessage, Tool, ChatResponse, - ProviderConfig, } from '@backstage-community/plugin-mcp-chat-common'; +import { type ProviderConfig } from './types'; /** * Abstract base class for all LLM providers. diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/src/index.ts b/workspaces/mcp-chat/plugins/mcp-chat-node/src/index.ts index 71a7e7ddd15..3714b5db815 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-node/src/index.ts +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/src/index.ts @@ -26,3 +26,4 @@ export { } from './extensions'; export { LLMProvider } from './base-provider'; +export type { ProviderConfig } from './types'; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/src/types.ts b/workspaces/mcp-chat/plugins/mcp-chat-node/src/types.ts new file mode 100644 index 00000000000..6759a100cb4 --- /dev/null +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/src/types.ts @@ -0,0 +1,55 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { LoggerService } from '@backstage/backend-plugin-api'; + +// ============================================================================= +// LLM Provider Configuration Types +// ============================================================================= + +/** + * Configuration for an LLM provider. + * + * @example + * ```typescript + * const openaiConfig: ProviderConfig = { + * type: 'openai', + * apiKey: 'sk-...', + * baseUrl: 'https://api.openai.com/v1', + * model: 'gpt-4' + * }; + * + * const ollamaConfig: ProviderConfig = { + * type: 'ollama', + * baseUrl: 'http://localhost:11434', + * model: 'llama2' + * }; + * ``` + * + * @public + */ +export interface ProviderConfig { + /** Provider type identifier */ + type: string; + /** API key for authentication (optional for local providers like Ollama) */ + apiKey?: string; + /** Base URL for the provider's API */ + baseUrl: string; + /** Model identifier to use */ + model: string; + /** Logger for debugging */ + logger?: LoggerService; +} diff --git a/workspaces/mcp-chat/yarn.lock b/workspaces/mcp-chat/yarn.lock index 1b4a809cec1..a670a7f8a41 100644 --- a/workspaces/mcp-chat/yarn.lock +++ b/workspaces/mcp-chat/yarn.lock @@ -165,61 +165,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-bedrock-runtime@npm:^3.0.0": - version: 3.1019.0 - resolution: "@aws-sdk/client-bedrock-runtime@npm:3.1019.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:^3.973.25" - "@aws-sdk/credential-provider-node": "npm:^3.972.27" - "@aws-sdk/eventstream-handler-node": "npm:^3.972.12" - "@aws-sdk/middleware-eventstream": "npm:^3.972.8" - "@aws-sdk/middleware-host-header": "npm:^3.972.8" - "@aws-sdk/middleware-logger": "npm:^3.972.8" - "@aws-sdk/middleware-recursion-detection": "npm:^3.972.9" - "@aws-sdk/middleware-user-agent": "npm:^3.972.26" - "@aws-sdk/middleware-websocket": "npm:^3.972.14" - "@aws-sdk/region-config-resolver": "npm:^3.972.10" - "@aws-sdk/token-providers": "npm:3.1019.0" - "@aws-sdk/types": "npm:^3.973.6" - "@aws-sdk/util-endpoints": "npm:^3.996.5" - "@aws-sdk/util-user-agent-browser": "npm:^3.972.8" - "@aws-sdk/util-user-agent-node": "npm:^3.973.12" - "@smithy/config-resolver": "npm:^4.4.13" - "@smithy/core": "npm:^3.23.12" - "@smithy/eventstream-serde-browser": "npm:^4.2.12" - "@smithy/eventstream-serde-config-resolver": "npm:^4.3.12" - "@smithy/eventstream-serde-node": "npm:^4.2.12" - "@smithy/fetch-http-handler": "npm:^5.3.15" - "@smithy/hash-node": "npm:^4.2.12" - "@smithy/invalid-dependency": "npm:^4.2.12" - "@smithy/middleware-content-length": "npm:^4.2.12" - "@smithy/middleware-endpoint": "npm:^4.4.27" - "@smithy/middleware-retry": "npm:^4.4.44" - "@smithy/middleware-serde": "npm:^4.2.15" - "@smithy/middleware-stack": "npm:^4.2.12" - "@smithy/node-config-provider": "npm:^4.3.12" - "@smithy/node-http-handler": "npm:^4.5.0" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/smithy-client": "npm:^4.12.7" - "@smithy/types": "npm:^4.13.1" - "@smithy/url-parser": "npm:^4.2.12" - "@smithy/util-base64": "npm:^4.3.2" - "@smithy/util-body-length-browser": "npm:^4.2.2" - "@smithy/util-body-length-node": "npm:^4.2.3" - "@smithy/util-defaults-mode-browser": "npm:^4.3.43" - "@smithy/util-defaults-mode-node": "npm:^4.2.47" - "@smithy/util-endpoints": "npm:^3.3.3" - "@smithy/util-middleware": "npm:^4.2.12" - "@smithy/util-retry": "npm:^4.2.12" - "@smithy/util-stream": "npm:^4.5.20" - "@smithy/util-utf8": "npm:^4.2.2" - tslib: "npm:^2.6.2" - checksum: 10/698b5448e7028fb8f7c679c3e007ebbb45f70fe67c73f0e53ec4c829ef7b97813b91b764a431ea4d3a39498dc487508bb643dc7c0b5a946a48f686139d77ff66 - languageName: node - linkType: hard - "@aws-sdk/client-codecommit@npm:^3.350.0": version: 3.1019.0 resolution: "@aws-sdk/client-codecommit@npm:3.1019.0" @@ -630,18 +575,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/eventstream-handler-node@npm:^3.972.12": - version: 3.972.12 - resolution: "@aws-sdk/eventstream-handler-node@npm:3.972.12" - dependencies: - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/eventstream-codec": "npm:^4.2.12" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/6f90ac1cb9faf204984c9dead9022ec79325b6565f03d87137f4636e653ff6ad03944ee0417b136effdcc5591419587673b54fc065e4f02c9ca67f42f8f8dbed - languageName: node - linkType: hard - "@aws-sdk/middleware-bucket-endpoint@npm:^3.972.8": version: 3.972.8 resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.972.8" @@ -657,18 +590,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-eventstream@npm:^3.972.8": - version: 3.972.8 - resolution: "@aws-sdk/middleware-eventstream@npm:3.972.8" - dependencies: - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/d69ea8e3787c30d1cec0f90568a1b1697f6a78db1368536bf2254becd2e4470c4b5009ab9742b74eab655086c7587e5a4c32df26a40af1b1693ac185ac7abb66 - languageName: node - linkType: hard - "@aws-sdk/middleware-expect-continue@npm:^3.972.8": version: 3.972.8 resolution: "@aws-sdk/middleware-expect-continue@npm:3.972.8" @@ -799,26 +720,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-websocket@npm:^3.972.14": - version: 3.972.14 - resolution: "@aws-sdk/middleware-websocket@npm:3.972.14" - dependencies: - "@aws-sdk/types": "npm:^3.973.6" - "@aws-sdk/util-format-url": "npm:^3.972.8" - "@smithy/eventstream-codec": "npm:^4.2.12" - "@smithy/eventstream-serde-browser": "npm:^4.2.12" - "@smithy/fetch-http-handler": "npm:^5.3.15" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/signature-v4": "npm:^5.3.12" - "@smithy/types": "npm:^4.13.1" - "@smithy/util-base64": "npm:^4.3.2" - "@smithy/util-hex-encoding": "npm:^4.2.2" - "@smithy/util-utf8": "npm:^4.2.2" - tslib: "npm:^2.6.2" - checksum: 10/ed114e4d0f8222dec2dfdde9ad3742014bd258ee02dab2e79236dd77f64147162be4ced63aeb0f00bc70c144e47fd252ca3254a757125fc6d385df8f0a6651ad - languageName: node - linkType: hard - "@aws-sdk/nested-clients@npm:^3.996.16": version: 3.996.16 resolution: "@aws-sdk/nested-clients@npm:3.996.16" @@ -917,7 +818,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/types@npm:^3.0.0, @aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0, @aws-sdk/types@npm:^3.973.6": +"@aws-sdk/types@npm:^3.222.0, @aws-sdk/types@npm:^3.347.0, @aws-sdk/types@npm:^3.973.6": version: 3.973.6 resolution: "@aws-sdk/types@npm:3.973.6" dependencies: @@ -949,18 +850,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-format-url@npm:^3.972.8": - version: 3.972.8 - resolution: "@aws-sdk/util-format-url@npm:3.972.8" - dependencies: - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/querystring-builder": "npm:^4.2.12" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/37aa7d0e47b32fbfbb9b6d2c7ec03512191cac3eab7ce45c996dd19b77d5317cf2e1636d90de87313a5604c3c7fb2f8a426c8fbb6f39f672f3774ca8a5e72d19 - languageName: node - linkType: hard - "@aws-sdk/util-locate-window@npm:^3.0.0": version: 3.965.5 resolution: "@aws-sdk/util-locate-window@npm:3.965.5" @@ -2635,110 +2524,20 @@ __metadata: languageName: node linkType: hard -"@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock@workspace:^, @backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock@workspace:plugins/mcp-chat-backend-module-amazon-bedrock": - version: 0.0.0-use.local - resolution: "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock@workspace:plugins/mcp-chat-backend-module-amazon-bedrock" - dependencies: - "@aws-sdk/client-bedrock-runtime": "npm:^3.0.0" - "@aws-sdk/types": "npm:^3.0.0" - "@backstage-community/plugin-mcp-chat-common": "workspace:^" - "@backstage-community/plugin-mcp-chat-node": "workspace:^" - "@backstage/backend-plugin-api": "npm:^1.4.0" - "@backstage/cli": "npm:^0.33.0" - "@backstage/config": "npm:^1.3.0" - "@backstage/integration-aws-node": "npm:^0.1.20" - languageName: unknown - linkType: soft - -"@backstage-community/plugin-mcp-chat-backend-module-anthropic@workspace:plugins/mcp-chat-backend-module-anthropic": - version: 0.0.0-use.local - resolution: "@backstage-community/plugin-mcp-chat-backend-module-anthropic@workspace:plugins/mcp-chat-backend-module-anthropic" - dependencies: - "@backstage-community/plugin-mcp-chat-common": "workspace:^" - "@backstage-community/plugin-mcp-chat-node": "workspace:^" - "@backstage/backend-plugin-api": "npm:^1.4.0" - "@backstage/cli": "npm:^0.33.0" - "@backstage/config": "npm:^1.3.0" - languageName: unknown - linkType: soft - -"@backstage-community/plugin-mcp-chat-backend-module-gemini@workspace:plugins/mcp-chat-backend-module-gemini": - version: 0.0.0-use.local - resolution: "@backstage-community/plugin-mcp-chat-backend-module-gemini@workspace:plugins/mcp-chat-backend-module-gemini" - dependencies: - "@backstage-community/plugin-mcp-chat-common": "workspace:^" - "@backstage-community/plugin-mcp-chat-node": "workspace:^" - "@backstage/backend-plugin-api": "npm:^1.4.0" - "@backstage/cli": "npm:^0.33.0" - "@backstage/config": "npm:^1.3.0" - "@google/genai": "npm:^1.41.0" - languageName: unknown - linkType: soft - -"@backstage-community/plugin-mcp-chat-backend-module-litellm@workspace:plugins/mcp-chat-backend-module-litellm": - version: 0.0.0-use.local - resolution: "@backstage-community/plugin-mcp-chat-backend-module-litellm@workspace:plugins/mcp-chat-backend-module-litellm" - dependencies: - "@backstage-community/plugin-mcp-chat-common": "workspace:^" - "@backstage-community/plugin-mcp-chat-node": "workspace:^" - "@backstage/backend-plugin-api": "npm:^1.4.0" - "@backstage/cli": "npm:^0.33.0" - "@backstage/config": "npm:^1.3.0" - languageName: unknown - linkType: soft - -"@backstage-community/plugin-mcp-chat-backend-module-ollama@workspace:plugins/mcp-chat-backend-module-ollama": - version: 0.0.0-use.local - resolution: "@backstage-community/plugin-mcp-chat-backend-module-ollama@workspace:plugins/mcp-chat-backend-module-ollama" - dependencies: - "@backstage-community/plugin-mcp-chat-common": "workspace:^" - "@backstage-community/plugin-mcp-chat-node": "workspace:^" - "@backstage/backend-plugin-api": "npm:^1.4.0" - "@backstage/cli": "npm:^0.33.0" - "@backstage/config": "npm:^1.3.0" - ollama: "npm:^0.6.0" - languageName: unknown - linkType: soft - -"@backstage-community/plugin-mcp-chat-backend-module-openai-responses@workspace:plugins/mcp-chat-backend-module-openai-responses": - version: 0.0.0-use.local - resolution: "@backstage-community/plugin-mcp-chat-backend-module-openai-responses@workspace:plugins/mcp-chat-backend-module-openai-responses" - dependencies: - "@backstage-community/plugin-mcp-chat-common": "workspace:^" - "@backstage-community/plugin-mcp-chat-node": "workspace:^" - "@backstage/backend-plugin-api": "npm:^1.4.0" - "@backstage/cli": "npm:^0.33.0" - "@backstage/config": "npm:^1.3.0" - languageName: unknown - linkType: soft - -"@backstage-community/plugin-mcp-chat-backend-module-openai@workspace:^, @backstage-community/plugin-mcp-chat-backend-module-openai@workspace:plugins/mcp-chat-backend-module-openai": - version: 0.0.0-use.local - resolution: "@backstage-community/plugin-mcp-chat-backend-module-openai@workspace:plugins/mcp-chat-backend-module-openai" - dependencies: - "@backstage-community/plugin-mcp-chat-common": "workspace:^" - "@backstage-community/plugin-mcp-chat-node": "workspace:^" - "@backstage/backend-plugin-api": "npm:^1.4.0" - "@backstage/cli": "npm:^0.33.0" - "@backstage/config": "npm:^1.3.0" - languageName: unknown - linkType: soft - "@backstage-community/plugin-mcp-chat-backend@workspace:plugins/mcp-chat-backend": version: 0.0.0-use.local resolution: "@backstage-community/plugin-mcp-chat-backend@workspace:plugins/mcp-chat-backend" dependencies: - "@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock": "workspace:^" - "@backstage-community/plugin-mcp-chat-backend-module-openai": "workspace:^" "@backstage-community/plugin-mcp-chat-common": "workspace:^" "@backstage-community/plugin-mcp-chat-node": "workspace:^" - "@backstage/backend-defaults": "npm:^0.11.0" - "@backstage/backend-plugin-api": "npm:^1.4.0" + "@backstage/backend-defaults": "npm:^0.16.0" + "@backstage/backend-plugin-api": "npm:^1.8.0" "@backstage/backend-test-utils": "npm:^1.6.0" "@backstage/cli": "npm:^0.33.0" - "@backstage/config": "npm:^1.3.0" + "@backstage/config": "npm:^1.3.6" "@backstage/errors": "npm:^1.2.7" "@backstage/plugin-catalog-node": "npm:^2.1.0" + "@google/genai": "npm:^1.41.0" "@modelcontextprotocol/sdk": "npm:^1.25.2" "@types/express": "npm:^4.17.6" "@types/supertest": "npm:^7.0.0" @@ -2746,6 +2545,7 @@ __metadata: express: "npm:^4.22.0" express-promise-router: "npm:^4.1.0" knex: "npm:^3.1.0" + ollama: "npm:^0.6.0" supertest: "npm:^7.0.0" uuid: "npm:^11.0.0" languageName: unknown @@ -2828,7 +2628,7 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-app-api@npm:^1.2.5, @backstage/backend-app-api@npm:^1.6.0": +"@backstage/backend-app-api@npm:^1.6.0": version: 1.6.0 resolution: "@backstage/backend-app-api@npm:1.6.0" dependencies: @@ -2839,89 +2639,6 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-defaults@npm:^0.11.0": - version: 0.11.1 - resolution: "@backstage/backend-defaults@npm:0.11.1" - dependencies: - "@aws-sdk/abort-controller": "npm:^3.347.0" - "@aws-sdk/client-codecommit": "npm:^3.350.0" - "@aws-sdk/client-s3": "npm:^3.350.0" - "@aws-sdk/credential-providers": "npm:^3.350.0" - "@aws-sdk/types": "npm:^3.347.0" - "@azure/storage-blob": "npm:^12.5.0" - "@backstage/backend-app-api": "npm:^1.2.5" - "@backstage/backend-dev-utils": "npm:^0.1.5" - "@backstage/backend-plugin-api": "npm:^1.4.1" - "@backstage/cli-node": "npm:^0.2.13" - "@backstage/config": "npm:^1.3.3" - "@backstage/config-loader": "npm:^1.10.2" - "@backstage/errors": "npm:^1.2.7" - "@backstage/integration": "npm:^1.17.1" - "@backstage/integration-aws-node": "npm:^0.1.17" - "@backstage/plugin-auth-node": "npm:^0.6.5" - "@backstage/plugin-events-node": "npm:^0.4.13" - "@backstage/plugin-permission-node": "npm:^0.10.2" - "@backstage/types": "npm:^1.2.1" - "@google-cloud/storage": "npm:^7.0.0" - "@keyv/memcache": "npm:^2.0.1" - "@keyv/redis": "npm:^4.0.1" - "@keyv/valkey": "npm:^1.0.1" - "@manypkg/get-packages": "npm:^1.1.3" - "@octokit/rest": "npm:^19.0.3" - "@opentelemetry/api": "npm:^1.9.0" - "@types/cors": "npm:^2.8.6" - "@types/express": "npm:^4.17.6" - archiver: "npm:^7.0.0" - base64-stream: "npm:^1.0.0" - better-sqlite3: "npm:^11.0.0" - compression: "npm:^1.7.4" - concat-stream: "npm:^2.0.0" - cookie: "npm:^0.7.0" - cors: "npm:^2.8.5" - cron: "npm:^3.0.0" - express: "npm:^4.17.1" - express-promise-router: "npm:^4.1.0" - express-rate-limit: "npm:^7.5.0" - fs-extra: "npm:^11.2.0" - git-url-parse: "npm:^15.0.0" - helmet: "npm:^6.0.0" - is-glob: "npm:^4.0.3" - jose: "npm:^5.0.0" - keyv: "npm:^5.2.1" - knex: "npm:^3.0.0" - lodash: "npm:^4.17.21" - logform: "npm:^2.3.2" - luxon: "npm:^3.0.0" - minimatch: "npm:^9.0.0" - mysql2: "npm:^3.0.0" - node-fetch: "npm:^2.7.0" - node-forge: "npm:^1.3.1" - p-limit: "npm:^3.1.0" - path-to-regexp: "npm:^8.0.0" - pg: "npm:^8.11.3" - pg-connection-string: "npm:^2.3.0" - pg-format: "npm:^1.0.4" - rate-limit-redis: "npm:^4.2.0" - raw-body: "npm:^2.4.1" - selfsigned: "npm:^2.0.0" - tar: "npm:^6.1.12" - triple-beam: "npm:^1.4.1" - uuid: "npm:^11.0.0" - winston: "npm:^3.2.1" - winston-transport: "npm:^4.5.0" - yauzl: "npm:^3.0.0" - yn: "npm:^4.0.0" - zod: "npm:^3.22.4" - zod-to-json-schema: "npm:^3.20.4" - peerDependencies: - "@google-cloud/cloud-sql-connector": ^1.4.0 - peerDependenciesMeta: - "@google-cloud/cloud-sql-connector": - optional: true - checksum: 10/984df8217c5c84221437e528b780fecaf0a7cd73106a51924c169ed65f2f829e42ac8ced53ac37613a6d6534d41483ac28db6ef1de6b9f9f714c416c139539b7 - languageName: node - linkType: hard - "@backstage/backend-defaults@npm:^0.16.0": version: 0.16.0 resolution: "@backstage/backend-defaults@npm:0.16.0" @@ -3010,14 +2727,14 @@ __metadata: languageName: node linkType: hard -"@backstage/backend-dev-utils@npm:^0.1.5, @backstage/backend-dev-utils@npm:^0.1.7": +"@backstage/backend-dev-utils@npm:^0.1.7": version: 0.1.7 resolution: "@backstage/backend-dev-utils@npm:0.1.7" checksum: 10/c10ca3636d48dc5963f269f3b5c504bb48956ca5d90b54895b4e5c76e05c5813f1f498e58f0020f99d073abedc2b31c76083e720e01252a1726940249663d09b languageName: node linkType: hard -"@backstage/backend-plugin-api@npm:^1.4.0, @backstage/backend-plugin-api@npm:^1.4.1, @backstage/backend-plugin-api@npm:^1.8.0": +"@backstage/backend-plugin-api@npm:^1.4.0, @backstage/backend-plugin-api@npm:^1.8.0": version: 1.8.0 resolution: "@backstage/backend-plugin-api@npm:1.8.0" dependencies: @@ -3708,7 +3425,7 @@ __metadata: languageName: node linkType: hard -"@backstage/config@npm:^1.3.0, @backstage/config@npm:^1.3.3, @backstage/config@npm:^1.3.6": +"@backstage/config@npm:^1.3.3, @backstage/config@npm:^1.3.6": version: 1.3.6 resolution: "@backstage/config@npm:1.3.6" dependencies: @@ -3963,7 +3680,7 @@ __metadata: languageName: node linkType: hard -"@backstage/integration-aws-node@npm:^0.1.17, @backstage/integration-aws-node@npm:^0.1.20": +"@backstage/integration-aws-node@npm:^0.1.20": version: 0.1.20 resolution: "@backstage/integration-aws-node@npm:0.1.20" dependencies: @@ -4080,7 +3797,7 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-auth-node@npm:^0.6.14, @backstage/plugin-auth-node@npm:^0.6.5": +"@backstage/plugin-auth-node@npm:^0.6.14": version: 0.6.14 resolution: "@backstage/plugin-auth-node@npm:0.6.14" dependencies: @@ -4183,7 +3900,7 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-events-node@npm:^0.4.13, @backstage/plugin-events-node@npm:^0.4.20": +"@backstage/plugin-events-node@npm:^0.4.20": version: 0.4.20 resolution: "@backstage/plugin-events-node@npm:0.4.20" dependencies: @@ -4215,7 +3932,7 @@ __metadata: languageName: node linkType: hard -"@backstage/plugin-permission-node@npm:^0.10.11, @backstage/plugin-permission-node@npm:^0.10.2": +"@backstage/plugin-permission-node@npm:^0.10.11": version: 0.10.11 resolution: "@backstage/plugin-permission-node@npm:0.10.11" dependencies: @@ -14418,17 +14135,6 @@ __metadata: languageName: node linkType: hard -"better-sqlite3@npm:^11.0.0": - version: 11.10.0 - resolution: "better-sqlite3@npm:11.10.0" - dependencies: - bindings: "npm:^1.5.0" - node-gyp: "npm:latest" - prebuild-install: "npm:^7.1.1" - checksum: 10/5e4c7437c4fe6033335a79c82974d7ab29f33c51c36f48b73e87e087d21578468575de1c56a7badd4f76f17255e25abefddaeacf018e5eeb9e0cb8d6e3e4a5e1 - languageName: node - linkType: hard - "better-sqlite3@npm:^12.0.0": version: 12.8.0 resolution: "better-sqlite3@npm:12.8.0" @@ -18146,15 +17852,6 @@ __metadata: languageName: node linkType: hard -"express-rate-limit@npm:^7.5.0": - version: 7.5.1 - resolution: "express-rate-limit@npm:7.5.1" - peerDependencies: - express: ">= 4.11" - checksum: 10/357c3398450144ab7bbce2841d0bf4f93a0f3fd9d1d5ed9a0ee331b557af969cc790941dc37b47f8d9b5672964aa0e31666f770e1f48b334dc7d1e69f6433040 - languageName: node - linkType: hard - "express-rate-limit@npm:^8.2.1, express-rate-limit@npm:^8.2.2": version: 8.3.1 resolution: "express-rate-limit@npm:8.3.1" @@ -24471,7 +24168,7 @@ __metadata: languageName: node linkType: hard -"node-forge@npm:^1, node-forge@npm:^1.3.1, node-forge@npm:^1.3.2": +"node-forge@npm:^1, node-forge@npm:^1.3.2": version: 1.4.0 resolution: "node-forge@npm:1.4.0" checksum: 10/d70fd769768e646eda73343d4d4105ccb6869315d975905a22117431c04ae5b6df6c488e34ed275b1a66b50195a09b84b5c8aeca3b8605c20605fcb8e9f109d9 @@ -31632,7 +31329,7 @@ __metadata: languageName: node linkType: hard -"yauzl@npm:^3.0.0, yauzl@npm:^3.2.1": +"yauzl@npm:^3.2.1": version: 3.2.1 resolution: "yauzl@npm:3.2.1" dependencies: @@ -31698,7 +31395,7 @@ __metadata: languageName: node linkType: hard -"zod-to-json-schema@npm:^3.20.4, zod-to-json-schema@npm:^3.25.1": +"zod-to-json-schema@npm:^3.25.1": version: 3.25.2 resolution: "zod-to-json-schema@npm:3.25.2" peerDependencies: From f94ed55c09290b3ebfb761566aa75fe22715d832 Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Sun, 29 Mar 2026 20:32:41 -0400 Subject: [PATCH 15/17] feat(mcp-chat): updated api reports Signed-off-by: Florian JUDITH --- .../plugins/mcp-chat-backend/report.api.md | 4 -- .../plugins/mcp-chat-common/report.api.md | 59 ------------------- .../plugins/mcp-chat-node/report.api.md | 53 ++++++++++++++++- .../plugins/mcp-chat/report-alpha.api.md | 23 -------- .../mcp-chat/plugins/mcp-chat/report.api.md | 2 +- 5 files changed, 53 insertions(+), 88 deletions(-) diff --git a/workspaces/mcp-chat/plugins/mcp-chat-backend/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-backend/report.api.md index 1ceff286f45..7723fd7541e 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-backend/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-backend/report.api.md @@ -11,7 +11,6 @@ import { ConversationRecord } from '@backstage-community/plugin-mcp-chat-common' import { DatabaseService } from '@backstage/backend-plugin-api'; import express from 'express'; import { HttpAuthService } from '@backstage/backend-plugin-api'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; import { LlmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; import { llmProviderExtensionPoint } from '@backstage-community/plugin-mcp-chat-node'; import { LoggerService } from '@backstage/backend-plugin-api'; @@ -74,8 +73,6 @@ export function executeToolCall( // @public export function findNpxPath(): Promise; -export { LLMProvider }; - export { LlmProviderExtensionPoint }; export { llmProviderExtensionPoint }; @@ -123,7 +120,6 @@ export class MCPClientServiceImpl implements MCPClientService { export type MCPClientServiceOptions = { logger: LoggerService; config: RootConfigService; - provider: LLMProvider; }; // @public diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-common/report.api.md index 789eeae959e..65c5d1caed9 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-common/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/report.api.md @@ -53,56 +53,6 @@ export interface ConversationRow { user_id: string; } -// @public -export abstract class LLMProvider { - constructor(config: ProviderConfig); - // (undocumented) - protected apiKey?: string; - // (undocumented) - protected baseUrl: string; - // (undocumented) - protected abstract formatRequest( - messages: ChatMessage[], - tools?: Tool[], - ): any; - getBaseUrl(): string; - // (undocumented) - protected abstract getHeaders(): Record; - getLastResponseOutput(): any; - getModel(): string; - getType(): string; - // (undocumented) - protected makeRequest(endpoint: string, body: any): Promise; - // (undocumented) - protected model: string; - // (undocumented) - protected abstract parseResponse(response: any): ChatResponse; - // (undocumented) - abstract sendMessage( - messages: ChatMessage[], - tools?: Tool[], - ): Promise; - setMcpServerConfigs(_configs: MCPServerFullConfig[]): void; - supportsNativeMcp(): boolean; - // (undocumented) - abstract testConnection(): Promise<{ - connected: boolean; - models?: string[]; - error?: string; - }>; - // (undocumented) - protected type: string; -} - -// @public -export type LLMProviderType = - | 'openai' - | 'openai-responses' - | 'claude' - | 'gemini' - | 'ollama' - | 'litellm'; - // @public export type MCPServer = MCPServerConfig & { status: { @@ -155,15 +105,6 @@ export interface MessageValidationResult { isValid: boolean; } -// @public -export interface ProviderConfig { - apiKey?: string; - auth?: Record; - baseUrl: string; - model: string; - type: string; -} - // @public export interface ProviderConnectionStatus { connected: boolean; diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat-node/report.api.md index 99613a00f77..8c414b47b0e 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-node/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/report.api.md @@ -3,8 +3,50 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts +import { ChatMessage } from '@backstage-community/plugin-mcp-chat-common'; +import { ChatResponse } from '@backstage-community/plugin-mcp-chat-common'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; -import { LLMProvider } from '@backstage-community/plugin-mcp-chat-common'; +import { LoggerService } from '@backstage/backend-plugin-api'; +import { Tool } from '@backstage-community/plugin-mcp-chat-common'; + +// @public +export abstract class LLMProvider { + constructor(config: ProviderConfig); + // (undocumented) + protected apiKey?: string; + // (undocumented) + protected baseUrl: string; + // (undocumented) + protected abstract formatRequest( + messages: ChatMessage[], + tools?: Tool[], + ): any; + // (undocumented) + protected abstract getHeaders(): Record; + // (undocumented) + protected logger?: LoggerService; + // (undocumented) + protected makeRequest(endpoint: string, body: any): Promise; + // (undocumented) + protected model: string; + // (undocumented) + protected abstract parseResponse(response: any): ChatResponse; + // (undocumented) + abstract sendMessage( + messages: ChatMessage[], + tools?: Tool[], + ): Promise; + // (undocumented) + abstract testConnection(): Promise<{ + connected: boolean; + models?: string[]; + error?: string; + }>; + // (undocumented) + protected truncateForLogging(data: string, maxLength?: number): string; + // (undocumented) + protected type: string; +} // @public export interface LlmProviderExtensionPoint { @@ -13,4 +55,13 @@ export interface LlmProviderExtensionPoint { // @public export const llmProviderExtensionPoint: ExtensionPoint; + +// @public +export interface ProviderConfig { + apiKey?: string; + baseUrl: string; + logger?: LoggerService; + model: string; + type: string; +} ``` diff --git a/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md b/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md index 14d183b1565..096193fb399 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat/report-alpha.api.md @@ -12,7 +12,6 @@ import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionBlueprintParams } from '@backstage/frontend-plugin-api'; import { ExtensionDataRef } from '@backstage/frontend-plugin-api'; import { ExtensionInput } from '@backstage/frontend-plugin-api'; -import { IconComponent } from '@backstage/frontend-plugin-api'; import { IconElement } from '@backstage/frontend-plugin-api'; import { JSX as JSX_2 } from 'react'; import { OverridableExtensionDefinition } from '@backstage/frontend-plugin-api'; @@ -44,27 +43,6 @@ const mcpChatPlugin: OverridableFrontendPlugin< params: ApiFactory, ) => ExtensionBlueprintParams; }>; - 'nav-item:mcp-chat': OverridableExtensionDefinition<{ - kind: 'nav-item'; - name: undefined; - config: {}; - configInput: {}; - output: ExtensionDataRef< - { - title: string; - icon: IconComponent; - routeRef: RouteRef_2; - }, - 'core.nav-item.target', - {} - >; - inputs: {}; - params: { - title: string; - icon: IconComponent; - routeRef: RouteRef_2; - }; - }>; 'page:mcp-chat': OverridableExtensionDefinition<{ kind: 'page'; name: undefined; @@ -133,7 +111,6 @@ const mcpChatPlugin: OverridableFrontendPlugin< >; }; params: { - defaultPath?: [Error: "Use the 'path' param instead"] | undefined; path: string; title?: string | undefined; icon?: IconElement | undefined; diff --git a/workspaces/mcp-chat/plugins/mcp-chat/report.api.md b/workspaces/mcp-chat/plugins/mcp-chat/report.api.md index 68ebe236ce0..1187852c303 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat/report.api.md +++ b/workspaces/mcp-chat/plugins/mcp-chat/report.api.md @@ -3,7 +3,7 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { ApiRef } from '@backstage/frontend-plugin-api'; +import { ApiRef } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; import { ComponentType } from 'react'; import { JSX as JSX_2 } from 'react/jsx-runtime'; From 5620679ce54d1ad158dc69b858f378937dd22369 Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Sun, 29 Mar 2026 20:37:52 -0400 Subject: [PATCH 16/17] feat(mcp-chat): add changeset Signed-off-by: Florian JUDITH --- workspaces/mcp-chat/.changeset/silly-jars-happen.md | 13 ------------- workspaces/mcp-chat/.changeset/sixty-sides-yell.md | 8 ++++++++ .../mcp-chat/plugins/mcp-chat-common/package.json | 1 - .../mcp-chat/plugins/mcp-chat-node/package.json | 1 - 4 files changed, 8 insertions(+), 15 deletions(-) delete mode 100644 workspaces/mcp-chat/.changeset/silly-jars-happen.md create mode 100644 workspaces/mcp-chat/.changeset/sixty-sides-yell.md diff --git a/workspaces/mcp-chat/.changeset/silly-jars-happen.md b/workspaces/mcp-chat/.changeset/silly-jars-happen.md deleted file mode 100644 index 02fd6db37cc..00000000000 --- a/workspaces/mcp-chat/.changeset/silly-jars-happen.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@backstage-community/plugin-mcp-chat': patch -'@backstage-community/plugin-mcp-chat-backend': major -'@backstage-community/plugin-mcp-chat-backend-module-amazon-bedrock': patch -'@backstage-community/plugin-mcp-chat-backend-module-openai-responses': patch -'@backstage-community/plugin-mcp-chat-backend-module-anthropic': patch -'@backstage-community/plugin-mcp-chat-backend-module-litellm': patch -'@backstage-community/plugin-mcp-chat-backend-module-gemini': patch -'@backstage-community/plugin-mcp-chat-backend-module-ollama': patch -'@backstage-community/plugin-mcp-chat-backend-module-openai': patch ---- - -refactor the backend plugin to isolate llm providers in dedicated backend modules diff --git a/workspaces/mcp-chat/.changeset/sixty-sides-yell.md b/workspaces/mcp-chat/.changeset/sixty-sides-yell.md new file mode 100644 index 00000000000..14d375bae63 --- /dev/null +++ b/workspaces/mcp-chat/.changeset/sixty-sides-yell.md @@ -0,0 +1,8 @@ +--- +'@backstage-community/plugin-mcp-chat-backend': minor +'@backstage-community/plugin-mcp-chat-common': minor +'@backstage-community/plugin-mcp-chat-node': minor +'@backstage-community/plugin-mcp-chat': minor +--- + +introduce shared libraries and extension points for future isolation of llm providers in dedicated backend modules diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/package.json b/workspaces/mcp-chat/plugins/mcp-chat-common/package.json index e163dcc3b6b..61ef320b133 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-common/package.json +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/package.json @@ -2,7 +2,6 @@ "name": "@backstage-community/plugin-mcp-chat-common", "version": "0.1.0", "license": "Apache-2.0", - "private": true, "description": "Common functionalities for the mcp-chat plugin", "main": "src/index.ts", "types": "src/index.ts", diff --git a/workspaces/mcp-chat/plugins/mcp-chat-node/package.json b/workspaces/mcp-chat/plugins/mcp-chat-node/package.json index dcbf50d8c02..f9c53bb394d 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-node/package.json +++ b/workspaces/mcp-chat/plugins/mcp-chat-node/package.json @@ -2,7 +2,6 @@ "name": "@backstage-community/plugin-mcp-chat-node", "version": "0.1.0", "license": "Apache-2.0", - "private": true, "description": "Node.js library for the mcp-chat plugin", "main": "src/index.ts", "types": "src/index.ts", From 23e0387f68281256a77722b2a456ebfba04faad6 Mon Sep 17 00:00:00 2001 From: Florian JUDITH Date: Sun, 29 Mar 2026 20:52:52 -0400 Subject: [PATCH 17/17] fix(mcp-chat): removed unused dependency Signed-off-by: Florian JUDITH --- workspaces/mcp-chat/plugins/mcp-chat-common/package.json | 3 --- workspaces/mcp-chat/yarn.lock | 1 - 2 files changed, 4 deletions(-) diff --git a/workspaces/mcp-chat/plugins/mcp-chat-common/package.json b/workspaces/mcp-chat/plugins/mcp-chat-common/package.json index 61ef320b133..62115ba3b86 100644 --- a/workspaces/mcp-chat/plugins/mcp-chat-common/package.json +++ b/workspaces/mcp-chat/plugins/mcp-chat-common/package.json @@ -29,9 +29,6 @@ "prepack": "backstage-cli package prepack", "postpack": "backstage-cli package postpack" }, - "dependencies": { - "@backstage/errors": "^1.2.7" - }, "devDependencies": { "@backstage/cli": "^0.33.0" }, diff --git a/workspaces/mcp-chat/yarn.lock b/workspaces/mcp-chat/yarn.lock index a670a7f8a41..9f68905fb61 100644 --- a/workspaces/mcp-chat/yarn.lock +++ b/workspaces/mcp-chat/yarn.lock @@ -2556,7 +2556,6 @@ __metadata: resolution: "@backstage-community/plugin-mcp-chat-common@workspace:plugins/mcp-chat-common" dependencies: "@backstage/cli": "npm:^0.33.0" - "@backstage/errors": "npm:^1.2.7" languageName: unknown linkType: soft