{"_id":"@aijora/sdk","name":"@aijora/sdk","dist-tags":{"latest":"0.3.0"},"versions":{"0.3.0":{"name":"@aijora/sdk","version":"0.3.0","description":"TypeScript SDK for Aijora AI API. OpenAI-compatible, with streaming, tool calling, structured output, agents, middleware, and React hooks.","main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.mjs","require":"./dist/react/index.js"},"./middleware":{"types":"./dist/middleware/index.d.ts","import":"./dist/middleware/index.mjs","require":"./dist/middleware/index.js"},"./testing":{"types":"./dist/testing/index.d.ts","import":"./dist/testing/index.mjs","require":"./dist/testing/index.js"},"./agents":{"types":"./dist/agents/index.d.ts","import":"./dist/agents/index.mjs","require":"./dist/agents/index.js"}},"sideEffects":false,"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","typecheck":"tsc --noEmit","lint":"eslint src tests","lint:fix":"eslint src tests --fix","format":"prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"","format:check":"prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"","audit:security":"npm audit --audit-level=moderate","validate":"npm run lint && npm run typecheck && npm run test","playground":"tsx examples/playground/server.ts","prepublishOnly":"npm run build"},"keywords":["aijora","ai","llm","openai","sdk","typescript","streaming","chat","completions","tools","agents","middleware","embeddings","structured-output"],"author":{"name":"Aijora"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/aijora/sdk.git"},"homepage":"https://github.com/aijora/sdk#readme","bugs":{"url":"https://github.com/aijora/sdk/issues"},"devDependencies":{"@testing-library/react":"^16.3.2","@types/node":"^25.1.0","@types/react":"^18.0.0","@typescript-eslint/eslint-plugin":"^8.54.0","@typescript-eslint/parser":"^8.54.0","@vitest/coverage-v8":"^2.1.9","eslint":"^9.39.2","eslint-config-prettier":"^10.1.8","jsdom":"^27.4.0","prettier":"^3.8.1","react":"^19.2.4","react-dom":"^19.2.4","tsup":"^8.0.0","tsx":"^4.21.0","typescript":"^5.5.0","vitest":"^2.0.0"},"peerDependencies":{"react":"^18.0.0 || ^19.0.0","zod":"^3.0.0"},"peerDependenciesMeta":{"react":{"optional":true},"zod":{"optional":true}},"engines":{"node":">=18.0.0"},"_id":"@aijora/sdk@0.3.0","_nodeVersion":"25.2.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-zZTqxUmnEocgFXa2P+3r0dxt64ouFkqnf+PKZ/SIyZxxC0weG6sSCkS+uAmZtQQRKDSjV7dwBv/MrMrbliB9Ug==","shasum":"37400ab6f7df2b9f7eb6e6826102bf57bb4cd3f5","tarball":"https://registry.npmjs.org/@aijora/sdk/-/sdk-0.3.0.tgz","fileCount":49,"unpackedSize":902927,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD75wkVclJFtzkQFrRq40RwSuv5F/+sRdFDV+NkEzsIawIhALGhfu1cVk2ya2uWynbGKH6/MOGWn/kcEvuImNid4N/M"}]},"_npmUser":{"name":"vladonsd","email":"vladoonsdd@gmail.com"},"directories":{},"maintainers":[{"name":"vladonsd","email":"vladoonsdd@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdk_0.3.0_1772162254928_0.2158737071126049"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-27T03:17:34.871Z","0.3.0":"2026-02-27T03:17:35.119Z","modified":"2026-02-27T03:17:35.287Z"},"maintainers":[{"name":"vladonsd","email":"vladoonsdd@gmail.com"}],"description":"TypeScript SDK for Aijora AI API. OpenAI-compatible, with streaming, tool calling, structured output, agents, middleware, and React hooks.","homepage":"https://github.com/aijora/sdk#readme","keywords":["aijora","ai","llm","openai","sdk","typescript","streaming","chat","completions","tools","agents","middleware","embeddings","structured-output"],"repository":{"type":"git","url":"git+https://github.com/aijora/sdk.git"},"author":{"name":"Aijora"},"bugs":{"url":"https://github.com/aijora/sdk/issues"},"license":"MIT","readme":"# @aijora/sdk\n\n[English](README.md) | **[Русский](README.ru.md)**\n\n[![npm version](https://img.shields.io/npm/v/@aijora/sdk.svg)](https://www.npmjs.com/package/@aijora/sdk)\n[![CI](https://github.com/aijora/sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/aijora/sdk/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![TypeScript](https://img.shields.io/badge/TypeScript-strict-blue.svg)](https://www.typescriptlang.org/)\n[![Node.js](https://img.shields.io/badge/Node.js-%3E%3D18-green.svg)](https://nodejs.org/)\n\nTypeScript SDK для Aijora Gateway API. Замена OpenAI SDK с поддержкой стриминга, вызова инструментов, структурированного вывода, агентов, middleware, React-хуков и многого другого.\n\n## Содержание\n\n- [Установка](#установка)\n- [Быстрый старт](#быстрый-старт)\n- [Стриминг](#стриминг)\n- [Генерация текста с инструментами](#генерация-текста-с-инструментами)\n- [Вызов инструментов](#вызов-инструментов)\n- [Структурированный вывод](#структурированный-вывод)\n- [Агенты](#агенты)\n- [Генерация изображений](#генерация-изображений)\n- [Эмбеддинги](#эмбеддинги)\n- [Аудио](#аудио)\n- [Мультимодальность / Vision](#мультимодальность--vision)\n- [Сообщения](#сообщения)\n- [Middleware](#middleware)\n- [Телеметрия](#телеметрия)\n- [Провайдеры](#провайдеры)\n- [React-хуки](#react-хуки)\n- [Тестирование](#тестирование)\n- [Конфигурация](#конфигурация)\n- [Обработка ошибок](#обработка-ошибок)\n- [Доступные модели](#доступные-модели)\n- [Под-пакеты](#под-пакеты)\n- [Миграция с OpenAI SDK](#миграция-с-openai-sdk)\n- [Требования](#требования)\n\n## Установка\n\n```bash\nnpm install @aijora/sdk\n```\n\n## Быстрый старт\n\n```typescript\nimport { Aijora } from '@aijora/sdk';\n\nconst client = new Aijora({\n  apiKey: process.env.AIJORA_API_KEY!,\n});\n\nconst response = await client.chat.completions.create({\n  model: 'gpt-4o',\n  messages: [{ role: 'user', content: 'Привет!' }],\n});\n\nconsole.log(response.choices[0].message.content);\n```\n\n## Стриминг\n\n```typescript\nconst stream = await client.chat.completions.create({\n  model: 'claude-3-5-sonnet-20241022',\n  messages: [{ role: 'user', content: 'Напиши историю' }],\n  stream: true,\n});\n\nfor await (const chunk of stream) {\n  process.stdout.write(chunk.choices[0]?.delta?.content || '');\n}\n\n// Или собрать весь текст сразу:\nconst text = await stream.toText();\n\n// Или собрать все чанки:\nconst chunks = await stream.toArray();\n```\n\n### Плавный стриминг\n\nЭффект набора текста для UI:\n\n```typescript\nimport { smoothStream } from '@aijora/sdk';\n\nfor await (const char of smoothStream(stream, { delayMs: 20, chunking: 'character' })) {\n  process.stdout.write(char);\n}\n```\n\n### Протоколы стриминга\n\nКонвертация потоков для интеграции с фреймворками:\n\n```typescript\nimport { toDataStreamProtocol, toTextStreamProtocol, toReadableStream } from '@aijora/sdk';\n\n// Next.js API route\nexport async function POST(req: Request) {\n  const stream = await client.chat.completions.create({ ..., stream: true });\n  return new Response(toReadableStream(toDataStreamProtocol(stream)));\n}\n```\n\n### Отмена потока\n\n```typescript\nconst stream = await client.chat.completions.create({ ..., stream: true });\n\nstream.onAbort(() => console.log('Отменено!'));\nsetTimeout(() => stream.abort(), 5000);\n```\n\n## Генерация текста с инструментами\n\nВысокоуровневые функции с автоматическим циклом вызова инструментов:\n\n```typescript\nimport { generateText, streamText, tool } from '@aijora/sdk';\n\nconst result = await generateText({\n  client,\n  model: 'gpt-4o',\n  prompt: 'Какая погода в Москве?',\n  tools: {\n    weather: tool({\n      description: 'Получить погоду в городе',\n      parameters: { type: 'object', properties: { city: { type: 'string' } }, required: ['city'] },\n      execute: async ({ city }) => `${city}: 15°C, облачно`,\n    }),\n  },\n  maxSteps: 5,\n  onStepFinish: ({ stepNumber, toolCalls }) => {\n    console.log(`Шаг ${stepNumber}: ${toolCalls.length} вызовов`);\n  },\n});\n\nconsole.log(result.text);\nconsole.log(result.usage); // { promptTokens, completionTokens, totalTokens }\n```\n\n### Потоковая генерация текста\n\n```typescript\nconst result = await streamText({\n  client,\n  model: 'gpt-4o',\n  prompt: 'Расскажи шутку',\n  onChunk: ({ content }) => process.stdout.write(content || ''),\n  onFinish: ({ text }) => console.log('\\nГотово:', text.length, 'символов'),\n});\n\nfor await (const delta of result.textStream) {\n  process.stdout.write(delta);\n}\n```\n\n## Вызов инструментов\n\n```typescript\nimport { tool, toolsToOpenAI, executeToolCalls } from '@aijora/sdk';\n\nconst tools = {\n  calculator: tool({\n    description: 'Вычислить математическое выражение',\n    parameters: { type: 'object', properties: { expression: { type: 'string' } } },\n    execute: ({ expression }) => String(eval(expression)),\n  }),\n};\n\nconst openaiTools = toolsToOpenAI(tools);\nconst results = await executeToolCalls(response.choices[0].message.tool_calls, tools);\n```\n\n## Структурированный вывод\n\nГенерация типизированных JSON-объектов с валидацией через Zod или JSON Schema:\n\n```typescript\nimport { generateObject, streamObject, zodSchema, jsonSchema } from '@aijora/sdk';\nimport { z } from 'zod';\n\nconst result = await generateObject({\n  client,\n  model: 'gpt-4o',\n  prompt: 'Сгенерируй профиль пользователя',\n  schema: zodSchema(z.object({\n    name: z.string(),\n    age: z.number(),\n    hobbies: z.array(z.string()),\n  })),\n  mode: 'json', // или 'tool'\n});\n\nconsole.log(result.object); // типизировано: { name, age, hobbies }\n```\n\n### Потоковые объекты\n\n```typescript\nconst result = await streamObject({ client, model: 'gpt-4o', prompt: '...', schema });\n\nfor await (const partial of result.partialObjectStream) {\n  console.log('Частично:', partial); // инкрементальный JSON\n}\n\nconst final = await result.object;\n```\n\n## Агенты\n\nМногошаговые AI-воркфлоу с инструментами:\n\n```typescript\nimport { Agent, runAgent } from '@aijora/sdk/agents';\n\nconst agent = new Agent({\n  client,\n  model: 'gpt-4o',\n  system: 'Ты полезный ассистент.',\n  tools: { weather: weatherTool },\n  maxSteps: 10,\n  onStepFinish: (step) => console.log(`Шаг ${step.stepNumber}`),\n  stopWhen: (step) => step.text.includes('DONE'),\n});\n\nconst result = await agent.run('Какая погода?');\n\n// Стриминг\nfor await (const event of agent.runStream('Расскажи про погоду')) {\n  if (event.type === 'text-delta') process.stdout.write(event.textDelta!);\n  if (event.type === 'finish') console.log(event.result);\n}\n\n// Однострочник\nconst result2 = await runAgent({ client, model: 'gpt-4o', tools, prompt: 'Привет' });\n```\n\n## Генерация изображений\n\n```typescript\nconst image = await client.images.generate({\n  model: 'dall-e-3',\n  prompt: 'Кот в шляпе',\n  size: '1024x1024',\n});\n\nconsole.log(image.data[0].url);\n```\n\n## Эмбеддинги\n\n```typescript\nimport { embed, embedMany, cosineSimilarity } from '@aijora/sdk';\n\nconst { embedding } = await embed({ client, model: 'text-embedding-3-small', value: 'Привет мир' });\nconst { embeddings } = await embedMany({ client, model: 'text-embedding-3-small', values: ['Привет', 'Мир'] });\nconst similarity = cosineSimilarity(embeddings[0], embeddings[1]); // 0.0 до 1.0\n```\n\n## Аудио\n\n```typescript\n// Транскрипция (Speech-to-Text)\nconst transcription = await client.audio.transcribe({\n  model: 'whisper-1',\n  file: audioBlob,\n  language: 'ru',\n});\n\n// Синтез речи (Text-to-Speech)\nconst audioBuffer = await client.audio.generateSpeech({\n  model: 'tts-1',\n  input: 'Привет, как дела?',\n  voice: 'alloy',\n});\n```\n\n## Мультимодальность / Vision\n\n```typescript\nimport { textPart, imageUrl, imageBase64, imageBuffer, userImageMessage } from '@aijora/sdk';\n\nconst response = await client.chat.completions.create({\n  model: 'gpt-4o',\n  messages: [userImageMessage('Что на картинке?', 'https://example.com/photo.jpg')],\n});\n```\n\n## Сообщения\n\n```typescript\nimport { convertToModelMessages, pruneMessages, estimateTokenCount, filterByRole, lastMessages } from '@aijora/sdk';\n\nconst modelMessages = convertToModelMessages(uiMessages);\nconst pruned = pruneMessages({ messages, maxTokens: 4096, strategy: 'keep-last' });\nconst tokens = estimateTokenCount(messages);\nconst last5 = lastMessages(messages, 5, true);\n```\n\n## Middleware\n\n```typescript\nimport { withMiddleware, loggingMiddleware, cachingMiddleware, rateLimitMiddleware } from '@aijora/sdk/middleware';\n\nconst client = withMiddleware(\n  new Aijora({ apiKey: '...' }),\n  loggingMiddleware(),\n  cachingMiddleware({ storage: new Map(), ttl: 60000 }),\n  rateLimitMiddleware({ maxRequests: 10, windowMs: 60000 }),\n);\n```\n\n### Свой Middleware\n\n```typescript\nimport type { Middleware } from '@aijora/sdk/middleware';\n\nconst myMiddleware: Middleware = {\n  name: 'my-middleware',\n  transformParams: (ctx) => ({ ...ctx, temperature: 0.5 }),\n  wrapGenerate: async (ctx, next) => {\n    const result = await next(ctx);\n    console.log('Токены:', result.usage?.totalTokens);\n    return result;\n  },\n};\n```\n\n### Извлечение и починка JSON\n\n```typescript\nimport { reasoningMiddleware, jsonExtractionMiddleware, repairJson, safeJsonParse } from '@aijora/sdk';\n\nconst fixed = repairJson('{ name: \"test\", }');\nconst parsed = safeJsonParse('invalid', { fallback: {} });\n```\n\n### Кэширование потоков\n\n```typescript\nimport { streamCachingMiddleware, withBackpressure, teeStream } from '@aijora/sdk';\n```\n\n## Телеметрия\n\n```typescript\nimport { telemetryMiddleware, InMemoryTracer, openTelemetryTracer } from '@aijora/sdk';\n\nconst tracer = new InMemoryTracer();\nconst client = withMiddleware(\n  new Aijora({ apiKey: '...' }),\n  telemetryMiddleware({ isEnabled: true, functionId: 'chatbot', tracer }),\n);\n```\n\n## Провайдеры\n\n```typescript\nimport { ProviderRegistry, createProvider, aijoraProvider, openaiProvider } from '@aijora/sdk';\n\nconst registry = new ProviderRegistry();\nregistry.register('aijora', aijoraProvider(process.env.AIJORA_KEY!));\nregistry.register('openai', openaiProvider(process.env.OPENAI_KEY!));\nconst { provider, model } = registry.resolveModel('openai:gpt-4o');\n```\n\n## React-хуки\n\n```typescript\nimport { useChat } from '@aijora/sdk/react';\n\nfunction Chat() {\n  const { messages, input, setInput, handleSubmit, isLoading, stop } = useChat({ api: '/api/chat' });\n  return (\n    <form onSubmit={handleSubmit}>\n      {messages.map(m => <div key={m.id}>{m.role}: {m.content}</div>)}\n      <input value={input} onChange={e => setInput(e.target.value)} />\n    </form>\n  );\n}\n```\n\nТакже доступны хуки `useCompletion` и `useObject`.\n\n## Тестирование\n\n```typescript\nimport { MockAijora, mockId, mockValues, simulateReadableStream } from '@aijora/sdk/testing';\n\nconst client = new MockAijora({\n  chatResponse: { content: 'Привет!' },\n  streamContent: 'Потоковый ответ',\n});\n\nconst result = await client.chat.completions.create({ model: 'test', messages: [] });\nconsole.log(client.lastCall);\nclient.reset();\n```\n\n## Конфигурация\n\n```typescript\nconst client = new Aijora({\n  apiKey: 'sk-...',                           // Обязательно\n  baseURL: 'https://api.aijora.com',          // По умолчанию\n  timeout: 60000,                             // 60 секунд\n  maxRetries: 2,                              // Авто-повтор при 5xx\n  defaultHeaders: { 'X-Request-ID': 'req' }, // Кастомные заголовки\n});\n```\n\n## Обработка ошибок\n\n20+ типизированных классов ошибок:\n\n```typescript\nimport { AijoraError, AuthenticationError, InsufficientBalanceError, RateLimitError } from '@aijora/sdk';\n\ntry {\n  await client.chat.completions.create({ ... });\n} catch (error) {\n  if (error instanceof InsufficientBalanceError) {\n    console.log(`Баланс: ${error.balance} ${error.currency}`);\n  } else if (error instanceof RateLimitError) {\n    console.log(`Повторить через ${error.retryAfter} сек`);\n  }\n}\n```\n\n## Доступные модели\n\n### Текст\n- `gpt-4o`, `gpt-4o-mini`, `o1`, `o3-mini`\n- `claude-3-5-sonnet-20241022`, `claude-3-5-haiku-20241022`, `claude-3-opus-20240229`\n- `gemini-2.0-flash`, `gemini-2.5-pro-preview`\n- `deepseek-chat`, `deepseek-reasoner`\n- `grok-2`, `mistral-large-latest`, `codestral-latest`, `sonar-pro`, `qwen-max`\n\n### Изображения\n- `dall-e-3`, `flux-pro`, `ideogram-v2`, `recraft-v3`\n\n## Под-пакеты\n\n```typescript\nimport { Aijora } from '@aijora/sdk';                  // ядро\nimport { useChat } from '@aijora/sdk/react';            // React-хуки\nimport { withMiddleware } from '@aijora/sdk/middleware'; // middleware\nimport { MockAijora } from '@aijora/sdk/testing';       // тестирование\nimport { Agent } from '@aijora/sdk/agents';             // агенты\n```\n\n## Playground\n\nИнтерактивный чат для тестирования:\n\n```bash\nAIJORA_API_KEY=sk-your-key npm run playground\n```\n\nОткройте [http://localhost:3737](http://localhost:3737)\n\n## Миграция с OpenAI SDK\n\n```diff\n- import OpenAI from 'openai';\n+ import { Aijora } from '@aijora/sdk';\n\n- const client = new OpenAI({ apiKey: '...' });\n+ const client = new Aijora({ apiKey: '...' });\n\n// Остальной код остаётся без изменений!\n```\n\n## Требования\n\n- Node.js >= 18 (использует нативный `fetch`)\n- TypeScript >= 5.0 (опционально)\n- React >= 18 (опционально, для хуков)\n- Zod >= 3.0 (опционально, для валидации схем)\n\n## Лицензия\n\nMIT\n","readmeFilename":"README.ru.md","_rev":"1-f8e52b28651db4d208b318fe63d95c8d"}