SDKs et Bibliothèques Client

SDKs officiels et bibliothèques client pour l’intégration avec la plateforme TeamDay.

Vue d’Ensemble

TeamDay fournit des bibliothèques client pour construire des applications sur la plateforme. Tous les SDKs utilisent Firebase comme couche de transport sous-jacente avec Firestore pour les données en temps réel et Firebase Auth pour l’authentification.

SDKStatutLangageCas d’Usage
JavaScript/TypeScript SDK✅ ProductionTypeScriptApplications web (Nuxt/Vue)
REST API🚧 PlanifiéN/AIntégrations côté serveur
Python SDK📋 RoadmapPythonScripts, automatisation
CLI Tool✅ ProductionTypeScriptWorkflow de développement

JavaScript/TypeScript SDK

Le SDK principal est construit avec des composables Vue 3 et fonctionne parfaitement avec les applications Nuxt 3.

Installation

# Using bun (recommended)
bun add firebase firebase/firestore

# Using npm
npm install firebase

Configuration

// nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    public: {
      firebase: {
        apiKey: process.env.NUXT_PUBLIC_FIREBASE_API_KEY,
        authDomain: process.env.NUXT_PUBLIC_FIREBASE_AUTH_DOMAIN,
        projectId: process.env.NUXT_PUBLIC_FIREBASE_PROJECT_ID,
        storageBucket: process.env.NUXT_PUBLIC_FIREBASE_STORAGE_BUCKET,
        messagingSenderId: process.env.NUXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID,
        appId: process.env.NUXT_PUBLIC_FIREBASE_APP_ID,
      }
    }
  }
})

Composables Principaux

Authentification - useAuth()

Gère l’authentification utilisateur et l’état de session.

const {
  user,           // Current user (reactive)
  loading,        // Auth state loading
  signInWithGoogle,
  signInWithGitHub,
  signOut
} = useAuth()

// Check if user is authenticated
if (user.value) {
  console.log('User ID:', user.value.uid)
  console.log('Email:', user.value.email)
}

// Sign in with Google
await signInWithGoogle()

// Sign out
await signOut()

Méthodes Disponibles:

  • signInWithGoogle() - OAuth avec Google
  • signInWithGitHub() - OAuth avec GitHub
  • signInWithEmail(email, password) - Authentification email/mot de passe
  • signOut() - Déconnexion de l’utilisateur actuel

Organisations - useOrganizations()

Gérer les organisations et les appartenances d’équipe.

const {
  organizations,           // Array of user's organizations
  loading,
  error,
  fetchUserOrganizations,
  getOrganization,
  createOrganization,
  updateOrganization
} = useOrganizations()

// Fetch user's organizations
await fetchUserOrganizations()

// Get specific organization
const org = await getOrganization('org_id')

// Create new organization
const newOrg = await createOrganization('Acme Corp')

// Update organization
await updateOrganization('org_id', {
  name: 'Acme Corporation',
  logoUrl: 'https://...'
})

Type Organization:

interface Organization {
  id: string
  name: string
  logoUrl?: string
  ownerId: string
  members: string[]
  subscription?: {
    tier: 'free' | 'pro' | 'enterprise'
    status: 'active' | 'cancelled' | 'expired'
  }
  createdAt: Date
  updatedAt: Date
}

Espaces - useSpaces()

Gérer les espaces de travail où les agents opèrent.

const {
  spaces,              // Array of spaces (reactive, real-time)
  chats,               // Chats in current space
  loading,
  error,
  fetchSpaces,
  createSpace,
  updateSpace,
  deleteSpace,
  initializeSpace
} = useSpaces()

// Subscribe to real-time updates
fetchSpaces('org_id')

// Create a new space
const space = await createSpace(
  'org_id',
  'Marketing Workspace',
  'Space for marketing team',
  'organization',  // visibility
  'https://cover-image.jpg'
)

// Update space
await updateSpace('space_id', {
  name: 'Updated Name',
  description: 'Updated description'
})

// Initialize workspace (creates file system)
await initializeSpace('space_id', {
  type: 'empty'  // or 'git', 'readme', 'starterKit'
})

// Soft delete (can be restored)
await softDeleteSpace('space_id')

// Restore deleted space
await restoreSpace('space_id')

// Permanent delete
await deleteSpace('space_id')

Type Space:

interface Space {
  id: string
  organizationId: string
  name: string
  description: string
  visibility: 'private' | 'organization' | 'public'
  ownerId: string
  assignedAgents?: string[]       // Character IDs
  skillIds?: string[]             // Skill IDs
  pluginIds?: string[]            // Plugin IDs
  chatCount?: number
  fileCount?: number
  createdAt: Date
  updatedAt: Date
}

Characters (Agents) - useCharacters()

Gérer les agents/assistants IA.

const {
  characters,          // Array of characters (reactive, real-time)
  loading,
  error,
  fetchCharacters,
  createCharacter,
  getCharacter,
  updateCharacter,
  deleteCharacter
} = useCharacters()

// Subscribe to real-time updates
fetchCharacters('org_id')

// Create a new agent
const agent = await createCharacter(
  'org_id',
  'Marketing Maven',
  'Marketing Assistant',
  'You are an expert marketing assistant...',
  'organization'  // visibility
)

// Get specific character
const character = await getCharacter('char_id')

// Update character
await updateCharacter('char_id', {
  name: 'Updated Name',
  systemPrompt: 'Updated prompt...',
  skillIds: ['research-assistant', 'technical-writer'],
  advanced_tools: ['mcp_google_analytics']
})

// Soft delete
await softDeleteCharacter('char_id')

// Restore
await restoreCharacter('char_id')

// Archive (soft delete alternative)
await deleteCharacter('char_id')

Type Character:

interface Character {
  id: string
  name: string
  role: string
  initialGreeting: string
  system_message: string
  image: string
  color: string
  model?: string
  visibility: 'private' | 'organization' | 'public' | 'unlisted'
  ownerId: string
  organizationId?: string
  skillIds?: string[]
  advanced_tools?: string[]
  tags?: string[]
  archived?: boolean
  createdAt: Date
}

Chats - useChatCrud()

Gérer les conversations avec les agents.

const {
  chats,               // Array of chats (reactive, real-time)
  loading,
  error,
  fetchChats,
  createChat,
  getChat,
  updateChat,
  deleteChat,
  toggleChatClosed
} = useChatCrud()

// Fetch chats for a space
await fetchChats('org_id', 'space_id')

// Create new chat
const chat = await createChat('org_id', 'space_id', 'New Conversation')

// Get specific chat
const chat = await getChat('chat_id')

// Update chat
await updateChat('chat_id', {
  title: 'Updated Title',
  status: 'done'
})

// Toggle closed state
await toggleChatClosed('chat_id')

// Delete chat
await deleteChat('chat_id')

Type Chat:

interface Chat {
  id: string
  organizationId: string
  spaceId: string
  title: string
  subtitle?: string
  status: 'standby' | 'working' | 'done' | 'needs_attention' | 'error'
  ownerId: string
  lastMessage?: string
  sessionId?: string
  closed: boolean
  closedAt?: Date | null
  createdAt: Date
  updatedAt: Date
}

Skills - useSkills()

Gérer les packages de prompts réutilisables.

const {
  skills,              // Array of skills
  loading,
  error,
  fetchSkills,
  createSkill,
  updateSkill,
  deleteSkill
} = useSkills()

// Fetch skills for organization
await fetchSkills('org_id')

// Create a skill
const skill = await createSkill({
  name: 'custom-researcher',
  displayName: 'Custom Researcher',
  description: 'Custom research skill',
  prompt: '# Research Skill\n\nInstructions...',
  category: 'research',
  builtInTools: ['WebSearch', 'Read'],
  visibility: 'organization',
  organizationId: 'org_id',
  ownerId: 'user_id'
})

// Update skill
await updateSkill('skill_id', {
  displayName: 'Updated Name',
  prompt: 'Updated instructions...'
})

// Delete skill
await deleteSkill('skill_id')

Type Skill:

interface Skill {
  id: string
  name: string                    // kebab-case
  displayName: string
  description: string
  prompt: string                  // Markdown instructions
  category: 'research' | 'writing' | 'data' | 'code' | 'marketing' | 'productivity' | 'file-handling' | 'other'
  builtInTools?: string[]
  requiredMCPs?: string[]
  visibility: 'private' | 'organization' | 'public'
  organizationId: string
  ownerId: string
  version: number
  createdAt: Date
}

Missions - useMissions()

Gérer les tâches autonomes de longue durée.

const {
  missions,            // Array of missions
  loading,
  error,
  fetchMissions,
  createMission,
  updateMission,
  pauseMission,
  resumeMission
} = useMissions()

// Fetch missions
await fetchMissions('org_id')

// Create mission
const mission = await createMission({
  title: 'Daily Report',
  goal: 'Generate daily analytics report',
  agentType: 'claude',
  schedule: {
    type: 'cron',
    value: '0 9 * * *'  // Every day at 9 AM
  },
  organizationId: 'org_id',
  userId: 'user_id'
})

// Update mission
await updateMission('mission_id', {
  status: 'paused'
})

// Pause/Resume
await pauseMission('mission_id')
await resumeMission('mission_id')

Abonnements en Temps Réel

Tous les composables de données fournissent des mises à jour en temps réel en utilisant onSnapshot de Firestore.

Cycle de Vie des Abonnements

const { fetchSpaces, unsubscribeSpaces } = useSpaces()

// Start subscription
fetchSpaces('org_id')

// Data updates automatically when Firestore changes
watch(spaces, (newSpaces) => {
  console.log('Spaces updated:', newSpaces.length)
})

// Cleanup on unmount
onUnmounted(() => {
  unsubscribeSpaces()
})

Nettoyage Automatique

Les composables gèrent le nettoyage automatiquement dans la plupart des cas:

// This automatically cleans up on component unmount
const { spaces } = useSpaces()
fetchSpaces('org_id')

Gestion des Erreurs

Tous les composables suivent un modèle d’erreur cohérent:

const { error, loading } = useSpaces()

// Check loading state
if (loading.value) {
  console.log('Loading...')
}

// Check for errors
if (error.value) {
  console.error('Error:', error.value)
}

// Try-catch for explicit operations
try {
  await createSpace(...)
} catch (err) {
  console.error('Failed to create space:', err)
}

Support TypeScript

Tous les types sont entièrement typés avec TypeScript:

import type { Space, Character, Skill, Chat } from '~/types'

const space: Space = await getSpace('space_id')
const character: Character = await getCharacter('char_id')

Exports de Types:

// From ~/types/space
export type { Space, Chat, ChatMessage, SpaceVisibility }

// From ~/types/character
export type { Character, CharacterVisibility }

// From ~/types/skill
export type { Skill, SkillCategory, SkillVisibility }

// From ~/types/mission
export type { Mission, MissionStatus, AgentType }

// From ~/types/task
export type { Task, TaskStatus, TaskPriority }

// From ~/types/execution
export type { Execution, ExecutionStatus }

Points de Terminaison de l’API Serveur

TeamDay fournit des points de terminaison d’API côté serveur pour les opérations nécessitant des permissions élevées.

URL de Base

Production: https://us.teamday.ai/api
Development: http://localhost:3000/api

Authentification

Utilisez les tokens ID Firebase pour l’authentification:

const idToken = await user.value?.getIdToken()

const response = await fetch('/api/endpoint', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${idToken}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(data)
})

Points de Terminaison Disponibles

Initialisation d’Espace

POST /api/spaces/:spaceId/init
Content-Type: application/json

{
  "type": "empty",      // or "git", "readme", "starterKit"
  "orgId": "org_id",
  "spaceName": "Workspace Name"
}

Variables d’Environnement d’Espace

POST /api/spaces/:spaceId/environment
Content-Type: application/json

{
  "environmentVariables": {
    "API_KEY": "encrypted_value",
    "DATABASE_URL": "encrypted_value"
  }
}

Exécution d’Agent

POST /api/agent/execute
Content-Type: application/json

{
  "characterId": "char_id",
  "spaceId": "space_id",
  "message": "User message",
  "sessionId": "session_id"
}

Analytiques d’Utilisation

GET /api/usage/organization/:orgId?period=daily&start=2024-01-01&end=2024-01-31
Authorization: Bearer <id_token>

Outil CLI

L’outil CLI TeamDay fournit des commandes de workflow de développement.

Installation

# Using bun
bun add -g @teamday/cli

# Using npm
npm install -g @teamday/cli

Authentification

# Login via browser OAuth
teamday login

# Verify authentication
teamday whoami

Commandes

# Initialize a new space
teamday space init

# Deploy an agent
teamday agent deploy ./agent-config.json

# Run a mission locally
teamday mission run mission_id

# Tail agent logs
teamday logs --follow --space space_id

# Manage environment variables
teamday env set API_KEY=value
teamday env list

Configuration

Créez .teamdayrc.json dans votre projet:

{
  "organizationId": "org_abc123",
  "defaultSpace": "space_456",
  "region": "us-central1"
}

Bonnes Pratiques

1. Toujours Nettoyer les Abonnements

const unsubscribe = ref<Unsubscribe | null>(null)

const subscribe = () => {
  if (unsubscribe.value) {
    unsubscribe.value()
  }

  unsubscribe.value = onSnapshot(query, callback)
}

onUnmounted(() => {
  if (unsubscribe.value) {
    unsubscribe.value()
  }
})

2. Gérer les Valeurs Undefined

Firestore n’autorise pas undefined. Utilisez toujours null ou omettez:

// ❌ Bad
await updateDoc(docRef, {
  optional: undefined
})

// ✅ Good
const cleanData = Object.fromEntries(
  Object.entries(data).filter(([_, v]) => v !== undefined)
)
await updateDoc(docRef, cleanData)

3. Utiliser les Server Timestamps

import { serverTimestamp } from 'firebase/firestore'

await updateDoc(docRef, {
  updatedAt: serverTimestamp()
})

4. Mises à Jour Optimistes

Pour une meilleure UX, affichez les changements immédiatement:

// Add optimistically
optimisticSpaces.value.push(newSpace)

// Then persist
await addDoc(collection, spaceData)

// Snapshot updates with real data

5. Limites d’Erreur

Enveloppez les opérations dans try-catch:

try {
  await createSpace(...)
} catch (error) {
  console.error('Operation failed:', error)
  // Show user-friendly error message
  toast.error('Failed to create space')
}

Migration de v1 vers v2

Changements Importants

Authentification:

  • Changé de JWT personnalisé vers Firebase Auth
  • Mise à jour: Remplacez useAuthToken() par useAuth()

Composables:

  • Renommé useAgents() en useCharacters()
  • Supprimé le champ skills inline, utilisez skillIds à la place

Types:

  • Agent renommé en Character
  • Champ systemPrompt renommé en system_message

Guide de Migration

// v1
const { agents } = useAgents()

// v2
const { characters } = useCharacters()

// v1
const agent = {
  systemPrompt: 'You are...',
  skills: [{ name: 'research', instructions: '...' }]
}

// v2
const character = {
  system_message: 'You are...',
  skillIds: ['research-assistant']
}

Compatibilité des Versions

Version TeamDayVersion SDKFirebase SDKVersion Nuxt
1.0.x1.0.x^10.7.0^3.9.0
2.0.x2.0.x^10.12.0^3.13.0

Exemples

Configuration Complète d’Espace de Travail

<script setup lang="ts">
const { user } = useAuth()
const { organizations, fetchUserOrganizations } = useOrganizations()
const { createSpace, fetchSpaces, spaces } = useSpaces()
const { createCharacter, fetchCharacters } = useCharacters()

// On mount, fetch user's organizations
onMounted(async () => {
  await fetchUserOrganizations()

  if (organizations.value.length > 0) {
    const orgId = organizations.value[0].id

    // Subscribe to spaces and characters
    fetchSpaces(orgId)
    fetchCharacters(orgId)
  }
})

// Create a complete workspace
const setupWorkspace = async () => {
  const orgId = organizations.value[0].id

  // 1. Create space
  const space = await createSpace(
    orgId,
    'My Workspace',
    'A workspace for my team',
    'organization'
  )

  // 2. Create agent
  const agent = await createCharacter(
    orgId,
    'Research Assistant',
    'Researcher',
    'You are an expert researcher...',
    'organization'
  )

  // 3. Assign agent to space
  if (space && agent) {
    await updateSpace(space.id, {
      assignedAgents: [agent.id]
    })
  }

  console.log('Workspace ready!')
}
</script>

Chat en Temps Réel

<script setup lang="ts">
const { chats, fetchChats } = useChatCrud()
const route = useRoute()

const spaceId = route.params.spaceId as string
const orgId = route.params.orgId as string

// Subscribe to chats in this space
fetchChats(orgId, spaceId)

// Watch for new messages
watch(chats, (newChats) => {
  const latestChat = newChats[0]
  if (latestChat?.status === 'done') {
    console.log('Agent finished:', latestChat.lastMessage)
  }
})
</script>

Support


Roadmap

Q1 2025

  • ✅ JavaScript/TypeScript SDK
  • ✅ CLI Tool
  • 🚧 REST API (beta)

Q2 2025

  • 📋 Python SDK
  • 📋 Abonnements webhook
  • 📋 GraphQL API

Q3 2025

  • 📋 Go SDK
  • 📋 SDKs mobiles (React Native)
  • 📋 API streaming pour la sortie d’agent en temps réel

Contribuer

Nous accueillons les contributions! Consultez notre Guide de Contribution pour plus de détails.

Configuration de Développement

# Clone the repository
git clone https://github.com/TeamDay-AI/teamday.git
cd teamday

# Install dependencies
bun install

# Start development server
bun run dev

# Run tests
bun test

Licence

Le SDK TeamDay est publié sous la licence MIT. Consultez LICENSE pour plus de détails.