@superfasttt/sdk
v1.0.0
Published
SDK TypeScript pour interagir avec l'API SUPERFASTTT
Readme
@superfasttt/sdk
SDK TypeScript pour la plateforme SUPERFASTTT. Fournit un client API type, l'authentification OAuth2, et des hooks React.
Installation
pnpm add @superfasttt/sdkPeer dependency optionnelle :
pnpm add react # uniquement si vous utilisez les hooks ReactQuick Start
React
import { SuperfastttProvider, useAuth, useApi } from "@superfasttt/sdk/react"
function App({ children }: { children: React.ReactNode }) {
return (
<SuperfastttProvider
appId="my-app"
apiUrl={process.env.NEXT_PUBLIC_API_URL!}
authUrl={process.env.NEXT_PUBLIC_AUTH_URL!}
publicRoutes={["/auth/callback"]}
>
{children}
</SuperfastttProvider>
)
}
function Dashboard() {
const { user, logout } = useAuth()
const api = useApi()
const loadModels = async () => {
const models = await api.llm.listModels({ mode: "chat" })
}
return (
<div>
<p>Bonjour {user?.full_name}</p>
<button onClick={logout}>Deconnexion</button>
<button onClick={loadModels}>Charger les modeles</button>
</div>
)
}Standalone (sans React)
import { createAuthClient } from "@superfasttt/sdk/auth"
import { createSuperfastttApi } from "@superfasttt/sdk/api"
const auth = createAuthClient({
apiUrl: "http://localhost:8001",
authUrl: "http://localhost:3004",
clientId: "my-app",
})
const api = createSuperfastttApi(auth.fetch.bind(auth), "http://localhost:8001")
const models = await api.llm.listModels({ mode: "chat" })
const memories = await api.memories.list()Server-to-Server (API Key)
import { createApiKeyClient } from "@superfasttt/sdk/api"
const sf = createApiKeyClient({
apiUrl: "https://api.superfasttt.ai",
apiKey: "sk-xxxxx",
})
const answer = await sf.ragChat.query({
question: "Quelle est la politique de conges ?",
memory_ids: ["mem-123"],
})
const models = await sf.llm.listModels({ mode: "chat" })Entry Points
Le SDK expose 4 entry points, chacun disponible en CJS, ESM et avec les types :
| Import | Contenu |
|--------|---------|
| @superfasttt/sdk | Re-export global (auth + apps + react + factory API) |
| @superfasttt/sdk/auth | createAuthClient, types auth, utilitaires token |
| @superfasttt/sdk/react | Provider, hooks React, guards |
| @superfasttt/sdk/api | createSuperfastttApi, modules API, erreurs, types |
Authentification
createAuthClient
import { createAuthClient } from "@superfasttt/sdk/auth"
const auth = createAuthClient({
apiUrl: "https://api.superfasttt.ai",
authUrl: "https://auth.superfasttt.ai",
clientId: "my-app",
// Optionnel :
storagePrefix: "superfasttt", // prefix localStorage (defaut: "superfasttt")
refreshThreshold: 300, // secondes avant expiration pour refresh (defaut: 300)
callbackPath: "/auth/callback", // path OAuth2 callback (defaut: "/auth/callback")
})Methodes AuthClient
| Methode | Description |
|---------|-------------|
| isAuthenticated() | Verifie si le token est valide et non expire |
| getToken() | Retourne le token d'acces courant |
| getUser() | Retourne l'utilisateur decode du token (AuthUser) |
| setTokens(tokens) | Stocke les tokens (avec validation tenant) |
| clearTokens() | Supprime tous les tokens du localStorage |
| redirectToLogin(returnPath?) | Redirige vers la page de login OAuth2 |
| authenticate(returnPath?) | Tente SSO silencieux, sinon redirige vers login |
| trySilentAuth(returnPath?) | Tente le SSO silencieux avec un refresh token existant |
| exchangeCode(code, redirectUri) | Echange un code d'autorisation contre des tokens |
| refreshAccessToken() | Rafraichit le token d'acces |
| getValidToken() | Retourne un token valide, en rafraichissant si necessaire |
| fetch(url, options?) | Fetch authentifie avec retry auto sur 401 |
| logout() | Supprime les tokens et redirige vers le endpoint de logout |
Flow OAuth2
1. User accede a l'app
2. AuthProvider detecte l'absence de token
3. Tentative de SSO silencieux (trySilentAuth)
4. Si echec → redirection vers auth.superfasttt.ai/login
5. Login reussi → redirection vers /auth/callback?code=xxx&state=yyy
6. exchangeCode(code, redirectUri) → TokenPair stocke en localStorage
7. Refresh automatique quand le token expire bientotTypes Auth
interface AuthUser {
user_id: string
email: string
full_name?: string
tenant_id: string
role: string
}
interface TokenPair {
access_token: string
refresh_token: string
token_type: string
expires_in: number
}
interface AuthConfig {
apiUrl: string
authUrl: string
clientId: string
storagePrefix?: string
refreshThreshold?: number
callbackPath?: string
}Client API
createSuperfastttApi
Factory qui cree un client API type avec tous les modules :
import { createSuperfastttApi } from "@superfasttt/sdk/api"
const api = createSuperfastttApi(authFetch, apiUrl)authFetch est une fonction (url: string, options?: RequestInit) => Promise<Response> — fournie par useAuth().authFetch ou auth.fetch.bind(auth).
Les 16 modules
| Module | Propriete | Description |
|--------|-----------|-------------|
| LLM | api.llm | Modeles, chat, images, audio, providers |
| Conversations | api.conversations | CRUD conversations et messages |
| Memories | api.memories | Bases de connaissances (CRUD) |
| Documents | api.documents | Upload, indexation, recherche de documents |
| RAG Chat | api.ragChat | Requetes RAG et Multi-RAG |
| Recordings | api.recordings | Enregistrements audio et workflows CR |
| Workflows | api.workflows | CRUD workflows, execution, versions, partage |
| Projects | api.projects | CRUD projets |
| Meetings | api.meetings | CRUD reunions et audio |
| Users | api.users | Gestion des utilisateurs |
| Budgets | api.budgets | Statut budget et gestion des limites |
| Tenant Keys | api.tenantKeys | Credentials des providers LLM |
| Webhooks | api.webhooks | Gestion des secrets webhook |
| Settings | api.settings | Parametres tenant et modeles par defaut |
| Providers | api.providers | Health checks des providers LLM |
| Apps | api.apps | Gestion des apps tierces |
Exemples par module
LLM — Chat et modeles
// Lister les modeles de chat disponibles
const models = await api.llm.listModels({ mode: "chat" })
// Lister tous les providers
const providers = await api.llm.listProviders()
// Chat completion
const response = await api.llm.chat({
model: "gpt-4o",
messages: [
{ role: "system", content: "Tu es un assistant utile." },
{ role: "user", content: "Bonjour !" },
],
temperature: 0.7,
})
// Generation d'images
const images = await api.llm.generateImage({
model: "dall-e-3",
prompt: "Un paysage de montagne au coucher du soleil",
size: "1024x1024",
})
// Transcription audio
const transcription = await api.llm.transcribeAudio({
model: "whisper-1",
audio_url: "https://example.com/audio.mp3",
})Documents — Upload et recherche
// Upload un document dans une base de connaissances
const doc = await api.documents.upload(file, memoryId)
// Lister les documents d'une base
const docs = await api.documents.list({ memory_id: memoryId })
// Recherche semantique
const results = await api.documents.query({
query: "politique de remboursement",
memory_ids: [memoryId],
top_k: 5,
})RAG Chat — Questions sur des documents
// Question simple sur une base de connaissances
const answer = await api.ragChat.query({
question: "Quelle est la politique de conges ?",
memory_ids: [memoryId],
model_id: "gpt-4o",
})
// Multi-RAG (recherche sur plusieurs bases avec @mentions)
const multiAnswer = await api.ragChat.multiRagQuery({
message: "Compare les politiques de @RH et @Finance",
model_id: "gpt-4o",
})Workflows — Automatisation
// Creer un workflow
const workflow = await api.workflows.create({
name: "Mon workflow",
description: "Traitement automatique des documents",
})
// Executer un workflow
const execution = await api.workflows.execute(workflow.id, {
input_data: { document_id: "abc-123" },
})
// Suivre l'execution
const status = await api.workflows.getExecutionStatus(execution.execution_id)
const logs = await api.workflows.getExecutionLogs(execution.execution_id)API Keys (Server-to-Server)
createApiKeyClient permet aux entreprises clientes d'appeler l'API SUPERFASTTT depuis leur propre backend sans authentification OAuth2.
Obtenir une API Key
Les API Keys se creent depuis le dashboard SUPERFASTTT : Parametres > API Keys > Creer une cle.
Chaque cle est liee a un utilisateur. Les depenses LLM sont imputees au budget de cet utilisateur.
Chaque cle donne acces a tous les endpoints disponibles via API Key (LLM, RAG, documents, memories). La securite est assuree par l'isolation tenant : chaque cle ne peut acceder qu'aux donnees de son propre tenant.
Rate Limiting
| Type | Limite | |------|--------| | Lecture | 120 requetes/min | | Ecriture | 60 requetes/min | | AI (LLM, RAG) | 30 requetes/min |
Usage
import { createApiKeyClient } from "@superfasttt/sdk/api"
const sf = createApiKeyClient({
apiUrl: "https://api.superfasttt.ai",
apiKey: process.env.SUPERFASTTT_API_KEY!,
})
// RAG — poser une question sur une base de connaissances
const answer = await sf.ragChat.query({
question: "Quelle est la politique de conges ?",
memory_ids: ["mem-123"],
model_id: "gpt-4o-mini",
})
// LLM — lister les modeles disponibles
const models = await sf.llm.listModels({ mode: "chat" })
// Documents — lister les documents d'une base
const docs = await sf.documents.list({ memory_id: "mem-123" })Modeles LLM multi-provider
Le SDK interagit avec tous les providers LLM via le proxy LiteLLM. Utilisez listModels pour decouvrir dynamiquement les modeles disponibles sur votre instance :
// Tous les modeles de chat
const chatModels = await api.llm.listModels({ mode: "chat" })
// Filtrer par provider
const openaiModels = await api.llm.listModels({ provider: "openai" })
// Modeles d'embedding
const embeddingModels = await api.llm.listModels({ mode: "embedding" })
// Modeles de generation d'images
const imageModels = await api.llm.listModels({ mode: "image_generation" })Providers supportes : OpenAI, Anthropic, Mistral, Google (Gemini), Ollama, Cohere, Azure OpenAI, et tout provider compatible LiteLLM.
Streaming SSE
Les modules llm et ragChat supportent le streaming via Server-Sent Events :
// Chat streaming
for await (const event of api.llm.chatStream({
model: "gpt-4o",
messages: [{ role: "user", content: "Raconte une histoire" }],
})) {
const chunk = JSON.parse(event.data)
process.stdout.write(chunk.choices[0]?.delta?.content || "")
}
// RAG streaming
for await (const event of api.ragChat.queryStream({
question: "Resume ce document",
memory_ids: [memoryId],
})) {
const chunk = JSON.parse(event.data)
// Traiter le chunk
}Annulation avec AbortController
const controller = new AbortController()
// Annuler apres 10 secondes
setTimeout(() => controller.abort(), 10_000)
try {
for await (const event of api.llm.chatStream(request, {
signal: controller.signal,
})) {
// ...
}
} catch (err) {
if (err instanceof DOMException && err.name === "AbortError") {
// Stream annule
}
}React Hooks
Tous les hooks sont importes depuis @superfasttt/sdk/react.
useApi
Client API type et memoize. C'est le hook principal pour interagir avec l'API.
import { useApi } from "@superfasttt/sdk/react"
function MyComponent() {
const api = useApi()
const loadData = async () => {
const models = await api.llm.listModels({ mode: "chat" })
const memories = await api.memories.list()
const docs = await api.documents.list({ memory_id: "xxx" })
}
}useAuth
Acces a l'etat d'authentification et aux actions.
import { useAuth } from "@superfasttt/sdk/react"
function UserMenu() {
const { user, isAuthenticated, isLoading, logout, authFetch, login } = useAuth()
if (isLoading) return <p>Chargement...</p>
if (!isAuthenticated) return <button onClick={() => login()}>Connexion</button>
return (
<div>
<p>{user!.email} ({user!.role})</p>
<button onClick={logout}>Deconnexion</button>
</div>
)
}useSuperfasttt
Client SDK bas niveau avec fetch et fetchJson authentifies.
import { useSuperfasttt } from "@superfasttt/sdk/react"
function MyComponent() {
const { apiUrl, appId, fetch, fetchJson } = useSuperfasttt()
const loadData = async () => {
// fetchJson gere Content-Type et parsing JSON
const data = await fetchJson<MyType>("/api/v1/my-endpoint")
}
}useProviderHealth
Monitoring de la sante des providers LLM.
import { useProviderHealth } from "@superfasttt/sdk/react"
function ModelSelector() {
const {
hasProviderIssue,
getProviderWarning,
providersWithIssues,
hasAnyIssue,
refresh,
} = useProviderHealth({
refreshInterval: 60000, // 1 minute
})
return (
<div>
{hasProviderIssue("openai") && (
<span className="text-amber-500">{getProviderWarning("openai")}</span>
)}
</div>
)
}useBudgetStatus
Polling du statut budget de l'utilisateur.
import { useBudgetStatus } from "@superfasttt/sdk/react"
function ChatInput() {
const { canUse, isExceeded, isWarning, usagePercent, message } = useBudgetStatus({
pollingInterval: 10000, // 10 secondes
})
if (isExceeded) return <p>{message}</p>
return <input disabled={!canUse} placeholder="Votre message..." />
}BudgetStatusGuard
Wrapper global qui affiche automatiquement une modale quand le budget est depasse et une banniere d'avertissement.
import { BudgetStatusGuard } from "@superfasttt/sdk/react"
function Layout({ children }: { children: React.ReactNode }) {
return (
<SuperfastttProvider appId="my-app" apiUrl={apiUrl} authUrl={authUrl}>
<BudgetStatusGuard pollingInterval={10000}>
{children}
</BudgetStatusGuard>
</SuperfastttProvider>
)
}Personnalisable via les props exceededModal et warningBanner.
useAppAccess
Verification de l'acces a une app tierce.
import { useAppAccess } from "@superfasttt/sdk/react"
function MyComponent() {
const { hasAccess, permissions, isLoading, isAdmin } = useAppAccess()
if (isLoading) return <p>Verification...</p>
if (!hasAccess) return <p>Acces refuse</p>
return <div>Permissions : {permissions.join(", ")}</div>
}Apps Tierces
Les apps tierces sont des applications installees sur un tenant avec un systeme de permissions granulaire.
AppAccessGuard
Composant qui affiche son contenu uniquement si l'utilisateur a acces a l'app :
import { SuperfastttProvider, AppAccessGuard } from "@superfasttt/sdk/react"
function App({ children }: { children: React.ReactNode }) {
return (
<SuperfastttProvider appId="my-third-party-app" apiUrl={apiUrl} authUrl={authUrl}>
<AppAccessGuard
requiredPermissions={["documents:read"]}
permissionMode="all"
loadingComponent={<MyLoader />}
accessDeniedComponent={<My403Page />}
>
{children}
</AppAccessGuard>
</SuperfastttProvider>
)
}withAppAccess HOC
import { withAppAccess } from "@superfasttt/sdk/react"
function MyProtectedPage() {
return <div>Contenu protege</div>
}
export default withAppAccess(MyProtectedPage, {
requiredPermissions: ["documents:write"],
})Hooks de permissions
import {
useHasPermission,
useHasAllPermissions,
useHasAnyPermission,
} from "@superfasttt/sdk/react"
function AdminPanel() {
const canEdit = useHasPermission("documents:write")
const canAdmin = useHasAllPermissions(["admin:read", "admin:write"])
const canView = useHasAnyPermission(["documents:read", "projects:read"])
if (!canEdit) return null
return <button>Modifier</button>
}Les admins (super_admin, tenant_admin) ont automatiquement toutes les permissions.
Gestion d'erreurs
ApiError
import { ApiError, ApiValidationError } from "@superfasttt/sdk/api"
try {
await api.documents.get("invalid-id")
} catch (err) {
if (err instanceof ApiValidationError) {
// Erreur 422 avec details par champ
for (const detail of err.validationErrors) {
// detail.field, detail.message, detail.type
}
} else if (err instanceof ApiError) {
err.status // Code HTTP
err.message // Message d'erreur
err.code // Code erreur (optionnel)
err.isUnauthorized // 401
err.isForbidden // 403
err.isNotFound // 404
err.isRateLimited // 429
err.isServerError // 5xx
}
}Types exportes
Tous les types sont disponibles via @superfasttt/sdk/api :
| Module | Types principaux |
|--------|-----------------|
| LLM | LLMModel, LLMProvider, ChatRequest, ChatResponse, ChatMessage, ImageGenerationRequest, AudioTranscriptionRequest |
| Conversations | Conversation, ConversationDetail, Message, CreateConversationRequest |
| Memories | Memory, MemoryStats, CreateMemoryRequest |
| Documents | Document, DocumentUploadResponse, DocumentQueryRequest, DocumentChunk |
| RAG Chat | RAGQueryRequest, RAGQueryResponse, RAGSource, MultiRAGRequest, MultiRAGResponse |
| Recordings | Recording, RecordingUploadResponse, CRType |
| Workflows | Workflow, WorkflowExecution, WorkflowExecutionLogs, NodeLog, WorkflowVersion |
| Projects | Project, CreateProjectRequest |
| Meetings | Meeting, MeetingDocument, CreateMeetingRequest |
| Users | User, CreateUserRequest, UserTeam |
| Budgets | BudgetStatus, Budget, UserBudgetLiteLLM |
| Tenant Keys | TenantCredentials, TenantCredentialsStatus |
| Webhooks | WebhookSecret, WebhookLog |
| Settings | DefaultModelsResponse, AppSettingsResponse |
| Providers | ProviderHealthStatus, ProvidersHealthResponse |
| Apps | AppConfig, AppManifest, AppInstallation, SystemPermission |
| Auth | AuthUser, AuthConfig, TokenPair, AuthState |
| Erreurs | ApiError, ApiValidationError, ValidationErrorDetail |
| Base | AuthFetch, SSEEvent, QueryParams, PaginatedResponse, SuccessResponse |
Build
cd packages/sdk
pnpm build # Build CJS + ESM + DTS pour les 4 entry points
pnpm typecheck # Verification des types sans build
pnpm dev # Build en mode watchLe build produit via tsup :
dist/
├── index.js / index.mjs / index.d.ts # @superfasttt/sdk
├── auth/index.js / index.mjs / index.d.ts # @superfasttt/sdk/auth
├── react/index.js / index.mjs / index.d.ts # @superfasttt/sdk/react
└── api/index.js / index.mjs / index.d.ts # @superfasttt/sdk/api