AACFlow

TypeScript

Официальный TypeScript/JavaScript SDK для AACFlow обеспечивает полную типобезопасность и поддерживает как Node.js, так и браузерные среды, позволяя выполнять рабочие процессы программно из ваших Node.js-приложений, веб-приложений и других JavaScript-сред.

TypeScript SDK обеспечивает полную типобезопасность, поддержку асинхронного выполнения, автоматическое ограничение скорости с экспоненциальной задержкой и отслеживание использования.

Установка

Установите SDK с помощью предпочитаемого менеджера пакетов:

npm install aacflow-ts-sdk
yarn add aacflow-ts-sdk
bun add aacflow-ts-sdk

Быстрый старт

Вот простой пример, чтобы начать работу:

import { AACFlowClient } from 'aacflow-ts-sdk';

// Инициализируем клиент
const client = new AACFlowClient({
  apiKey: 'your-api-key-here',
  baseUrl: 'https://aacflow.io' // опционально, по умолчанию https://aacflow.io
});

// Выполняем рабочий процесс
try {
  const result = await client.executeWorkflow('workflow-id');
  console.log('Рабочий процесс выполнен успешно:', result);
} catch (error) {
  console.error('Выполнение рабочего процесса не удалось:', error);
}

Справочник по API

AACFlowClient

Конструктор

new AACFlowClient(config: AACFlowConfig)

Конфигурация:

  • config.apiKey (string): Ваш API-ключ AACFlow
  • config.baseUrl (string, опционально): Базовый URL для API AACFlow (по умолчанию https://aacflow.io)

Методы

executeWorkflow()

Выполняет рабочий процесс с опциональными входными данными.

const result = await client.executeWorkflow('workflow-id', { message: 'Hello, world!' }, {
  timeout: 30000 // 30 секунд
});

Параметры:

  • workflowId (string): ID рабочего процесса для выполнения
  • input (any, опционально): Входные данные для передачи в рабочий процесс
  • options (ExecutionOptions, опционально):
    • timeout (number): Таймаут в миллисекундах (по умолчанию: 30000)
    • stream (boolean): Включить потоковые ответы (по умолчанию: false)
    • selectedOutputs (string[]): Выходные данные блоков для потоковой передачи в формате blockName.attribute (например, ["agent1.content"])
    • async (boolean): Выполнять асинхронно (по умолчанию: false)

Возвращает: Promise<WorkflowExecutionResult | AsyncExecutionResult>

Когда async: true, возвращает немедленно с ID задачи для опроса. В противном случае ожидает завершения.

getWorkflowStatus()

Получает статус рабочего процесса (статус развертывания и т.д.).

const status = await client.getWorkflowStatus('workflow-id');
console.log('Развернут:', status.isDeployed);

Параметры:

  • workflowId (string): ID рабочего процесса

Возвращает: Promise<WorkflowStatus>

validateWorkflow()

Проверяет, готов ли рабочий процесс к выполнению.

const isReady = await client.validateWorkflow('workflow-id');
if (isReady) {
  // Рабочий процесс развернут и готов
}

Параметры:

  • workflowId (string): ID рабочего процесса

Возвращает: Promise<boolean>

getJobStatus()

Получает статус асинхронного выполнения задачи.

const status = await client.getJobStatus('task-id-from-async-execution');
console.log('Статус:', status.status); // 'queued', 'processing', 'completed', 'failed'
if (status.status === 'completed') {
  console.log('Выходные данные:', status.output);
}

Параметры:

  • taskId (string): ID задачи, возвращенный из асинхронного выполнения

Возвращает: Promise<JobStatus>

Поля ответа:

  • success (boolean): Успешен ли запрос
  • taskId (string): ID задачи
  • status (string): Один из 'queued', 'processing', 'completed', 'failed', 'cancelled'
  • metadata (object): Содержит startedAt, completedAt и duration
  • output (any, опционально): Выходные данные рабочего процесса (при завершении)
  • error (any, опционально): Детали ошибки (при сбое)
  • estimatedDuration (number, опционально): Предполагаемая продолжительность в миллисекундах (при обработке/в очереди)
executeWithRetry()

Выполняет рабочий процесс с автоматической повторной попыткой при ошибках ограничения скорости с использованием экспоненциальной задержки.

const result = await client.executeWithRetry('workflow-id', { message: 'Hello' }, {
  timeout: 30000
}, {
  maxRetries: 3,           // Максимальное количество повторных попыток
  initialDelay: 1000,      // Начальная задержка в мс (1 секунда)
  maxDelay: 30000,         // Максимальная задержка в мс (30 секунд)
  backoffMultiplier: 2     // Множитель экспоненциальной задержки
});

Параметры:

  • workflowId (string): ID рабочего процесса для выполнения
  • input (any, опционально): Входные данные для передачи в рабочий процесс
  • options (ExecutionOptions, опционально): То же, что и executeWorkflow()
  • retryOptions (RetryOptions, опционально):
    • maxRetries (number): Максимальное количество повторных попыток (по умолчанию: 3)
    • initialDelay (number): Начальная задержка в мс (по умолчанию: 1000)
    • maxDelay (number): Максимальная задержка в мс (по умолчанию: 30000)
    • backoffMultiplier (number): Множитель задержки (по умолчанию: 2)

Возвращает: Promise<WorkflowExecutionResult | AsyncExecutionResult>

Логика повторных попыток использует экспоненциальную задержку (1с → 2с → 4с → 8с...) с ±25% случайным отклонением для предотвращения "стадного эффекта". Если API предоставляет заголовок retry-after, он будет использован вместо этого.

getRateLimitInfo()

Получает текущую информацию об ограничении скорости из последнего ответа API.

const rateLimitInfo = client.getRateLimitInfo();
if (rateLimitInfo) {
  console.log('Лимит:', rateLimitInfo.limit);
  console.log('Осталось:', rateLimitInfo.remaining);
  console.log('Сброс:', new Date(rateLimitInfo.reset * 1000));
}

Возвращает: RateLimitInfo | null

getUsageLimits()

Получает текущие лимиты использования и информацию о квоте для вашей учетной записи.

const limits = await client.getUsageLimits();
console.log('Осталось синхронных запросов:', limits.rateLimit.sync.remaining);
console.log('Осталось асинхронных запросов:', limits.rateLimit.async.remaining);
console.log('Текущая стоимость периода:', limits.usage.currentPeriodCost);
console.log('Тариф:', limits.usage.plan);

Возвращает: Promise<UsageLimits>

Структура ответа:

{
  success: boolean
  rateLimit: {
    sync: {
      isLimited: boolean
      limit: number
      remaining: number
      resetAt: string
    }
    async: {
      isLimited: boolean
      limit: number
      remaining: number
      resetAt: string
    }
    authType: string  // 'api' или 'manual'
  }
  usage: {
    currentPeriodCost: number
    limit: number
    plan: string  // например, 'free', 'pro'
  }
}
setApiKey()

Обновляет API-ключ.

client.setApiKey('new-api-key');
setBaseUrl()

Обновляет базовый URL.

client.setBaseUrl('https://my-custom-domain.com');

Типы

WorkflowExecutionResult

interface WorkflowExecutionResult {
  success: boolean;
  output?: any;
  error?: string;
  logs?: any[];
  metadata?: {
    duration?: number;
    executionId?: string;
    [key: string]: any;
  };
  traceSpans?: any[];
  totalDuration?: number;
}

AsyncExecutionResult

interface AsyncExecutionResult {
  success: boolean;
  taskId: string;
  status: 'queued';
  createdAt: string;
  links: {
    status: string;  // например, "/api/jobs/{taskId}"
  };
}

WorkflowStatus

interface WorkflowStatus {
  isDeployed: boolean;
  deployedAt?: string;
  needsRedeployment: boolean;
}

RateLimitInfo

interface RateLimitInfo {
  limit: number;
  remaining: number;
  reset: number;
  retryAfter?: number;
}

UsageLimits

interface UsageLimits {
  success: boolean;
  rateLimit: {
    sync: {
      isLimited: boolean;
      limit: number;
      remaining: number;
      resetAt: string;
    };
    async: {
      isLimited: boolean;
      limit: number;
      remaining: number;
      resetAt: string;
    };
    authType: string;
  };
  usage: {
    currentPeriodCost: number;
    limit: number;
    plan: string;
  };
}

AACFlowError

class AACFlowError extends Error {
  code?: string;
  status?: number;
}

Распространенные коды ошибок:

  • UNAUTHORIZED: Неверный API-ключ
  • TIMEOUT: Превышено время ожидания запроса
  • RATE_LIMIT_EXCEEDED: Превышено ограничение скорости
  • USAGE_LIMIT_EXCEEDED: Превышен лимит использования
  • EXECUTION_ERROR: Сбой выполнения рабочего процесса

Примеры

Базовое выполнение рабочего процесса

Настройте AACFlowClient с вашим API-ключом.

Проверьте, развернут ли рабочий процесс и готов ли к выполнению.

Запустите рабочий процесс с вашими входными данными.

Обработайте результат выполнения и обработайте любые ошибки.

import { AACFlowClient } from 'aacflow-ts-sdk';

const client = new AACFlowClient({
  apiKey: process.env.AACFLOW_API_KEY!
});

async function runWorkflow() {
  try {
    // Проверьте, готов ли рабочий процесс
    const isReady = await client.validateWorkflow('my-workflow-id');
    if (!isReady) {
      throw new Error('Workflow is not deployed or ready');
    }

    // Выполните рабочий процесс
    const result = await client.executeWorkflow('my-workflow-id', {
        message: 'Process this data',
        userId: '12345'
    });

    if (result.success) {
      console.log('Output:', result.output);
      console.log('Duration:', result.metadata?.duration);
    } else {
      console.error('Workflow failed:', result.error);
    }
  } catch (error) {
    console.error('Error:', error);
  }
}

runWorkflow();

Обработка ошибок

Обрабатывайте различные типы ошибок, которые могут возникнуть во время выполнения рабочего процесса:

import { AACFlowClient, AACFlowError } from 'aacflow-ts-sdk';

const client = new AACFlowClient({
  apiKey: process.env.AACFLOW_API_KEY!
});

async function executeWithErrorHandling() {
  try {
    const result = await client.executeWorkflow('workflow-id');
    return result;
  } catch (error) {
    if (error instanceof AACFlowError) {
      switch (error.code) {
        case 'UNAUTHORIZED':
          console.error('Invalid API key');
          break;
        case 'TIMEOUT':
          console.error('Workflow execution timed out');
          break;
        case 'USAGE_LIMIT_EXCEEDED':
          console.error('Usage limit exceeded');
          break;
        case 'INVALID_JSON':
          console.error('Invalid JSON in request body');
          break;
        default:
          console.error('Workflow error:', error.message);
      }
    } else {
      console.error('Unexpected error:', error);
    }
    throw error;
  }
}

Конфигурация окружения

Настройте клиент с использованием переменных окружения:

import { AACFlowClient } from 'aacflow-ts-sdk';

// Конфигурация для разработки
const apiKey = process.env.AACFLOW_API_KEY;
if (!apiKey) {
  throw new Error('AACFLOW_API_KEY environment variable is required');
}

const client = new AACFlowClient({
  apiKey,
  baseUrl: process.env.SIM_BASE_URL // опционально
});
import { AACFlowClient } from 'aacflow-ts-sdk';

// Конфигурация для продакшена с валидацией
const apiKey = process.env.AACFLOW_API_KEY;
if (!apiKey) {
  throw new Error('AACFLOW_API_KEY environment variable is required');
}

const client = new AACFlowClient({
  apiKey,
  baseUrl: process.env.SIM_BASE_URL || 'https://aacflow.io'
});

Интеграция с Node.js Express

Интегрируйте с сервером Express.js:

import express from 'express';
import { AACFlowClient } from 'aacflow-ts-sdk';

const app = express();
const client = new AACFlowClient({
  apiKey: process.env.AACFLOW_API_KEY!
});

app.use(express.json());

app.post('/execute-workflow', async (req, res) => {
  try {
    const { workflowId, input } = req.body;
    
    const result = await client.executeWorkflow(workflowId, input, {
      timeout: 60000
    });

    res.json({
      success: true,
      data: result
    });
  } catch (error) {
    console.error('Workflow execution error:', error);
    res.status(500).json({
      success: false,
      error: error instanceof Error ? error.message : 'Unknown error'
    });
  }
});

app.listen(3000, () => {
  console.log('Server running on port 3000');
});

Next.js API Route

Используйте с Next.js API routes:

// pages/api/workflow.ts или app/api/workflow/route.ts
import { NextApiRequest, NextApiResponse } from 'next';
import { AACFlowClient } from 'aacflow-ts-sdk';

const client = new AACFlowClient({
  apiKey: process.env.AACFLOW_API_KEY!
});

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  if (req.method !== 'POST') {
    return res.status(405).json({ error: 'Method not allowed' });
  }

  try {
    const { workflowId, input } = req.body;

    const result = await client.executeWorkflow(workflowId, input, {
      timeout: 30000
    });

    res.status(200).json(result);
  } catch (error) {
    console.error('Error executing workflow:', error);
    res.status(500).json({
      error: 'Failed to execute workflow'
    });
  }
}

Использование в браузере

Используйте в браузере (с правильной конфигурацией CORS):

import { AACFlowClient } from 'aacflow-ts-sdk';

// Примечание: В продакшене используйте прокси-сервер, чтобы избежать раскрытия API-ключей
const client = new AACFlowClient({
  apiKey: 'your-public-api-key', // Используйте с осторожностью в браузере
  baseUrl: 'https://aacflow.io'
});

async function executeClientSideWorkflow() {
  try {
    const result = await client.executeWorkflow('workflow-id', {
        userInput: 'Hello from browser'
    });

    console.log('Workflow result:', result);

    // Обновите UI с результатом
    document.getElementById('result')!.textContent =
      JSON.stringify(result.output, null, 2);
  } catch (error) {
    console.error('Error:', error);
  }
}

Загрузка файлов

Объекты File автоматически обнаруживаются и преобразуются в формат base64. Включите их в ваши входные данные под именем поля, соответствующему формату ввода API-триггера вашего рабочего процесса.

SDK преобразует объекты File в этот формат:

{
  type: 'file',
  data: 'data:mime/type;base64,base64data',
  name: 'filename',
  mime: 'mime/type'
}

Альтернативно, вы можете вручную предоставить файлы, используя формат URL:

{
  type: 'url',
  data: 'https://example.com/file.pdf',
  name: 'file.pdf',
  mime: 'application/pdf'
}
import { AACFlowClient } from 'aacflow-ts-sdk';

const client = new AACFlowClient({
  apiKey: process.env.NEXT_PUBLIC_AACFLOW_API_KEY!
});

// Из файлового ввода
async function handleFileUpload(event: Event) {
  const input = event.target as HTMLInputElement;
  const files = Array.from(input.files || []);

  // Включите файлы под именем поля из формата ввода API-триггера вашего рабочего процесса
  const result = await client.executeWorkflow('workflow-id', {
      documents: files,  // Должно соответствовать имени поля "files" вашего рабочего процесса
      instructions: 'Analyze these documents'
  });

  console.log('Result:', result);
}
import { AACFlowClient } from 'aacflow-ts-sdk';
import fs from 'fs';

const client = new AACFlowClient({
  apiKey: process.env.AACFLOW_API_KEY!
});

// Прочитайте файл и создайте объект File
const fileBuffer = fs.readFileSync('./document.pdf');
const file = new File([fileBuffer], 'document.pdf', {
  type: 'application/pdf'
});

// Включите файлы под именем поля из формата ввода API-триггера вашего рабочего процесса
const result = await client.executeWorkflow('workflow-id', {
    documents: [file],  // Должно соответствовать имени поля "files" вашего рабочего процесса
    query: 'Summarize this document'
});

При использовании SDK в браузере будьте осторожны, чтобы не раскрыть чувствительные API-ключи. Рассмотрите возможность использования бэкенд-прокси или публичных API-ключей с ограниченными разрешениями.

Пример React Hook

Создайте пользовательский React hook для выполнения рабочих процессов:

import { useState, useCallback } from 'react';
import { AACFlowClient, WorkflowExecutionResult } from 'aacflow-ts-sdk';

const client = new AACFlowClient({
  apiKey: process.env.AACFLOW_API_KEY!
});

interface UseWorkflowResult {
  result: WorkflowExecutionResult | null;
  loading: boolean;
  error: Error | null;
  executeWorkflow: (workflowId: string, input?: any) => Promise<void>;
}

export function useWorkflow(): UseWorkflowResult {
  const [result, setResult] = useState<WorkflowExecutionResult | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<Error | null>(null);

  const executeWorkflow = useCallback(async (workflowId: string, input?: any) => {
    setLoading(true);
    setError(null);
    setResult(null);

    try {
      const workflowResult = await client.executeWorkflow(workflowId, input, {
        timeout: 30000
      });
      setResult(workflowResult);
    } catch (err) {
      setError(err instanceof Error ? err : new Error('Unknown error'));
    } finally {
      setLoading(false);
    }
  }, []);

  return {
    result,
    loading,
    error,
    executeWorkflow
  };
}

// Использование в компоненте
function WorkflowComponent() {
  const { result, loading, error, executeWorkflow } = useWorkflow();

  const handleExecute = () => {
    executeWorkflow('my-workflow-id', {
      message: 'Hello from React!'
    });
  };

  return (
    <div>
      <button onClick={handleExecute} disabled={loading}>
        {loading ? 'Executing...' : 'Execute Workflow'}
      </button>

      {error && <div>Error: {error.message}</div>}
      {result && (
        <div>
          <h3>Result:</h3>
          <pre>{JSON.stringify(result, null, 2)}</pre>
        </div>
      )}
    </div>
  );
}

Асинхронное выполнение рабочих процессов

Выполняйте рабочие процессы асинхронно для длительных задач:

import { AACFlowClient, AsyncExecutionResult } from 'aacflow-ts-sdk';

const client = new AACFlowClient({
  apiKey: process.env.AACFLOW_API_KEY!
});

async function executeAsync() {
  try {
    // Начните асинхронное выполнение
    const result = await client.executeWorkflow('workflow-id', { data: 'large dataset' }, {
      async: true  // Выполнить асинхронно
    });

    // Проверьте, является ли результат асинхронным выполнением
    if ('taskId' in result) {
      console.log('Task ID:', result.taskId);
      console.log('Status endpoint:', result.links.status);

      // Опрос на завершение
      let status = await client.getJobStatus(result.taskId);

      while (status.status === 'queued' || status.status === 'processing') {
        console.log('Current status:', status.status);
        await new Promise(resolve => setTimeout(resolve, 2000)); // Подождите 2 секунды
        status = await client.getJobStatus(result.taskId);
      }

      if (status.status === 'completed') {
        console.log('Workflow completed!');
        console.log('Output:', status.output);
        console.log('Duration:', status.metadata.duration);
      } else {
        console.error('Workflow failed:', status.error);
      }
    }
  } catch (error) {
    console.error('Error:', error);
  }
}

executeAsync();

Ограничение скорости и повторные попытки

Обрабатывайте ограничения скорости автоматически с экспоненциальной задержкой:

import { AACFlowClient, AACFlowError } from 'aacflow-ts-sdk';

const client = new AACFlowClient({
  apiKey: process.env.AACFLOW_API_KEY!
});

async function executeWithRetryHandling() {
  try {
    // Автоматически повторяет при ограничении скорости
    const result = await client.executeWithRetry('workflow-id', { message: 'Process this' }, {}, {
      maxRetries: 5,
      initialDelay: 1000,
      maxDelay: 60000,
      backoffMultiplier: 2
    });

    console.log('Success:', result);
  } catch (error) {
    if (error instanceof AACFlowError && error.code === 'RATE_LIMIT_EXCEEDED') {
      console.error('Rate limit exceeded after all retries');

      // Проверьте информацию об ограничении скорости
      const rateLimitInfo = client.getRateLimitInfo();
      if (rateLimitInfo) {
        console.log('Rate limit resets at:', new Date(rateLimitInfo.reset * 1000));
      }
    }
  }
}

Мониторинг использования

Отслеживайте использование вашего аккаунта и лимиты:

import { AACFlowClient } from 'aacflow-ts-sdk';

const client = new AACFlowClient({
  apiKey: process.env.AACFLOW_API_KEY!
});

async function checkUsage() {
  try {
    const limits = await client.getUsageLimits();

    console.log('=== Rate Limits ===');
    console.log('Sync requests:');
    console.log('  Limit:', limits.rateLimit.sync.limit);
    console.log('  Remaining:', limits.rateLimit.sync.remaining);
    console.log('  Resets at:', limits.rateLimit.sync.resetAt);
    console.log('  Is limited:', limits.rateLimit.sync.isLimited);

    console.log('\nAsync requests:');
    console.log('  Limit:', limits.rateLimit.async.limit);
    console.log('  Remaining:', limits.rateLimit.async.remaining);
    console.log('  Resets at:', limits.rateLimit.async.resetAt);
    console.log('  Is limited:', limits.rateLimit.async.isLimited);

    console.log('\n=== Usage ===');
    console.log('Current period cost: $' + limits.usage.currentPeriodCost.toFixed(2));
    console.log('Limit: $' + limits.usage.limit.toFixed(2));
    console.log('Plan:', limits.usage.plan);

    const percentUsed = (limits.usage.currentPeriodCost / limits.usage.limit) * 100;
    console.log('Usage: ' + percentUsed.toFixed(1) + '%');

    if (percentUsed > 80) {
      console.warn('⚠️  Warning: You are approaching your usage limit!');
    }
  } catch (error) {
    console.error('Error checking usage:', error);
  }
}

checkUsage();

Потоковое выполнение рабочих процессов

Выполняйте рабочие процессы с потоковыми ответами в реальном времени:

import { AACFlowClient } from 'aacflow-ts-sdk';

const client = new AACFlowClient({
  apiKey: process.env.AACFLOW_API_KEY!
});

async function executeWithStreaming() {
  try {
    // Включите потоковую передачу для определенных выходов блоков
    const result = await client.executeWorkflow('workflow-id', { message: 'Count to five' }, {
      stream: true,
      selectedOutputs: ['agent1.content'] // Используйте формат blockName.attribute
    });

    console.log('Workflow result:', result);
  } catch (error) {
    console.error('Error:', error);
  }
}

Потоковый ответ следует формату Server-Sent Events (SSE):

data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":"One"}

data: {"blockId":"7b7735b9-19e5-4bd6-818b-46aae2596e9f","chunk":", two"}

data: {"event":"done","success":true,"output":{},"metadata":{"duration":610}}

data: [DONE]

Пример потоковой передачи в React:

import { useState, useEffect } from 'react';

function StreamingWorkflow() {
  const [output, setOutput] = useState('');
  const [loading, setLoading] = useState(false);

  const executeStreaming = async () => {
    setLoading(true);
    setOutput('');

    // ВАЖНО: Сделайте этот API-вызов с вашего бэкенд-сервера, а не из браузера
    // Никогда не раскрывайте ваш API-ключ в клиентском коде
    const response = await fetch('https://aacflow.io/api/workflows/WORKFLOW_ID/execute', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': process.env.AACFLOW_API_KEY! // Только серверная переменная окружения
      },
      body: JSON.stringify({
        message: 'Generate a story',
        stream: true,
        selectedOutputs: ['agent1.content']
      })
    });

    const reader = response.body?.getReader();
    const decoder = new TextDecoder();

    while (reader) {
      const { done, value } = await reader.read();
      if (done) break;

      const chunk = decoder.decode(value);
      const lines = chunk.split('\n\n');

      for (const line of lines) {
        if (line.startsWith('data: ')) {
          const data = line.slice(6);
          if (data === '[DONE]') {
            setLoading(false);
            break;
          }

          try {
            const parsed = JSON.parse(data);
            if (parsed.chunk) {
              setOutput(prev => prev + parsed.chunk);
            } else if (parsed.event === 'done') {
              console.log('Execution complete:', parsed.metadata);
            }
          } catch (e) {
            // Пропустить невалидный JSON
          }
        }
      }
    }
  };

  return (
    <div>
      <button onClick={executeStreaming} disabled={loading}>
        {loading ? 'Generating...' : 'Start Streaming'}
      </button>
      <div style={{ whiteSpace: 'pre-wrap' }}>{output}</div>
    </div>
  );
}

Получение вашего API-ключа

Перейдите на AACFlow и войдите в свой аккаунт.

Перейдите к рабочему процессу, который вы хотите выполнить программно.

Нажмите "Deploy", чтобы развернуть ваш рабочий процесс, если он еще не развернут.

Во время процесса развертывания выберите или создайте API-ключ.

Скопируйте API-ключ для использования в вашем TypeScript/JavaScript приложении.

Требования

  • Node.js 16+
  • TypeScript 5.0+ (для TypeScript проектов)

Лицензия

Apache-2.0

Common Questions

On this page

Начните создавать сегодня
Нам доверяют более 100 000 разработчиков.
SaaS-платформа для создания AI-агентов и управления агентным workforce.
Начать