Bold VideoDocs

AI Methods

Chat, semantic search, and recommendations, grounded in your videos

The ai namespace is how your app talks to Bold's AI. Every method streams by default (see Streaming) and accepts stream: false for plain JSON.

ai.chat(options)

Library-wide Q&A, or scoped to one video by passing videoId.

// Streaming (default)
const stream = await bold.ai.chat({ prompt: 'How do I price my SaaS?' });
for await (const event of stream) {
  if (event.type === 'text_delta') process.stdout.write(event.delta);
  if (event.type === 'sources') console.log('Sources:', event.sources);
}

// Non-streaming
const response = await bold.ai.chat({
  prompt: 'What are the best closing techniques?',
  stream: false
});
console.log(response.content);

Scoped to one video (uses only that video's transcript as context):

const stream = await bold.ai.chat({
  videoId: 'video-id',
  prompt: 'What is discussed at the 5 minute mark?',
  currentTime: 300   // optional playback position
});

Continue a conversation:

const stream = await bold.ai.chat({
  prompt: 'Tell me more about that',
  conversationId: 'conv-id'   // from message_start / message_complete events
});
OptionTypeDefaultDescription
promptstring-The question (required)
streambooleantrueSSE stream vs JSON
videoIdstring-Scope to a single video
currentTimenumber-Playback position (with videoId)
conversationIdstring-Continue an existing conversation
collectionIdstring-Restrict context to a collection
tagsstring[]-Restrict context by tags
imagesImageInput[]-Attach images (e.g. homework review): File, Blob, or base64

Plan availability

Library-wide chat (no videoId) is the AI Coach, available on Growth and Enterprise plans. Video-scoped chat works on every plan.

ai.search(options)

Semantic search with a short AI-written summary of the results.

const stream = await bold.ai.search({ prompt: 'pricing strategies', limit: 10 });
for await (const event of stream) {
  if (event.type === 'sources') console.log(`Found ${event.sources.length} clips`);
  if (event.type === 'text_delta') process.stdout.write(event.delta);
}
OptionTypeDefaultDescription
promptstring-Search query (required)
streambooleantrueSSE stream vs JSON
limitnumber-Max results
collectionId / tags / videoId--Scope the search
contextAIContextMessage[]-Previous turns, for follow-up queries

ai.recommendations(options)

Topic-based recommendations, ideal for learning paths and "what should I watch next."

const stream = await bold.ai.recommendations({
  topics: ['contract law', 'ethics', 'client management']
});

for await (const event of stream) {
  if (event.type === 'recommendations') {
    for (const rec of event.recommendations) {
      console.log(rec.topic, rec.videos.map(v => v.title));
    }
  }
  if (event.type === 'text_delta') process.stdout.write(event.delta); // AI guidance
}
OptionTypeDefaultDescription
topicsstring[]-Topics to cover (required)
limitnumber5Max videos per topic (max 20)
includeGuidancebooleantrueNarrative learning-path text
collectionId / tags--Scope the pool
contextAIContextMessage[]-Previous turns
streambooleantrueSSE stream vs JSON

ai.getConversation(id)

const conversation = await bold.ai.getConversation('conv-id');
for (const message of conversation.messages) {
  console.log(`${message.role}: ${message.content}`);
}

Multi-turn without conversations

Search and recommendations accept a context array instead of a conversation ID:

const first = await bold.ai.search({ prompt: 'How do indie designers find clients?', stream: false });
const followUp = await bold.ai.search({
  prompt: 'What about cold outreach specifically?',
  context: first.context,
  stream: false
});

Deprecated aliases

ai.ask(), ai.coach() → use ai.chat(). ai.recommend() → use ai.recommendations(). The old names still work but will be removed in v2.

On this page