├── .eslintignore ├── .DS_Store ├── docs ├── src │ ├── assets │ │ └── gigachat.webp │ ├── content.config.ts │ ├── content │ │ ├── docs │ │ │ ├── guides │ │ │ │ ├── censored.md │ │ │ │ ├── security.md │ │ │ │ ├── vision.md │ │ │ │ ├── image.md │ │ │ │ └── readme.md │ │ │ ├── api │ │ │ │ ├── interfaces │ │ │ │ │ ├── balance │ │ │ │ │ │ └── interfaces │ │ │ │ │ │ │ ├── IBalanceResponse.md │ │ │ │ │ │ │ └── IBalance.md │ │ │ │ │ ├── file │ │ │ │ │ │ └── interfaces │ │ │ │ │ │ │ ├── IFileDeleteResponse.md │ │ │ │ │ │ │ └── IFile.md │ │ │ │ │ ├── extract │ │ │ │ │ │ └── interfaces │ │ │ │ │ │ │ └── IExtractImage.md │ │ │ │ │ ├── model │ │ │ │ │ │ └── interfaces │ │ │ │ │ │ │ ├── IAllModelResponse.md │ │ │ │ │ │ │ └── IModelResponse.md │ │ │ │ │ ├── token │ │ │ │ │ │ └── interfaces │ │ │ │ │ │ │ └── ITokenResponse.md │ │ │ │ │ ├── embedding │ │ │ │ │ │ └── interfaces │ │ │ │ │ │ │ ├── IEmbedding.md │ │ │ │ │ │ │ └── IEmbeddingResponse.md │ │ │ │ │ ├── summarize │ │ │ │ │ │ └── interfaces │ │ │ │ │ │ │ └── ISummarizeResponse.md │ │ │ │ │ ├── completion │ │ │ │ │ │ └── interfaces │ │ │ │ │ │ │ ├── ICompletionUsage.md │ │ │ │ │ │ │ ├── ICompletionChoice.md │ │ │ │ │ │ │ ├── ICompletionResponse.md │ │ │ │ │ │ │ └── ICompletionRequest.md │ │ │ │ │ ├── config │ │ │ │ │ │ └── interfaces │ │ │ │ │ │ │ └── GigaChatConfig.md │ │ │ │ │ └── message │ │ │ │ │ │ └── interfaces │ │ │ │ │ │ └── IMessage.md │ │ │ │ ├── README.md │ │ │ │ └── index │ │ │ │ │ └── classes │ │ │ │ │ ├── GigaChatError.md │ │ │ │ │ └── GigaChat.md │ │ │ ├── examples │ │ │ │ ├── images.md │ │ │ │ ├── tgbot.md │ │ │ │ ├── rest.md │ │ │ │ └── tgbot-images.md │ │ │ └── index.mdx │ │ └── i18n │ │ │ └── ru.json │ └── custom.css ├── dist │ ├── pagefind │ │ ├── pagefind-entry.json │ │ ├── wasm.ru.pagefind │ │ ├── wasm.unknown.pagefind │ │ ├── index │ │ │ └── ru_25dc835.pf_index │ │ ├── fragment │ │ │ ├── ru_0809876.pf_fragment │ │ │ ├── ru_23cbf74.pf_fragment │ │ │ ├── ru_2ebe389.pf_fragment │ │ │ ├── ru_321050c.pf_fragment │ │ │ ├── ru_37ea17b.pf_fragment │ │ │ ├── ru_39dfb1f.pf_fragment │ │ │ ├── ru_39f96c6.pf_fragment │ │ │ ├── ru_3c46333.pf_fragment │ │ │ ├── ru_53b2cb8.pf_fragment │ │ │ ├── ru_569fa06.pf_fragment │ │ │ ├── ru_5860777.pf_fragment │ │ │ ├── ru_75c6555.pf_fragment │ │ │ ├── ru_7848259.pf_fragment │ │ │ ├── ru_7bc1985.pf_fragment │ │ │ ├── ru_819cee7.pf_fragment │ │ │ ├── ru_84dde83.pf_fragment │ │ │ ├── ru_988263e.pf_fragment │ │ │ ├── ru_9bd3dff.pf_fragment │ │ │ ├── ru_a79de81.pf_fragment │ │ │ ├── ru_a9c8277.pf_fragment │ │ │ ├── ru_aa97daa.pf_fragment │ │ │ ├── ru_ab5e26d.pf_fragment │ │ │ ├── ru_bcbf9f6.pf_fragment │ │ │ ├── ru_cf36c43.pf_fragment │ │ │ ├── ru_cf6ac24.pf_fragment │ │ │ ├── ru_d228d49.pf_fragment │ │ │ ├── ru_d387b5c.pf_fragment │ │ │ ├── ru_d7762ca.pf_fragment │ │ │ ├── ru_ec5bcad.pf_fragment │ │ │ └── ru_f02e73d.pf_fragment │ │ ├── pagefind.ru_c690e5802f.pf_meta │ │ ├── pagefind-modular-ui.css │ │ ├── pagefind-ui.css │ │ └── pagefind-modular-ui.js │ ├── sitemap-index.xml │ ├── _astro │ │ ├── MobileTableOfContents.astro_astro_type_script_index_0_lang.C181hMzK.js │ │ ├── TableOfContents.astro_astro_type_script_index_0_lang.CKWWgpjV.js │ │ ├── page.7qqag-5g.js │ │ ├── ec.8zarh.js │ │ ├── Search.astro_astro_type_script_index_0_lang.DrM75iIr.js │ │ ├── print.BJ0teN4y.css │ │ └── ec.tm3va.css │ └── sitemap-0.xml ├── tsconfig.json ├── package.json └── astro.config.mjs ├── nodemon.json ├── .prettierrc.json ├── .npmignore ├── jest.config.js ├── src ├── interfaces │ ├── extract.ts │ ├── token.ts │ ├── summarize.ts │ ├── balance.ts │ ├── model.ts │ ├── embedding.ts │ ├── message.ts │ ├── config.ts │ ├── file.ts │ └── completion.ts ├── utils │ ├── GigaChatError.ts │ ├── FormDataFile.ts │ ├── FormDataBuilder.ts │ └── HTTPClient.ts └── index.ts ├── .gitignore ├── tsconfig.json ├── .husky └── pre-commit ├── .github └── workflows │ ├── deploy_docs.yml │ └── publish.yml ├── LICENSE ├── __tests__ └── index.test.ts ├── .eslintrc ├── package.json └── readme.md /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | example/ 4 | docs/ -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/.DS_Store -------------------------------------------------------------------------------- /docs/src/assets/gigachat.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/src/assets/gigachat.webp -------------------------------------------------------------------------------- /nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": ["src", "example"], 3 | "ext": "ts", 4 | "exec": "ts-node ./example/index.ts" 5 | } -------------------------------------------------------------------------------- /docs/dist/pagefind/pagefind-entry.json: -------------------------------------------------------------------------------- 1 | {"version":"1.3.0","languages":{"ru":{"hash":"ru_c690e5802f","wasm":"ru","page_count":30}}} -------------------------------------------------------------------------------- /docs/dist/pagefind/wasm.ru.pagefind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/wasm.ru.pagefind -------------------------------------------------------------------------------- /docs/dist/pagefind/wasm.unknown.pagefind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/wasm.unknown.pagefind -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true, 4 | "trailingComma": "all", 5 | "printWidth": 100, 6 | "tabWidth": 2 7 | } -------------------------------------------------------------------------------- /docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "include": [".astro/types.d.ts", "**/*"], 4 | "exclude": ["dist"] 5 | } 6 | -------------------------------------------------------------------------------- /docs/dist/pagefind/index/ru_25dc835.pf_index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/index/ru_25dc835.pf_index -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_0809876.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_0809876.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_23cbf74.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_23cbf74.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_2ebe389.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_2ebe389.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_321050c.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_321050c.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_37ea17b.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_37ea17b.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_39dfb1f.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_39dfb1f.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_39f96c6.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_39f96c6.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_3c46333.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_3c46333.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_53b2cb8.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_53b2cb8.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_569fa06.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_569fa06.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_5860777.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_5860777.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_75c6555.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_75c6555.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_7848259.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_7848259.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_7bc1985.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_7bc1985.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_819cee7.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_819cee7.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_84dde83.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_84dde83.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_988263e.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_988263e.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_9bd3dff.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_9bd3dff.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_a79de81.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_a79de81.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_a9c8277.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_a9c8277.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_aa97daa.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_aa97daa.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_ab5e26d.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_ab5e26d.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_bcbf9f6.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_bcbf9f6.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_cf36c43.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_cf36c43.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_cf6ac24.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_cf6ac24.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_d228d49.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_d228d49.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_d387b5c.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_d387b5c.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_d7762ca.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_d7762ca.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_ec5bcad.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_ec5bcad.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/fragment/ru_f02e73d.pf_fragment: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/fragment/ru_f02e73d.pf_fragment -------------------------------------------------------------------------------- /docs/dist/pagefind/pagefind.ru_c690e5802f.pf_meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zloishavrin/gigachat-node/HEAD/docs/dist/pagefind/pagefind.ru_c690e5802f.pf_meta -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | test 4 | src 5 | nodemon.json 6 | .eslintrc 7 | .eslintignore 8 | .prettierrc.json 9 | LICENSE 10 | docs 11 | jsdoc.json 12 | *.ts 13 | *.map -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} **/ 2 | module.exports = { 3 | testEnvironment: "node", 4 | transform: { 5 | "^.+.tsx?$": ["ts-jest",{}], 6 | }, 7 | }; -------------------------------------------------------------------------------- /docs/dist/sitemap-index.xml: -------------------------------------------------------------------------------- 1 | https://zloishavrin.github.io/gigachat-node/sitemap-0.xml -------------------------------------------------------------------------------- /src/interfaces/extract.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Интерфейс, который представляет результаты извлечения ID изображения из ответа. 3 | */ 4 | export interface IExtractImage { 5 | /** 6 | * Идентификатор изображения. 7 | */ 8 | imageId: string; 9 | 10 | /** 11 | * Текст без тега . 12 | */ 13 | text: string; 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | package-lock.json 4 | 5 | # secrets 6 | .env 7 | 8 | # build and test output 9 | /dist 10 | /coverage 11 | /example 12 | .astro 13 | 14 | # logs 15 | npm-debug.log* 16 | yarn-debug.log* 17 | yarn-error.log* 18 | pnpm-debug.log* 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | 23 | # vscode-specific files 24 | .vscode -------------------------------------------------------------------------------- /src/interfaces/token.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Интерфейс, представляющий ответ с токеном доступа. 3 | */ 4 | export interface ITokenResponse { 5 | /** 6 | * Строка токена доступа, используемого для аутентификации API-запросов. 7 | */ 8 | access_token: string; 9 | 10 | /** 11 | * Временная метка (timestamp) истечения срока действия токена (в секундах с начала эпохи Unix). 12 | */ 13 | expires_at: number; 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "types": ["node", "jest"], 5 | "module": "commonjs", 6 | "declaration": true, 7 | "outDir": "dist", 8 | "strict": true, 9 | "sourceMap": false, 10 | "baseUrl": "./", 11 | "paths": { 12 | "@interfaces/*": ["src/interfaces/*"] 13 | } 14 | }, 15 | "include": ["src"], 16 | "exclude": ["node_modules", "__tests__"] 17 | } 18 | -------------------------------------------------------------------------------- /docs/src/content.config.ts: -------------------------------------------------------------------------------- 1 | import { defineCollection, z } from 'astro:content'; 2 | import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders'; 3 | import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'; 4 | 5 | export const collections = { 6 | docs: defineCollection({ loader: docsLoader(), schema: docsSchema() }), 7 | i18n: defineCollection({ 8 | loader: i18nLoader(), 9 | schema: i18nSchema(), 10 | }), 11 | }; 12 | -------------------------------------------------------------------------------- /src/interfaces/summarize.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Интерфейс, представляющий ответ на запрос суммаризации. 3 | */ 4 | export interface ISummarizeResponse { 5 | /** 6 | * Тип объекта (например, "summary"). 7 | */ 8 | object: string; 9 | 10 | /** 11 | * Количество токенов в суммаризированном тексте. 12 | */ 13 | tokens: number; 14 | 15 | /** 16 | * Количество символов в суммаризированном тексте. 17 | */ 18 | characters: number; 19 | } 20 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npm install 5 | 6 | # Lint&Prettier 7 | npx lint-staged 8 | 9 | # Обновление руководства из readme в документацию 10 | # Добавление заголовка в README перед копированием 11 | echo "---\ntitle: GigaChatJS\ndescription: Начните работу c GigaChatAPI.\n---\n\n$(cat ./readme.md)" > ./docs/src/content/docs/guides/readme.md 12 | 13 | # Билд документации 14 | cd ./docs && npm install && npm run build 15 | 16 | git add . -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "type": "module", 4 | "version": "0.0.1", 5 | "scripts": { 6 | "dev": "astro dev", 7 | "start": "astro dev", 8 | "build": "astro build", 9 | "preview": "astro preview", 10 | "astro": "astro" 11 | }, 12 | "dependencies": { 13 | "@astrojs/starlight": "^0.32.1", 14 | "astro": "^5.1.5", 15 | "sharp": "^0.32.5", 16 | "starlight-typedoc": "^0.19.0", 17 | "typedoc": "^0.27.7", 18 | "typedoc-plugin-markdown": "^4.4.2" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/interfaces/balance.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Интерфейс, представляющий баланс токенов для модели. 3 | */ 4 | export interface IBalance { 5 | /** 6 | * Название модели. 7 | */ 8 | usage: string; 9 | 10 | /** 11 | * Остаток токенов. 12 | */ 13 | value: number; 14 | } 15 | 16 | /** 17 | * Интерфейс ответа на запрос баланса токенов. 18 | */ 19 | export interface IBalanceResponse { 20 | /** 21 | * Массив объектов с информацией о балансе токенов по каждой модели. 22 | */ 23 | balance: IBalance[]; 24 | } 25 | -------------------------------------------------------------------------------- /.github/workflows/deploy_docs.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Documentation to GitHub Pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | build_and_deploy: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout repository 14 | uses: actions/checkout@v2 15 | 16 | - name: Deploy to GitHub Pages 17 | uses: peaceiris/actions-gh-pages@v3 18 | with: 19 | personal_token: ${{ secrets.GH_TOKEN }} 20 | publish_dir: ./docs/dist 21 | publish_branch: gh-pages -------------------------------------------------------------------------------- /docs/src/content/docs/guides/censored.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Отключение цензуры 3 | description: Отключение цензуры. 4 | --- 5 | 6 | ## Отключение цензуры 7 | 8 | > **Важно:** Отключение цензуры не проверено. 9 | 10 | Отключение цензуры доступно только в том случае, если Вы пользуетесь GigaChat, как юридическое лицо. Далее следующий алгоритм: 11 | 12 | 1. Необходимо написать запрос на почту **gigachat@sberbank.ru** с указанием id пространства и client id, который дается при получении ключа. 13 | 2. После одобрения запроса, необходимо добавить свойство объекта **profanity_check** со значением **false** в запросе на завершение чата. -------------------------------------------------------------------------------- /docs/src/content/docs/guides/security.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Сертификат безопасности 3 | description: Сертификат Минцифры c GigaChatAPI. 4 | --- 5 | 6 | Для использования GigaChat API необходимо использовать публичный сертификат НУЦ Минцифры. Его можно установить на уровне OC или приложения. Однако, можно отключить проверку сертификата, для этого в конструкторе класса необходимо указать флаг *isIgnoreTSL* 7 | 8 | ```javascript 9 | const client = new GigaChat({ 10 | ... 11 | isIgnoreTSL: true, 12 | ... 13 | }); 14 | ``` 15 | 16 | Подробнее можно ознакомиться в [официальной документации](https://developers.sber.ru/docs/ru/gigachat/certificates). -------------------------------------------------------------------------------- /src/interfaces/model.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Интерфейс, представляющий информацию о модели. 3 | */ 4 | export interface IModelResponse { 5 | /** 6 | * Уникальный идентификатор модели. 7 | */ 8 | id: string; 9 | 10 | /** 11 | * Тип объекта (например, "model"). 12 | */ 13 | object: string; 14 | 15 | /** 16 | * Владелец модели. 17 | */ 18 | owned_by: string; 19 | } 20 | 21 | /** 22 | * Интерфейс, представляющий ответ, содержащий список доступных моделей. 23 | */ 24 | export interface IAllModelResponse { 25 | /** 26 | * Тип объекта (например, "list"). 27 | */ 28 | object: string; 29 | 30 | /** 31 | * Список моделей. 32 | */ 33 | data: IModelResponse[]; 34 | } 35 | -------------------------------------------------------------------------------- /docs/dist/_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.C181hMzK.js: -------------------------------------------------------------------------------- 1 | import{S as r}from"./TableOfContents.astro_astro_type_script_index_0_lang.CKWWgpjV.js";class c extends r{set current(e){super.current=e;const t=this.querySelector(".display-current");t&&(t.textContent=e.textContent)}constructor(){super();const e=this.querySelector("details");if(!e)return;const t=()=>{e.open=!1};e.querySelectorAll("a").forEach(s=>{s.addEventListener("click",t)}),window.addEventListener("click",s=>{e.contains(s.target)||t()}),window.addEventListener("keydown",s=>{if(s.key==="Escape"&&e.open){const o=e.contains(document.activeElement);if(t(),o){const n=e.querySelector("summary");n&&n.focus()}}})}}customElements.define("mobile-starlight-toc",c); 2 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/balance/interfaces/IBalanceResponse.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "IBalanceResponse" 6 | --- 7 | 8 | Defined in: [src/interfaces/balance.ts:19](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/balance.ts#L19) 9 | 10 | Интерфейс ответа на запрос баланса токенов. 11 | 12 | ## Properties 13 | 14 | ### balance 15 | 16 | > **balance**: [`IBalance`](/gigachat-node/api/interfaces/balance/interfaces/ibalance/)[] 17 | 18 | Defined in: [src/interfaces/balance.ts:23](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/balance.ts#L23) 19 | 20 | Массив объектов с информацией о балансе токенов по каждой модели. 21 | -------------------------------------------------------------------------------- /src/interfaces/embedding.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Представляет один эмбеддинг в ответе. 3 | */ 4 | export interface IEmbedding { 5 | /** 6 | * Тип объекта (например, "embedding"). 7 | */ 8 | object: string; 9 | 10 | /** 11 | * Числовой массив эмбеддинга, представляющий векторное представление данных. 12 | */ 13 | embedding: number[]; 14 | 15 | /** 16 | * Индекс эмбеддинга в массиве. 17 | */ 18 | index: number; 19 | } 20 | 21 | /** 22 | * Интерфейс ответа на запрос эмбеддингов. 23 | */ 24 | export interface IEmbeddingResponse { 25 | /** 26 | * Тип объекта (например, "embedding"). 27 | */ 28 | object: string; 29 | 30 | /** 31 | * Название модели, использованной для генерации эмбеддингов. 32 | */ 33 | model: string; 34 | 35 | /** 36 | * Массив эмбеддингов, полученных в ответе. 37 | */ 38 | data: IEmbedding[]; 39 | } 40 | -------------------------------------------------------------------------------- /docs/src/custom.css: -------------------------------------------------------------------------------- 1 | /* Dark mode colors. */ 2 | :root { 3 | --sl-color-accent-low: #877811; 4 | --sl-color-accent: #F0DB4F; 5 | --sl-color-accent-high: #ebe6ca; 6 | --sl-color-white: #ffffff; 7 | --sl-color-gray-1: #eeeeee; 8 | --sl-color-gray-2: #c8c8c8; 9 | --sl-color-gray-3: #a4a4a4; 10 | --sl-color-gray-4: #585858; 11 | --sl-color-gray-5: #383838; 12 | --sl-color-gray-6: #272727; 13 | --sl-color-black: #181818; 14 | } 15 | /* Light mode colors. */ 16 | :root[data-theme='light'] { 17 | --sl-color-accent-low: #ddd8b7; 18 | --sl-color-accent: #594f00; 19 | --sl-color-accent-high: #3a3300; 20 | --sl-color-white: #181818; 21 | --sl-color-gray-1: #272727; 22 | --sl-color-gray-2: #383838; 23 | --sl-color-gray-3: #585858; 24 | --sl-color-gray-4: #8b8b8b; 25 | --sl-color-gray-5: #c2c2c2; 26 | --sl-color-gray-6: #eeeeee; 27 | --sl-color-gray-7: #f6f6f6; 28 | --sl-color-black: #ffffff; 29 | } -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/balance/interfaces/IBalance.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "IBalance" 6 | --- 7 | 8 | Defined in: [src/interfaces/balance.ts:4](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/balance.ts#L4) 9 | 10 | Интерфейс, представляющий баланс токенов для модели. 11 | 12 | ## Properties 13 | 14 | ### usage 15 | 16 | > **usage**: `string` 17 | 18 | Defined in: [src/interfaces/balance.ts:8](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/balance.ts#L8) 19 | 20 | Название модели. 21 | 22 | *** 23 | 24 | ### value 25 | 26 | > **value**: `number` 27 | 28 | Defined in: [src/interfaces/balance.ts:13](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/balance.ts#L13) 29 | 30 | Остаток токенов. 31 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "gigachat-node" 6 | --- 7 | 8 | ## Modules 9 | 10 | - [index](/gigachat-node/api/index/readme/) 11 | - [interfaces/balance](/gigachat-node/api/interfaces/balance/readme/) 12 | - [interfaces/completion](/gigachat-node/api/interfaces/completion/readme/) 13 | - [interfaces/config](/gigachat-node/api/interfaces/config/readme/) 14 | - [interfaces/embedding](/gigachat-node/api/interfaces/embedding/readme/) 15 | - [interfaces/extract](/gigachat-node/api/interfaces/extract/readme/) 16 | - [interfaces/file](/gigachat-node/api/interfaces/file/readme/) 17 | - [interfaces/message](/gigachat-node/api/interfaces/message/readme/) 18 | - [interfaces/model](/gigachat-node/api/interfaces/model/readme/) 19 | - [interfaces/summarize](/gigachat-node/api/interfaces/summarize/readme/) 20 | - [interfaces/token](/gigachat-node/api/interfaces/token/readme/) 21 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/file/interfaces/IFileDeleteResponse.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "IFileDeleteResponse" 6 | --- 7 | 8 | Defined in: [src/interfaces/file.ts:45](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/file.ts#L45) 9 | 10 | Ответ на запрос на удаление файла. 11 | 12 | ## Properties 13 | 14 | ### deleted 15 | 16 | > **deleted**: `boolean` 17 | 18 | Defined in: [src/interfaces/file.ts:54](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/file.ts#L54) 19 | 20 | Признак удаления файла. 21 | 22 | *** 23 | 24 | ### id 25 | 26 | > **id**: `string` 27 | 28 | Defined in: [src/interfaces/file.ts:49](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/file.ts#L49) 29 | 30 | Уникальный идентификатор файла. 31 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/extract/interfaces/IExtractImage.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "IExtractImage" 6 | --- 7 | 8 | Defined in: [src/interfaces/extract.ts:4](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/extract.ts#L4) 9 | 10 | Интерфейс, который представляет результаты извлечения ID изображения из ответа. 11 | 12 | ## Properties 13 | 14 | ### imageId 15 | 16 | > **imageId**: `string` 17 | 18 | Defined in: [src/interfaces/extract.ts:8](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/extract.ts#L8) 19 | 20 | Идентификатор изображения. 21 | 22 | *** 23 | 24 | ### text 25 | 26 | > **text**: `string` 27 | 28 | Defined in: [src/interfaces/extract.ts:13](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/extract.ts#L13) 29 | 30 | Текст без тега . 31 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/model/interfaces/IAllModelResponse.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "IAllModelResponse" 6 | --- 7 | 8 | Defined in: [src/interfaces/model.ts:24](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/model.ts#L24) 9 | 10 | Интерфейс, представляющий ответ, содержащий список доступных моделей. 11 | 12 | ## Properties 13 | 14 | ### data 15 | 16 | > **data**: [`IModelResponse`](/gigachat-node/api/interfaces/model/interfaces/imodelresponse/)[] 17 | 18 | Defined in: [src/interfaces/model.ts:33](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/model.ts#L33) 19 | 20 | Список моделей. 21 | 22 | *** 23 | 24 | ### object 25 | 26 | > **object**: `string` 27 | 28 | Defined in: [src/interfaces/model.ts:28](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/model.ts#L28) 29 | 30 | Тип объекта (например, "list"). 31 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/token/interfaces/ITokenResponse.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "ITokenResponse" 6 | --- 7 | 8 | Defined in: [src/interfaces/token.ts:4](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/token.ts#L4) 9 | 10 | Интерфейс, представляющий ответ с токеном доступа. 11 | 12 | ## Properties 13 | 14 | ### access\_token 15 | 16 | > **access\_token**: `string` 17 | 18 | Defined in: [src/interfaces/token.ts:8](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/token.ts#L8) 19 | 20 | Строка токена доступа, используемого для аутентификации API-запросов. 21 | 22 | *** 23 | 24 | ### expires\_at 25 | 26 | > **expires\_at**: `number` 27 | 28 | Defined in: [src/interfaces/token.ts:13](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/token.ts#L13) 29 | 30 | Временная метка (timestamp) истечения срока действия токена (в секундах с начала эпохи Unix). 31 | -------------------------------------------------------------------------------- /src/interfaces/message.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Интерфейс, представляющий сообщение в чате. 3 | */ 4 | export interface IMessage { 5 | /** 6 | * Роль отправителя сообщения. 7 | * - `user` — сообщение от пользователя. 8 | * - `assistant` — сообщение от ассистента (ИИ). 9 | * - `system` — системное сообщение. 10 | * - `search_result` — результат поиска. 11 | */ 12 | role: 'user' | 'assistant' | 'system' | 'search_result'; 13 | 14 | /** 15 | * Текстовое содержимое сообщения. 16 | */ 17 | content: string; 18 | 19 | /** 20 | * Уникальный идентификатор изображения, если сообщение его содержит. 21 | */ 22 | image?: string; 23 | 24 | /** Временная метка создания ответа (в формате Unix timestamp). */ 25 | created?: number; 26 | 27 | /** Название вызванной встроенной функции. */ 28 | name?: string; 29 | 30 | /** Идентификатор, который объединяет массив функций, переданных в запросе. */ 31 | functions_state_id?: string; 32 | 33 | /** Объект вызванной функции. */ 34 | function_call?: any; 35 | 36 | /** Массив с уникальными идентификаторами файлов */ 37 | attachments?: [string]; 38 | } 39 | -------------------------------------------------------------------------------- /src/interfaces/config.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Конфигурационный интерфейс для настройки GigaChat. 3 | */ 4 | export interface GigaChatConfig { 5 | /** 6 | * Секретный ключ клиента, используемый для аутентификации. 7 | */ 8 | clientSecretKey: string; 9 | 10 | /** 11 | * Игнорировать ли проверку TLS (SSL-сертификатов). 12 | * `true` — проверка отключена (используется для обхода проблем с сертификатами). 13 | * `false` — проверка включена. 14 | * @default true 15 | */ 16 | isIgnoreTSL?: boolean; 17 | 18 | /** 19 | * Используется ли персональный доступ (Personal API). 20 | * `true` — персональный доступ, `false` — корпоративный. 21 | * @default true 22 | */ 23 | isPersonal?: boolean; 24 | 25 | /** 26 | * Автоматически ли обновлять токен при его истечении. 27 | * `true` — токен будет обновляться автоматически. 28 | * @default true 29 | */ 30 | autoRefreshToken?: boolean; 31 | 32 | /** 33 | * Включена ли обработка изображений в ответах. 34 | * Если `true`, изображения будут извлекаться в виде fileId в ответе модели. 35 | * @default true 36 | */ 37 | imgOn?: boolean; 38 | } 39 | -------------------------------------------------------------------------------- /src/interfaces/file.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Интерфейс, представляющий загруженный файл. 3 | */ 4 | export interface IFile { 5 | /** 6 | * Размер файла в байтах. 7 | */ 8 | bytes: number; 9 | 10 | /** 11 | * Временная метка создания файла (в формате Unix Timestamp). 12 | */ 13 | created_at: number; 14 | 15 | /** 16 | * Имя файла. 17 | */ 18 | filename: string; 19 | 20 | /** 21 | * Уникальный идентификатор файла. 22 | */ 23 | id: string; 24 | 25 | /** 26 | * Тип объекта (например, "file"). 27 | */ 28 | object: string; 29 | 30 | /** 31 | * Назначение файла (например, "general" или другое). 32 | */ 33 | purpose: string; 34 | 35 | /** 36 | * Политика доступа к файлу: `private` (по умолчанию) или `public`. 37 | * Опциональный параметр. 38 | */ 39 | access_policy?: 'private' | 'public'; 40 | } 41 | 42 | /** 43 | * Ответ на запрос на удаление файла. 44 | */ 45 | export interface IFileDeleteResponse { 46 | /** 47 | * Уникальный идентификатор файла. 48 | */ 49 | id: string; 50 | 51 | /** 52 | * Признак удаления файла. 53 | */ 54 | deleted: boolean; 55 | } 56 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to NPM 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | publish: 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - name: Checkout repo 17 | uses: actions/checkout@v4 18 | 19 | - name: Setup Node.js 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: 18 23 | registry-url: 'https://registry.npmjs.org/' 24 | 25 | - name: Install dependencies 26 | run: npm install 27 | 28 | - name: Build package 29 | run: npm run build 30 | 31 | - name: Copy package.json to dist 32 | run: jq 'del(.devDependencies, .scripts)' package.json > dist/package.json 33 | 34 | - name: Copy README to dist 35 | run: cp readme.md dist/README.md 36 | 37 | - name: Minify JS/TS files in dist 38 | run: npm run minify 39 | 40 | - name: Publish to npm 41 | run: | 42 | cd dist 43 | npm publish --access public 44 | env: 45 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/model/interfaces/IModelResponse.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "IModelResponse" 6 | --- 7 | 8 | Defined in: [src/interfaces/model.ts:4](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/model.ts#L4) 9 | 10 | Интерфейс, представляющий информацию о модели. 11 | 12 | ## Properties 13 | 14 | ### id 15 | 16 | > **id**: `string` 17 | 18 | Defined in: [src/interfaces/model.ts:8](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/model.ts#L8) 19 | 20 | Уникальный идентификатор модели. 21 | 22 | *** 23 | 24 | ### object 25 | 26 | > **object**: `string` 27 | 28 | Defined in: [src/interfaces/model.ts:13](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/model.ts#L13) 29 | 30 | Тип объекта (например, "model"). 31 | 32 | *** 33 | 34 | ### owned\_by 35 | 36 | > **owned\_by**: `string` 37 | 38 | Defined in: [src/interfaces/model.ts:18](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/model.ts#L18) 39 | 40 | Владелец модели. 41 | -------------------------------------------------------------------------------- /docs/src/content/docs/guides/vision.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: GigaChat Vision 3 | description: Работа с файлами в GigaChat API. 4 | --- 5 | 6 | > **Важно:** В будущем планируется переписать метод загрузки файлов, чтобы вместо указания пути до файла, можно было передавать бинарные данные файла. Совместимость с указанием пути до файла останется. 7 | 8 | С помощью библиотеки и GigaChat API можно работать с файлами в контексте LLM. Для того, чтобы получить ответ модели на основе какого-то документа или изображения, необходимо загрузить файл, а затем в запросе к модели передать уникальный идентификатор файла в запрос. 9 | 10 | Загрузить файл можно с помощью метода *uploadFile* с указанием пути до файла. 11 | 12 | ```javascript 13 | const uploadedFile = await client.uploadFile('./example.png'); 14 | 15 | const completion = await client.completion({ 16 | model: "GigaChat-Pro", 17 | messages: [ 18 | { 19 | role: "user", 20 | content: "На этой картинке изображен человек?", 21 | attachments: [uploadedFile.id] 22 | } 23 | ], 24 | }); 25 | 26 | console.log(completion.choices[0].message.content); 27 | ``` 28 | 29 | Подробнее можно ознакомиться с работой с файлами в [официальной документации](https://developers.sber.ru/docs/ru/gigachat/api/working-with-files). -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to -------------------------------------------------------------------------------- /src/utils/GigaChatError.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Класс ошибки API GigaChat с дополнительной информацией 3 | * @class 4 | * @extends Error 5 | * @property {string} code - Уникальный код ошибки для идентификации типа проблемы 6 | * @property {string} name - Название ошибки (всегда 'GigaChatError') 7 | * 8 | * @example 9 | * try { 10 | * await gigachat.completion(...); 11 | * } catch (error) { 12 | * if (error instanceof GigaChatError) { 13 | * console.error(`Код ошибки: ${error.code}`, error.message); 14 | * } 15 | * } 16 | */ 17 | export class GigaChatError extends Error { 18 | /** 19 | * Уникальный код ошибки для программной обработки 20 | * @type {string} 21 | */ 22 | public readonly code: string; 23 | 24 | /** 25 | * Создает экземпляр ошибки GigaChat 26 | * @constructor 27 | * @param {string} message Человекочитаемое описание ошибки 28 | * @param {string} code Уникальный идентификатор типа ошибки 29 | */ 30 | constructor(message: string, code: string) { 31 | super(message); 32 | /** 33 | * Код ошибки для логирования и обработки 34 | * @type {string} 35 | */ 36 | this.code = code; 37 | 38 | /** 39 | * Название класса ошибки 40 | * @type {string} 41 | */ 42 | this.name = 'GigaChatError'; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/embedding/interfaces/IEmbedding.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "IEmbedding" 6 | --- 7 | 8 | Defined in: [src/interfaces/embedding.ts:4](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/embedding.ts#L4) 9 | 10 | Представляет один эмбеддинг в ответе. 11 | 12 | ## Properties 13 | 14 | ### embedding 15 | 16 | > **embedding**: `number`[] 17 | 18 | Defined in: [src/interfaces/embedding.ts:13](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/embedding.ts#L13) 19 | 20 | Числовой массив эмбеддинга, представляющий векторное представление данных. 21 | 22 | *** 23 | 24 | ### index 25 | 26 | > **index**: `number` 27 | 28 | Defined in: [src/interfaces/embedding.ts:18](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/embedding.ts#L18) 29 | 30 | Индекс эмбеддинга в массиве. 31 | 32 | *** 33 | 34 | ### object 35 | 36 | > **object**: `string` 37 | 38 | Defined in: [src/interfaces/embedding.ts:8](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/embedding.ts#L8) 39 | 40 | Тип объекта (например, "embedding"). 41 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/summarize/interfaces/ISummarizeResponse.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "ISummarizeResponse" 6 | --- 7 | 8 | Defined in: [src/interfaces/summarize.ts:4](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/summarize.ts#L4) 9 | 10 | Интерфейс, представляющий ответ на запрос суммаризации. 11 | 12 | ## Properties 13 | 14 | ### characters 15 | 16 | > **characters**: `number` 17 | 18 | Defined in: [src/interfaces/summarize.ts:18](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/summarize.ts#L18) 19 | 20 | Количество символов в суммаризированном тексте. 21 | 22 | *** 23 | 24 | ### object 25 | 26 | > **object**: `string` 27 | 28 | Defined in: [src/interfaces/summarize.ts:8](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/summarize.ts#L8) 29 | 30 | Тип объекта (например, "summary"). 31 | 32 | *** 33 | 34 | ### tokens 35 | 36 | > **tokens**: `number` 37 | 38 | Defined in: [src/interfaces/summarize.ts:13](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/summarize.ts#L13) 39 | 40 | Количество токенов в суммаризированном тексте. 41 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/completion/interfaces/ICompletionUsage.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "ICompletionUsage" 6 | --- 7 | 8 | Defined in: [src/interfaces/completion.ts:91](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L91) 9 | 10 | Информация об использовании токенов в запросе и ответе. 11 | 12 | ## Properties 13 | 14 | ### completion\_tokens 15 | 16 | > **completion\_tokens**: `number` 17 | 18 | Defined in: [src/interfaces/completion.ts:96](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L96) 19 | 20 | Количество токенов в сгенерированном ответе. 21 | 22 | *** 23 | 24 | ### prompt\_tokens 25 | 26 | > **prompt\_tokens**: `number` 27 | 28 | Defined in: [src/interfaces/completion.ts:93](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L93) 29 | 30 | Количество токенов во входном запросе. 31 | 32 | *** 33 | 34 | ### total\_tokens 35 | 36 | > **total\_tokens**: `number` 37 | 38 | Defined in: [src/interfaces/completion.ts:99](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L99) 39 | 40 | Общее количество использованных токенов. 41 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/embedding/interfaces/IEmbeddingResponse.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "IEmbeddingResponse" 6 | --- 7 | 8 | Defined in: [src/interfaces/embedding.ts:24](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/embedding.ts#L24) 9 | 10 | Интерфейс ответа на запрос эмбеддингов. 11 | 12 | ## Properties 13 | 14 | ### data 15 | 16 | > **data**: [`IEmbedding`](/gigachat-node/api/interfaces/embedding/interfaces/iembedding/)[] 17 | 18 | Defined in: [src/interfaces/embedding.ts:38](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/embedding.ts#L38) 19 | 20 | Массив эмбеддингов, полученных в ответе. 21 | 22 | *** 23 | 24 | ### model 25 | 26 | > **model**: `string` 27 | 28 | Defined in: [src/interfaces/embedding.ts:33](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/embedding.ts#L33) 29 | 30 | Название модели, использованной для генерации эмбеддингов. 31 | 32 | *** 33 | 34 | ### object 35 | 36 | > **object**: `string` 37 | 38 | Defined in: [src/interfaces/embedding.ts:28](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/embedding.ts#L28) 39 | 40 | Тип объекта (например, "embedding"). 41 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/completion/interfaces/ICompletionChoice.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "ICompletionChoice" 6 | --- 7 | 8 | Defined in: [src/interfaces/completion.ts:105](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L105) 9 | 10 | Один из вариантов ответа в completion-запросе. 11 | 12 | ## Properties 13 | 14 | ### finish\_reason 15 | 16 | > **finish\_reason**: `string` 17 | 18 | Defined in: [src/interfaces/completion.ts:110](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L110) 19 | 20 | Причина завершения генерации (например, "stop" или "length"). 21 | 22 | *** 23 | 24 | ### index 25 | 26 | > **index**: `number` 27 | 28 | Defined in: [src/interfaces/completion.ts:107](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L107) 29 | 30 | Индекс данного варианта ответа в списке. 31 | 32 | *** 33 | 34 | ### message 35 | 36 | > **message**: [`IMessage`](/gigachat-node/api/interfaces/message/interfaces/imessage/) 37 | 38 | Defined in: [src/interfaces/completion.ts:113](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L113) 39 | 40 | Сгенерированное сообщение с ответом. 41 | -------------------------------------------------------------------------------- /docs/src/content/docs/guides/image.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Генерация изображений 3 | description: Генерация изображений c GigaChatAPI. 4 | --- 5 | 6 | С помощью библиотеки и GigaChat API можно сгенерировать изображения. 7 | 8 | Если в конструкторе класса параметр *imgOn* выключен, то объект *message* будет следующего формата 9 | 10 | ```javascript 11 | { 12 | content: ' Какой-то текст', 13 | role: 'assistant' 14 | } 15 | ``` 16 | 17 | Если включить параметр (или оставить включенным по умолчанию), то уникальный идентификатор сгенерированного изображения будет извлечен из ответа модели и объект *message* придет следующего вида 18 | 19 | ```javascript 20 | { 21 | content: 'Какой-то тест', 22 | role: 'assistant', 23 | image: 'fileId' 24 | } 25 | ``` 26 | 27 | Затем *fileId* можно использовать для получения бинарного представления изображения 28 | 29 | ```javascript 30 | const completion = await client.completion({ 31 | model: "GigaChat", 32 | messages: [ 33 | { 34 | role: "user", 35 | content: "Нарисуй что-то" 36 | } 37 | ], 38 | function_call: "auto" 39 | }); 40 | 41 | if(completion.choices[0].message.image) { 42 | const binary = await client.downloadFile(completion.choices[0].message.image); 43 | ... 44 | } 45 | ``` 46 | 47 | Подробнее можно ознакомиться с генерацией изображения в [официальной документации](https://developers.sber.ru/docs/ru/gigachat/api/images-generation). -------------------------------------------------------------------------------- /__tests__/index.test.ts: -------------------------------------------------------------------------------- 1 | import { jest } from '@jest/globals'; 2 | import axios from 'axios'; 3 | 4 | import { GigaChat } from '../src/index'; 5 | 6 | jest.mock('axios'); 7 | const mockedAxios = axios as jest.Mocked; 8 | 9 | describe('GigaChatJS', () => { 10 | const config = { 11 | clientSecretKey: 'secret-key', 12 | isIgnoreTSL: true, 13 | isPersonal: true, 14 | autoRefreshToken: true, 15 | imgOn: true, 16 | imgPath: './__tests__/images/', 17 | }; 18 | 19 | let client: GigaChat; 20 | 21 | beforeEach(() => { 22 | client = new GigaChat(config); 23 | }); 24 | 25 | afterEach(() => { 26 | jest.clearAllMocks(); 27 | }); 28 | 29 | describe('Создание токена', () => { 30 | it('Должен успешно создать токен', async () => { 31 | const mockTokenResponse = { data: { access_token: 'test_token' } }; 32 | mockedAxios.post.mockResolvedValueOnce(mockTokenResponse); 33 | const tokenResponse = await client.createToken(); 34 | 35 | expect(tokenResponse.access_token).toBe('test_token'); 36 | expect(mockedAxios.post).toHaveBeenCalledTimes(1); 37 | }); 38 | 39 | it('Должен обработать ошибку при создании токена', async () => { 40 | mockedAxios.post.mockRejectedValueOnce(new Error('Network error')); 41 | await expect(client.createToken()).rejects.toThrow( 42 | 'Unknown error (create token): Error: Network error', 43 | ); 44 | }); 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": false, 4 | "node": true, 5 | "es2021": true 6 | }, 7 | "parser": "@typescript-eslint/parser", 8 | "parserOptions": { 9 | "sourceType": "module", 10 | "ecmaVersion": "latest", 11 | "project": "./tsconfig.json" 12 | }, 13 | "plugins": ["@typescript-eslint", "import", "prettier", "unused-imports"], 14 | "extends": [ 15 | "eslint:recommended", 16 | "plugin:@typescript-eslint/recommended", 17 | "plugin:import/recommended", 18 | "plugin:prettier/recommended" 19 | ], 20 | "rules": { 21 | "import/named": 0, 22 | "import/no-duplicates": "warn", 23 | "prettier/prettier": "error", 24 | "no-console": "warn", 25 | "unused-imports/no-unused-imports": "error", 26 | "import/order": [ 27 | "error", 28 | { 29 | "groups": ["builtin", "external", "internal", "parent", "sibling", "index"], 30 | "alphabetize": { "order": "asc", "caseInsensitive": true }, 31 | "newlines-between": "always" 32 | } 33 | ], 34 | "@typescript-eslint/no-explicit-any": "off", 35 | "@typescript-eslint/explicit-function-return-type": "off", 36 | "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }] 37 | }, 38 | "settings": { 39 | "import/resolver": { 40 | "node": { 41 | "extensions": [".js", ".ts"], 42 | "moduleDirectory": ["node_modules", "src"] 43 | }, 44 | "typescript": { 45 | "alwaysTryTypes": true, 46 | "project": "./tsconfig.json" 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /docs/dist/_astro/TableOfContents.astro_astro_type_script_index_0_lang.CKWWgpjV.js: -------------------------------------------------------------------------------- 1 | const g="_top";class f extends HTMLElement{constructor(){super(),this._current=this.querySelector('a[aria-current="true"]'),this.minH=parseInt(this.dataset.minH||"2",10),this.maxH=parseInt(this.dataset.maxH||"3",10),this.onIdle=e=>(window.requestIdleCallback||(o=>setTimeout(o,1)))(e),this.init=()=>{const e=[...this.querySelectorAll("a")],o=t=>{if(t instanceof HTMLHeadingElement){if(t.id===g)return!0;const s=t.tagName[1];if(s){const n=parseInt(s,10);if(n>=this.minH&&n<=this.maxH)return!0}}return!1},i=t=>{if(!t)return null;const s=t;for(;t;){if(o(t))return t;for(t=t.previousElementSibling;t?.lastElementChild;)t=t.lastElementChild;const n=i(t);if(n)return n}return i(s.parentElement)},c=t=>{for(const{isIntersecting:s,target:n}of t){if(!s)continue;const l=i(n);if(!l)continue;const m=e.find(d=>d.hash==="#"+encodeURIComponent(l.id));if(m){this.current=m;break}}},a=document.querySelectorAll("main [id], main [id] ~ *, main .content > *");let r;const u=()=>{r||(r=new IntersectionObserver(c,{rootMargin:this.getRootMargin()}),a.forEach(t=>r.observe(t)))};u();let h;window.addEventListener("resize",()=>{r&&(r.disconnect(),r=void 0),clearTimeout(h),h=setTimeout(()=>this.onIdle(u),200)})},this.onIdle(()=>this.init())}set current(e){e!==this._current&&(this._current&&this._current.removeAttribute("aria-current"),e.setAttribute("aria-current","true"),this._current=e)}getRootMargin(){const e=document.querySelector("header")?.getBoundingClientRect().height||0,o=this.querySelector("summary")?.getBoundingClientRect().height||0,i=e+o+32,c=i+53,a=document.documentElement.clientHeight;return`-${i}px 0% ${c-a}px`}}customElements.define("starlight-toc",f);export{f as S}; 2 | -------------------------------------------------------------------------------- /docs/src/content/docs/examples/images.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Массовая генерация изображений (JavaScript) 3 | description: Массовая генерация изображений с GigaChat API. 4 | --- 5 | 6 | [Репозиторий с кодом](https://github.com/zloishavrin/gigachat-text2image) 7 | 8 | ```shell 9 | npm install gigachat-node 10 | ``` 11 | 12 | Реализация генерации на JavaScript с помощью GigaChatJS. 13 | 14 | ```javascript 15 | const GigaChat = require('gigachat-node').GigaChat; 16 | const fs = require('fs'); 17 | 18 | // Ваш ключ от GigaChat API 19 | const GIGACHAT_API_TOKEN = 'GIGACHAT_API_KEY'; 20 | 21 | // Инициализация класса GigaChat и передача объекта конфигурации в конструктор 22 | const client = new GigaChat({ 23 | clientSecretKey: GIGACHAT_API_TOKEN, 24 | isIgnoreTSL: true, 25 | isPersonal: true, 26 | autoRefreshToken: true, 27 | imgOn: true 28 | }); 29 | 30 | const main = async () => { 31 | // Получение токена GigaChat для аутентификации запросов 32 | await client.createToken(); 33 | 34 | for(let index = 0; index < 10; index++) { 35 | const response = await client.completion({ 36 | model: "GigaChat", 37 | messages: [{ role: "user", content: `Нарисуй белую комнату` }], 38 | function_call: "auto" 39 | }); 40 | 41 | const imageId = response.choices[0].message.image; 42 | 43 | if(imageId) { 44 | const binaryData = await client.downloadFile(imageId); 45 | const buffer = Buffer.from(binaryData, 'base64'); 46 | fs.writeFile(`image${index}.jpg`, buffer, (err) => { 47 | if (err) { 48 | console.error('Ошибка при сохранении файла:', err); 49 | } else { 50 | console.log('Файл успешно сохранён!'); 51 | } 52 | }); 53 | } 54 | } 55 | } 56 | 57 | main(); 58 | ``` -------------------------------------------------------------------------------- /docs/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'astro/config'; 2 | import starlight from '@astrojs/starlight'; 3 | import starlightTypeDoc, { typeDocSidebarGroup } from 'starlight-typedoc' 4 | 5 | export default defineConfig({ 6 | site: 'https://zloishavrin.github.io/gigachat-node', 7 | base: '/gigachat-node', 8 | output: 'static', 9 | integrations: [ 10 | starlight({ 11 | title: 'GigaChatJS', 12 | locales: { 13 | root: { 14 | label: "Русский", 15 | lang: "ru" 16 | } 17 | }, 18 | customCss: [ 19 | "./src/custom.css", 20 | ], 21 | social: { 22 | github: 'https://github.com/zloishavrin/gigachat-node', 23 | }, 24 | plugins: [ 25 | starlightTypeDoc({ 26 | entryPoints: [ 27 | '../src/index.ts', 28 | "../src/interfaces/*.ts", 29 | ], 30 | tsconfig: '../tsconfig.json', 31 | locale: "ru" 32 | }), 33 | ], 34 | sidebar: [ 35 | { 36 | label: 'Руководство', 37 | items: [ 38 | { label: 'Начать работу', slug: 'guides/readme' }, 39 | { label: 'Генерация изображений', slug: 'guides/image' }, 40 | { label: 'GigaChat Vision', slug: 'guides/vision' }, 41 | { label: 'Сертификат безопасности', slug: 'guides/security' }, 42 | { label: 'Отключение цензуры', slug: 'guides/censored' } 43 | ], 44 | }, 45 | { 46 | label: 'Примеры использования', 47 | items: [ 48 | { label: 'Телеграм-бот', slug: 'examples/tgbot'}, 49 | { label: 'Массовая генерация изображений', slug: 'examples/images' }, 50 | { label: 'REST', slug: 'examples/rest' }, 51 | { label: 'Телеграм-бот с генерацией изображений', slug: 'examples/tgbot-images' } 52 | ] 53 | }, 54 | typeDocSidebarGroup, 55 | ], 56 | }), 57 | ], 58 | }); 59 | -------------------------------------------------------------------------------- /docs/src/content/docs/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: GigaChatJS 3 | description: Начните работу с GigaChatAPI с помощью GigaChatJS 4 | template: splash 5 | hero: 6 | tagline: Неофициальная библиотека для GigaChat API 7 | image: 8 | file: ../../assets/gigachat.svg 9 | actions: 10 | - text: Начать работу 11 | link: /gigachat-node/guides/readme/ 12 | icon: right-arrow 13 | - text: Документация 14 | link: /gigachat-node/api/index/classes/gigachat/ 15 | icon: external 16 | variant: minimal 17 | --- 18 | 19 | import { Card, CardGrid } from '@astrojs/starlight/components'; 20 | 21 | 22 | 23 | ```shell 24 | npm install gigachat-node 25 | ``` 26 | 27 | 28 | [Ознакомьтесь с руководством](/gigachat-node/guides/readme/) 29 | 30 | 31 | [Ознакомьтесь с документацией](/gigachat-node/api/index/classes/gigachat/) 32 | 33 | 34 | [Ознакомьтесь с примерами использования библиотеки](/gigachat-node/examples/tgbot/) 35 | 36 | 37 | Смотрите также [GigaChat.NET](https://gitverse.ru/who_is_likhoded/GigaChat.NET) 38 | 39 | 40 | 41 |
![GitHub Repo stars](https://img.shields.io/github/stars/zloishavrin/gigachat-node) ![NPM Version](https://img.shields.io/npm/v/gigachat-node?style=flat-square) ![NPM Downloads](https://img.shields.io/npm/dw/gigachat-node?style=flat-square) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/gigachat-node?style=flat-square) ![Static Badge](https://img.shields.io/badge/dependencies-0-0?style=flat-square)
-------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gigachat-node", 3 | "version": "2.4.5", 4 | "description": "The unoffical JavaScript/TypesSript library for the GigaChat API", 5 | "main": "index.js", 6 | "type": "commonjs", 7 | "repository": "git+https://github.com/zloishavrin/gigachat-node.git", 8 | "homepage": "https://zloishavrin.github.io/gigachat-node/", 9 | "scripts": { 10 | "prepare": "husky install", 11 | "build": "tsc", 12 | "example": "nodemon", 13 | "lint": "eslint src --ext .ts", 14 | "lint:fix": "eslint src --ext .ts --fix", 15 | "format": "prettier --write src", 16 | "test": "jest", 17 | "test:coverage": "jest --coverage", 18 | "minify": "for file in dist/**/*.js; do terser $file -c -m -o $file; done" 19 | }, 20 | "lint-staged": { 21 | "*.ts": [ 22 | "eslint --fix", 23 | "prettier --write" 24 | ] 25 | }, 26 | "keywords": [ 27 | "ai", 28 | "gigachat", 29 | "sber", 30 | "kandynski", 31 | "Сбер", 32 | "Гигачат", 33 | "Кандинский", 34 | "llm" 35 | ], 36 | "author": "Nikita Shavrin", 37 | "license": "ISC", 38 | "devDependencies": { 39 | "@babel/cli": "^7.26.4", 40 | "@babel/preset-typescript": "^7.26.0", 41 | "@types/jest": "^29.5.14", 42 | "@types/node": "^20.9.3", 43 | "@typescript-eslint/eslint-plugin": "^6.19.1", 44 | "@typescript-eslint/parser": "^6.19.1", 45 | "eslint": "^8.57.1", 46 | "eslint-config-prettier": "^10.0.1", 47 | "eslint-import-resolver-node": "^0.3.9", 48 | "eslint-import-resolver-typescript": "^3.8.3", 49 | "eslint-plugin-import": "^2.31.0", 50 | "eslint-plugin-prettier": "^5.2.3", 51 | "eslint-plugin-unused-imports": "^4.1.4", 52 | "husky": "^8.0.0", 53 | "jest": "^29.7.0", 54 | "lint-staged": "^15.4.3", 55 | "nodemon": "^3.0.3", 56 | "prettier": "^3.5.1", 57 | "terser": "^5.39.0", 58 | "ts-jest": "^29.2.5", 59 | "ts-node": "^10.9.2", 60 | "typescript": "5.3" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/completion/interfaces/ICompletionResponse.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "ICompletionResponse" 6 | --- 7 | 8 | Defined in: [src/interfaces/completion.ts:71](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L71) 9 | 10 | Интерфейс ответа на запрос генерации текста (completion). 11 | 12 | ## Properties 13 | 14 | ### choices 15 | 16 | > **choices**: [`ICompletionChoice`](/gigachat-node/api/interfaces/completion/interfaces/icompletionchoice/)[] 17 | 18 | Defined in: [src/interfaces/completion.ts:85](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L85) 19 | 20 | Список возможных вариантов ответа. 21 | 22 | *** 23 | 24 | ### created 25 | 26 | > **created**: `number` 27 | 28 | Defined in: [src/interfaces/completion.ts:73](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L73) 29 | 30 | Временная метка создания ответа (в формате Unix timestamp). 31 | 32 | *** 33 | 34 | ### model 35 | 36 | > **model**: `string` 37 | 38 | Defined in: [src/interfaces/completion.ts:76](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L76) 39 | 40 | Название модели, использованной для генерации. 41 | 42 | *** 43 | 44 | ### object 45 | 46 | > **object**: `string` 47 | 48 | Defined in: [src/interfaces/completion.ts:79](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L79) 49 | 50 | Тип объекта ответа (обычно "text_completion"). 51 | 52 | *** 53 | 54 | ### usage 55 | 56 | > **usage**: [`ICompletionUsage`](/gigachat-node/api/interfaces/completion/interfaces/icompletionusage/) 57 | 58 | Defined in: [src/interfaces/completion.ts:82](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L82) 59 | 60 | Информация об использовании токенов. 61 | -------------------------------------------------------------------------------- /docs/dist/_astro/page.7qqag-5g.js: -------------------------------------------------------------------------------- 1 | const d=new Set,c=new WeakSet;let f=!0,h,l=!1;function v(e){l||(l=!0,f??=!1,h??="hover",g(),p(),w(),L())}function g(){for(const e of["touchstart","mousedown"])document.body.addEventListener(e,t=>{i(t.target,"tap")&&s(t.target.href,{ignoreSlowConnection:!0})},{passive:!0})}function p(){let e;document.body.addEventListener("focusin",n=>{i(n.target,"hover")&&t(n)},{passive:!0}),document.body.addEventListener("focusout",o,{passive:!0}),u(()=>{for(const n of document.getElementsByTagName("a"))c.has(n)||i(n,"hover")&&(c.add(n),n.addEventListener("mouseenter",t,{passive:!0}),n.addEventListener("mouseleave",o,{passive:!0}))});function t(n){const r=n.target.href;e&&clearTimeout(e),e=setTimeout(()=>{s(r)},80)}function o(){e&&(clearTimeout(e),e=0)}}function w(){let e;u(()=>{for(const t of document.getElementsByTagName("a"))c.has(t)||i(t,"viewport")&&(c.add(t),e??=y(),e.observe(t))})}function y(){const e=new WeakMap;return new IntersectionObserver((t,o)=>{for(const n of t){const r=n.target,a=e.get(r);n.isIntersecting?(a&&clearTimeout(a),e.set(r,setTimeout(()=>{o.unobserve(r),e.delete(r),s(r.href)},300))):a&&(clearTimeout(a),e.delete(r))}})}function L(){u(()=>{for(const e of document.getElementsByTagName("a"))i(e,"load")&&s(e.href)})}function s(e,t){e=e.replace(/#.*/,"");const o=t?.ignoreSlowConnection??!1;if(S(e,o))if(d.add(e),document.createElement("link").relList?.supports?.("prefetch")&&t?.with!=="fetch"){const n=document.createElement("link");n.rel="prefetch",n.setAttribute("href",e),document.head.append(n)}else fetch(e,{priority:"low"})}function S(e,t){if(!navigator.onLine||!t&&m())return!1;try{const o=new URL(e,location.href);return location.origin===o.origin&&(location.pathname!==o.pathname||location.search!==o.search)&&!d.has(e)}catch{}return!1}function i(e,t){if(e?.tagName!=="A")return!1;const o=e.dataset.astroPrefetch;return o==="false"?!1:t==="tap"&&(o!=null||f)&&m()?!0:o==null&&f||o===""?t===h:o===t}function m(){if("connection"in navigator){const e=navigator.connection;return e.saveData||/2g/.test(e.effectiveType)}return!1}function u(e){e();let t=!1;document.addEventListener("astro:page-load",()=>{if(!t){t=!0;return}e()})}v(); 2 | -------------------------------------------------------------------------------- /docs/src/content/docs/examples/tgbot.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Телеграм-бот (JavaScript) 3 | description: Телеграм-бот с GigaChat API. 4 | --- 5 | 6 | [Репозиторий с кодом](https://github.com/zloishavrin/gigachat-tg-bot) 7 | 8 | Установка библиотек 9 | 10 | ```shell 11 | npm install gigachat-node node-telegram-bot-api 12 | ``` 13 | 14 | Реализация бота на JavaScript с помощью GigaChatJS 15 | 16 | ```javascript 17 | const TelegramBot = require('node-telegram-bot-api'); 18 | const GigaChat = require('gigachat-node').GigaChat; 19 | 20 | // Ваш ключ от Telegram Bot API 21 | const TG_API_TOKEN = "YOUR_TELEGRAM_BOT_API_KEY"; 22 | // Ваш ключ от GigaChat API 23 | const GIGACHAT_API_TOKEN = "YOUR_GIGACHAT_API_KEY"; 24 | 25 | const bot = new TelegramBot(TG_API_TOKEN, { polling: true }); 26 | 27 | // Инициализация класса GigaChat и передача объекта конфигурации в конструктор 28 | const client = new GigaChat({ 29 | clientSecretKey: GIGACHAT_API_TOKEN, 30 | isIgnoreTSL: true, 31 | isPersonal: true, 32 | autoRefreshToken: true 33 | }); 34 | 35 | const main = async () => { 36 | // Получение токена GigaChat для аутентификации запросов 37 | await client.createToken(); 38 | 39 | bot.on('message', async (msg) => { 40 | const chatId = msg.chat.id; 41 | const messageText = msg.text.trim(); 42 | 43 | try { 44 | // Отправка сообщения в GigaChat 45 | const response = await client.completion({ 46 | model: "GigaChat:latest", 47 | messages: [{ role: "user", content: messageText }] 48 | }); 49 | 50 | // Проверка на пустой ответ 51 | if (!response || !response.choices || response.choices.length === 0) { 52 | bot.sendMessage(chatId, 'Произошла ошибка при обработке запроса.'); 53 | return; 54 | } 55 | 56 | const replyText = response.choices[0].message.content; 57 | 58 | // Отправка ответа пользователю 59 | bot.sendMessage(chatId, replyText); 60 | } 61 | catch (error) { 62 | // Обработка ошибок при запросе к GigaChat 63 | bot.sendMessage(chatId, 'Произошла ошибка при общении с GigaChat. Попробуйте снова позже.'); 64 | } 65 | }); 66 | } 67 | 68 | main(); 69 | ``` -------------------------------------------------------------------------------- /docs/src/content/i18n/ru.json: -------------------------------------------------------------------------------- 1 | { 2 | "skipLink.label": "Пропустить", 3 | "search.label": "Поиск", 4 | "search.ctrlKey": "Ctrl", 5 | "search.cancelLabel": "Отмена", 6 | "search.devWarning": "Поиск доступен только в производственных сборках. \nПопробуйте создать и предварительно просмотреть сайт, чтобы протестировать его локально.", 7 | "themeSelect.accessibleLabel": "Выбрать тему", 8 | "themeSelect.dark": "Темная", 9 | "themeSelect.light": "Светлая", 10 | "themeSelect.auto": "Авто", 11 | "languageSelect.accessibleLabel": "Выбрать язык", 12 | "menuButton.accessibleLabel": "Меню", 13 | "sidebarNav.accessibleLabel": "Основное", 14 | "tableOfContents.onThisPage": "На этой странице", 15 | "tableOfContents.overview": "Обзор", 16 | "i18n.untranslatedContent": "Этот контент пока недоступен на вашем языке.", 17 | "page.editLink": "Редактировать страницу", 18 | "page.lastUpdated": "Последнее обновление:", 19 | "page.previousLink": "Предыдущее", 20 | "page.nextLink": "Следующее", 21 | "page.draft": "Этот контент является черновым вариантом и не будет включен в производственные сборки.", 22 | "404.text": "Страница не найдена. Проверьте URL-адрес или попробуйте воспользоваться строкой поиска.", 23 | "aside.note": "Замечание", 24 | "aside.tip": "Совет", 25 | "aside.caution": "Внимание", 26 | "aside.danger": "Опасно", 27 | "fileTree.directory": "Каталог", 28 | "builtWithStarlight.label": "Автодокументация", 29 | "expressiveCode.copyButtonCopied": "Скопировано", 30 | "expressiveCode.copyButtonTooltip": "Скопировать", 31 | "expressiveCode.terminalWindowFallbackTitle": "Окно терминала", 32 | "pagefind.clear_search": "Очистить", 33 | "pagefind.load_more": "Загрузить еще", 34 | "pagefind.search_label": "Поиск на этом сайте", 35 | "pagefind.filters_label": "Фильтры", 36 | "pagefind.zero_results": "Нет результатов для [SEARCH_TERM]", 37 | "pagefind.many_results": "[COUNT] результатов для [SEARCH_TERM]", 38 | "pagefind.one_result": "[COUNT] результат для [SEARCH_TERM]", 39 | "pagefind.alt_search": "Нет результатов для [SEARCH_TERM]. Показать результаты для [DIFFERENT_TERM]", 40 | "pagefind.search_suggestion": "Нет результатов для [SEARCH_TERM]. Попробуйте воспользоваться одним из следующих способов поиска:", 41 | "pagefind.searching": "Поиск [SEARCH_TERM]..." 42 | } -------------------------------------------------------------------------------- /docs/dist/_astro/ec.8zarh.js: -------------------------------------------------------------------------------- 1 | try{(()=>{function a(e){if(!e)return;let t=e.getAttribute("tabindex")!==null,n=e.scrollWidth>e.clientWidth;n&&!t?e.setAttribute("tabindex","0"):!n&&t&&e.removeAttribute("tabindex")}var u=window.requestIdleCallback||(e=>setTimeout(e,1)),i=window.cancelIdleCallback||clearTimeout;function l(e){let t=new Set,n,r;return new ResizeObserver(c=>{c.forEach(o=>t.add(o.target)),n&&clearTimeout(n),r&&i(r),n=setTimeout(()=>{r&&i(r),r=u(()=>{t.forEach(o=>e(o)),t.clear()})},250)})}function d(e,t){e.querySelectorAll?.(".expressive-code pre > code").forEach(n=>{let r=n.parentElement;r&&t.observe(r)})}var s=l(a);d(document,s);var b=new MutationObserver(e=>e.forEach(t=>t.addedNodes.forEach(n=>{d(n,s)})));b.observe(document.body,{childList:!0,subtree:!0});document.addEventListener("astro:page-load",()=>{d(document,s)});})();}catch(e){console.error("[EC] tabindex-js-module failed:",e)} 2 | try{(()=>{function i(o){let e=document.createElement("pre");Object.assign(e.style,{opacity:"0",pointerEvents:"none",position:"absolute",overflow:"hidden",left:"0",top:"0",width:"20px",height:"20px",webkitUserSelect:"auto",userSelect:"all"}),e.ariaHidden="true",e.textContent=o,document.body.appendChild(e);let a=document.createRange();a.selectNode(e);let n=getSelection();if(!n)return!1;n.removeAllRanges(),n.addRange(a);let r=!1;try{r=document.execCommand("copy")}finally{n.removeAllRanges(),document.body.removeChild(e)}return r}async function l(o){let e=o.currentTarget,a=e.dataset,n=!1,r=a.code.replace(/\u007f/g,` 3 | `);try{await navigator.clipboard.writeText(r),n=!0}catch{n=i(r)}if(!n||e.parentNode?.querySelector(".feedback"))return;let t=document.createElement("div");t.classList.add("feedback"),t.append(a.copied),e.before(t),t.offsetWidth,requestAnimationFrame(()=>t?.classList.add("show"));let c=()=>!t||t.classList.remove("show"),d=()=>{!t||parseFloat(getComputedStyle(t).opacity)>0||(t.remove(),t=void 0)};setTimeout(c,1500),setTimeout(d,2500),e.addEventListener("blur",c),t.addEventListener("transitioncancel",d),t.addEventListener("transitionend",d)}function s(o){o.querySelectorAll?.(".expressive-code .copy button").forEach(e=>e.addEventListener("click",l))}s(document);var u=new MutationObserver(o=>o.forEach(e=>e.addedNodes.forEach(a=>{s(a)})));u.observe(document.body,{childList:!0,subtree:!0});document.addEventListener("astro:page-load",()=>{s(document)});})();}catch(e){console.error("[EC] copy-js-module failed:",e)} -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/file/interfaces/IFile.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "IFile" 6 | --- 7 | 8 | Defined in: [src/interfaces/file.ts:4](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/file.ts#L4) 9 | 10 | Интерфейс, представляющий загруженный файл. 11 | 12 | ## Properties 13 | 14 | ### access\_policy? 15 | 16 | > `optional` **access\_policy**: `"private"` \| `"public"` 17 | 18 | Defined in: [src/interfaces/file.ts:39](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/file.ts#L39) 19 | 20 | Политика доступа к файлу: `private` (по умолчанию) или `public`. 21 | Опциональный параметр. 22 | 23 | *** 24 | 25 | ### bytes 26 | 27 | > **bytes**: `number` 28 | 29 | Defined in: [src/interfaces/file.ts:8](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/file.ts#L8) 30 | 31 | Размер файла в байтах. 32 | 33 | *** 34 | 35 | ### created\_at 36 | 37 | > **created\_at**: `number` 38 | 39 | Defined in: [src/interfaces/file.ts:13](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/file.ts#L13) 40 | 41 | Временная метка создания файла (в формате Unix Timestamp). 42 | 43 | *** 44 | 45 | ### filename 46 | 47 | > **filename**: `string` 48 | 49 | Defined in: [src/interfaces/file.ts:18](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/file.ts#L18) 50 | 51 | Имя файла. 52 | 53 | *** 54 | 55 | ### id 56 | 57 | > **id**: `string` 58 | 59 | Defined in: [src/interfaces/file.ts:23](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/file.ts#L23) 60 | 61 | Уникальный идентификатор файла. 62 | 63 | *** 64 | 65 | ### object 66 | 67 | > **object**: `string` 68 | 69 | Defined in: [src/interfaces/file.ts:28](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/file.ts#L28) 70 | 71 | Тип объекта (например, "file"). 72 | 73 | *** 74 | 75 | ### purpose 76 | 77 | > **purpose**: `string` 78 | 79 | Defined in: [src/interfaces/file.ts:33](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/file.ts#L33) 80 | 81 | Назначение файла (например, "general" или другое). 82 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/config/interfaces/GigaChatConfig.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "GigaChatConfig" 6 | --- 7 | 8 | Defined in: [src/interfaces/config.ts:4](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/config.ts#L4) 9 | 10 | Конфигурационный интерфейс для настройки GigaChat. 11 | 12 | ## Properties 13 | 14 | ### autoRefreshToken? 15 | 16 | > `optional` **autoRefreshToken**: `boolean` 17 | 18 | Defined in: [src/interfaces/config.ts:30](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/config.ts#L30) 19 | 20 | Автоматически ли обновлять токен при его истечении. 21 | `true` — токен будет обновляться автоматически. 22 | 23 | #### Default 24 | 25 | ```ts 26 | true 27 | ``` 28 | 29 | *** 30 | 31 | ### clientSecretKey 32 | 33 | > **clientSecretKey**: `string` 34 | 35 | Defined in: [src/interfaces/config.ts:8](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/config.ts#L8) 36 | 37 | Секретный ключ клиента, используемый для аутентификации. 38 | 39 | *** 40 | 41 | ### imgOn? 42 | 43 | > `optional` **imgOn**: `boolean` 44 | 45 | Defined in: [src/interfaces/config.ts:37](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/config.ts#L37) 46 | 47 | Включена ли обработка изображений в ответах. 48 | Если `true`, изображения будут извлекаться в виде fileId в ответе модели. 49 | 50 | #### Default 51 | 52 | ```ts 53 | true 54 | ``` 55 | 56 | *** 57 | 58 | ### isIgnoreTSL? 59 | 60 | > `optional` **isIgnoreTSL**: `boolean` 61 | 62 | Defined in: [src/interfaces/config.ts:16](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/config.ts#L16) 63 | 64 | Игнорировать ли проверку TLS (SSL-сертификатов). 65 | `true` — проверка отключена (используется для обхода проблем с сертификатами). 66 | `false` — проверка включена. 67 | 68 | #### Default 69 | 70 | ```ts 71 | true 72 | ``` 73 | 74 | *** 75 | 76 | ### isPersonal? 77 | 78 | > `optional` **isPersonal**: `boolean` 79 | 80 | Defined in: [src/interfaces/config.ts:23](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/config.ts#L23) 81 | 82 | Используется ли персональный доступ (Personal API). 83 | `true` — персональный доступ, `false` — корпоративный. 84 | 85 | #### Default 86 | 87 | ```ts 88 | true 89 | ``` 90 | -------------------------------------------------------------------------------- /docs/dist/_astro/Search.astro_astro_type_script_index_0_lang.DrM75iIr.js: -------------------------------------------------------------------------------- 1 | const y="modulepreload",w=function(m){return"/gigachat-node/"+m},f={},S=function(u,i,c){let h=Promise.resolve();if(i&&i.length>0){document.getElementsByTagName("link");const r=document.querySelector("meta[property=csp-nonce]"),t=r?.nonce||r?.getAttribute("nonce");h=Promise.allSettled(i.map(n=>{if(n=w(n),n in f)return;f[n]=!0;const d=n.endsWith(".css"),p=d?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${n}"]${p}`))return;const o=document.createElement("link");if(o.rel=d?"stylesheet":y,d||(o.as="script"),o.crossOrigin="",o.href=n,t&&o.setAttribute("nonce",t),document.head.appendChild(o),d)return new Promise((e,s)=>{o.addEventListener("load",e),o.addEventListener("error",()=>s(new Error(`Unable to preload CSS for ${n}`)))})}))}function l(r){const t=new Event("vite:preloadError",{cancelable:!0});if(t.payload=r,window.dispatchEvent(t),!t.defaultPrevented)throw r}return h.then(r=>{for(const t of r||[])t.status==="rejected"&&l(t.reason);return u().catch(l)})},E={ranking:{pageLength:.1,termFrequency:.1,termSaturation:2,termSimilarity:9}};class v extends HTMLElement{constructor(){super();const u=this.querySelector("button[data-open-modal]"),i=this.querySelector("button[data-close-modal]"),c=this.querySelector("dialog"),h=this.querySelector(".dialog-frame"),l=e=>{("href"in(e.target||{})||document.body.contains(e.target)&&!h.contains(e.target))&&t()},r=e=>{c.showModal(),document.body.toggleAttribute("data-search-modal-open",!0),this.querySelector("input")?.focus(),e?.stopPropagation(),window.addEventListener("click",l)},t=()=>c.close();u.addEventListener("click",r),u.disabled=!1,i.addEventListener("click",t),c.addEventListener("close",()=>{document.body.toggleAttribute("data-search-modal-open",!1),window.removeEventListener("click",l)}),window.addEventListener("keydown",e=>{(e.metaKey===!0||e.ctrlKey===!0)&&e.key==="k"&&(c.open?t():r(),e.preventDefault())});let n={};try{n=JSON.parse(this.dataset.translations||"{}")}catch{}const o=this.dataset.stripTrailingSlash!==void 0?e=>e.replace(/(.)\/(#.*)?$/,"$1$2"):e=>e;window.addEventListener("DOMContentLoaded",()=>{(window.requestIdleCallback||(s=>setTimeout(s,1)))(async()=>{const{PagefindUI:s}=await S(async()=>{const{PagefindUI:a}=await import("./ui-core.B_vBCAZW.js");return{PagefindUI:a}},[]);new s({...E,element:"#starlight__search",baseUrl:"/gigachat-node",bundlePath:"/gigachat-node".replace(/\/$/,"")+"/pagefind/",showImages:!1,translations:n,showSubResults:!0,processResult:a=>{a.url=o(a.url),a.sub_results=a.sub_results.map(g=>(g.url=o(g.url),g))}})})})}}customElements.define("site-search",v);export{S as _}; 2 | -------------------------------------------------------------------------------- /docs/src/content/docs/examples/rest.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: RESTful API (TypeScript) 3 | description: RESTful API с GigaChat API. 4 | --- 5 | 6 | [Репозиторий с кодом](https://github.com/zloishavrin/gigachat-rest-api) 7 | 8 | Установка библиотек 9 | 10 | ```shell 11 | npm install gigachat-node express body-parser 12 | npm install --save-dev @types/express 13 | ``` 14 | 15 | Реализация RESTFul API с помощью GigaChatJS 16 | 17 | ```typescript 18 | import express, { Request, Response } from 'express'; 19 | import bodyParser from 'body-parser'; 20 | import { GigaChat } from 'gigachat-node'; 21 | 22 | // Ваш ключ от GigaChat API 23 | const GIGACHAT_API_TOKEN = 'YOUR_GIGACHAT_API_KEY'; 24 | 25 | // Инициализация Express приложения 26 | const app = express(); 27 | const port = 3000; 28 | 29 | // Инициализация клиента GigaChat 30 | const client = new GigaChat({ 31 | clientSecretKey: GIGACHAT_API_TOKEN, 32 | isIgnoreTSL: true, 33 | isPersonal: true, 34 | autoRefreshToken: true 35 | }); 36 | 37 | app.use(bodyParser.json()); 38 | 39 | // Создаем эндпоинт для обработки сообщений 40 | app.post('/chat', async (req: Request, res: Response): Promise => { 41 | const messageText: string = req.body.message?.trim(); 42 | 43 | // Проверяем, что сообщение присутствует в теле запроса 44 | if (!messageText) { 45 | res.status(400).json({ error: 'Message is required' }); 46 | return; 47 | } 48 | 49 | try { 50 | // Отправляем запрос в GigaChat API 51 | const response = await client.completion({ 52 | model: 'GigaChat:latest', 53 | messages: [{ role: 'user', content: messageText }] 54 | }); 55 | 56 | // Проверка на пустой ответ от GigaChat 57 | if (!response || !response.choices || response.choices.length === 0) { 58 | res.status(500).json({ error: 'Error during message processing' }); 59 | return; 60 | } 61 | 62 | const replyText = response.choices[0].message.content; 63 | 64 | // Отправляем ответ на запрос 65 | res.json({ reply: replyText }); 66 | } 67 | catch (error: any) { 68 | res.status(500).json({ 69 | error: 'An error occurred while processing your request. Please try again later.' 70 | }); 71 | } 72 | }); 73 | 74 | // Запускаем сервер 75 | app.listen(port, async () => { 76 | // Создаем токен GigaChat для аутентификации запросов 77 | await client.createToken(); 78 | 79 | console.log(`Server running on http://localhost:${port}`); 80 | }); 81 | ``` 82 | 83 | Пример запроса 84 | 85 | ```shell 86 | curl -X POST http://localhost:3000/chat -H "Content-Type: application/json" -d '{"message": "Привет, как дела?"}' 87 | ``` -------------------------------------------------------------------------------- /src/utils/FormDataFile.ts: -------------------------------------------------------------------------------- 1 | import { statSync, readFileSync } from 'fs'; 2 | import { basename, extname } from 'path'; 3 | 4 | /** 5 | * Класс для работы с файлами при загрузке через форму. Автоматически определяет MIME-тип и размер файла. 6 | * 7 | * @class 8 | * @property {string} name - Имя файла (например: "изображение.png") 9 | * @property {string} mimeType - Определенный MIME-тип на основе расширения файла 10 | * @property {number} size - Размер файла в байтах 11 | */ 12 | export class FormDataFile { 13 | /** Базовое имя файла, извлеченное из пути */ 14 | public readonly name: string; 15 | 16 | /** Автоматически определенный MIME-тип */ 17 | public readonly mimeType: string; 18 | 19 | /** Размер файла в байтах */ 20 | public readonly size: number; 21 | 22 | /** Полный путь к файлу */ 23 | private readonly filePath: string; 24 | 25 | /** 26 | * Создает экземпляр FormDataFile 27 | * @constructor 28 | * @param {string} pathToFile - Абсолютный или относительный путь к файлу 29 | * @throws {Error} Если файл недоступен 30 | */ 31 | constructor(pathToFile: string) { 32 | this.filePath = pathToFile; 33 | this.name = basename(pathToFile); 34 | this.mimeType = this.detectMimeType(); 35 | this.size = this.getFileSize(); 36 | } 37 | 38 | /** 39 | * Определяет MIME-тип по расширению файла 40 | * @private 41 | * @returns {string} MIME-тип из предустановленных значений или 'application/octet-stream' 42 | */ 43 | private detectMimeType(): string { 44 | const ext = extname(this.filePath).toLowerCase().slice(1); 45 | const mimeMap: Record = { 46 | png: 'image/png', 47 | jpg: 'image/jpeg', 48 | jpeg: 'image/jpeg', 49 | gif: 'image/gif', 50 | txt: 'text/plain', 51 | pdf: 'application/pdf', 52 | doc: 'application/msword', 53 | docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 54 | }; 55 | return mimeMap[ext] || 'application/octet-stream'; 56 | } 57 | 58 | /** 59 | * Получает размер файла с помощью синхронного метода stat 60 | * @private 61 | * @returns {number} Размер файла в байтах 62 | * @throws {Error} Если файл недоступен 63 | */ 64 | private getFileSize(): number { 65 | const stats = statSync(this.filePath); 66 | return stats.size; 67 | } 68 | 69 | /** 70 | * Читает содержимое файла в буфер 71 | * @public 72 | * @returns {Buffer} Содержимое файла в бинарном виде 73 | * @throws {Error} Если не удалось прочитать файл 74 | * @example 75 | * const file = new FormDataFile('документ.pdf'); 76 | * const buffer = file.readFile(); 77 | */ 78 | public readFile(): Buffer { 79 | return readFileSync(this.filePath); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /docs/src/content/docs/examples/tgbot-images.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Телеграм-бот c генерацией изображений (JavaScript) 3 | description: Телеграм-бот с GigaChat API. 4 | --- 5 | 6 | [Репозиторий с кодом](https://github.com/zloishavrin/gigachat-tg-bot) 7 | 8 | Установка библиотек 9 | 10 | ```shell 11 | npm install gigachat-node node-telegram-bot-api 12 | ``` 13 | 14 | Реализация бота на JavaScript с помощью GigaChatJS 15 | 16 | ```javascript 17 | const TelegramBot = require('node-telegram-bot-api'); 18 | const GigaChat = require('gigachat-node').GigaChat; 19 | 20 | // Ваш ключ от Telegram Bot API 21 | const TG_API_TOKEN = "TG_API_KEY"; 22 | // Ваш ключ от GigaChat API 23 | const GIGACHAT_API_TOKEN = 'GIGACHAT_API_KEY'; 24 | 25 | const bot = new TelegramBot(TG_API_TOKEN, { polling: true }); 26 | 27 | // Инициализация класса GigaChat и передача объекта конфигурации в конструктор 28 | const client = new GigaChat({ 29 | clientSecretKey: GIGACHAT_API_TOKEN, 30 | isIgnoreTSL: true, 31 | isPersonal: true, 32 | autoRefreshToken: true, 33 | imgOn: true 34 | }); 35 | 36 | const main = async () => { 37 | // Получение токена GigaChat для аутентификации запросов 38 | await client.createToken(); 39 | 40 | bot.on('message', async (msg) => { 41 | const chatId = msg.chat.id; 42 | const messageText = msg.text.trim(); 43 | 44 | try { 45 | // Обработка старта 46 | if(messageText === '/start') { 47 | bot.sendMessage(chatId, 'Привет! Я могу нарисовать что угодно. Что ты хочешь увидеть?'); 48 | return; 49 | } 50 | 51 | // Отправка сообщения в GigaChat 52 | const response = await client.completion({ 53 | model: "GigaChat", 54 | messages: [{ role: "user", content: `Нарисуй ${messageText}` }], 55 | function_call: "auto" 56 | }); 57 | 58 | // Проверка на пустой ответ 59 | if (!response || !response.choices || response.choices.length === 0) { 60 | bot.sendMessage(chatId, 'Произошла ошибка при обработке запроса.'); 61 | return; 62 | } 63 | 64 | const imageId = response.choices[0].message.image; 65 | // Обработка случая, когда не удалось сгенерировать изображение. 66 | if(!imageId) { 67 | bot.sendMessage(chatId, 'Не удалось изобразить данный запрос :('); 68 | } 69 | 70 | // Получение изображения в бинарном формате 71 | const binaryImage = await client.downloadFile(imageId); 72 | 73 | const replyText = response.choices[0].message.content; 74 | 75 | // Отправка ответа пользователю 76 | bot.sendPhoto(chatId, binaryImage, { 77 | caption: replyText 78 | }) 79 | } 80 | catch (error) { 81 | console.error(error); 82 | // Обработка ошибок при запросе к GigaChat 83 | bot.sendMessage(chatId, 'Произошла ошибка при общении с GigaChat. Попробуйте снова позже.'); 84 | } 85 | }); 86 | } 87 | 88 | main(); 89 | ``` -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/message/interfaces/IMessage.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "IMessage" 6 | --- 7 | 8 | Defined in: [src/interfaces/message.ts:4](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/message.ts#L4) 9 | 10 | Интерфейс, представляющий сообщение в чате. 11 | 12 | ## Properties 13 | 14 | ### attachments? 15 | 16 | > `optional` **attachments**: \[`string`\] 17 | 18 | Defined in: [src/interfaces/message.ts:37](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/message.ts#L37) 19 | 20 | Массив с уникальными идентификаторами файлов 21 | 22 | *** 23 | 24 | ### content 25 | 26 | > **content**: `string` 27 | 28 | Defined in: [src/interfaces/message.ts:17](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/message.ts#L17) 29 | 30 | Текстовое содержимое сообщения. 31 | 32 | *** 33 | 34 | ### created? 35 | 36 | > `optional` **created**: `number` 37 | 38 | Defined in: [src/interfaces/message.ts:25](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/message.ts#L25) 39 | 40 | Временная метка создания ответа (в формате Unix timestamp). 41 | 42 | *** 43 | 44 | ### function\_call? 45 | 46 | > `optional` **function\_call**: `any` 47 | 48 | Defined in: [src/interfaces/message.ts:34](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/message.ts#L34) 49 | 50 | Объект вызванной функции. 51 | 52 | *** 53 | 54 | ### functions\_state\_id? 55 | 56 | > `optional` **functions\_state\_id**: `string` 57 | 58 | Defined in: [src/interfaces/message.ts:31](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/message.ts#L31) 59 | 60 | Идентификатор, который объединяет массив функций, переданных в запросе. 61 | 62 | *** 63 | 64 | ### image? 65 | 66 | > `optional` **image**: `string` 67 | 68 | Defined in: [src/interfaces/message.ts:22](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/message.ts#L22) 69 | 70 | Уникальный идентификатор изображения, если сообщение его содержит. 71 | 72 | *** 73 | 74 | ### name? 75 | 76 | > `optional` **name**: `string` 77 | 78 | Defined in: [src/interfaces/message.ts:28](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/message.ts#L28) 79 | 80 | Название вызванной встроенной функции. 81 | 82 | *** 83 | 84 | ### role 85 | 86 | > **role**: `"user"` \| `"assistant"` \| `"system"` \| `"search_result"` 87 | 88 | Defined in: [src/interfaces/message.ts:12](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/message.ts#L12) 89 | 90 | Роль отправителя сообщения. 91 | - `user` — сообщение от пользователя. 92 | - `assistant` — сообщение от ассистента (ИИ). 93 | - `system` — системное сообщение. 94 | - `search_result` — результат поиска. 95 | -------------------------------------------------------------------------------- /docs/dist/sitemap-0.xml: -------------------------------------------------------------------------------- 1 | https://zloishavrin.github.io/gigachat-nodehttps://zloishavrin.github.io/gigachat-node/api/index/classes/gigachat/https://zloishavrin.github.io/gigachat-node/api/index/classes/gigachaterror/https://zloishavrin.github.io/gigachat-node/api/interfaces/balance/interfaces/ibalance/https://zloishavrin.github.io/gigachat-node/api/interfaces/balance/interfaces/ibalanceresponse/https://zloishavrin.github.io/gigachat-node/api/interfaces/completion/interfaces/icompletionchoice/https://zloishavrin.github.io/gigachat-node/api/interfaces/completion/interfaces/icompletionrequest/https://zloishavrin.github.io/gigachat-node/api/interfaces/completion/interfaces/icompletionresponse/https://zloishavrin.github.io/gigachat-node/api/interfaces/completion/interfaces/icompletionusage/https://zloishavrin.github.io/gigachat-node/api/interfaces/config/interfaces/gigachatconfig/https://zloishavrin.github.io/gigachat-node/api/interfaces/embedding/interfaces/iembedding/https://zloishavrin.github.io/gigachat-node/api/interfaces/embedding/interfaces/iembeddingresponse/https://zloishavrin.github.io/gigachat-node/api/interfaces/extract/interfaces/iextractimage/https://zloishavrin.github.io/gigachat-node/api/interfaces/file/interfaces/ifile/https://zloishavrin.github.io/gigachat-node/api/interfaces/file/interfaces/ifiledeleteresponse/https://zloishavrin.github.io/gigachat-node/api/interfaces/message/interfaces/imessage/https://zloishavrin.github.io/gigachat-node/api/interfaces/model/interfaces/iallmodelresponse/https://zloishavrin.github.io/gigachat-node/api/interfaces/model/interfaces/imodelresponse/https://zloishavrin.github.io/gigachat-node/api/interfaces/summarize/interfaces/isummarizeresponse/https://zloishavrin.github.io/gigachat-node/api/interfaces/token/interfaces/itokenresponse/https://zloishavrin.github.io/gigachat-node/api/readme/https://zloishavrin.github.io/gigachat-node/examples/images/https://zloishavrin.github.io/gigachat-node/examples/rest/https://zloishavrin.github.io/gigachat-node/examples/tgbot-images/https://zloishavrin.github.io/gigachat-node/examples/tgbot/https://zloishavrin.github.io/gigachat-node/guides/censored/https://zloishavrin.github.io/gigachat-node/guides/image/https://zloishavrin.github.io/gigachat-node/guides/readme/https://zloishavrin.github.io/gigachat-node/guides/security/https://zloishavrin.github.io/gigachat-node/guides/vision/ -------------------------------------------------------------------------------- /src/interfaces/completion.ts: -------------------------------------------------------------------------------- 1 | import { IMessage } from './message'; 2 | 3 | /** 4 | * Интерфейс запроса на генерацию текста (completion). 5 | */ 6 | export interface ICompletionRequest { 7 | /** Название модели, которая будет использоваться для генерации. */ 8 | model: string; 9 | 10 | /** Массив сообщений, на основе которых будет сформирован ответ. */ 11 | messages: IMessage[]; 12 | 13 | /** 14 | * Температура генерации (чем выше значение, тем более случайными будут ответы). 15 | * Значение должно быть от 0 до 1. 16 | * @default 1 17 | */ 18 | temperature?: number; 19 | 20 | /** 21 | * Альтернативный параметр управления случайностью выборки токенов. 22 | * Используется вместо `temperature`, если задано. 23 | * Значение должно быть от 0 до 1. 24 | */ 25 | top_p?: number; 26 | 27 | /** 28 | * Количество альтернативных ответов, которые должны быть сгенерированы. 29 | * @default 1 30 | */ 31 | n?: number; 32 | 33 | /** 34 | * Максимальное количество токенов в ответе. 35 | * Если не указано, используется значение по умолчанию модели. 36 | */ 37 | max_tokens?: number; 38 | 39 | /** 40 | * Коэффициент штрафа за повторение слов или фраз. 41 | * Чем выше значение, тем меньше модель склонна повторяться. 42 | */ 43 | repetition_penalty?: number; 44 | 45 | /** 46 | * Интервал обновления потока данных (в миллисекундах). 47 | * Используется в потоковом режиме. 48 | */ 49 | update_interval?: number; 50 | 51 | /** 52 | * Флаг проверки ненормативной лексики в сгенерированном тексте. 53 | * @default false 54 | */ 55 | profanity_check?: boolean; 56 | 57 | /** 58 | * Поле, которое отвечает за то, как GigaChat будет работать с функциями. 59 | */ 60 | function_call?: any; 61 | 62 | /** 63 | * Массив с описанием пользовательских функций. 64 | */ 65 | functions?: [any]; 66 | } 67 | 68 | /** 69 | * Интерфейс ответа на запрос генерации текста (completion). 70 | */ 71 | export interface ICompletionResponse { 72 | /** Временная метка создания ответа (в формате Unix timestamp). */ 73 | created: number; 74 | 75 | /** Название модели, использованной для генерации. */ 76 | model: string; 77 | 78 | /** Тип объекта ответа (обычно "text_completion"). */ 79 | object: string; 80 | 81 | /** Информация об использовании токенов. */ 82 | usage: ICompletionUsage; 83 | 84 | /** Список возможных вариантов ответа. */ 85 | choices: ICompletionChoice[]; 86 | } 87 | 88 | /** 89 | * Информация об использовании токенов в запросе и ответе. 90 | */ 91 | export interface ICompletionUsage { 92 | /** Количество токенов во входном запросе. */ 93 | prompt_tokens: number; 94 | 95 | /** Количество токенов в сгенерированном ответе. */ 96 | completion_tokens: number; 97 | 98 | /** Общее количество использованных токенов. */ 99 | total_tokens: number; 100 | } 101 | 102 | /** 103 | * Один из вариантов ответа в completion-запросе. 104 | */ 105 | export interface ICompletionChoice { 106 | /** Индекс данного варианта ответа в списке. */ 107 | index: number; 108 | 109 | /** Причина завершения генерации (например, "stop" или "length"). */ 110 | finish_reason: string; 111 | 112 | /** Сгенерированное сообщение с ответом. */ 113 | message: IMessage; 114 | } 115 | -------------------------------------------------------------------------------- /src/utils/FormDataBuilder.ts: -------------------------------------------------------------------------------- 1 | import { randomBytes } from 'crypto'; 2 | 3 | import { FormDataFile } from './FormDataFile'; 4 | 5 | /** 6 | * Класс для построения multipart/form-data запросов 7 | * @class 8 | * @property {string} boundary Уникальный разделитель частей формы 9 | * @property {Buffer[]} parts Буферы данных частей формы 10 | */ 11 | export class FormDataBuilder { 12 | /** Уникальный разделитель частей формы */ 13 | private readonly boundary: string; 14 | 15 | /** Буферы данных частей формы */ 16 | private readonly parts: Buffer[] = []; 17 | 18 | /** Разделитель строк согласно стандарту */ 19 | private readonly lineEnding = '\r\n'; 20 | 21 | /** 22 | * Создает экземпляр FormDataBuilder 23 | * @constructor 24 | * @description Генерирует уникальный boundary для разделения частей формы 25 | */ 26 | constructor() { 27 | this.boundary = `----${randomBytes(16).toString('hex')}`; 28 | } 29 | 30 | /** 31 | * Добавляет текстовое поле в форму 32 | * @param {string} name Название поля 33 | * @param {string} value Значение поля 34 | * @example 35 | * builder.appendField('username', 'JohnDoe'); 36 | */ 37 | public appendField(name: string, value: string): void { 38 | this.parts.push( 39 | Buffer.from( 40 | `--${this.boundary}${this.lineEnding}` + 41 | `Content-Disposition: form-data; name="${name}"${this.lineEnding}${this.lineEnding}` + 42 | `${value}${this.lineEnding}`, 43 | ), 44 | ); 45 | } 46 | 47 | /** 48 | * Добавляет файл в форму 49 | * @param {string} name Название поля для файла 50 | * @param {FormDataFile} file Экземпляр файла 51 | * @example 52 | * const file = new FormDataFile('photo.jpg'); 53 | * builder.appendFile('avatar', file); 54 | */ 55 | public appendFile(name: string, file: FormDataFile): void { 56 | const fileHeader = 57 | `--${this.boundary}${this.lineEnding}` + 58 | `Content-Disposition: form-data; name="${name}"; filename="${file.name}"${this.lineEnding}` + 59 | `Content-Type: ${file.mimeType}${this.lineEnding}${this.lineEnding}`; 60 | 61 | this.parts.push(Buffer.from(fileHeader), file.readFile(), Buffer.from(this.lineEnding)); 62 | } 63 | 64 | /** 65 | * Возвращает заголовки для HTTP-запроса 66 | * @returns {Object} Объект с заголовками 67 | * @property {string} Content-Type MIME-тип с boundary 68 | * @property {string} [Content-Length] Размер тела запроса 69 | */ 70 | public getHeaders(): { 'Content-Type': string; 'Content-Length'?: string } { 71 | return { 72 | 'Content-Type': `multipart/form-data; boundary=${this.boundary}`, 73 | 'Content-Length': this.getTotalLength().toString(), 74 | }; 75 | } 76 | 77 | /** 78 | * Собирает итоговое тело запроса 79 | * @returns {Buffer} Буфер с данными формы 80 | * @description Объединяет все части и добавляет финальный boundary 81 | */ 82 | public getBody(): Buffer { 83 | const finalBoundary = Buffer.from(`${this.lineEnding}--${this.boundary}--${this.lineEnding}`); 84 | return Buffer.concat([...this.parts, finalBoundary]); 85 | } 86 | 87 | /** 88 | * Вычисляет общий размер тела запроса 89 | * @private 90 | * @returns {number} Общий размер в байтах 91 | */ 92 | private getTotalLength(): number { 93 | return ( 94 | this.parts.reduce((acc, part) => acc + part.length, 0) + 95 | Buffer.from(`${this.lineEnding}--${this.boundary}--${this.lineEnding}`).length 96 | ); 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /docs/dist/_astro/print.BJ0teN4y.css: -------------------------------------------------------------------------------- 1 | @media print{:root[data-theme]:is(:root){--sl-color-white: hsl(224, 10%, 10%);--sl-color-gray-1: hsl(224, 14%, 16%);--sl-color-gray-2: hsl(224, 10%, 23%);--sl-color-gray-3: hsl(224, 7%, 36%);--sl-color-gray-4: hsl(224, 6%, 56%);--sl-color-gray-5: hsl(224, 6%, 77%);--sl-color-gray-6: hsl(224, 20%, 94%);--sl-color-gray-7: hsl(224, 19%, 97%);--sl-color-black: hsl(0, 0%, 100%);--sl-color-orange-high: hsl(var(--sl-hue-orange), 80%, 25%);--sl-color-orange: hsl(var(--sl-hue-orange), 90%, 60%);--sl-color-orange-low: hsl(var(--sl-hue-orange), 90%, 88%);--sl-color-green-high: hsl(var(--sl-hue-green), 80%, 22%);--sl-color-green: hsl(var(--sl-hue-green), 90%, 46%);--sl-color-green-low: hsl(var(--sl-hue-green), 85%, 90%);--sl-color-blue-high: hsl(var(--sl-hue-blue), 80%, 30%);--sl-color-blue: hsl(var(--sl-hue-blue), 90%, 60%);--sl-color-blue-low: hsl(var(--sl-hue-blue), 88%, 90%);--sl-color-purple-high: hsl(var(--sl-hue-purple), 90%, 30%);--sl-color-purple: hsl(var(--sl-hue-purple), 90%, 60%);--sl-color-purple-low: hsl(var(--sl-hue-purple), 80%, 90%);--sl-color-red-high: hsl(var(--sl-hue-red), 80%, 30%);--sl-color-red: hsl(var(--sl-hue-red), 90%, 60%);--sl-color-red-low: hsl(var(--sl-hue-red), 80%, 90%);--sl-color-accent-high: hsl(234, 80%, 30%);--sl-color-accent: hsl(234, 90%, 60%);--sl-color-accent-low: hsl(234, 88%, 90%);--sl-color-text-accent: var(--sl-color-accent);--sl-color-text-invert: var(--sl-color-black);--sl-color-bg-nav: var(--sl-color-gray-7);--sl-color-bg-sidebar: var(--sl-color-bg);--sl-color-bg-inline-code: var(--sl-color-gray-6);--sl-color-bg-accent: var(--sl-color-accent);--sl-color-hairline-light: var(--sl-color-gray-6);--sl-color-hairline-shade: var(--sl-color-gray-6);--sl-color-backdrop-overlay: hsla(225, 9%, 36%, .66);--sl-shadow-sm: none;--sl-shadow-md: none;--sl-shadow-lg: none}.print\:hidden{display:none!important}.print\:flex{display:flex!important}.print\:block{display:block!important}main{padding-bottom:0!important}main>.content-panel{padding-block-start:0!important}.content-panel+.content-panel{border:0!important}.page>header{position:relative!important}.page>.main-frame{padding-top:0;padding-inline-start:0}.main-pane{--sl-sidebar-width: 0px !important;--sl-content-width: 100% !important}.sl-banner{--sl-color-banner-text: var(--sl-color-white) !important;background-color:transparent!important}.sl-markdown-content :is(h1,h2,h3,h4,h5,h6){break-after:avoid}.sl-markdown-content :is(p,li){orphans:2;widows:2}.sl-markdown-content pre{overflow-x:hidden!important;white-space:pre-wrap!important}.sl-markdown-content .expressive-code,.sl-markdown-content figure,.sl-markdown-content pre{break-inside:avoid}.expressive-code .frame.is-terminal .header:before{box-shadow:inset 99rem 99rem var(--sl-color-gray-5)}.expressive-code .frame.has-title:not(.is-terminal) .header{background:transparent!important;border-bottom:1px solid var(--sl-color-gray-6)!important}.expressive-code .frame.has-title:not(.is-terminal) .title{background:transparent!important}.expressive-code .frame.has-title:not(.is-terminal) .title:after{border-top:0!important}.expressive-code .copy{display:none!important}.sl-markdown-content code:not(:where(.not-content *)){background-color:transparent!important;padding:0!important;margin-block:unset!important;font-size:.9375em!important}.sl-badge{background:transparent!important;color:var(--sl-color-white)!important}starlight-file-tree{break-inside:avoid}starlight-file-tree .highlight{outline:3px solid var(--sl-color-accent-low);color:var(--sl-color-text)!important;background-color:transparent!important}.starlight-aside{break-inside:avoid}.sl-link-button.primary{background:transparent!important;border-color:var(--sl-color-white)!important;color:var(--sl-color-white)!important}starlight-tabs{break-inside:avoid}.sl-steps>li:after{box-shadow:inset 99rem 99rem var(--sl-color-hairline-light)}} 2 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/index/classes/GigaChatError.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "GigaChatError" 6 | --- 7 | 8 | Defined in: [src/utils/GigaChatError.ts:17](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/utils/GigaChatError.ts#L17) 9 | 10 | Класс ошибки API GigaChat с дополнительной информацией 11 | 12 | ## Example 13 | 14 | ```ts 15 | try { 16 | await gigachat.completion(...); 17 | } catch (error) { 18 | if (error instanceof GigaChatError) { 19 | console.error(`Код ошибки: ${error.code}`, error.message); 20 | } 21 | } 22 | ``` 23 | 24 | ## Extends 25 | 26 | - `Error` 27 | 28 | ## Constructors 29 | 30 | ### new GigaChatError() 31 | 32 | > **new GigaChatError**(`message`, `code`): [`GigaChatError`](/gigachat-node/api/index/classes/gigachaterror/) 33 | 34 | Defined in: [src/utils/GigaChatError.ts:30](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/utils/GigaChatError.ts#L30) 35 | 36 | Создает экземпляр ошибки GigaChat 37 | 38 | #### Parameters 39 | 40 | ##### message 41 | 42 | `string` 43 | 44 | Человекочитаемое описание ошибки 45 | 46 | ##### code 47 | 48 | `string` 49 | 50 | Уникальный идентификатор типа ошибки 51 | 52 | #### Returns 53 | 54 | [`GigaChatError`](/gigachat-node/api/index/classes/gigachaterror/) 55 | 56 | #### Overrides 57 | 58 | `Error.constructor` 59 | 60 | ## Properties 61 | 62 | ### code 63 | 64 | > `readonly` **code**: `string` 65 | 66 | Defined in: [src/utils/GigaChatError.ts:22](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/utils/GigaChatError.ts#L22) 67 | 68 | Уникальный код ошибки для идентификации типа проблемы 69 | 70 | *** 71 | 72 | ### message 73 | 74 | > **message**: `string` 75 | 76 | Defined in: docs/node\_modules/typescript/lib/lib.es5.d.ts:1077 77 | 78 | #### Inherited from 79 | 80 | `Error.message` 81 | 82 | *** 83 | 84 | ### name 85 | 86 | > **name**: `string` 87 | 88 | Defined in: docs/node\_modules/typescript/lib/lib.es5.d.ts:1076 89 | 90 | Название ошибки (всегда 'GigaChatError') 91 | 92 | #### Inherited from 93 | 94 | `Error.name` 95 | 96 | *** 97 | 98 | ### stack? 99 | 100 | > `optional` **stack**: `string` 101 | 102 | Defined in: docs/node\_modules/typescript/lib/lib.es5.d.ts:1078 103 | 104 | #### Inherited from 105 | 106 | `Error.stack` 107 | 108 | *** 109 | 110 | ### prepareStackTrace()? 111 | 112 | > `static` `optional` **prepareStackTrace**: (`err`, `stackTraces`) => `any` 113 | 114 | Defined in: node\_modules/@types/node/globals.d.ts:98 115 | 116 | Optional override for formatting stack traces 117 | 118 | #### Parameters 119 | 120 | ##### err 121 | 122 | `Error` 123 | 124 | ##### stackTraces 125 | 126 | `CallSite`[] 127 | 128 | #### Returns 129 | 130 | `any` 131 | 132 | #### See 133 | 134 | https://v8.dev/docs/stack-trace-api#customizing-stack-traces 135 | 136 | #### Inherited from 137 | 138 | `Error.prepareStackTrace` 139 | 140 | *** 141 | 142 | ### stackTraceLimit 143 | 144 | > `static` **stackTraceLimit**: `number` 145 | 146 | Defined in: node\_modules/@types/node/globals.d.ts:100 147 | 148 | #### Inherited from 149 | 150 | `Error.stackTraceLimit` 151 | 152 | ## Methods 153 | 154 | ### captureStackTrace() 155 | 156 | > `static` **captureStackTrace**(`targetObject`, `constructorOpt`?): `void` 157 | 158 | Defined in: node\_modules/@types/node/globals.d.ts:91 159 | 160 | Create .stack property on a target object 161 | 162 | #### Parameters 163 | 164 | ##### targetObject 165 | 166 | `object` 167 | 168 | ##### constructorOpt? 169 | 170 | `Function` 171 | 172 | #### Returns 173 | 174 | `void` 175 | 176 | #### Inherited from 177 | 178 | `Error.captureStackTrace` 179 | -------------------------------------------------------------------------------- /docs/src/content/docs/api/interfaces/completion/interfaces/ICompletionRequest.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "ICompletionRequest" 6 | --- 7 | 8 | Defined in: [src/interfaces/completion.ts:6](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L6) 9 | 10 | Интерфейс запроса на генерацию текста (completion). 11 | 12 | ## Properties 13 | 14 | ### function\_call? 15 | 16 | > `optional` **function\_call**: `any` 17 | 18 | Defined in: [src/interfaces/completion.ts:60](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L60) 19 | 20 | Поле, которое отвечает за то, как GigaChat будет работать с функциями. 21 | 22 | *** 23 | 24 | ### functions? 25 | 26 | > `optional` **functions**: \[`any`\] 27 | 28 | Defined in: [src/interfaces/completion.ts:65](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L65) 29 | 30 | Массив с описанием пользовательских функций. 31 | 32 | *** 33 | 34 | ### max\_tokens? 35 | 36 | > `optional` **max\_tokens**: `number` 37 | 38 | Defined in: [src/interfaces/completion.ts:37](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L37) 39 | 40 | Максимальное количество токенов в ответе. 41 | Если не указано, используется значение по умолчанию модели. 42 | 43 | *** 44 | 45 | ### messages 46 | 47 | > **messages**: [`IMessage`](/gigachat-node/api/interfaces/message/interfaces/imessage/)[] 48 | 49 | Defined in: [src/interfaces/completion.ts:11](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L11) 50 | 51 | Массив сообщений, на основе которых будет сформирован ответ. 52 | 53 | *** 54 | 55 | ### model 56 | 57 | > **model**: `string` 58 | 59 | Defined in: [src/interfaces/completion.ts:8](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L8) 60 | 61 | Название модели, которая будет использоваться для генерации. 62 | 63 | *** 64 | 65 | ### n? 66 | 67 | > `optional` **n**: `number` 68 | 69 | Defined in: [src/interfaces/completion.ts:31](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L31) 70 | 71 | Количество альтернативных ответов, которые должны быть сгенерированы. 72 | 73 | #### Default 74 | 75 | ```ts 76 | 1 77 | ``` 78 | 79 | *** 80 | 81 | ### profanity\_check? 82 | 83 | > `optional` **profanity\_check**: `boolean` 84 | 85 | Defined in: [src/interfaces/completion.ts:55](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L55) 86 | 87 | Флаг проверки ненормативной лексики в сгенерированном тексте. 88 | 89 | #### Default 90 | 91 | ```ts 92 | false 93 | ``` 94 | 95 | *** 96 | 97 | ### repetition\_penalty? 98 | 99 | > `optional` **repetition\_penalty**: `number` 100 | 101 | Defined in: [src/interfaces/completion.ts:43](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L43) 102 | 103 | Коэффициент штрафа за повторение слов или фраз. 104 | Чем выше значение, тем меньше модель склонна повторяться. 105 | 106 | *** 107 | 108 | ### temperature? 109 | 110 | > `optional` **temperature**: `number` 111 | 112 | Defined in: [src/interfaces/completion.ts:18](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L18) 113 | 114 | Температура генерации (чем выше значение, тем более случайными будут ответы). 115 | Значение должно быть от 0 до 1. 116 | 117 | #### Default 118 | 119 | ```ts 120 | 1 121 | ``` 122 | 123 | *** 124 | 125 | ### top\_p? 126 | 127 | > `optional` **top\_p**: `number` 128 | 129 | Defined in: [src/interfaces/completion.ts:25](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L25) 130 | 131 | Альтернативный параметр управления случайностью выборки токенов. 132 | Используется вместо `temperature`, если задано. 133 | Значение должно быть от 0 до 1. 134 | 135 | *** 136 | 137 | ### update\_interval? 138 | 139 | > `optional` **update\_interval**: `number` 140 | 141 | Defined in: [src/interfaces/completion.ts:49](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/interfaces/completion.ts#L49) 142 | 143 | Интервал обновления потока данных (в миллисекундах). 144 | Используется в потоковом режиме. 145 | -------------------------------------------------------------------------------- /src/utils/HTTPClient.ts: -------------------------------------------------------------------------------- 1 | import { Agent, RequestOptions, request as httpsRequest } from 'https'; 2 | import { Readable } from 'stream'; 3 | 4 | import { FormDataBuilder } from './FormDataBuilder'; 5 | import { FormDataFile } from './FormDataFile'; 6 | import { GigaChatError } from './GigaChatError'; 7 | 8 | export class HTTPClient { 9 | private baseUrl: string; 10 | private authorization: string | undefined; 11 | private isIgnoreTSL: boolean; 12 | 13 | constructor(baseUrl: string, authorization: string | undefined, isIgnoreTSL: boolean) { 14 | this.baseUrl = baseUrl; 15 | this.authorization = authorization; 16 | this.isIgnoreTSL = isIgnoreTSL; 17 | } 18 | 19 | public async setAuthorization(authorization: string) { 20 | this.authorization = authorization; 21 | } 22 | 23 | public async makeRequest( 24 | options: RequestOptions, 25 | data: string | Buffer, 26 | redirectCount: number = 0, 27 | stream: boolean = false, 28 | ): Promise { 29 | return new Promise((resolve, reject) => { 30 | const request = httpsRequest(options, (result) => { 31 | if ( 32 | result.statusCode && 33 | result.statusCode >= 300 && 34 | result.statusCode < 400 && 35 | result.headers.location 36 | ) { 37 | if (redirectCount < 5) { 38 | reject(new Error('Too many redirects')); 39 | return; 40 | } 41 | 42 | const redirectUrl = new URL( 43 | result.headers.location, 44 | `https://${options.hostname}${options.path}`, 45 | ); 46 | const newOptions = { ...options }; 47 | 48 | newOptions.hostname = redirectUrl.hostname; 49 | newOptions.path = redirectUrl.pathname + redirectUrl.search; 50 | newOptions.port = redirectUrl.port || 443; 51 | 52 | if (result.statusCode === 307 || result.statusCode === 308) { 53 | newOptions.method = options.method; 54 | } else { 55 | newOptions.method = 'GET'; 56 | data = ''; 57 | } 58 | 59 | if (newOptions.method === 'GET') { 60 | delete newOptions.headers!['Content-Length']; 61 | delete newOptions.headers!['Content-Type']; 62 | } 63 | 64 | this.makeRequest(newOptions, data, redirectCount + 1) 65 | .then(resolve) 66 | .catch(reject); 67 | return; 68 | } 69 | 70 | if (result.statusCode && (result.statusCode < 200 || result.statusCode >= 300)) { 71 | reject(new Error(`HTTP Error: ${result.statusCode} ${result.statusMessage}`)); 72 | return; 73 | } 74 | 75 | if (options.headers && options.headers.Accept === 'application/jpg') { 76 | const chunks: Buffer[] = []; 77 | result.on('data', (chunk) => chunks.push(chunk)); 78 | result.on('end', () => { 79 | const buffer = Buffer.concat(chunks); 80 | resolve(buffer); 81 | }); 82 | return; 83 | } else if (stream) { 84 | const transformStream = new Readable({ 85 | read() {}, 86 | }); 87 | 88 | result.on('data', (chunk) => { 89 | const decodedChunk = chunk.toString('utf-8'); 90 | if (decodedChunk.startsWith('data: [DONE]')) { 91 | transformStream.push(null); 92 | return; 93 | } else if (decodedChunk.startsWith('data: ')) { 94 | transformStream.push(chunk); 95 | } 96 | }); 97 | 98 | resolve(transformStream); 99 | } else { 100 | let rawData = ''; 101 | 102 | result.on('data', (chunk) => { 103 | rawData += chunk; 104 | }); 105 | result.on('end', () => { 106 | try { 107 | const parseData = JSON.parse(rawData); 108 | resolve(parseData); 109 | } catch (error) { 110 | resolve(rawData); 111 | } 112 | }); 113 | } 114 | }); 115 | 116 | request.on('error', reject); 117 | 118 | if (options.method === 'POST') { 119 | request.write(data); 120 | } 121 | 122 | request.end(); 123 | }); 124 | } 125 | 126 | /** 127 | * Выполняет GET-запрос к API. 128 | * @param {string} path Путь запроса. 129 | * @param {boolean} isImage Флаг для получения изображения. 130 | * @returns {Promise} Ответ API. 131 | */ 132 | public async get(path: string, isImage: boolean = false): Promise { 133 | const url = new URL(`${this.baseUrl}${path}`); 134 | const options: RequestOptions = { 135 | hostname: url.hostname, 136 | path: url.pathname + url.search, 137 | port: url.port || 443, 138 | method: 'GET', 139 | headers: { 140 | Authorization: `Bearer ${this.authorization}`, 141 | Accept: isImage ? 'application/jpg' : 'application/json', 142 | }, 143 | agent: new Agent({ 144 | rejectUnauthorized: !this.isIgnoreTSL, 145 | }), 146 | }; 147 | 148 | const response = await this.makeRequest(options, ''); 149 | return response; 150 | } 151 | 152 | /** 153 | * Выполняет POST-запрос к API. 154 | * @param {string} path Путь запроса. 155 | * @param {object} data Данные запроса. 156 | * @param {boolean} [stream=false] Флаг для потокового ответа. 157 | * @returns {Promise} Ответ API. 158 | */ 159 | public async post(path: string, data: object, stream: boolean = false): Promise { 160 | const url = new URL(`${this.baseUrl}${path}`); 161 | const dataString = JSON.stringify(data); 162 | 163 | const options: RequestOptions = { 164 | hostname: url.hostname, 165 | path: url.pathname + url.search, 166 | port: url.port || 443, 167 | method: 'POST', 168 | headers: { 169 | Authorization: `Bearer ${this.authorization}`, 170 | 'Content-Type': 'application/json', 171 | 'Content-Length': Buffer.byteLength(dataString), 172 | }, 173 | agent: new Agent({ 174 | rejectUnauthorized: !this.isIgnoreTSL, 175 | }), 176 | }; 177 | 178 | const response = await this.makeRequest(options, dataString, 0, stream); 179 | return response; 180 | } 181 | 182 | /** 183 | * Загружает файл на сервер 184 | * @param {string} pathToFile Путь до файла. 185 | * @param {string} purpose Признак использования. 186 | * @returns {Promise} Ответ API. 187 | */ 188 | public async postFiles(pathToFile: string, purpose: string): Promise { 189 | const file = new FormDataFile(pathToFile); 190 | const formData = new FormDataBuilder(); 191 | 192 | formData.appendField('purpose', purpose); 193 | formData.appendFile('file', file); 194 | 195 | const url = new URL(`${this.baseUrl}/files`); 196 | const options: RequestOptions = { 197 | hostname: url.hostname, 198 | path: url.pathname + url.search, 199 | port: url.port || 443, 200 | method: 'POST', 201 | headers: { 202 | Authorization: `Bearer ${this.authorization}`, 203 | Accept: 'application/json', 204 | ...formData.getHeaders(), 205 | }, 206 | agent: new Agent({ 207 | rejectUnauthorized: !this.isIgnoreTSL, 208 | }), 209 | }; 210 | 211 | try { 212 | const response = await this.makeRequest(options, formData.getBody()); 213 | return response; 214 | } catch (error) { 215 | throw new GigaChatError(`File upload failed: ${error}`, 'FILE_UPLOAD_ERROR'); 216 | } 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /docs/dist/pagefind/pagefind-modular-ui.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --pagefind-ui-scale: 0.8; 3 | --pagefind-ui-primary: #034AD8; 4 | --pagefind-ui-fade: #707070; 5 | --pagefind-ui-text: #393939; 6 | --pagefind-ui-background: #ffffff; 7 | --pagefind-ui-border: #eeeeee; 8 | --pagefind-ui-tag: #eeeeee; 9 | --pagefind-ui-border-width: 2px; 10 | --pagefind-ui-border-radius: 8px; 11 | --pagefind-ui-image-border-radius: 8px; 12 | --pagefind-ui-image-box-ratio: 3 / 2; 13 | --pagefind-ui-font: system, -apple-system, ".SFNSText-Regular", 14 | "San Francisco", "Roboto", "Segoe UI", "Helvetica Neue", 15 | "Lucida Grande", sans-serif; 16 | } 17 | 18 | [data-pfmod-hidden] { 19 | display: none !important; 20 | } 21 | 22 | [data-pfmod-suppressed] { 23 | opacity: 0 !important; 24 | pointer-events: none !important; 25 | } 26 | 27 | [data-pfmod-sr-hidden] { 28 | -webkit-clip: rect(0 0 0 0) !important; 29 | clip: rect(0 0 0 0) !important; 30 | -webkit-clip-path: inset(100%) !important; 31 | clip-path: inset(100%) !important; 32 | height: 1px !important; 33 | overflow: hidden !important; 34 | overflow: clip !important; 35 | position: absolute !important; 36 | white-space: nowrap !important; 37 | width: 1px !important; 38 | } 39 | 40 | [data-pfmod-loading] { 41 | color: var(--pagefind-ui-text); 42 | background-color: var(--pagefind-ui-text); 43 | border-radius: var(--pagefind-ui-border-radius); 44 | opacity: 0.1; 45 | pointer-events: none; 46 | } 47 | 48 | /* Input */ 49 | 50 | .pagefind-modular-input-wrapper { 51 | position: relative; 52 | } 53 | 54 | .pagefind-modular-input-wrapper::before { 55 | background-color: var(--pagefind-ui-text); 56 | width: calc(18px * var(--pagefind-ui-scale)); 57 | height: calc(18px * var(--pagefind-ui-scale)); 58 | top: calc(23px * var(--pagefind-ui-scale)); 59 | left: calc(20px * var(--pagefind-ui-scale)); 60 | content: ""; 61 | position: absolute; 62 | display: block; 63 | opacity: 0.7; 64 | -webkit-mask-image: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A"); 65 | mask-image: url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A"); 66 | -webkit-mask-size: 100%; 67 | mask-size: 100%; 68 | z-index: 9; 69 | pointer-events: none; 70 | } 71 | 72 | .pagefind-modular-input { 73 | height: calc(64px * var(--pagefind-ui-scale)); 74 | padding: 0 calc(70px * var(--pagefind-ui-scale)) 0 calc(54px * var(--pagefind-ui-scale)); 75 | background-color: var(--pagefind-ui-background); 76 | border: var(--pagefind-ui-border-width) solid var(--pagefind-ui-border); 77 | border-radius: var(--pagefind-ui-border-radius); 78 | font-size: calc(21px * var(--pagefind-ui-scale)); 79 | position: relative; 80 | appearance: none; 81 | -webkit-appearance: none; 82 | display: flex; 83 | width: 100%; 84 | box-sizing: border-box; 85 | font-weight: 700; 86 | } 87 | 88 | .pagefind-modular-input::placeholder { 89 | opacity: 0.2; 90 | } 91 | 92 | .pagefind-modular-input-clear { 93 | position: absolute; 94 | top: calc(2px * var(--pagefind-ui-scale)); 95 | right: calc(2px * var(--pagefind-ui-scale)); 96 | height: calc(60px * var(--pagefind-ui-scale)); 97 | border-radius: var(--pagefind-ui-border-radius); 98 | padding: 0 calc(15px * var(--pagefind-ui-scale)) 0 calc(2px * var(--pagefind-ui-scale)); 99 | color: var(--pagefind-ui-text); 100 | font-size: calc(14px * var(--pagefind-ui-scale)); 101 | cursor: pointer; 102 | background-color: var(--pagefind-ui-background); 103 | border: none; 104 | appearance: none; 105 | } 106 | 107 | /* ResultList */ 108 | 109 | .pagefind-modular-list-result { 110 | list-style-type: none; 111 | display: flex; 112 | align-items: flex-start; 113 | gap: min(calc(40px * var(--pagefind-ui-scale)), 3%); 114 | padding: calc(30px * var(--pagefind-ui-scale)) 0 calc(40px * var(--pagefind-ui-scale)); 115 | border-top: solid var(--pagefind-ui-border-width) var(--pagefind-ui-border); 116 | } 117 | 118 | .pagefind-modular-list-result:last-of-type { 119 | border-bottom: solid var(--pagefind-ui-border-width) var(--pagefind-ui-border); 120 | } 121 | 122 | .pagefind-modular-list-thumb { 123 | width: min(30%, 124 | calc((30% - (100px * var(--pagefind-ui-scale))) * 100000)); 125 | max-width: calc(120px * var(--pagefind-ui-scale)); 126 | margin-top: calc(10px * var(--pagefind-ui-scale)); 127 | aspect-ratio: var(--pagefind-ui-image-box-ratio); 128 | position: relative; 129 | } 130 | 131 | .pagefind-modular-list-image { 132 | display: block; 133 | position: absolute; 134 | left: 50%; 135 | transform: translateX(-50%); 136 | font-size: 0; 137 | width: auto; 138 | height: auto; 139 | max-width: 100%; 140 | max-height: 100%; 141 | border-radius: var(--pagefind-ui-image-border-radius); 142 | } 143 | 144 | .pagefind-modular-list-inner { 145 | flex: 1; 146 | display: flex; 147 | flex-direction: column; 148 | align-items: flex-start; 149 | margin-top: calc(10px * var(--pagefind-ui-scale)); 150 | } 151 | 152 | .pagefind-modular-list-title { 153 | display: inline-block; 154 | font-weight: 700; 155 | font-size: calc(21px * var(--pagefind-ui-scale)); 156 | margin-top: 0; 157 | margin-bottom: 0; 158 | } 159 | 160 | .pagefind-modular-list-link { 161 | color: var(--pagefind-ui-text); 162 | text-decoration: none; 163 | } 164 | 165 | .pagefind-modular-list-link:hover { 166 | text-decoration: underline; 167 | } 168 | 169 | .pagefind-modular-list-excerpt { 170 | display: inline-block; 171 | font-weight: 400; 172 | font-size: calc(16px * var(--pagefind-ui-scale)); 173 | margin-top: calc(4px * var(--pagefind-ui-scale)); 174 | margin-bottom: 0; 175 | min-width: calc(250px * var(--pagefind-ui-scale)); 176 | } 177 | 178 | /* FilterPills */ 179 | 180 | .pagefind-modular-filter-pills-wrapper { 181 | overflow-x: scroll; 182 | padding: 15px 0; 183 | } 184 | 185 | .pagefind-modular-filter-pills { 186 | display: flex; 187 | gap: 6px; 188 | } 189 | 190 | .pagefind-modular-filter-pill { 191 | display: flex; 192 | justify-content: center; 193 | align-items: center; 194 | border: none; 195 | appearance: none; 196 | padding: 0 calc(24px * var(--pagefind-ui-scale)); 197 | background-color: var(--pagefind-ui-background); 198 | color: var(--pagefind-ui-fade); 199 | border: var(--pagefind-ui-border-width) solid var(--pagefind-ui-border); 200 | border-radius: calc(25px * var(--pagefind-ui-scale)); 201 | font-size: calc(18px * var(--pagefind-ui-scale)); 202 | height: calc(50px * var(--pagefind-ui-scale)); 203 | cursor: pointer; 204 | white-space: nowrap; 205 | } 206 | 207 | .pagefind-modular-filter-pill:hover { 208 | border-color: var(--pagefind-ui-primary); 209 | } 210 | 211 | .pagefind-modular-filter-pill[aria-pressed="true"] { 212 | border-color: var(--pagefind-ui-primary); 213 | color: var(--pagefind-ui-primary); 214 | } -------------------------------------------------------------------------------- /docs/src/content/docs/api/index/classes/GigaChat.md: -------------------------------------------------------------------------------- 1 | --- 2 | editUrl: false 3 | next: false 4 | prev: false 5 | title: "GigaChat" 6 | --- 7 | 8 | Defined in: [src/index.ts:22](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L22) 9 | 10 | Класс для взаимодействия с API GigaChat. 11 | Позволяет выполнять авторизацию, отправлять запросы к модели, загружать файлы и работать с потоками данных. 12 | 13 | ## Constructors 14 | 15 | ### new GigaChat() 16 | 17 | > **new GigaChat**(`config`): [`GigaChat`](/gigachat-node/api/index/classes/gigachat/) 18 | 19 | Defined in: [src/index.ts:82](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L82) 20 | 21 | Создает новый экземпляр GigaChat. 22 | 23 | #### Parameters 24 | 25 | ##### config 26 | 27 | [`GigaChatConfig`](/gigachat-node/api/interfaces/config/interfaces/gigachatconfig/) 28 | 29 | Конфигурация клиента. 30 | 31 | #### Returns 32 | 33 | [`GigaChat`](/gigachat-node/api/index/classes/gigachat/) 34 | 35 | ## Properties 36 | 37 | ### authorization 38 | 39 | > **authorization**: `undefined` \| `string` 40 | 41 | Defined in: [src/index.ts:31](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L31) 42 | 43 | Токен авторизации для API. 44 | 45 | ## Methods 46 | 47 | ### allModels() 48 | 49 | > **allModels**(): `Promise`\<[`IAllModelResponse`](/gigachat-node/api/interfaces/model/interfaces/iallmodelresponse/)\> 50 | 51 | Defined in: [src/index.ts:275](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L275) 52 | 53 | Получает список всех моделей. 54 | 55 | #### Returns 56 | 57 | `Promise`\<[`IAllModelResponse`](/gigachat-node/api/interfaces/model/interfaces/iallmodelresponse/)\> 58 | 59 | Ответ сервера с моделями. 60 | 61 | *** 62 | 63 | ### completion() 64 | 65 | > **completion**(`data`): `Promise`\<[`ICompletionResponse`](/gigachat-node/api/interfaces/completion/interfaces/icompletionresponse/)\> 66 | 67 | Defined in: [src/index.ts:229](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L229) 68 | 69 | Отправляет запрос на завершение чата. 70 | 71 | #### Parameters 72 | 73 | ##### data 74 | 75 | [`ICompletionRequest`](/gigachat-node/api/interfaces/completion/interfaces/icompletionrequest/) 76 | 77 | Данные запроса. 78 | 79 | #### Returns 80 | 81 | `Promise`\<[`ICompletionResponse`](/gigachat-node/api/interfaces/completion/interfaces/icompletionresponse/)\> 82 | 83 | Ответ сервера. 84 | 85 | *** 86 | 87 | ### completionStream() 88 | 89 | > **completionStream**(`data`): `Promise`\<`Readable`\> 90 | 91 | Defined in: [src/index.ts:258](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L258) 92 | 93 | Отправляет потоковый запрос на завершение чата. 94 | 95 | #### Parameters 96 | 97 | ##### data 98 | 99 | [`ICompletionRequest`](/gigachat-node/api/interfaces/completion/interfaces/icompletionrequest/) 100 | 101 | Данные запроса. 102 | 103 | #### Returns 104 | 105 | `Promise`\<`Readable`\> 106 | 107 | Потоковый ответ сервера. 108 | 109 | *** 110 | 111 | ### createToken() 112 | 113 | > **createToken**(): `Promise`\<[`ITokenResponse`](/gigachat-node/api/interfaces/token/interfaces/itokenresponse/)\> 114 | 115 | Defined in: [src/index.ts:178](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L178) 116 | 117 | Создает новый токен доступа. 118 | 119 | #### Returns 120 | 121 | `Promise`\<[`ITokenResponse`](/gigachat-node/api/interfaces/token/interfaces/itokenresponse/)\> 122 | 123 | Данные токена. 124 | 125 | *** 126 | 127 | ### deleteFile() 128 | 129 | > **deleteFile**(`fileId`): `Promise`\<[`IFileDeleteResponse`](/gigachat-node/api/interfaces/file/interfaces/ifiledeleteresponse/)\> 130 | 131 | Defined in: [src/index.ts:377](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L377) 132 | 133 | Удаление файла по идентификатору. 134 | 135 | #### Parameters 136 | 137 | ##### fileId 138 | 139 | `string` 140 | 141 | Идентификатор файла. 142 | 143 | #### Returns 144 | 145 | `Promise`\<[`IFileDeleteResponse`](/gigachat-node/api/interfaces/file/interfaces/ifiledeleteresponse/)\> 146 | 147 | Ответ сервера. 148 | 149 | *** 150 | 151 | ### downloadFile() 152 | 153 | > **downloadFile**(`fileId`): `Promise`\<`any`\> 154 | 155 | Defined in: [src/index.ts:405](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L405) 156 | 157 | #### Parameters 158 | 159 | ##### fileId 160 | 161 | `string` 162 | 163 | #### Returns 164 | 165 | `Promise`\<`any`\> 166 | 167 | *** 168 | 169 | ### embedding() 170 | 171 | > **embedding**(`input`): `Promise`\<[`IEmbeddingResponse`](/gigachat-node/api/interfaces/embedding/interfaces/iembeddingresponse/)\> 172 | 173 | Defined in: [src/index.ts:292](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L292) 174 | 175 | Выполняет embedding запроса. 176 | 177 | #### Parameters 178 | 179 | ##### input 180 | 181 | `string`[] 182 | 183 | Входные данные. 184 | 185 | #### Returns 186 | 187 | `Promise`\<[`IEmbeddingResponse`](/gigachat-node/api/interfaces/embedding/interfaces/iembeddingresponse/)\> 188 | 189 | Ответ сервера с embedding. 190 | 191 | *** 192 | 193 | ### getAllFiles() 194 | 195 | > **getAllFiles**(): `Promise`\<[`IFile`](/gigachat-node/api/interfaces/file/interfaces/ifile/)[]\> 196 | 197 | Defined in: [src/index.ts:343](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L343) 198 | 199 | Получение списка доступных файлов. 200 | 201 | #### Returns 202 | 203 | `Promise`\<[`IFile`](/gigachat-node/api/interfaces/file/interfaces/ifile/)[]\> 204 | 205 | Массив объектов с информацией о доступных файлах. 206 | 207 | *** 208 | 209 | ### getBalance() 210 | 211 | > **getBalance**(): `Promise`\<[`IBalanceResponse`](/gigachat-node/api/interfaces/balance/interfaces/ibalanceresponse/)\> 212 | 213 | Defined in: [src/index.ts:393](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L393) 214 | 215 | Получение баланса токенов по всем моделям. 216 | 217 | #### Returns 218 | 219 | `Promise`\<[`IBalanceResponse`](/gigachat-node/api/interfaces/balance/interfaces/ibalanceresponse/)\> 220 | 221 | Ответ сервера с информацией о балансе. 222 | 223 | *** 224 | 225 | ### getFileInfo() 226 | 227 | > **getFileInfo**(`fileId`): `Promise`\<[`IFile`](/gigachat-node/api/interfaces/file/interfaces/ifile/)\> 228 | 229 | Defined in: [src/index.ts:360](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L360) 230 | 231 | Получение информации о файле по идентификатору. 232 | 233 | #### Parameters 234 | 235 | ##### fileId 236 | 237 | `string` 238 | 239 | Идентификатор файла. 240 | 241 | #### Returns 242 | 243 | `Promise`\<[`IFile`](/gigachat-node/api/interfaces/file/interfaces/ifile/)\> 244 | 245 | Объект с информацией о файле. 246 | 247 | *** 248 | 249 | ### summarize() 250 | 251 | > **summarize**(`model`, `input`): `Promise`\<[`ISummarizeResponse`](/gigachat-node/api/interfaces/summarize/interfaces/isummarizeresponse/)[]\> 252 | 253 | Defined in: [src/index.ts:310](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L310) 254 | 255 | Подсчитывает количество токенов в тексте. 256 | 257 | #### Parameters 258 | 259 | ##### model 260 | 261 | `string` 262 | 263 | Модель. 264 | 265 | ##### input 266 | 267 | `string`[] 268 | 269 | Входные данные. 270 | 271 | #### Returns 272 | 273 | `Promise`\<[`ISummarizeResponse`](/gigachat-node/api/interfaces/summarize/interfaces/isummarizeresponse/)[]\> 274 | 275 | Ответ с количеством токенов. 276 | 277 | *** 278 | 279 | ### uploadFile() 280 | 281 | > **uploadFile**(`pathToFile`, `purpose`?): `Promise`\<[`IFile`](/gigachat-node/api/interfaces/file/interfaces/ifile/)\> 282 | 283 | Defined in: [src/index.ts:328](https://github.com/zloishavrin/gigachat-node/blob/73265cae60cba8596986acf3536cf528c60d2cf0/src/index.ts#L328) 284 | 285 | Загружает файл в сервис. 286 | 287 | #### Parameters 288 | 289 | ##### pathToFile 290 | 291 | `string` 292 | 293 | Путь к файлу. 294 | 295 | ##### purpose? 296 | 297 | `string` = `'general'` 298 | 299 | Назначение файла. 300 | 301 | #### Returns 302 | 303 | `Promise`\<[`IFile`](/gigachat-node/api/interfaces/file/interfaces/ifile/)\> 304 | 305 | Ответ сервера с данными файла. 306 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 |
2 |      3 |
4 | 5 | # GigaChat API Library 6 | 7 | Эта библиотека обеспечивает удобный доступ к GigaChat REST API из TypeScript или JavaScript. 8 | 9 | Чтобы узнать, как использовать GigaChat API, ознакомьтесь с [документацией по API](https://developers.sber.ru/docs/ru/gigachat/api/overview). 10 | 11 | * [Установка](#установка) 12 | * [Импорт](#импорт) 13 | * [Начало работы](#начало-работы) 14 | * [Получение всех моделей](#получение-всех-моделей) 15 | * [Завершение чата](#завершение-чата) 16 | * [Завершение чата в потоке](#завершение-чата-в-потоке) 17 | * [Генерация изображений](#генерация-изображений) 18 | * [Векторное представление текста](#векторное-представление-текста) 19 | * [Подсчет кол-ва токенов](#подсчет-кол-ва-токенов) 20 | * [Загрузка файлов](#загрузка-файлов) 21 | * [Получение доступных файлов](#получение-доступных-файлов) 22 | * [Получение информации о файле](#получение-информации-о-файле) 23 | * [Удаление файла](#удаление-файла) 24 | * [Получение баланса токенов](#получение-баланса-токенов) 25 | * [Скачивание файла](#скачивание-файла) 26 | * [Примеры работы](#примеры-работы) 27 | 28 | ## Использование 29 | 30 | ### Установка 31 | 32 | ```bash 33 | npm i gigachat-node 34 | ``` 35 | 36 | ### Импорт 37 | 38 | Первый вариант импорта: 39 | ```javascript 40 | import { GigaChat } from 'gigachat-node'; 41 | ``` 42 | 43 | Второй вариант импорта: 44 | ```javascript 45 | const GigaChat = require('gigachat-node').GigaChat; 46 | ``` 47 | 48 | ### Начало работы 49 | 50 | Создание экземпляра класса и получение токена доступа к API [(подробнее в документации)](https://developers.sber.ru/docs/ru/gigachat/api/authorization). Обратите внимание, что при получении CLIENT_SECRET необходимо копировать значение в Base64, иначе придется переводить самостоятельно ключ в Base64. 51 | 52 | ```js 53 | const client = new GigaChat({ 54 | clientSecretKey: 'CLIENT-SECRET-KEY', 55 | isIgnoreTSL: true, 56 | isPersonal: true, 57 | autoRefreshToken: true 58 | }); 59 | await client.createToken(); 60 | ``` 61 | | Аргумент конструктора | Характеристика | 62 | |-----------------------|----------------| 63 | |clientSecretKey| Нужен для получения токена доступа к API. Получить можно в [личном кабинете](https://developers.sber.ru/studio). Обязательно в base64. | 64 | |isIgnoreTSL| Используется для настройки https-агента. Некоторые системы считают сертификат безопасности Сбербанка ненадежным. Если сертикат безопасности игнорируется, то может снизиться безопасность обмена данными. Если же сертификат безопасности не игнорируется, то необходимо его [установить](https://developers.sber.ru/docs/ru/gigachat/certificates). | 65 | |isPersonal| Нужно для получения токена доступа к API. Если вы используете API, как физическое лицо - ставьте true. Если юридическое лицо - false. | 66 | |autoRefreshToken| Если параметр указан true, то токен будет автоматически обновляться. Токен обновляется, если при запросе получена ошибка о том, что срок действия токена закончился (запрос при этом выполняется повторно). Если параметр указан false, то при попытке использовать недействительный токен вернется ошибка. Срок действия токена - 30 минут. | 67 | |imgOn|Включить возвращение изображений из генерации завершений чата. | 68 | 69 | ### Получение всех моделей 70 | 71 | Возвращает массив объектов с данными доступных моделей. 72 | 73 | ```js 74 | const responce = await client.allModels(); 75 | ``` 76 | 77 | ### Завершение чата 78 | 79 | Возвращает ответ модели с учетом переданных сообщений. Подробнее про параметры запроса можно прочитать в [оффициальной документации](https://developers.sber.ru/docs/ru/gigachat/api/reference#post-chat-completions). 80 | 81 | ```js 82 | const responce = await client.completion({ 83 | "model":"GigaChat:latest", 84 | "messages": [ 85 | { 86 | role:"user", 87 | content:"Привет! Как дела?" 88 | } 89 | ] 90 | }); 91 | 92 | console.log(responce.choices[0].message); 93 | ``` 94 | 95 | ### Завершение чата в потоке 96 | 97 | Возвращает ответ модели в потоке в base64. Подробнее можно прочитать в [оффициальной документации](https://developers.sber.ru/docs/ru/gigachat/api/response-token-streaming). 98 | 99 | ```js 100 | const stream = await client.completionStream({ 101 | "model":"GigaChat:latest", 102 | "messages": [ 103 | { 104 | role:"user", 105 | content:"Привет! Напиши текст на 2000 слов про историю часов." 106 | } 107 | ] 108 | }); 109 | 110 | let str = ''; 111 | 112 | stream.on('data', async (data) => { 113 | const decodedData = await data.toString('utf-8'); 114 | const jsonData = await JSON.parse(decodedData.substring(6)); 115 | str += jsonData.choices[0].delta.content; 116 | }) 117 | 118 | stream.on('end', () => { 119 | console.log('Поток завершился.') 120 | }) 121 | ``` 122 | 123 | ### Векторное представление текста 124 | 125 | Возвращает векторные представления соответствующих текстовых запросов. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/post-embeddings). 126 | 127 | ```javascript 128 | const embed = await client.embedding(["Как дела?", "Векторное представлеие? 0_0"]); 129 | console.log(embed.data); 130 | ``` 131 | 132 | ### Подсчет кол-ва токенов 133 | 134 | Возвращает объект с информацией о количестве токенов, посчитанных заданной моделью. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/post-tokens-count). 135 | 136 | ```javascript 137 | const sum = await client.summarize("GigaChat", ["Подсчитай кол-во токенов в этой строке"]); 138 | console.log(sum[0].tokens); 139 | ``` 140 | 141 | ### Загрузка файлов 142 | 143 | Загружает в хранилище текстовые документы или изображения. Возвращает объект с данными загруженного файла. Загруженные файлы доступны только вам. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/post-file). 144 | 145 | ```javascript 146 | const file = await client.uploadFile("path/to/file"); 147 | console.log(file); 148 | ``` 149 | 150 | ### Получение доступных файлов 151 | 152 | Получение списка всех доступных файлов. Возвращает массив объектов с данными доступных файлов. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/get-files). 153 | 154 | ```javascript 155 | const files = await client.getAllFiles(); 156 | console.log(files); 157 | ``` 158 | 159 | ### Получение информации о файле 160 | 161 | Получение информации о файле по уникальному идентификатору. Возвращает объект с описанием указанного файла. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/get-file). 162 | 163 | ```javascript 164 | const file = await client.getFileInfo('fileId'); 165 | console.log(file); 166 | ``` 167 | 168 | ### Получение баланса токенов 169 | 170 | Возвращает доступный остаток токенов для каждой из моделей. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/get-balance). 171 | 172 | ```javascript 173 | const balance = await client.getBalance(); 174 | console.log(balance); 175 | ``` 176 | 177 | ### Удаление файла 178 | 179 | Удаление файла по уникальному идентификатору. Переводит статус файла в значение *deleted*. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/file-delete). 180 | 181 | ```javascript 182 | const deletedFile = await client.deleteFile('fileId'); 183 | console.log(deletedFile); 184 | ``` 185 | 186 | ### Скачивание файла 187 | 188 | Получение файла в бинарном формате по уникальному идентификатору. 189 | 190 | ```javascript 191 | const binary = await client.downloadFile("fileId"); 192 | console.log(binary); 193 | ``` 194 | 195 | ## RoadMap 196 | 197 | | Задача | Статус | 198 | |--------|--------| 199 | |Создание токена доступа|☑️| 200 | |Завершение чата|☑️| 201 | |Автоматическая смена токена, если срок действия подходит к концу|☑️| 202 | |Завершение чата в потоке|☑️| 203 | |Генерация картинок при завершении чата|☑️| 204 | |Написание интерфейсов|☑️| 205 | |Векторное представление текста|☑️| 206 | |Метод для расчета кол-ва токенов по строчке запроса|☑️| 207 | |Автоматическое добавление свойства **stream** при передаче ответа в потоке|☑️| 208 | |Обновление интерфейсов: добавление **search_result** в message, добавление **update_interval** в completion|☑️| 209 | |Возможность отключения цензуры|☑️| 210 | |Загрузка файлов|☑️| 211 | |Конфиг-интерфейс для конструктора класса|☑️| 212 | |Настройка ESLinter|☑️| 213 | |Настройка Prettier|☑️| 214 | |Автодокументирование|☑️| 215 | |Pre-Commit|☑️| 216 | |GH-Action для NPM-публикации|☑️| 217 | |Примеры использования|☑️| 218 | |Избавиться от UUID-зависимости|☑️| 219 | |Избавиться от FormData-зависимости|☑️| 220 | |Добавить обработку ошибок|☑️| 221 | |Настроить дженерики для обработки ошибок|☑️| 222 | |Настроить экспорт ошибки|☑️| 223 | |Настройка тестов в проекте|☑️| 224 | |Переписать библиотеку на нативный HTTPS вместо Axios|☑️| 225 | |Настроить минификацию пакета в CI|☑️| 226 | |Метод для получения списка доступных файлов|☑️| 227 | |Метод для получения информации о файле|☑️| 228 | |Метод для удаления файла|☑️| 229 | |Метод для получения баланса|☑️| 230 | |Метод для скачивания файла|☑️| 231 | |Добавить поддержку загрузки файла с помощью бинарных данных| | 232 | |Рефакторинг обработки ошибок| | 233 | |Тесты для публичных методов| | 234 | |Извлечение видео из завершения чата| | 235 | |Поддержка работы из браузерной среды| | -------------------------------------------------------------------------------- /docs/src/content/docs/guides/readme.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: GigaChatJS 3 | description: Начните работу c GigaChatAPI. 4 | --- 5 | 6 |
7 |      8 |
9 | 10 | # GigaChat API Library 11 | 12 | Эта библиотека обеспечивает удобный доступ к GigaChat REST API из TypeScript или JavaScript. 13 | 14 | Чтобы узнать, как использовать GigaChat API, ознакомьтесь с [документацией по API](https://developers.sber.ru/docs/ru/gigachat/api/overview). 15 | 16 | * [Установка](#установка) 17 | * [Импорт](#импорт) 18 | * [Начало работы](#начало-работы) 19 | * [Получение всех моделей](#получение-всех-моделей) 20 | * [Завершение чата](#завершение-чата) 21 | * [Завершение чата в потоке](#завершение-чата-в-потоке) 22 | * [Генерация изображений](#генерация-изображений) 23 | * [Векторное представление текста](#векторное-представление-текста) 24 | * [Подсчет кол-ва токенов](#подсчет-кол-ва-токенов) 25 | * [Загрузка файлов](#загрузка-файлов) 26 | * [Получение доступных файлов](#получение-доступных-файлов) 27 | * [Получение информации о файле](#получение-информации-о-файле) 28 | * [Удаление файла](#удаление-файла) 29 | * [Получение баланса токенов](#получение-баланса-токенов) 30 | * [Скачивание файла](#скачивание-файла) 31 | * [Примеры работы](#примеры-работы) 32 | 33 | ## Использование 34 | 35 | ### Установка 36 | 37 | ```bash 38 | npm i gigachat-node 39 | ``` 40 | 41 | ### Импорт 42 | 43 | Первый вариант импорта: 44 | ```javascript 45 | import { GigaChat } from 'gigachat-node'; 46 | ``` 47 | 48 | Второй вариант импорта: 49 | ```javascript 50 | const GigaChat = require('gigachat-node').GigaChat; 51 | ``` 52 | 53 | ### Начало работы 54 | 55 | Создание экземпляра класса и получение токена доступа к API [(подробнее в документации)](https://developers.sber.ru/docs/ru/gigachat/api/authorization). Обратите внимание, что при получении CLIENT_SECRET необходимо копировать значение в Base64, иначе придется переводить самостоятельно ключ в Base64. 56 | 57 | ```js 58 | const client = new GigaChat({ 59 | clientSecretKey: 'CLIENT-SECRET-KEY', 60 | isIgnoreTSL: true, 61 | isPersonal: true, 62 | autoRefreshToken: true 63 | }); 64 | await client.createToken(); 65 | ``` 66 | | Аргумент конструктора | Характеристика | 67 | |-----------------------|----------------| 68 | |clientSecretKey| Нужен для получения токена доступа к API. Получить можно в [личном кабинете](https://developers.sber.ru/studio). Обязательно в base64. | 69 | |isIgnoreTSL| Используется для настройки https-агента. Некоторые системы считают сертификат безопасности Сбербанка ненадежным. Если сертикат безопасности игнорируется, то может снизиться безопасность обмена данными. Если же сертификат безопасности не игнорируется, то необходимо его [установить](https://developers.sber.ru/docs/ru/gigachat/certificates). | 70 | |isPersonal| Нужно для получения токена доступа к API. Если вы используете API, как физическое лицо - ставьте true. Если юридическое лицо - false. | 71 | |autoRefreshToken| Если параметр указан true, то токен будет автоматически обновляться. Токен обновляется, если при запросе получена ошибка о том, что срок действия токена закончился (запрос при этом выполняется повторно). Если параметр указан false, то при попытке использовать недействительный токен вернется ошибка. Срок действия токена - 30 минут. | 72 | |imgOn|Включить возвращение изображений из генерации завершений чата. | 73 | 74 | ### Получение всех моделей 75 | 76 | Возвращает массив объектов с данными доступных моделей. 77 | 78 | ```js 79 | const responce = await client.allModels(); 80 | ``` 81 | 82 | ### Завершение чата 83 | 84 | Возвращает ответ модели с учетом переданных сообщений. Подробнее про параметры запроса можно прочитать в [оффициальной документации](https://developers.sber.ru/docs/ru/gigachat/api/reference#post-chat-completions). 85 | 86 | ```js 87 | const responce = await client.completion({ 88 | "model":"GigaChat:latest", 89 | "messages": [ 90 | { 91 | role:"user", 92 | content:"Привет! Как дела?" 93 | } 94 | ] 95 | }); 96 | 97 | console.log(responce.choices[0].message); 98 | ``` 99 | 100 | ### Завершение чата в потоке 101 | 102 | Возвращает ответ модели в потоке в base64. Подробнее можно прочитать в [оффициальной документации](https://developers.sber.ru/docs/ru/gigachat/api/response-token-streaming). 103 | 104 | ```js 105 | const stream = await client.completionStream({ 106 | "model":"GigaChat:latest", 107 | "messages": [ 108 | { 109 | role:"user", 110 | content:"Привет! Напиши текст на 2000 слов про историю часов." 111 | } 112 | ] 113 | }); 114 | 115 | let str = ''; 116 | 117 | stream.on('data', async (data) => { 118 | const decodedData = await data.toString('utf-8'); 119 | const jsonData = await JSON.parse(decodedData.substring(6)); 120 | str += jsonData.choices[0].delta.content; 121 | }) 122 | 123 | stream.on('end', () => { 124 | console.log('Поток завершился.') 125 | }) 126 | ``` 127 | 128 | ### Векторное представление текста 129 | 130 | Возвращает векторные представления соответствующих текстовых запросов. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/post-embeddings). 131 | 132 | ```javascript 133 | const embed = await client.embedding(["Как дела?", "Векторное представлеие? 0_0"]); 134 | console.log(embed.data); 135 | ``` 136 | 137 | ### Подсчет кол-ва токенов 138 | 139 | Возвращает объект с информацией о количестве токенов, посчитанных заданной моделью. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/post-tokens-count). 140 | 141 | ```javascript 142 | const sum = await client.summarize("GigaChat", ["Подсчитай кол-во токенов в этой строке"]); 143 | console.log(sum[0].tokens); 144 | ``` 145 | 146 | ### Загрузка файлов 147 | 148 | Загружает в хранилище текстовые документы или изображения. Возвращает объект с данными загруженного файла. Загруженные файлы доступны только вам. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/post-file). 149 | 150 | ```javascript 151 | const file = await client.uploadFile("path/to/file"); 152 | console.log(file); 153 | ``` 154 | 155 | ### Получение доступных файлов 156 | 157 | Получение списка всех доступных файлов. Возвращает массив объектов с данными доступных файлов. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/get-files). 158 | 159 | ```javascript 160 | const files = await client.getAllFiles(); 161 | console.log(files); 162 | ``` 163 | 164 | ### Получение информации о файле 165 | 166 | Получение информации о файле по уникальному идентификатору. Возвращает объект с описанием указанного файла. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/get-file). 167 | 168 | ```javascript 169 | const file = await client.getFileInfo('fileId'); 170 | console.log(file); 171 | ``` 172 | 173 | ### Получение баланса токенов 174 | 175 | Возвращает доступный остаток токенов для каждой из моделей. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/get-balance). 176 | 177 | ```javascript 178 | const balance = await client.getBalance(); 179 | console.log(balance); 180 | ``` 181 | 182 | ### Удаление файла 183 | 184 | Удаление файла по уникальному идентификатору. Переводит статус файла в значение *deleted*. [Подробнее в документации API](https://developers.sber.ru/docs/ru/gigachat/api/reference/rest/file-delete). 185 | 186 | ```javascript 187 | const deletedFile = await client.deleteFile('fileId'); 188 | console.log(deletedFile); 189 | ``` 190 | 191 | ### Скачивание файла 192 | 193 | Получение файла в бинарном формате по уникальному идентификатору. 194 | 195 | ```javascript 196 | const binary = await client.downloadFile("fileId"); 197 | console.log(binary); 198 | ``` 199 | 200 | ## RoadMap 201 | 202 | | Задача | Статус | 203 | |--------|--------| 204 | |Создание токена доступа|☑️| 205 | |Завершение чата|☑️| 206 | |Автоматическая смена токена, если срок действия подходит к концу|☑️| 207 | |Завершение чата в потоке|☑️| 208 | |Генерация картинок при завершении чата|☑️| 209 | |Написание интерфейсов|☑️| 210 | |Векторное представление текста|☑️| 211 | |Метод для расчета кол-ва токенов по строчке запроса|☑️| 212 | |Автоматическое добавление свойства **stream** при передаче ответа в потоке|☑️| 213 | |Обновление интерфейсов: добавление **search_result** в message, добавление **update_interval** в completion|☑️| 214 | |Возможность отключения цензуры|☑️| 215 | |Загрузка файлов|☑️| 216 | |Конфиг-интерфейс для конструктора класса|☑️| 217 | |Настройка ESLinter|☑️| 218 | |Настройка Prettier|☑️| 219 | |Автодокументирование|☑️| 220 | |Pre-Commit|☑️| 221 | |GH-Action для NPM-публикации|☑️| 222 | |Примеры использования|☑️| 223 | |Избавиться от UUID-зависимости|☑️| 224 | |Избавиться от FormData-зависимости|☑️| 225 | |Добавить обработку ошибок|☑️| 226 | |Настроить дженерики для обработки ошибок|☑️| 227 | |Настроить экспорт ошибки|☑️| 228 | |Настройка тестов в проекте|☑️| 229 | |Переписать библиотеку на нативный HTTPS вместо Axios|☑️| 230 | |Настроить минификацию пакета в CI|☑️| 231 | |Метод для получения списка доступных файлов|☑️| 232 | |Метод для получения информации о файле|☑️| 233 | |Метод для удаления файла|☑️| 234 | |Метод для получения баланса|☑️| 235 | |Метод для скачивания файла|☑️| 236 | |Добавить поддержку загрузки файла с помощью бинарных данных| | 237 | |Рефакторинг обработки ошибок| | 238 | |Тесты для публичных методов| | 239 | |Извлечение видео из завершения чата| | 240 | |Поддержка работы из браузерной среды| | 241 | -------------------------------------------------------------------------------- /docs/dist/pagefind/pagefind-ui.css: -------------------------------------------------------------------------------- 1 | .pagefind-ui__result.svelte-j9e30.svelte-j9e30{list-style-type:none;display:flex;align-items:flex-start;gap:min(calc(40px * var(--pagefind-ui-scale)),3%);padding:calc(30px * var(--pagefind-ui-scale)) 0 calc(40px * var(--pagefind-ui-scale));border-top:solid var(--pagefind-ui-border-width) var(--pagefind-ui-border)}.pagefind-ui__result.svelte-j9e30.svelte-j9e30:last-of-type{border-bottom:solid var(--pagefind-ui-border-width) var(--pagefind-ui-border)}.pagefind-ui__result-thumb.svelte-j9e30.svelte-j9e30{width:min(30%,calc((30% - (100px * var(--pagefind-ui-scale))) * 100000));max-width:calc(120px * var(--pagefind-ui-scale));margin-top:calc(10px * var(--pagefind-ui-scale));aspect-ratio:var(--pagefind-ui-image-box-ratio);position:relative}.pagefind-ui__result-image.svelte-j9e30.svelte-j9e30{display:block;position:absolute;left:50%;transform:translate(-50%);font-size:0;width:auto;height:auto;max-width:100%;max-height:100%;border-radius:var(--pagefind-ui-image-border-radius)}.pagefind-ui__result-inner.svelte-j9e30.svelte-j9e30{flex:1;display:flex;flex-direction:column;align-items:flex-start;margin-top:calc(10px * var(--pagefind-ui-scale))}.pagefind-ui__result-title.svelte-j9e30.svelte-j9e30{display:inline-block;font-weight:700;font-size:calc(21px * var(--pagefind-ui-scale));margin-top:0;margin-bottom:0}.pagefind-ui__result-title.svelte-j9e30 .pagefind-ui__result-link.svelte-j9e30{color:var(--pagefind-ui-text);text-decoration:none}.pagefind-ui__result-title.svelte-j9e30 .pagefind-ui__result-link.svelte-j9e30:hover{text-decoration:underline}.pagefind-ui__result-excerpt.svelte-j9e30.svelte-j9e30{display:inline-block;font-weight:400;font-size:calc(16px * var(--pagefind-ui-scale));margin-top:calc(4px * var(--pagefind-ui-scale));margin-bottom:0;min-width:calc(250px * var(--pagefind-ui-scale))}.pagefind-ui__loading.svelte-j9e30.svelte-j9e30{color:var(--pagefind-ui-text);background-color:var(--pagefind-ui-text);border-radius:var(--pagefind-ui-border-radius);opacity:.1;pointer-events:none}.pagefind-ui__result-tags.svelte-j9e30.svelte-j9e30{list-style-type:none;padding:0;display:flex;gap:calc(20px * var(--pagefind-ui-scale));flex-wrap:wrap;margin-top:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__result-tag.svelte-j9e30.svelte-j9e30{padding:calc(4px * var(--pagefind-ui-scale)) calc(8px * var(--pagefind-ui-scale));font-size:calc(14px * var(--pagefind-ui-scale));border-radius:var(--pagefind-ui-border-radius);background-color:var(--pagefind-ui-tag)}.pagefind-ui__result.svelte-4xnkmf.svelte-4xnkmf{list-style-type:none;display:flex;align-items:flex-start;gap:min(calc(40px * var(--pagefind-ui-scale)),3%);padding:calc(30px * var(--pagefind-ui-scale)) 0 calc(40px * var(--pagefind-ui-scale));border-top:solid var(--pagefind-ui-border-width) var(--pagefind-ui-border)}.pagefind-ui__result.svelte-4xnkmf.svelte-4xnkmf:last-of-type{border-bottom:solid var(--pagefind-ui-border-width) var(--pagefind-ui-border)}.pagefind-ui__result-nested.svelte-4xnkmf.svelte-4xnkmf{display:flex;flex-direction:column;padding-left:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__result-nested.svelte-4xnkmf.svelte-4xnkmf:first-of-type{padding-top:calc(10px * var(--pagefind-ui-scale))}.pagefind-ui__result-nested.svelte-4xnkmf .pagefind-ui__result-link.svelte-4xnkmf{font-size:.9em;position:relative}.pagefind-ui__result-nested.svelte-4xnkmf .pagefind-ui__result-link.svelte-4xnkmf:before{content:"\2937 ";position:absolute;top:0;right:calc(100% + .1em)}.pagefind-ui__result-thumb.svelte-4xnkmf.svelte-4xnkmf{width:min(30%,calc((30% - (100px * var(--pagefind-ui-scale))) * 100000));max-width:calc(120px * var(--pagefind-ui-scale));margin-top:calc(10px * var(--pagefind-ui-scale));aspect-ratio:var(--pagefind-ui-image-box-ratio);position:relative}.pagefind-ui__result-image.svelte-4xnkmf.svelte-4xnkmf{display:block;position:absolute;left:50%;transform:translate(-50%);font-size:0;width:auto;height:auto;max-width:100%;max-height:100%;border-radius:var(--pagefind-ui-image-border-radius)}.pagefind-ui__result-inner.svelte-4xnkmf.svelte-4xnkmf{flex:1;display:flex;flex-direction:column;align-items:flex-start;margin-top:calc(10px * var(--pagefind-ui-scale))}.pagefind-ui__result-title.svelte-4xnkmf.svelte-4xnkmf{display:inline-block;font-weight:700;font-size:calc(21px * var(--pagefind-ui-scale));margin-top:0;margin-bottom:0}.pagefind-ui__result-title.svelte-4xnkmf .pagefind-ui__result-link.svelte-4xnkmf{color:var(--pagefind-ui-text);text-decoration:none}.pagefind-ui__result-title.svelte-4xnkmf .pagefind-ui__result-link.svelte-4xnkmf:hover{text-decoration:underline}.pagefind-ui__result-excerpt.svelte-4xnkmf.svelte-4xnkmf{display:inline-block;font-weight:400;font-size:calc(16px * var(--pagefind-ui-scale));margin-top:calc(4px * var(--pagefind-ui-scale));margin-bottom:0;min-width:calc(250px * var(--pagefind-ui-scale))}.pagefind-ui__loading.svelte-4xnkmf.svelte-4xnkmf{color:var(--pagefind-ui-text);background-color:var(--pagefind-ui-text);border-radius:var(--pagefind-ui-border-radius);opacity:.1;pointer-events:none}.pagefind-ui__result-tags.svelte-4xnkmf.svelte-4xnkmf{list-style-type:none;padding:0;display:flex;gap:calc(20px * var(--pagefind-ui-scale));flex-wrap:wrap;margin-top:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__result-tag.svelte-4xnkmf.svelte-4xnkmf{padding:calc(4px * var(--pagefind-ui-scale)) calc(8px * var(--pagefind-ui-scale));font-size:calc(14px * var(--pagefind-ui-scale));border-radius:var(--pagefind-ui-border-radius);background-color:var(--pagefind-ui-tag)}legend.svelte-1v2r7ls.svelte-1v2r7ls{position:absolute;clip:rect(0 0 0 0)}.pagefind-ui__filter-panel.svelte-1v2r7ls.svelte-1v2r7ls{min-width:min(calc(260px * var(--pagefind-ui-scale)),100%);flex:1;display:flex;flex-direction:column;margin-top:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__filter-group.svelte-1v2r7ls.svelte-1v2r7ls{border:0;padding:0}.pagefind-ui__filter-block.svelte-1v2r7ls.svelte-1v2r7ls{padding:0;display:block;border-bottom:solid calc(2px * var(--pagefind-ui-scale)) var(--pagefind-ui-border);padding:calc(20px * var(--pagefind-ui-scale)) 0}.pagefind-ui__filter-name.svelte-1v2r7ls.svelte-1v2r7ls{font-size:calc(16px * var(--pagefind-ui-scale));position:relative;display:flex;align-items:center;list-style:none;font-weight:700;cursor:pointer;height:calc(24px * var(--pagefind-ui-scale))}.pagefind-ui__filter-name.svelte-1v2r7ls.svelte-1v2r7ls::-webkit-details-marker{display:none}.pagefind-ui__filter-name.svelte-1v2r7ls.svelte-1v2r7ls:after{position:absolute;content:"";right:calc(6px * var(--pagefind-ui-scale));top:50%;width:calc(8px * var(--pagefind-ui-scale));height:calc(8px * var(--pagefind-ui-scale));border:solid calc(2px * var(--pagefind-ui-scale)) currentColor;border-right:0;border-top:0;transform:translateY(-70%) rotate(-45deg)}.pagefind-ui__filter-block[open].svelte-1v2r7ls .pagefind-ui__filter-name.svelte-1v2r7ls:after{transform:translateY(-70%) rotate(-225deg)}.pagefind-ui__filter-group.svelte-1v2r7ls.svelte-1v2r7ls{display:flex;flex-direction:column;gap:calc(20px * var(--pagefind-ui-scale));padding-top:calc(30px * var(--pagefind-ui-scale))}.pagefind-ui__filter-value.svelte-1v2r7ls.svelte-1v2r7ls{position:relative;display:flex;align-items:center;gap:calc(8px * var(--pagefind-ui-scale))}.pagefind-ui__filter-value.svelte-1v2r7ls.svelte-1v2r7ls:before{position:absolute;content:"";top:50%;left:calc(8px * var(--pagefind-ui-scale));width:0px;height:0px;border:solid 1px #fff;opacity:0;transform:translate(calc(4.5px * var(--pagefind-ui-scale) * -1),calc(.8px * var(--pagefind-ui-scale))) skew(-5deg) rotate(-45deg);transform-origin:top left;border-top:0;border-right:0;pointer-events:none}.pagefind-ui__filter-value.pagefind-ui__filter-value--checked.svelte-1v2r7ls.svelte-1v2r7ls:before{opacity:1;width:calc(9px * var(--pagefind-ui-scale));height:calc(4px * var(--pagefind-ui-scale));transition:width .1s ease-out .1s,height .1s ease-in}.pagefind-ui__filter-checkbox.svelte-1v2r7ls.svelte-1v2r7ls{margin:0;width:calc(16px * var(--pagefind-ui-scale));height:calc(16px * var(--pagefind-ui-scale));border:solid 1px var(--pagefind-ui-border);appearance:none;-webkit-appearance:none;border-radius:calc(var(--pagefind-ui-border-radius) / 2);background-color:var(--pagefind-ui-background);cursor:pointer}.pagefind-ui__filter-checkbox.svelte-1v2r7ls.svelte-1v2r7ls:checked{background-color:var(--pagefind-ui-primary);border:solid 1px var(--pagefind-ui-primary)}.pagefind-ui__filter-label.svelte-1v2r7ls.svelte-1v2r7ls{cursor:pointer;font-size:calc(16px * var(--pagefind-ui-scale));font-weight:400}.pagefind-ui--reset *:where(:not(html,iframe,canvas,img,svg,video):not(svg *,symbol *)){all:unset;display:revert;outline:revert}.pagefind-ui--reset *,.pagefind-ui--reset *:before,.pagefind-ui--reset *:after{box-sizing:border-box}.pagefind-ui--reset a,.pagefind-ui--reset button{cursor:revert}.pagefind-ui--reset ol,.pagefind-ui--reset ul,.pagefind-ui--reset menu{list-style:none}.pagefind-ui--reset img{max-width:100%}.pagefind-ui--reset table{border-collapse:collapse}.pagefind-ui--reset input,.pagefind-ui--reset textarea{-webkit-user-select:auto}.pagefind-ui--reset textarea{white-space:revert}.pagefind-ui--reset meter{-webkit-appearance:revert;appearance:revert}.pagefind-ui--reset ::placeholder{color:unset}.pagefind-ui--reset :where([hidden]){display:none}.pagefind-ui--reset :where([contenteditable]:not([contenteditable="false"])){-moz-user-modify:read-write;-webkit-user-modify:read-write;overflow-wrap:break-word;-webkit-line-break:after-white-space;-webkit-user-select:auto}.pagefind-ui--reset :where([draggable="true"]){-webkit-user-drag:element}.pagefind-ui--reset mark{all:revert}:root{--pagefind-ui-scale:.8;--pagefind-ui-primary:#393939;--pagefind-ui-text:#393939;--pagefind-ui-background:#ffffff;--pagefind-ui-border:#eeeeee;--pagefind-ui-tag:#eeeeee;--pagefind-ui-border-width:2px;--pagefind-ui-border-radius:8px;--pagefind-ui-image-border-radius:8px;--pagefind-ui-image-box-ratio:3 / 2;--pagefind-ui-font:system, -apple-system, "BlinkMacSystemFont", ".SFNSText-Regular", "San Francisco", "Roboto", "Segoe UI", "Helvetica Neue", "Lucida Grande", "Ubuntu", "arial", sans-serif}.pagefind-ui.svelte-e9gkc3{width:100%;color:var(--pagefind-ui-text);font-family:var(--pagefind-ui-font)}.pagefind-ui__hidden.svelte-e9gkc3{display:none!important}.pagefind-ui__suppressed.svelte-e9gkc3{opacity:0;pointer-events:none}.pagefind-ui__form.svelte-e9gkc3{position:relative}.pagefind-ui__form.svelte-e9gkc3:before{background-color:var(--pagefind-ui-text);width:calc(18px * var(--pagefind-ui-scale));height:calc(18px * var(--pagefind-ui-scale));top:calc(23px * var(--pagefind-ui-scale));left:calc(20px * var(--pagefind-ui-scale));content:"";position:absolute;display:block;opacity:.7;-webkit-mask-image:url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A");mask-image:url("data:image/svg+xml,%3Csvg width='18' height='18' viewBox='0 0 18 18' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12.7549 11.255H11.9649L11.6849 10.985C12.6649 9.845 13.2549 8.365 13.2549 6.755C13.2549 3.165 10.3449 0.255005 6.75488 0.255005C3.16488 0.255005 0.254883 3.165 0.254883 6.755C0.254883 10.345 3.16488 13.255 6.75488 13.255C8.36488 13.255 9.84488 12.665 10.9849 11.685L11.2549 11.965V12.755L16.2549 17.745L17.7449 16.255L12.7549 11.255ZM6.75488 11.255C4.26488 11.255 2.25488 9.245 2.25488 6.755C2.25488 4.26501 4.26488 2.255 6.75488 2.255C9.24488 2.255 11.2549 4.26501 11.2549 6.755C11.2549 9.245 9.24488 11.255 6.75488 11.255Z' fill='%23000000'/%3E%3C/svg%3E%0A");-webkit-mask-size:100%;mask-size:100%;z-index:9;pointer-events:none}.pagefind-ui__search-input.svelte-e9gkc3{height:calc(64px * var(--pagefind-ui-scale));padding:0 calc(70px * var(--pagefind-ui-scale)) 0 calc(54px * var(--pagefind-ui-scale));background-color:var(--pagefind-ui-background);border:var(--pagefind-ui-border-width) solid var(--pagefind-ui-border);border-radius:var(--pagefind-ui-border-radius);font-size:calc(21px * var(--pagefind-ui-scale));position:relative;appearance:none;-webkit-appearance:none;display:flex;width:100%;box-sizing:border-box;font-weight:700}.pagefind-ui__search-input.svelte-e9gkc3::placeholder{opacity:.2}.pagefind-ui__search-clear.svelte-e9gkc3{position:absolute;top:calc(3px * var(--pagefind-ui-scale));right:calc(3px * var(--pagefind-ui-scale));height:calc(58px * var(--pagefind-ui-scale));padding:0 calc(15px * var(--pagefind-ui-scale)) 0 calc(2px * var(--pagefind-ui-scale));color:var(--pagefind-ui-text);font-size:calc(14px * var(--pagefind-ui-scale));cursor:pointer;background-color:var(--pagefind-ui-background);border-radius:var(--pagefind-ui-border-radius)}.pagefind-ui__drawer.svelte-e9gkc3{gap:calc(60px * var(--pagefind-ui-scale));display:flex;flex-direction:row;flex-wrap:wrap}.pagefind-ui__results-area.svelte-e9gkc3{min-width:min(calc(400px * var(--pagefind-ui-scale)),100%);flex:1000;margin-top:calc(20px * var(--pagefind-ui-scale))}.pagefind-ui__results.svelte-e9gkc3{padding:0}.pagefind-ui__message.svelte-e9gkc3{box-sizing:content-box;font-size:calc(16px * var(--pagefind-ui-scale));height:calc(24px * var(--pagefind-ui-scale));padding:calc(20px * var(--pagefind-ui-scale)) 0;display:flex;align-items:center;font-weight:700;margin-top:0}.pagefind-ui__button.svelte-e9gkc3{margin-top:calc(40px * var(--pagefind-ui-scale));border:var(--pagefind-ui-border-width) solid var(--pagefind-ui-border);border-radius:var(--pagefind-ui-border-radius);height:calc(48px * var(--pagefind-ui-scale));padding:0 calc(12px * var(--pagefind-ui-scale));font-size:calc(16px * var(--pagefind-ui-scale));color:var(--pagefind-ui-primary);background:var(--pagefind-ui-background);width:100%;text-align:center;font-weight:700;cursor:pointer}.pagefind-ui__button.svelte-e9gkc3:hover{border-color:var(--pagefind-ui-primary);color:var(--pagefind-ui-primary);background:var(--pagefind-ui-background)} 2 | -------------------------------------------------------------------------------- /docs/dist/pagefind/pagefind-modular-ui.js: -------------------------------------------------------------------------------- 1 | (()=>{var b=Object.defineProperty;var w=(i,e)=>{for(var t in e)b(i,t,{get:e[t],enumerable:!0})};var f={};w(f,{FilterPills:()=>h,Input:()=>l,Instance:()=>p,ResultList:()=>a,Summary:()=>o});var r=class i{constructor(e){this.element=document.createElement(e)}id(e){return this.element.id=e,this}class(e){return this.element.classList.add(e),this}attrs(e){for(let[t,s]of Object.entries(e))this.element.setAttribute(t,s);return this}text(e){return this.element.innerText=e,this}html(e){return this.element.innerHTML=e,this}handle(e,t){return this.element.addEventListener(e,t),this}addTo(e){return e instanceof i?e.element.appendChild(this.element):e.appendChild(this.element),this.element}};var T=async(i=100)=>new Promise(e=>setTimeout(e,i)),l=class{constructor(e={}){if(this.inputEl=null,this.clearEl=null,this.instance=null,this.searchID=0,this.debounceTimeoutMs=e.debounceTimeoutMs??300,e.inputElement){if(e.containerElement){console.warn("[Pagefind Input component]: inputElement and containerElement both supplied. Ignoring the container option.");return}this.initExisting(e.inputElement)}else if(e.containerElement)this.initContainer(e.containerElement);else{console.error("[Pagefind Input component]: No selector supplied for containerElement or inputElement");return}this.inputEl.addEventListener("input",async t=>{if(this.instance&&typeof t?.target?.value=="string"){this.updateState(t.target.value);let s=++this.searchID;if(await T(this.debounceTimeoutMs),s!==this.searchID)return null;this.instance?.triggerSearch(t.target.value)}}),this.inputEl.addEventListener("keydown",t=>{t.key==="Escape"&&(++this.searchID,this.inputEl.value="",this.instance?.triggerSearch(""),this.updateState("")),t.key==="Enter"&&t.preventDefault()}),this.inputEl.addEventListener("focus",()=>{this.instance?.triggerLoad()})}initContainer(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind Input component]: No container found for ${e} selector`);return}if(t.tagName==="INPUT")console.warn(`[Pagefind Input component]: Encountered input element for ${e} when a container was expected`),console.warn("[Pagefind Input component]: Treating containerElement option as inputElement and proceeding"),this.initExisting(e);else{t.innerHTML="";let s=0;for(;document.querySelector(`#pfmod-input-${s}`);)s+=1;let n=new r("form").class("pagefind-modular-input-wrapper").attrs({role:"search","aria-label":"Search this site",action:"javascript:void(0);"});new r("label").attrs({for:`pfmod-input-${s}`,"data-pfmod-sr-hidden":"true"}).text("Search this site").addTo(n),this.inputEl=new r("input").id(`pfmod-input-${s}`).class("pagefind-modular-input").attrs({autocapitalize:"none",enterkeyhint:"search"}).addTo(n),this.clearEl=new r("button").class("pagefind-modular-input-clear").attrs({"data-pfmod-suppressed":"true"}).text("Clear").handle("click",()=>{this.inputEl.value="",this.instance.triggerSearch(""),this.updateState("")}).addTo(n),n.addTo(t)}}initExisting(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind Input component]: No input element found for ${e} selector`);return}if(t.tagName!=="INPUT"){console.error(`[Pagefind Input component]: Expected ${e} to be an element`);return}this.inputEl=t}updateState(e){this.clearEl&&(e&&e?.length?this.clearEl.removeAttribute("data-pfmod-suppressed"):this.clearEl.setAttribute("data-pfmod-suppressed","true"))}register(e){this.instance=e,this.instance.on("search",(t,s)=>{this.inputEl&&document.activeElement!==this.inputEl&&(this.inputEl.value=t,this.updateState(t))})}focus(){this.inputEl&&this.inputEl.focus()}};var g=i=>{if(i instanceof Element)return[i];if(Array.isArray(i)&&i.every(e=>e instanceof Element))return i;if(typeof i=="string"||i instanceof String){let e=document.createElement("div");return e.innerHTML=i,[...e.childNodes]}else return console.error(`[Pagefind ResultList component]: Expected template function to return an HTML element or string, got ${typeof i}`),[]},v=()=>{let i=(e=30)=>". ".repeat(Math.floor(10+Math.random()*e));return`
  • 2 |
    3 |
    4 |

    ${i(30)}

    5 |

    ${i(40)}

    6 |
    7 |
  • `},y=i=>{let e=new r("li").class("pagefind-modular-list-result"),t=new r("div").class("pagefind-modular-list-thumb").addTo(e);i?.meta?.image&&new r("img").class("pagefind-modular-list-image").attrs({src:i.meta.image,alt:i.meta.image_alt||i.meta.title}).addTo(t);let s=new r("div").class("pagefind-modular-list-inner").addTo(e),n=new r("p").class("pagefind-modular-list-title").addTo(s);return new r("a").class("pagefind-modular-list-link").text(i.meta?.title).attrs({href:i.meta?.url||i.url}).addTo(n),new r("p").class("pagefind-modular-list-excerpt").html(i.excerpt).addTo(s),e.element},E=i=>{if(!(i instanceof HTMLElement))return null;let e=window.getComputedStyle(i).overflowY;return e!=="visible"&&e!=="hidden"?i:E(i.parentNode)},d=class{constructor(e={}){this.rawResult=e.result,this.placeholderNodes=e.placeholderNodes,this.resultFn=e.resultFn,this.intersectionEl=e.intersectionEl,this.result=null,this.waitForIntersection()}waitForIntersection(){if(!this.placeholderNodes?.length)return;let e={root:this.intersectionEl,rootMargin:"0px",threshold:.01};new IntersectionObserver((s,n)=>{this.result===null&&s?.[0]?.isIntersecting&&(this.load(),n.disconnect())},e).observe(this.placeholderNodes[0])}async load(){if(!this.placeholderNodes?.length)return;this.result=await this.rawResult.data();let e=this.resultFn(this.result),t=g(e);for(;this.placeholderNodes.length>1;)this.placeholderNodes.pop().remove();this.placeholderNodes[0].replaceWith(...t)}},a=class{constructor(e){if(this.intersectionEl=document.body,this.containerEl=null,this.results=[],this.placeholderTemplate=e.placeholderTemplate??v,this.resultTemplate=e.resultTemplate??y,e.containerElement)this.initContainer(e.containerElement);else{console.error("[Pagefind ResultList component]: No selector supplied for containerElement");return}}initContainer(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind ResultList component]: No container found for ${e} selector`);return}this.containerEl=t}append(e){for(let t of e)this.containerEl.appendChild(t)}register(e){e.on("results",t=>{this.containerEl&&(this.containerEl.innerHTML="",this.intersectionEl=E(this.containerEl),this.results=t.results.map(s=>{let n=g(this.placeholderTemplate());return this.append(n),new d({result:s,placeholderNodes:n,resultFn:this.resultTemplate,intersectionEl:this.intersectionEl})}))}),e.on("loading",()=>{this.containerEl&&(this.containerEl.innerHTML="")})}};var o=class{constructor(e={}){if(this.containerEl=null,this.defaultMessage=e.defaultMessage??"",this.term="",e.containerElement)this.initContainer(e.containerElement);else{console.error("[Pagefind Summary component]: No selector supplied for containerElement");return}}initContainer(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind Summary component]: No container found for ${e} selector`);return}this.containerEl=t,this.containerEl.innerText=this.defaultMessage}register(e){e.on("search",(t,s)=>{this.term=t}),e.on("results",t=>{if(!this.containerEl||!t)return;if(!this.term){this.containerEl.innerText=this.defaultMessage;return}let s=t?.results?.length??0;this.containerEl.innerText=`${s} result${s===1?"":"s"} for ${this.term}`}),e.on("loading",()=>{this.containerEl&&(this.containerEl.innerText=`Searching for ${this.term}...`)})}};var h=class{constructor(e={}){if(this.instance=null,this.wrapper=null,this.pillContainer=null,this.available={},this.selected=["All"],this.total=0,this.filterMemo="",this.filter=e.filter,this.ordering=e.ordering??null,this.alwaysShow=e.alwaysShow??!1,this.selectMultiple=e.selectMultiple??!1,!this.filter?.length){console.error("[Pagefind FilterPills component]: No filter option supplied, nothing to display");return}if(e.containerElement)this.initContainer(e.containerElement);else{console.error("[Pagefind FilterPills component]: No selector supplied for containerElement");return}}initContainer(e){let t=document.querySelector(e);if(!t){console.error(`[Pagefind FilterPills component]: No container found for ${e} selector`);return}t.innerHTML="";let s=`pagefind_modular_filter_pills_${this.filter}`,n=new r("div").class("pagefind-modular-filter-pills-wrapper").attrs({role:"group","aria-labelledby":s});this.alwaysShow||n.attrs({"data-pfmod-hidden":!0}),new r("div").id(s).class("pagefind-modular-filter-pills-label").attrs({"data-pfmod-sr-hidden":!0}).text(`Filter results by ${this.filter}`).addTo(n),this.pillContainer=new r("div").class("pagefind-modular-filter-pills").addTo(n),this.wrapper=n.addTo(t)}update(){let e=this.available.map(t=>t[0]).join("~");e==this.filterMemo?this.updateExisting():(this.renderNew(),this.filterMemo=e)}pushFilters(){let e=this.selected.filter(t=>t!=="All");this.instance.triggerFilter(this.filter,e)}pillInner(e,t){return this.total?`${e} (${t})`:`${e}`}renderNew(){this.available.forEach(([e,t])=>{new r("button").class("pagefind-modular-filter-pill").html(this.pillInner(e,t)).attrs({"aria-pressed":this.selected.includes(e),type:"button"}).handle("click",()=>{e==="All"?this.selected=["All"]:this.selected.includes(e)?this.selected=this.selected.filter(s=>s!==e):this.selectMultiple?this.selected.push(e):this.selected=[e],this.selected?.length?this.selected?.length>1&&(this.selected=this.selected.filter(s=>s!=="All")):this.selected=["All"],this.update(),this.pushFilters()}).addTo(this.pillContainer)})}updateExisting(){let e=[...this.pillContainer.childNodes];this.available.forEach(([t,s],n)=>{e[n].innerHTML=this.pillInner(t,s),e[n].setAttribute("aria-pressed",this.selected.includes(t))})}register(e){this.instance=e,this.instance.on("filters",t=>{if(!this.pillContainer)return;this.selectMultiple?t=t.available:t=t.total;let s=t[this.filter];if(!s){console.warn(`[Pagefind FilterPills component]: No possible values found for the ${this.filter} filter`);return}this.available=Object.entries(s),Array.isArray(this.ordering)?this.available.sort((n,c)=>{let m=this.ordering.indexOf(n[0]),_=this.ordering.indexOf(c[0]);return(m===-1?1/0:m)-(_===-1?1/0:_)}):this.available.sort((n,c)=>n[0].localeCompare(c[0])),this.available.unshift(["All",this.total]),this.update()}),e.on("results",t=>{this.pillContainer&&(this.total=t?.unfilteredResultCount||0,this.available?.[0]?.[0]==="All"&&(this.available[0][1]=this.total),this.total||this.alwaysShow?this.wrapper.removeAttribute("data-pfmod-hidden"):this.wrapper.setAttribute("data-pfmod-hidden","true"),this.update())})}};var P=async(i=50)=>await new Promise(e=>setTimeout(e,i)),u;try{document?.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&(u=new URL(document.currentScript.src).pathname.match(/^(.*\/)(?:pagefind-)?modular-ui.js.*$/)[1])}catch{u="/pagefind/"}var p=class{constructor(e={}){this.__pagefind__=null,this.__initializing__=null,this.__searchID__=0,this.__hooks__={search:[],filters:[],loading:[],results:[]},this.components=[],this.searchTerm="",this.searchFilters={},this.searchResult={},this.availableFilters=null,this.totalFilters=null,this.options={bundlePath:e.bundlePath??u,mergeIndex:e.mergeIndex??[]},delete e.bundlePath,delete e.resetStyles,delete e.processResult,delete e.processTerm,delete e.debounceTimeoutMs,delete e.mergeIndex,delete e.translations,this.pagefindOptions=e}add(e){e?.register?.(this),this.components.push(e)}on(e,t){if(!this.__hooks__[e]){let s=Object.keys(this.__hooks__).join(", ");console.error(`[Pagefind Composable]: Unknown event type ${e}. Supported events: [${s}]`);return}if(typeof t!="function"){console.error(`[Pagefind Composable]: Expected callback to be a function, received ${typeof t}`);return}this.__hooks__[e].push(t)}triggerLoad(){this.__load__()}triggerSearch(e){this.searchTerm=e,this.__dispatch__("search",e,this.searchFilters),this.__search__(e,this.searchFilters)}triggerSearchWithFilters(e,t){this.searchTerm=e,this.searchFilters=t,this.__dispatch__("search",e,t),this.__search__(e,t)}triggerFilters(e){this.searchFilters=e,this.__dispatch__("search",this.searchTerm,e),this.__search__(this.searchTerm,e)}triggerFilter(e,t){this.searchFilters=this.searchFilters||{},this.searchFilters[e]=t,this.__dispatch__("search",this.searchTerm,this.searchFilters),this.__search__(this.searchTerm,this.searchFilters)}__dispatch__(e,...t){this.__hooks__[e]?.forEach(s=>s?.(...t))}async __clear__(){this.__dispatch__("results",{results:[],unfilteredTotalCount:0}),this.availableFilters=await this.__pagefind__.filters(),this.totalFilters=this.availableFilters,this.__dispatch__("filters",{available:this.availableFilters,total:this.totalFilters})}async __search__(e,t){this.__dispatch__("loading"),await this.__load__();let s=++this.__searchID__;if(!e||!e.length)return this.__clear__();let n=await this.__pagefind__.search(e,{filters:t});n&&this.__searchID__===s&&(n.filters&&Object.keys(n.filters)?.length&&(this.availableFilters=n.filters,this.totalFilters=n.totalFilters,this.__dispatch__("filters",{available:this.availableFilters,total:this.totalFilters})),this.searchResult=n,this.__dispatch__("results",this.searchResult))}async __load__(){if(this.__initializing__){for(;!this.__pagefind__;)await P(50);return}if(this.__initializing__=!0,!this.__pagefind__){let e;try{e=await import(`${this.options.bundlePath}pagefind.js`)}catch(t){console.error(t),console.error([`Pagefind couldn't be loaded from ${this.options.bundlePath}pagefind.js`,"You can configure this by passing a bundlePath option to PagefindComposable Instance"].join(` 8 | `)),document?.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"?console.error(`[DEBUG: Loaded from ${document.currentScript?.src??"bad script location"}]`):console.error("no known script location")}await e.options(this.pagefindOptions||{});for(let t of this.options.mergeIndex){if(!t.bundlePath)throw new Error("mergeIndex requires a bundlePath parameter");let s=t.bundlePath;delete t.bundlePath,await e.mergeIndex(s,t)}this.__pagefind__=e}this.availableFilters=await this.__pagefind__.filters(),this.totalFilters=this.availableFilters,this.__dispatch__("filters",{available:this.availableFilters,total:this.totalFilters})}};window.PagefindModularUI=f;})(); 9 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { randomUUID } from 'crypto'; 2 | import { Agent, RequestOptions } from 'https'; 3 | import { Readable } from 'stream'; 4 | 5 | import { IBalanceResponse } from '@interfaces/balance'; 6 | import { ICompletionRequest, ICompletionResponse } from '@interfaces/completion'; 7 | import { GigaChatConfig } from '@interfaces/config'; 8 | import { IEmbeddingResponse } from '@interfaces/embedding'; 9 | import { IExtractImage } from '@interfaces/extract'; 10 | import { IFile, IFileDeleteResponse } from '@interfaces/file'; 11 | import { IAllModelResponse } from '@interfaces/model'; 12 | import { ISummarizeResponse } from '@interfaces/summarize'; 13 | import { ITokenResponse } from '@interfaces/token'; 14 | 15 | import { GigaChatError } from './utils/GigaChatError'; 16 | import { HTTPClient } from './utils/HTTPClient'; 17 | 18 | /** 19 | * Класс для взаимодействия с API GigaChat. 20 | * Позволяет выполнять авторизацию, отправлять запросы к модели, загружать файлы и работать с потоками данных. 21 | */ 22 | class GigaChat { 23 | /** 24 | * HTTP-Клиент для обработки запросов. 25 | */ 26 | private httpClient: HTTPClient; 27 | 28 | /** 29 | * Токен авторизации для API. 30 | */ 31 | public authorization: string | undefined; 32 | 33 | /** 34 | * Секретный ключ клиента. 35 | */ 36 | private clientSecretKey: string; 37 | 38 | /** 39 | * Флаг, определяющий, следует ли игнорировать ошибки TLS. 40 | */ 41 | private isIgnoreTSL: boolean; 42 | 43 | /** 44 | * Флаг, определяющий, является ли клиент личным пользователем (Personal) или корпоративным (Corporation). 45 | */ 46 | private isPersonal: boolean; 47 | 48 | /** 49 | * Флаг, разрешающий автоматическое обновление токена при истечении срока его действия. 50 | */ 51 | private autoRefreshToken: boolean; 52 | 53 | /** 54 | * Включена ли обработка изображений в ответах модели. 55 | */ 56 | private imgOn: boolean; 57 | 58 | /** 59 | * Основной URL API GigaChat. 60 | */ 61 | private url: string = 'https://gigachat.devices.sberbank.ru/api/v1'; 62 | 63 | /** 64 | * URL для авторизации и получения токена. 65 | */ 66 | private urlAuth: string = 'https://ngw.devices.sberbank.ru:9443/api/v2/oauth'; 67 | 68 | /** 69 | * Область действия (scope) API для личных пользователей. 70 | */ 71 | private scopeForPersonal: string = 'GIGACHAT_API_PERS'; 72 | 73 | /** 74 | * Область действия (scope) API для корпоративных пользователей. 75 | */ 76 | private scopeForCorporation: string = 'GIGACHAT_API_CORP'; 77 | 78 | /** 79 | * Создает новый экземпляр GigaChat. 80 | * @param {GigaChatConfig} config Конфигурация клиента. 81 | */ 82 | constructor({ 83 | clientSecretKey, 84 | isIgnoreTSL = true, 85 | isPersonal = true, 86 | autoRefreshToken = true, 87 | imgOn = true, 88 | }: GigaChatConfig) { 89 | this.clientSecretKey = clientSecretKey; 90 | this.isIgnoreTSL = isIgnoreTSL; 91 | this.isPersonal = isPersonal; 92 | this.autoRefreshToken = autoRefreshToken; 93 | this.imgOn = imgOn; 94 | 95 | this.httpClient = new HTTPClient(this.url, undefined, this.isIgnoreTSL); 96 | } 97 | 98 | /** 99 | * Извлекает URL изображения из ответа модели. 100 | * @param {string} completionContent Содержимое ответа. 101 | * @returns {IExtractImage | null} Результат извлечения изображения. 102 | */ 103 | private extractImageSource(completionContent: string): IExtractImage | null { 104 | const imgTagRegex = /]+src\s*=\s*['"]([^'"]+)['"][^>]*>/; 105 | const match = completionContent.match(imgTagRegex); 106 | if (match) { 107 | return { 108 | imageId: match[1], 109 | text: completionContent.replace(imgTagRegex, ''), 110 | }; 111 | } else { 112 | return null; 113 | } 114 | } 115 | 116 | /** 117 | * Обработка ошибки 118 | * @param {unknown} error Ошибка. 119 | * @param {() => Promise} currentFunction Функция, которую надо выполнить, если проблема была в токенах и она решилась. 120 | * @returns {Promise} Результат выполнения currentFunction(). 121 | * @throws {GigaChatError} Специфичная ошибка API 122 | */ 123 | private async handlingError(error: unknown, currentFunction: () => Promise): Promise { 124 | if (error) 125 | if (error instanceof Error) { 126 | const err = error as NodeJS.ErrnoException; 127 | 128 | // TLS/SSL 129 | if (err.code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' || err.code === 'CERT_HAS_EXPIRED') { 130 | throw new GigaChatError(`SSL/TLS error: ${err.message}`, 'SSL_ERROR'); 131 | } 132 | 133 | // Network 134 | if (err.code === 'ECONNRESET' || err.code === 'ETIMEDOUT' || err.code === 'EPROTO') { 135 | throw new GigaChatError(`Network error: ${err.message}`, 'NETWORK_ERROR'); 136 | } 137 | 138 | // HTTP 139 | if (/^HTTP Error: \d{3} .+$/.test(err.message)) { 140 | const match = err.message.match(/^HTTP Error: (\d{3}) (.+)$/); 141 | 142 | if (match) { 143 | const errorData = { 144 | statusCode: Number(match[1]), 145 | statusMessage: match[2], 146 | }; 147 | 148 | if (errorData.statusCode === 401) { 149 | if (this.autoRefreshToken) { 150 | await this.createToken(); 151 | return currentFunction(); 152 | } 153 | throw new GigaChatError('Authorization token expired', 'AUTH_EXPIRED'); 154 | } 155 | 156 | if (errorData.statusCode === 400) { 157 | throw new GigaChatError( 158 | `Validation error: ${errorData?.statusMessage}`, 159 | 'VALIDATION_ERROR', 160 | ); 161 | } 162 | 163 | if (errorData.statusCode >= 500) { 164 | throw new GigaChatError('Internal server error', 'SERVER_ERROR'); 165 | } 166 | } 167 | } 168 | } 169 | 170 | // Обработка неизвестных ошибок 171 | throw new GigaChatError(`Unknown error: ${error}`, 'UNKNOWN_ERROR'); 172 | } 173 | 174 | /** 175 | * Создает новый токен доступа. 176 | * @returns {Promise} Данные токена. 177 | */ 178 | public async createToken(): Promise { 179 | try { 180 | const requestUID = randomUUID(); 181 | const data = new URLSearchParams(); 182 | 183 | if (this.isPersonal) { 184 | data.append('scope', this.scopeForPersonal); 185 | } else { 186 | data.append('scope', this.scopeForCorporation); 187 | } 188 | 189 | const url = new URL(this.urlAuth); 190 | const options: RequestOptions = { 191 | hostname: url.hostname, 192 | path: url.pathname + url.search, 193 | port: url.port || 443, 194 | method: 'POST', 195 | headers: { 196 | Authorization: `Bearer ${this.clientSecretKey}`, 197 | RqUID: requestUID, 198 | 'Content-Type': 'application/x-www-form-urlencoded', 199 | 'Content-Length': Buffer.byteLength(data.toString()), 200 | }, 201 | agent: new Agent({ 202 | rejectUnauthorized: !this.isIgnoreTSL, 203 | }), 204 | }; 205 | const response = await this.httpClient.makeRequest(options, data.toString()); 206 | this.authorization = response.access_token; 207 | this.httpClient.setAuthorization(response.access_token); 208 | return response; 209 | } catch (error) { 210 | const err = error as NodeJS.ErrnoException; 211 | 212 | if (err.code === 'ECONNRESET' || err.code === 'ETIMEDOUT' || err.code === 'EPROTO') { 213 | throw new GigaChatError(`HTTPS error (create token): ${err.message}`, 'HTTPS_ERROR'); 214 | } 215 | 216 | if (err.code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' || err.code === 'CERT_HAS_EXPIRED') { 217 | throw new GigaChatError(`SSL/TLS error (create token): ${err.message}`, 'SSL_ERROR'); 218 | } 219 | 220 | throw new GigaChatError(`Unknown error (create token): ${err.message}`, 'UNKNOWN_ERROR'); 221 | } 222 | } 223 | 224 | /** 225 | * Отправляет запрос на завершение чата. 226 | * @param {ICompletionRequest} data - Данные запроса. 227 | * @returns {Promise} Ответ сервера. 228 | */ 229 | public async completion(data: ICompletionRequest): Promise { 230 | const path = '/chat/completions'; 231 | try { 232 | const response = await this.httpClient.post(path, data); 233 | 234 | for (let index = 0; index < response.choices.length; index++) { 235 | const completionContent = response.choices[index].message.content; 236 | if (this.imgOn) { 237 | const extractedResult = this.extractImageSource(completionContent); 238 | if (extractedResult) { 239 | response.choices[index].message.image = extractedResult.imageId; 240 | response.choices[index].message.content = extractedResult.text; 241 | } 242 | } 243 | } 244 | 245 | return response; 246 | } catch (error) { 247 | return await this.handlingError(error, async () => { 248 | return await this.httpClient.post(path, data); 249 | }); 250 | } 251 | } 252 | 253 | /** 254 | * Отправляет потоковый запрос на завершение чата. 255 | * @param {ICompletionRequest} data - Данные запроса. 256 | * @returns {Promise} Потоковый ответ сервера. 257 | */ 258 | public async completionStream(data: ICompletionRequest): Promise { 259 | const path = '/chat/completions'; 260 | const streamData = { ...data, stream: true }; 261 | try { 262 | const response = await this.httpClient.post(path, streamData, true); 263 | return response; 264 | } catch (error) { 265 | return await this.handlingError(error, async () => { 266 | return await this.httpClient.post(path, streamData, true); 267 | }); 268 | } 269 | } 270 | 271 | /** 272 | * Получает список всех моделей. 273 | * @returns {Promise} Ответ сервера с моделями. 274 | */ 275 | public async allModels(): Promise { 276 | const path = '/models'; 277 | try { 278 | const responce = await this.httpClient.get(path); 279 | return responce.data; 280 | } catch (error) { 281 | return await this.handlingError(error, async () => { 282 | return await this.httpClient.get(path); 283 | }); 284 | } 285 | } 286 | 287 | /** 288 | * Выполняет embedding запроса. 289 | * @param {string[]} input - Входные данные. 290 | * @returns {Promise} Ответ сервера с embedding. 291 | */ 292 | public async embedding(input: string[]): Promise { 293 | const path = '/embeddings'; 294 | try { 295 | const responce = await this.httpClient.post(path, { model: 'Embeddings', input: input }); 296 | return responce.data; 297 | } catch (error) { 298 | return await this.handlingError(error, async () => { 299 | return await this.httpClient.post(path, { input: input }); 300 | }); 301 | } 302 | } 303 | 304 | /** 305 | * Подсчитывает количество токенов в тексте. 306 | * @param {string} model - Модель. 307 | * @param {string[]} input - Входные данные. 308 | * @returns {Promise} Ответ с количеством токенов. 309 | */ 310 | public async summarize(model: string, input: string[]): Promise { 311 | const path = '/tokens/count'; 312 | try { 313 | const responce = await this.httpClient.post(path, { model, input }); 314 | return responce; 315 | } catch (error) { 316 | return await this.handlingError(error, async () => { 317 | return await this.httpClient.post(path, { model, input }); 318 | }); 319 | } 320 | } 321 | 322 | /** 323 | * Загружает файл в сервис. 324 | * @param {string} pathToFile - Путь к файлу. 325 | * @param {string} [purpose='general'] - Назначение файла. 326 | * @returns {Promise} Ответ сервера с данными файла. 327 | */ 328 | public async uploadFile(pathToFile: string, purpose: string = 'general'): Promise { 329 | try { 330 | const response = await this.httpClient.postFiles(pathToFile, purpose); 331 | return response; 332 | } catch (error) { 333 | return await this.handlingError(error, async () => { 334 | return await this.httpClient.postFiles(pathToFile, purpose); 335 | }); 336 | } 337 | } 338 | 339 | /** 340 | * Получение списка доступных файлов. 341 | * @returns {Promise} Массив объектов с информацией о доступных файлах. 342 | */ 343 | public async getAllFiles(): Promise { 344 | const path = '/files'; 345 | try { 346 | const response = await this.httpClient.get(path); 347 | return response; 348 | } catch (error) { 349 | return await this.handlingError(error, async () => { 350 | return await this.httpClient.get(path); 351 | }); 352 | } 353 | } 354 | 355 | /** 356 | * Получение информации о файле по идентификатору. 357 | * @param {string} fileId - Идентификатор файла. 358 | * @returns {Promise} Объект с информацией о файле. 359 | */ 360 | public async getFileInfo(fileId: string): Promise { 361 | const path = `/files/${fileId}`; 362 | try { 363 | const response = await this.httpClient.get(path); 364 | return response; 365 | } catch (error) { 366 | return await this.handlingError(error, async () => { 367 | return await this.httpClient.get(path); 368 | }); 369 | } 370 | } 371 | 372 | /** 373 | * Удаление файла по идентификатору. 374 | * @param {string} fileId - Идентификатор файла. 375 | * @returns {Promise} Ответ сервера. 376 | */ 377 | public async deleteFile(fileId: string): Promise { 378 | const path = `/files/${fileId}/delete`; 379 | try { 380 | const response = await this.httpClient.post(path, {}); 381 | return response; 382 | } catch (error) { 383 | return await this.handlingError(error, async () => { 384 | return await this.httpClient.post(path, {}); 385 | }); 386 | } 387 | } 388 | 389 | /** 390 | * Получение баланса токенов по всем моделям. 391 | * @returns {Promise} Ответ сервера с информацией о балансе. 392 | */ 393 | public async getBalance(): Promise { 394 | const path = '/balance'; 395 | try { 396 | const response = await this.httpClient.get(path); 397 | return response; 398 | } catch (error) { 399 | return await this.handlingError(error, async () => { 400 | return await this.httpClient.get(path); 401 | }); 402 | } 403 | } 404 | 405 | public async downloadFile(fileId: string): Promise { 406 | const path = `/files/${fileId}/content`; 407 | try { 408 | const response = await this.httpClient.get(path, true); 409 | return response; 410 | } catch (error) { 411 | return await this.handlingError(error, async () => { 412 | return await this.httpClient.get(path); 413 | }); 414 | } 415 | } 416 | } 417 | 418 | export { GigaChat, GigaChatError }; 419 | -------------------------------------------------------------------------------- /docs/dist/_astro/ec.tm3va.css: -------------------------------------------------------------------------------- 1 | .expressive-code{font-family:var(--ec-uiFontFml);font-size:var(--ec-uiFontSize);font-weight:var(--ec-uiFontWg);line-height:var(--ec-uiLineHt);text-size-adjust:none;-webkit-text-size-adjust:none}.expressive-code *:not(:is(svg, svg *)){all:revert;box-sizing:border-box}.expressive-code pre{display:flex;margin:0;padding:0;border:var(--ec-brdWd) solid var(--ec-brdCol);border-radius:calc(var(--ec-brdRad) + var(--ec-brdWd));background:var(--ec-codeBg)}.expressive-code pre:focus-visible{outline:3px solid var(--ec-focusBrd);outline-offset:-3px}.expressive-code pre > code{all:unset;display:block;flex:1 0 100%;padding:var(--ec-codePadBlk) 0;color:var(--ec-codeFg);font-family:var(--ec-codeFontFml);font-size:var(--ec-codeFontSize);font-weight:var(--ec-codeFontWg);line-height:var(--ec-codeLineHt)}.expressive-code pre{overflow-x:auto}.expressive-code pre.wrap .ec-line .code{white-space:pre-wrap;overflow-wrap:break-word;min-width:min(20ch, var(--ecMaxLine, 20ch))}.expressive-code pre.wrap .ec-line .code span.indent{white-space:pre}.expressive-code pre::-webkit-scrollbar,.expressive-code pre::-webkit-scrollbar-track{background-color:inherit;border-radius:calc(var(--ec-brdRad) + var(--ec-brdWd));border-top-left-radius:0;border-top-right-radius:0}.expressive-code pre::-webkit-scrollbar-thumb{background-color:var(--ec-sbThumbCol);border:4px solid transparent;background-clip:content-box;border-radius:10px}.expressive-code pre::-webkit-scrollbar-thumb:hover{background-color:var(--ec-sbThumbHoverCol)}.expressive-code .ec-line{direction:ltr;unicode-bidi:isolate;display:grid;grid-template-areas:'gutter code';grid-template-columns:auto 1fr;position:relative}.expressive-code .ec-line .gutter{grid-area:gutter;color:var(--ec-gtrFg)}.expressive-code .ec-line .gutter > *{pointer-events:none;user-select:none;-webkit-user-select:none}.expressive-code .ec-line .gutter ~ .code{--ecLineBrdCol:var(--ec-gtrBrdCol)}.expressive-code .ec-line.highlight .gutter{color:var(--ec-gtrHlFg)}.expressive-code .ec-line .code{grid-area:code;position:relative;box-sizing:content-box;padding-inline-start:calc(var(--ecIndent, 0ch) + var(--ec-codePadInl) - var(--ecGtrBrdWd));padding-inline-end:var(--ec-codePadInl);text-indent:calc(var(--ecIndent, 0ch) * -1)}.expressive-code .ec-line .code::before,.expressive-code .ec-line .code::after,.expressive-code .ec-line .code :where(*){text-indent:0}.expressive-code .ec-line .code{--ecGtrBrdWd:var(--ec-gtrBrdWd);border-inline-start:var(--ecGtrBrdWd) solid var(--ecLineBrdCol, transparent)}.expressive-code .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);white-space:nowrap;border-width:0}.expressive-code .ec-line.mark{--tmLineBgCol:var(--ec-tm-markBg)}.expressive-code .ec-line.mark .code{--ecLineBrdCol:var(--ec-tm-markBrdCol)}.expressive-code .ec-line.ins{--tmLineBgCol:var(--ec-tm-insBg);--tmLabel:var(--ec-tm-insDiffIndContent)}.expressive-code .ec-line.ins .code{--ecLineBrdCol:var(--ec-tm-insBrdCol)}.expressive-code .ec-line.ins .code::before{color:var(--ec-tm-insDiffIndCol)}.expressive-code .ec-line.del{--tmLineBgCol:var(--ec-tm-delBg);--tmLabel:var(--ec-tm-delDiffIndContent)}.expressive-code .ec-line.del .code{--ecLineBrdCol:var(--ec-tm-delBrdCol)}.expressive-code .ec-line.del .code::before{color:var(--ec-tm-delDiffIndCol)}.expressive-code .ec-line.mark,.expressive-code .ec-line.ins,.expressive-code .ec-line.del{background:var(--tmLineBgCol)}.expressive-code .ec-line.mark .code,.expressive-code .ec-line.ins .code,.expressive-code .ec-line.del .code{--ecGtrBrdWd:var(--ec-tm-lineMarkerAccentWd)}.expressive-code .ec-line.mark .code::before,.expressive-code .ec-line.ins .code::before,.expressive-code .ec-line.del .code::before{display:block;position:absolute;left:0;box-sizing:border-box;content:var(--tmLabel, ' ');padding-inline-start:var(--ec-tm-lineDiffIndMargLeft);text-align:center;white-space:pre}.expressive-code .ec-line.mark.tm-label .code::before,.expressive-code .ec-line.ins.tm-label .code::before,.expressive-code .ec-line.del.tm-label .code::before{background:var(--ecLineBrdCol);padding:0 calc(var(--ec-tm-lineMarkerLabelPadInl) + var(--ec-tm-lineMarkerAccentWd)) 0 var(--ec-tm-lineMarkerLabelPadInl);color:var(--ec-tm-lineMarkerLabelCol)}.expressive-code .ec-line mark{--tmInlineBgCol:var(--ec-tm-markBg);--tmInlineBrdCol:var(--ec-tm-markBrdCol)}.expressive-code .ec-line ins{--tmInlineBgCol:var(--ec-tm-insBg);--tmInlineBrdCol:var(--ec-tm-insBrdCol)}.expressive-code .ec-line del{--tmInlineBgCol:var(--ec-tm-delBg);--tmInlineBrdCol:var(--ec-tm-delBrdCol)}.expressive-code .ec-line mark,.expressive-code .ec-line ins,.expressive-code .ec-line del{all:unset;display:inline-block;position:relative;--tmBrdL:var(--ec-tm-inlMarkerBrdWd);--tmBrdR:var(--ec-tm-inlMarkerBrdWd);--tmRadL:var(--ec-tm-inlMarkerBrdRad);--tmRadR:var(--ec-tm-inlMarkerBrdRad);margin-inline:0.025rem;padding-inline:var(--ec-tm-inlMarkerPad);border-radius:var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);background:var(--tmInlineBgCol);background-clip:padding-box}.expressive-code .ec-line mark.open-start,.expressive-code .ec-line ins.open-start,.expressive-code .ec-line del.open-start{margin-inline-start:0;padding-inline-start:0;--tmBrdL:0px;--tmRadL:0}.expressive-code .ec-line mark.open-end,.expressive-code .ec-line ins.open-end,.expressive-code .ec-line del.open-end{margin-inline-end:0;padding-inline-end:0;--tmBrdR:0px;--tmRadR:0}.expressive-code .ec-line mark::before,.expressive-code .ec-line ins::before,.expressive-code .ec-line del::before{content:'';position:absolute;pointer-events:none;display:inline-block;inset:0;border-radius:var(--tmRadL) var(--tmRadR) var(--tmRadR) var(--tmRadL);border:var(--ec-tm-inlMarkerBrdWd) solid var(--tmInlineBrdCol);border-inline-width:var(--tmBrdL) var(--tmBrdR)}.expressive-code .frame{all:unset;position:relative;display:block;--header-border-radius:calc(var(--ec-brdRad) + var(--ec-brdWd));--tab-border-radius:calc(var(--ec-frm-edTabBrdRad) + var(--ec-brdWd));--button-spacing:0.4rem;--code-background:var(--ec-frm-edBg);border-radius:var(--header-border-radius);box-shadow:var(--ec-frm-frameBoxShdCssVal)}.expressive-code .frame .header{display:none;z-index:1;position:relative;border-radius:var(--header-border-radius) var(--header-border-radius) 0 0}.expressive-code .frame.has-title pre,.expressive-code .frame.has-title code,.expressive-code .frame.is-terminal pre,.expressive-code .frame.is-terminal code{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.expressive-code .frame .title:empty:before{content:'\a0'}.expressive-code .frame.has-title:not(.is-terminal){--button-spacing:calc(1.9rem + 2 * (var(--ec-uiPadBlk) + var(--ec-frm-edActTabIndHt)))}.expressive-code .frame.has-title:not(.is-terminal) .title{position:relative;color:var(--ec-frm-edActTabFg);background:var(--ec-frm-edActTabBg);background-clip:padding-box;margin-block-start:var(--ec-frm-edTabsMargBlkStart);padding:calc(var(--ec-uiPadBlk) + var(--ec-frm-edActTabIndHt)) var(--ec-uiPadInl);border:var(--ec-brdWd) solid var(--ec-frm-edActTabBrdCol);border-radius:var(--tab-border-radius) var(--tab-border-radius) 0 0;border-bottom:none;overflow:hidden}.expressive-code .frame.has-title:not(.is-terminal) .title::after{content:'';position:absolute;pointer-events:none;inset:0;border-top:var(--ec-frm-edActTabIndHt) solid var(--ec-frm-edActTabIndTopCol);border-bottom:var(--ec-frm-edActTabIndHt) solid var(--ec-frm-edActTabIndBtmCol)}.expressive-code .frame.has-title:not(.is-terminal) .header{display:flex;background:linear-gradient(to top, var(--ec-frm-edTabBarBrdBtmCol) var(--ec-brdWd), transparent var(--ec-brdWd)),linear-gradient(var(--ec-frm-edTabBarBg), var(--ec-frm-edTabBarBg));background-repeat:no-repeat;padding-inline-start:var(--ec-frm-edTabsMargInlStart)}.expressive-code .frame.has-title:not(.is-terminal) .header::before{content:'';position:absolute;pointer-events:none;inset:0;border:var(--ec-brdWd) solid var(--ec-frm-edTabBarBrdCol);border-radius:inherit;border-bottom:none}.expressive-code .frame.is-terminal{--button-spacing:calc(1.9rem + var(--ec-brdWd) + 2 * var(--ec-uiPadBlk));--code-background:var(--ec-frm-trmBg)}.expressive-code .frame.is-terminal .header{display:flex;align-items:center;justify-content:center;padding-block:var(--ec-uiPadBlk);padding-block-end:calc(var(--ec-uiPadBlk) + var(--ec-brdWd));position:relative;font-weight:500;letter-spacing:0.025ch;color:var(--ec-frm-trmTtbFg);background:var(--ec-frm-trmTtbBg);border:var(--ec-brdWd) solid var(--ec-brdCol);border-bottom:none}.expressive-code .frame.is-terminal .header::before{content:'';position:absolute;pointer-events:none;left:var(--ec-uiPadInl);width:2.1rem;height:0.56rem;line-height:0;background-color:var(--ec-frm-trmTtbDotsFg);opacity:var(--ec-frm-trmTtbDotsOpa);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 16' preserveAspectRatio='xMidYMid meet'%3E%3Ccircle cx='8' cy='8' r='8'/%3E%3Ccircle cx='30' cy='8' r='8'/%3E%3Ccircle cx='52' cy='8' r='8'/%3E%3C/svg%3E");-webkit-mask-repeat:no-repeat;mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 60 16' preserveAspectRatio='xMidYMid meet'%3E%3Ccircle cx='8' cy='8' r='8'/%3E%3Ccircle cx='30' cy='8' r='8'/%3E%3Ccircle cx='52' cy='8' r='8'/%3E%3C/svg%3E");mask-repeat:no-repeat}.expressive-code .frame.is-terminal .header::after{content:'';position:absolute;pointer-events:none;inset:0;border-bottom:var(--ec-brdWd) solid var(--ec-frm-trmTtbBrdBtmCol)}.expressive-code .frame pre{background:var(--code-background)}.expressive-code .copy{display:flex;gap:0.25rem;flex-direction:row;position:absolute;inset-block-start:calc(var(--ec-brdWd) + var(--button-spacing));inset-inline-end:calc(var(--ec-brdWd) + var(--ec-uiPadInl) / 2)}@media (scripting: none){.expressive-code .copy{display:none}}.expressive-code .copy{direction:ltr;unicode-bidi:isolate}.expressive-code .copy button{position:relative;align-self:flex-end;margin:0;padding:0;border:none;border-radius:0.2rem;z-index:1;cursor:pointer;transition-property:opacity, background, border-color;transition-duration:0.2s;transition-timing-function:cubic-bezier(0.25, 0.46, 0.45, 0.94);width:2.5rem;height:2.5rem;background:var(--code-background);opacity:0.75}.expressive-code .copy button div{position:absolute;inset:0;border-radius:inherit;background:var(--ec-frm-inlBtnBg);opacity:var(--ec-frm-inlBtnBgIdleOpa);transition-property:inherit;transition-duration:inherit;transition-timing-function:inherit}.expressive-code .copy button::before{content:'';position:absolute;pointer-events:none;inset:0;border-radius:inherit;border:var(--ec-brdWd) solid var(--ec-frm-inlBtnBrd);opacity:var(--ec-frm-inlBtnBrdOpa)}.expressive-code .copy button::after{content:'';position:absolute;pointer-events:none;inset:0;background-color:var(--ec-frm-inlBtnFg);-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75'%3E%3Cpath d='M3 19a2 2 0 0 1-1-2V2a2 2 0 0 1 1-1h13a2 2 0 0 1 2 1'/%3E%3Crect x='6' y='5' width='16' height='18' rx='1.5' ry='1.5'/%3E%3C/svg%3E");-webkit-mask-repeat:no-repeat;mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75'%3E%3Cpath d='M3 19a2 2 0 0 1-1-2V2a2 2 0 0 1 1-1h13a2 2 0 0 1 2 1'/%3E%3Crect x='6' y='5' width='16' height='18' rx='1.5' ry='1.5'/%3E%3C/svg%3E");mask-repeat:no-repeat;margin:0.475rem;line-height:0}.expressive-code .copy button:hover,.expressive-code .copy button:focus:focus-visible{opacity:1}.expressive-code .copy button:hover div,.expressive-code .copy button:focus:focus-visible div{opacity:var(--ec-frm-inlBtnBgHoverOrFocusOpa)}.expressive-code .copy button:active{opacity:1}.expressive-code .copy button:active div{opacity:var(--ec-frm-inlBtnBgActOpa)}.expressive-code .copy .feedback{--tooltip-arrow-size:0.35rem;--tooltip-bg:var(--ec-frm-tooltipSuccessBg);color:var(--ec-frm-tooltipSuccessFg);pointer-events:none;user-select:none;-webkit-user-select:none;position:relative;align-self:center;background-color:var(--tooltip-bg);z-index:99;padding:0.125rem 0.75rem;border-radius:0.2rem;margin-inline-end:var(--tooltip-arrow-size);opacity:0;transition-property:opacity, transform;transition-duration:0.2s;transition-timing-function:ease-in-out;transform:translate3d(0, 0.25rem, 0)}.expressive-code .copy .feedback::after{content:'';position:absolute;pointer-events:none;top:calc(50% - var(--tooltip-arrow-size));inset-inline-end:calc(-2 * (var(--tooltip-arrow-size) - 0.5px));border:var(--tooltip-arrow-size) solid transparent;border-inline-start-color:var(--tooltip-bg)}.expressive-code .copy .feedback.show{opacity:1;transform:translate3d(0, 0, 0)}@media (hover: hover){.expressive-code{}.expressive-code .copy button{opacity:0;width:2rem;height:2rem}.expressive-code .frame:hover .copy button:not(:hover),.expressive-code .frame:focus-within :focus-visible ~ .copy button:not(:hover),.expressive-code .frame .copy .feedback.show ~ button:not(:hover){opacity:0.75}}.expressive-code :nth-child(1 of .ec-line) .code{padding-inline-end:calc(2rem + var(--ec-codePadInl))}:root,:root:not([data-theme='dark']) .expressive-code[data-theme='dark']{--ec-brdRad:0px;--ec-brdWd:1px;--ec-brdCol:color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-codeFontFml:var(--__sl-font-mono);--ec-codeFontSize:var(--sl-text-code);--ec-codeFontWg:400;--ec-codeLineHt:var(--sl-line-height);--ec-codePadBlk:0.75rem;--ec-codePadInl:1rem;--ec-codeBg:#23262f;--ec-codeFg:#d6deeb;--ec-codeSelBg:#1d3b53;--ec-gtrFg:#63798b;--ec-gtrBrdCol:#63798b33;--ec-gtrBrdWd:1.5px;--ec-gtrHlFg:#c5e4fd97;--ec-uiFontFml:var(--__sl-font);--ec-uiFontSize:0.9rem;--ec-uiFontWg:400;--ec-uiLineHt:1.65;--ec-uiPadBlk:0.25rem;--ec-uiPadInl:1rem;--ec-uiSelBg:#234d708c;--ec-uiSelFg:#ffffff;--ec-focusBrd:#122d42;--ec-sbThumbCol:#ffffff17;--ec-sbThumbHoverCol:#ffffff47;--ec-tm-lineMarkerAccentMarg:0rem;--ec-tm-lineMarkerAccentWd:0.15rem;--ec-tm-lineMarkerLabelPadInl:0.2rem;--ec-tm-lineMarkerLabelCol:white;--ec-tm-lineDiffIndMargLeft:0.25rem;--ec-tm-inlMarkerBrdWd:1.5px;--ec-tm-inlMarkerBrdRad:0.2rem;--ec-tm-inlMarkerPad:0.15rem;--ec-tm-insDiffIndContent:'+';--ec-tm-delDiffIndContent:'-';--ec-tm-markBg:#ffffff17;--ec-tm-markBrdCol:#ffffff40;--ec-tm-insBg:#1e571599;--ec-tm-insBrdCol:#487f3bd0;--ec-tm-insDiffIndCol:#79b169d0;--ec-tm-delBg:#862d2799;--ec-tm-delBrdCol:#b4554bd0;--ec-tm-delDiffIndCol:#ed8779d0;--ec-frm-shdCol:#011627;--ec-frm-frameBoxShdCssVal:none;--ec-frm-edActTabBg:var(--sl-color-gray-6);--ec-frm-edActTabFg:var(--sl-color-text);--ec-frm-edActTabBrdCol:transparent;--ec-frm-edActTabIndHt:1px;--ec-frm-edActTabIndTopCol:var(--sl-color-accent-high);--ec-frm-edActTabIndBtmCol:transparent;--ec-frm-edTabsMargInlStart:0;--ec-frm-edTabsMargBlkStart:0;--ec-frm-edTabBrdRad:0px;--ec-frm-edTabBarBg:var(--sl-color-black);--ec-frm-edTabBarBrdCol:color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edTabBarBrdBtmCol:color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-edBg:var(--sl-color-gray-6);--ec-frm-trmTtbDotsFg:color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmTtbDotsOpa:0.75;--ec-frm-trmTtbBg:var(--sl-color-black);--ec-frm-trmTtbFg:var(--sl-color-text);--ec-frm-trmTtbBrdBtmCol:color-mix(in srgb, var(--sl-color-gray-5), transparent 25%);--ec-frm-trmBg:var(--sl-color-gray-6);--ec-frm-inlBtnFg:var(--sl-color-text);--ec-frm-inlBtnBg:var(--sl-color-text);--ec-frm-inlBtnBgIdleOpa:0;--ec-frm-inlBtnBgHoverOrFocusOpa:0.2;--ec-frm-inlBtnBgActOpa:0.3;--ec-frm-inlBtnBrd:var(--sl-color-text);--ec-frm-inlBtnBrdOpa:0.4;--ec-frm-tooltipSuccessBg:#158744;--ec-frm-tooltipSuccessFg:white}.expressive-code .ec-line :where(span[style^='--']:not([class])),:root:not([data-theme='dark']) .expressive-code[data-theme='dark'] .ec-line :where(span[style^='--']:not([class])){color:var(--0, inherit);font-style:var(--0fs, inherit);font-weight:var(--0fw, inherit);text-decoration:var(--0td, inherit)}@media (prefers-color-scheme: light){:root:not([data-theme='dark']){--ec-codeBg:#f6f7f9;--ec-codeFg:#403f53;--ec-codeSelBg:#e0e0e0;--ec-gtrFg:#788b94;--ec-gtrBrdCol:#788b9433;--ec-gtrHlFg:#403f53c4;--ec-uiSelBg:#d3e8f8;--ec-uiSelFg:#403f53;--ec-focusBrd:#93a1a1;--ec-sbThumbCol:#0000001a;--ec-sbThumbHoverCol:#0000005c;--ec-tm-markBg:#0000001a;--ec-tm-markBrdCol:#00000055;--ec-tm-insBg:#8ec77d99;--ec-tm-insDiffIndCol:#336a28d0;--ec-tm-delBg:#ff9c8e99;--ec-tm-delDiffIndCol:#9d4138d0;--ec-frm-shdCol:#d9d9d9;--ec-frm-edActTabBg:var(--sl-color-gray-7);--ec-frm-edActTabIndTopCol:var(--sl-color-accent);--ec-frm-edTabBarBg:var(--sl-color-gray-6);--ec-frm-edBg:var(--sl-color-gray-7);--ec-frm-trmTtbBg:var(--sl-color-gray-6);--ec-frm-trmBg:var(--sl-color-gray-7);--ec-frm-tooltipSuccessBg:#078662}:root:not([data-theme='dark']) .expressive-code .ec-line :where(span[style^='--']:not([class])){color:var(--1, inherit);font-style:var(--1fs, inherit);font-weight:var(--1fw, inherit);text-decoration:var(--1td, inherit)}}:root[data-theme='light'] .expressive-code:not([data-theme='dark']),.expressive-code[data-theme='light']{--ec-codeBg:#f6f7f9;--ec-codeFg:#403f53;--ec-codeSelBg:#e0e0e0;--ec-gtrFg:#788b94;--ec-gtrBrdCol:#788b9433;--ec-gtrHlFg:#403f53c4;--ec-uiSelBg:#d3e8f8;--ec-uiSelFg:#403f53;--ec-focusBrd:#93a1a1;--ec-sbThumbCol:#0000001a;--ec-sbThumbHoverCol:#0000005c;--ec-tm-markBg:#0000001a;--ec-tm-markBrdCol:#00000055;--ec-tm-insBg:#8ec77d99;--ec-tm-insDiffIndCol:#336a28d0;--ec-tm-delBg:#ff9c8e99;--ec-tm-delDiffIndCol:#9d4138d0;--ec-frm-shdCol:#d9d9d9;--ec-frm-edActTabBg:var(--sl-color-gray-7);--ec-frm-edActTabIndTopCol:var(--sl-color-accent);--ec-frm-edTabBarBg:var(--sl-color-gray-6);--ec-frm-edBg:var(--sl-color-gray-7);--ec-frm-trmTtbBg:var(--sl-color-gray-6);--ec-frm-trmBg:var(--sl-color-gray-7);--ec-frm-tooltipSuccessBg:#078662}:root[data-theme='light'] .expressive-code:not([data-theme='dark']) .ec-line :where(span[style^='--']:not([class])),.expressive-code[data-theme='light'] .ec-line :where(span[style^='--']:not([class])){color:var(--1, inherit);font-style:var(--1fs, inherit);font-weight:var(--1fw, inherit);text-decoration:var(--1td, inherit)} --------------------------------------------------------------------------------