Framework-agnostic HTTP client and types for Hiyve Cloud AI services. Works with any JavaScript runtime -- Node.js, browsers, Deno, or edge functions. For React applications, use @hiyve/react-intelligence which wraps this package with React context and hooks.
npm install @hiyve/cloud
import { CloudClient } from '@hiyve/cloud';
// Create a client with a token generator (most common pattern)
const client = new CloudClient({
generateCloudToken: async () => {
const res = await fetch('/api/generate-cloud-token', { method: 'POST' });
const data = await res.json();
return data.cloudToken;
},
});
// AI query
const response = await client.query('Summarize the discussion', {
userId: 'user@example.com',
roomName: 'team-standup',
});
console.log(response.content);
// Generate a meeting summary
const summary = await client.getSummary(transcript, {
userId: 'user@example.com',
maxLength: 500,
});
// Extract action items
const items = await client.getActionItems(transcript, {
userId: 'user@example.com',
});
CloudClient requires either a cloudToken or a generateCloudToken function. Tokens are generated lazily on first request and automatically refreshed when expired.
Provide a function that fetches a cloud token from your backend. Tokens are generated lazily on first request and automatically refreshed when expired. When your server uses @hiyve/admin middleware, your endpoint can delegate to the built-in token route.
const client = new CloudClient({
generateCloudToken: async () => {
const res = await fetch('/api/generate-cloud-token', { method: 'POST' });
return (await res.json()).cloudToken;
},
});
A pre-generated short-lived token (prefixed ct_). Obtain from your backend by calling POST https://api.hiyve.dev/cloud-token with your API key.
const client = new CloudClient({
cloudToken: 'ct_abc123...',
});
You can update the token later with client.setCloudToken(newToken) or force a refresh with client.clearToken().
new CloudClient(config: CloudConfig)
| Option | Type | Default | Description |
|---|---|---|---|
cloudToken |
string |
- | Pre-generated cloud token |
generateCloudToken |
(params) => Promise<CloudTokenResponse> |
- | Token generator function |
userId |
string |
- | User email for token generation. Required when using generateCloudToken |
environment |
'production' | 'development' |
'production' |
Target environment |
baseUrl |
string |
- | Custom API URL (overrides environment) |
timeout |
number |
30000 |
Request timeout in milliseconds |
presence |
boolean | { intervalMs?: number } |
false |
Enable automatic presence heartbeat. true uses 10s interval; pass { intervalMs } to customize |
| Method | Description |
|---|---|
setCloudToken(token) |
Update the cached cloud token |
clearToken() |
Clear cached token, forcing re-generation on next request |
setUserId(userId) |
Set or change the current user's email. Forces a token refresh on next request |
query(text, options): Promise<AIResponse>Send a general AI query.
const response = await client.query('What were the key takeaways?', {
userId: 'user@example.com',
roomName: 'team-standup',
model: 'gpt-4o-mini',
systemPrompt: 'You are a meeting analyst.',
context: 'Additional context here...',
});
console.log(response.content);
getSummary(transcript, options): Promise<string>Generate a summary from a transcript.
const summary = await client.getSummary(transcript, {
userId: 'user@example.com',
maxLength: 200,
});
getActionItems(transcript, options): Promise<ActionItem[]>Extract action items from a transcript.
const items = await client.getActionItems(transcript, {
userId: 'user@example.com',
});
items.forEach(item => {
console.log(`[${item.priority}] ${item.action} (${item.category})`);
});
enhanceNote(text, options): Promise<string>Enhance or polish text content.
const enhanced = await client.enhanceNote(roughNotes, {
userId: 'user@example.com',
style: 'professional', // 'professional' | 'casual' | 'academic' etc.
});
queryResponse(responseId, userId, query, options?): Promise<AIResponse>Query against accumulated meeting context identified by a response ID.
const response = await client.queryResponse(
'resp_abc123',
'user@example.com',
'Summarize the first 10 minutes.'
);
pushMoodToResponse(responseId, userId, sentimentContext): Promise<{ responseId: string }>Push mood data to a specific response context.
await client.pushMoodToResponse('resp_abc123', 'user@example.com', [
{ participant: 'user@example.com', sentiment: 'positive', confidence: 0.9 },
]);
getAlertSettings(roomId): Promise<AlertSettings>Retrieve alert settings for a room.
updateAlertSettings(roomId, settings): Promise<AlertSettings>Update alert settings for a room.
const updated = await client.updateAlertSettings('room-123', {
enabled: true,
audioAlerts: false,
categories: {
action_item: { enabled: true, sensitivity: 'high', minConfidence: 0.6 },
},
});
getAlertHistory(roomId, options?): Promise<MeetingAlert[]>Retrieve alert history with optional filtering.
const alerts = await client.getAlertHistory('room-123', {
limit: 50,
priority: 'high',
type: 'action_item',
since: '2024-01-01T00:00:00Z',
});
acknowledgeAlert(alertId, note?): Promise<MeetingAlert>Acknowledge a meeting alert.
await client.acknowledgeAlert('alert-456', 'Reviewed and assigned to team.');
createMeeting(options): Promise<Meeting>Create a scheduled meeting.
const meeting = await client.createMeeting({
title: 'Weekly Standup',
startTime: new Date('2024-06-01T09:00:00Z'),
endTime: new Date('2024-06-01T09:30:00Z'),
timezone: 'America/New_York',
participants: [
{ email: 'john@example.com', name: 'John', role: 'organizer' },
{ email: 'jane@example.com', name: 'Jane', role: 'attendee' },
],
recurrence: { pattern: 'weekly', interval: 1 },
});
getMeetings(options?): Promise<Meeting[]>List meetings with optional filters.
const meetings = await client.getMeetings({ limit: 20, status: 'scheduled' });
getMeeting(meetingId): Promise<Meeting>Get details for a specific meeting.
updateMeeting(meetingId, updates): Promise<Meeting>Update a meeting.
await client.updateMeeting('meeting-123', { title: 'Updated Standup' });
cancelMeeting(meetingId): Promise<void>Cancel a meeting.
sendMeetingNotification(meetingId, type?): Promise<void>Send a notification to meeting participants.
await client.sendMeetingNotification('meeting-123', 'reminder');
// type: 'reminder' | 'invitation' | 'update' | 'cancellation'
Semantic search across meeting transcriptions and documents.
search(query, options?): Promise<SearchResults>Search across all sources.
const results = await client.search('budget discussion', {
userId: 'user@example.com',
roomNames: ['team-standup'],
limit: 10,
threshold: 0.6,
});
results.results.forEach(r => {
console.log(`[${r.source}] ${r.content} (score: ${r.similarity})`);
});
searchTranscriptions(query, options?): Promise<SearchResults>Search within transcriptions only.
searchDocuments(query, options?): Promise<SearchResults>Search within documents only.
ask(query, options?): Promise<AskResponse>Search for relevant context, then generate an AI answer from the results.
const answer = await client.ask('What was decided about the launch date?', {
userId: 'user@example.com',
roomNames: ['product-review'],
model: 'gpt-4o-mini',
});
console.log(answer.content);
console.log(`Sources: ${answer.sources.length}`);
SearchOptions
| Option | Type | Default | Description |
|---|---|---|---|
sources |
('transcriptions' | 'documents')[] |
all | Filter by source type |
roomNames |
string[] |
- | Filter by room names |
dateRange |
{ start?, end? } |
- | Filter by date range |
limit |
number |
20 |
Maximum results |
threshold |
number |
0.5 |
Minimum similarity score (0-1) |
userId |
string |
- | User ID for scoping |
roomName |
string |
- | Room name for scoping |
recordingId |
string |
- | Recording ID for scoping |
Analyze meeting transcripts with purpose-built scorecards.
analyzeSalesCall(options): Promise<AnalysisResponse<SalesScorecard>>Score a sales call across discovery, qualification, objection handling, closing, and next steps.
const result = await client.analyzeSalesCall({
transcript,
userId: 'user@example.com',
});
console.log(`Overall: ${result.analysis.overallScore}/100`);
console.log(`Discovery: ${result.analysis.dimensions.discovery.score}/100`);
analyzeInterview(options): Promise<AnalysisResponse<InterviewAssessment>>Assess an interview across technical competency, communication, problem solving, culture fit, and enthusiasm.
const result = await client.analyzeInterview({ transcript, userId: 'user@example.com' });
console.log(`Recommendation: ${result.analysis.hiringRecommendation}`);
analyzeSession(options): Promise<AnalysisResponse<SessionSummary>>Summarize a session including primary concerns, topics discussed, recommendations, and follow-ups.
analyzeCoaching(options): Promise<AnalysisResponse<CoachingAnalysis>>Analyze communication patterns including talk/listen ratio, filler words, interruptions, and question quality.
analyzeCustom(options): Promise<AnalysisResponse<CustomAnalysis>>Run a custom analysis with your own rubric dimensions.
const result = await client.analyzeCustom({
transcript,
userId: 'user@example.com',
rubric: {
dimensions: [
{ name: 'Clarity', description: 'How clearly were points communicated?' },
{ name: 'Engagement', description: 'How engaged were participants?' },
],
},
});
console.log(`Clarity: ${result.analysis.dimensions['Clarity'].score}/100`);
AnalysisOptions
| Option | Type | Description |
|---|---|---|
transcript |
string |
Meeting transcript text (required) |
userId |
string |
User ID |
roomName |
string |
Room name |
model |
string |
AI model override |
checkPresence(callerProfileId, match): Promise<string[]>Check which connected users match a metadata-based relationship with the caller. The server derives match values from the caller's profile.
const onlineUserIds = await client.checkPresence('profile_123', {
userField: 'organizationId',
callerField: 'organizationId',
});
console.log('Online teammates:', onlineUserIds);
Advertise rooms and discover active rooms in real time.
advertiseRoom(options): Promise<void>Make a room discoverable by targeted users.
await client.advertiseRoom({
name: 'team-standup',
ownerDisplayName: 'John',
targetUserIds: ['jane@example.com', 'bob@example.com'],
metadata: { passwordRequired: false },
});
removeAdvertisedRoom(roomName): Promise<void>Remove a room from discovery.
updateAdvertisedRoom(roomName, updates): Promise<void>Update an advertised room's metadata or target users.
getActiveRooms(userId?): Promise<ActiveRoom[]>List active rooms. When userId is provided, only rooms targeting that user are returned.
const rooms = await client.getActiveRooms('jane@example.com');
rooms.forEach(room => {
console.log(`${room.name} by ${room.ownerDisplayName}`);
});
getActiveRoomsStreamUrl(userId): Promise<string>Get a signed SSE stream URL for active room discovery. The URL includes a single-use ticket for authentication (since EventSource does not support custom headers).
const url = await client.getActiveRoomsStreamUrl('jane@example.com');
const eventSource = new EventSource(url);
connectActiveRoomsStream(userId, handlers?): Promise<ActiveRoomsStreamHandle>Open a real-time stream for active room updates. Returns a handle with close() to disconnect.
const stream = await client.connectActiveRoomsStream('jane@example.com', {
onSnapshot: (rooms) => console.log('All rooms:', rooms),
onRoomAdded: (room) => console.log('New room:', room.name),
onRoomRemoved: (name) => console.log('Room closed:', name),
onRoomUpdated: (room) => console.log('Room updated:', room.name),
onError: (err) => console.error('Stream error:', err),
});
// Later: disconnect
stream.close();
Persistent chat with real-time streaming via SSE.
getConversations(userId): Promise<ChatConversation[]>Get all conversations the user has participated in, sorted by most recent activity.
const conversations = await client.getConversations('user@example.com');
conversations.forEach(c => {
console.log(`${c.roomName}: ${c.messageCount} messages`);
});
getChatHistory(roomName, options?): Promise<ChatHistoryResponse>Get paginated message history for a room. Use cursor-based pagination for older messages.
const history = await client.getChatHistory('team-standup', { limit: 50 });
history.messages.forEach(m => {
console.log(`[${m.userId}] ${m.message}`);
});
// Load older messages
if (history.nextCursor) {
const older = await client.getChatHistory('team-standup', {
cursor: history.nextCursor,
limit: 50,
});
}
sendChatMessage(roomName, message, userId): Promise<{ messageId: string }>Send a message to a room. Returns the persisted message ID.
const { messageId } = await client.sendChatMessage(
'team-standup',
'Hello team!',
'user@example.com'
);
connectChatStream(roomName, handlers?): Promise<ChatStreamHandle>Open a real-time SSE stream for chat messages. Returns a handle with close() to disconnect.
const stream = await client.connectChatStream('team-standup', {
onSnapshot: (messages) => console.log('Recent messages:', messages),
onMessage: (msg) => console.log('New message:', msg.message),
onError: (err) => console.error('Stream error:', err),
});
// Later: disconnect
stream.close();
getChatStreamUrl(roomName): Promise<string>Get a signed SSE stream URL for chat messages. Useful when you need to manage the EventSource directly.
const url = await client.getChatStreamUrl('team-standup');
const eventSource = new EventSource(url);
For server-side admin operations (managing user profiles, organizations, API keys), use the dedicated @hiyve/admin package. It provides three layers of server-only enforcement to prevent accidental client-side usage.
npm install @hiyve/admin
Utility functions for converting emotion data from @hiyve/mood-analysis into the sentiment format used by the cloud API.
emotionToSentiment(emotion): 'positive' | 'negative' | 'neutral'Maps an emotion string to a sentiment classification.
| Emotion | Sentiment |
|---|---|
happy, surprised |
positive |
angry, fearful, disgusted, sad |
negative |
neutral (and all others) |
neutral |
import { emotionToSentiment } from '@hiyve/cloud';
emotionToSentiment('happy'); // 'positive'
emotionToSentiment('angry'); // 'negative'
emotionToSentiment('neutral'); // 'neutral'
moodStateToSentimentEntry(participantId, moodState): SentimentEntryConverts a mood state object into a SentimentEntry for use with pushMoodToResponse.
import { moodStateToSentimentEntry } from '@hiyve/cloud';
const entry = moodStateToSentimentEntry('user@example.com', {
emotion: 'happy',
confidence: 0.92,
timestamp: Date.now(),
});
// { participant: 'user@example.com', sentiment: 'positive', confidence: 0.92, timestamp: ... }
await client.pushMoodToResponse('resp_abc123', 'user@example.com', [entry]);
The moodState parameter accepts any object matching the MoodStateLike interface, including the full MoodState type from @hiyve/mood-analysis.
Client-side validation helpers to catch invalid input before making API requests.
import {
validateLength,
validateRoomName,
validateTranscriptBatch,
validateSearchQuery,
MAX_QUERY_LENGTH,
MAX_TRANSCRIPT_LENGTH,
MAX_ROOM_NAME_LENGTH,
MAX_TRANSCRIPT_BATCH_SIZE,
} from '@hiyve/cloud';
| Function | Description |
|---|---|
validateLength(value, maxLength, fieldName) |
Throws if string exceeds max length |
validateRoomName(roomName) |
Throws if room name is empty or exceeds 256 characters |
validateTranscriptBatch(segments) |
Throws if batch exceeds 1000 segments |
validateSearchQuery(query) |
Throws if search query is empty or exceeds max length |
| Constant | Value |
|---|---|
MAX_QUERY_LENGTH |
32,000 characters |
MAX_TRANSCRIPT_LENGTH |
500,000 characters |
MAX_ROOM_NAME_LENGTH |
256 characters |
MAX_TRANSCRIPT_BATCH_SIZE |
1,000 segments |
import { CloudClient, ENVIRONMENT_URLS } from '@hiyve/cloud';
// Use production (default)
const client = new CloudClient({ cloudToken: 'ct_...' });
// Use development environment
const client = new CloudClient({
cloudToken: 'ct_...',
environment: 'development',
});
// Use a custom URL (overrides environment)
const client = new CloudClient({
cloudToken: 'ct_...',
baseUrl: 'https://custom-api.example.com',
});
| Environment | Description |
|---|---|
production (default) |
Production API endpoint |
development |
Development/staging API endpoint |
The correct URL for each environment is resolved automatically via ENVIRONMENT_URLS. You can override with baseUrl if needed. HTTPS is required for all URLs. HTTP is only permitted for localhost and 127.0.0.1 during development.
For React applications, use @hiyve/react-intelligence instead. It wraps CloudClient with React context and provides hooks like useIntelligence, useLiveContext, useAlerts, and useScheduling. When used with IdentityProvider and @hiyve/admin server middleware, cloud tokens are generated automatically -- no props needed.
import { IdentityProvider } from '@hiyve/react-identity';
import { CloudProvider } from '@hiyve/react-intelligence';
function App() {
return (
<IdentityProvider>
<CloudProvider>
<MeetingRoom />
</CloudProvider>
</IdentityProvider>
);
}
| Constant | Value | Description |
|---|---|---|
DEFAULT_BASE_URL |
ENVIRONMENT_URLS.production |
Default API base URL (production endpoint) |
DEFAULT_TIMEOUT |
30000 |
Default request timeout in milliseconds |
DEFAULT_ENVIRONMENT |
'production' |
Default cloud environment |
DEFAULT_MODEL |
'gpt-4o-mini' |
Default AI model |
DEFAULT_SUMMARY_MAX_LENGTH |
100 |
Default summary max length (words) |
DEFAULT_ENHANCE_STYLE |
'professional' |
Default note enhancement style |
DEFAULT_ALERT_SETTINGS |
{ enabled: true, ... } |
Default alert settings with medium sensitivity for all categories |
All types are exported from the package entry point. Key types by category:
Configuration: CloudConfig, CloudEnvironment, CloudTokenResponse, GenerateCloudTokenParams
AI Intelligence: QueryOptions, AIResponse, SummaryOptions, ActionItem, ActionItemsOptions, EnhanceOptions
Transcription & Sentiment: TranscriptSegment, SentimentEntry, SentimentContext, MoodStateLike, TranscriptionMoodData
Alerts: MeetingAlert, AlertSettings, AlertHistoryOptions
Scheduling: Meeting, MeetingParticipant, CreateMeetingOptions, NotificationType
Search: SearchOptions, SearchResult, SearchResults, AskOptions, AskResponse
Analysis: AnalysisOptions, CustomAnalysisOptions, AnalysisResponse, DimensionScore, SalesScorecard, InterviewAssessment, SessionSummary, CoachingAnalysis, CustomAnalysis
Active Rooms: CloudActiveRoom, CloudAdvertiseRoomOptions, ActiveRoomsStreamHandle
Chat: ChatConversation, ChatHistoryResponse, ChatHistoryMessage, ChatStreamMessage, ChatStreamHandle
Pagination: Pagination
Proprietary - Hiyve SDK
@hiyve/cloud - Framework-agnostic HTTP client for Hiyve Cloud AI services
This package provides the core cloud client and types that can be used with any JavaScript framework. For React applications, use
@hiyve/react-intelligencewhich wraps this package with React context and hooks.Example