> ## Documentation Index
> Fetch the complete documentation index at: https://www.studyfetch.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Chat

> AI-powered chat assistant for your study materials

## Overview

The Chat component creates an AI-powered assistant that can answer questions based on your study materials. It supports web search, RAG (Retrieval Augmented Generation), and multi-step reasoning.

## Creating a Chat Component

<CodeGroup>
  ```javascript JavaScript theme={null}
  import StudyfetchSDK from '@studyfetch/sdk';

  const client = new StudyfetchSDK({
    apiKey: 'your-api-key',
    baseURL: 'https://studyfetchapi.com',
  });

  const chatComponent = await client.v1.components.create({
    name: 'Biology Study Assistant',
    type: 'chat',
    config: {
      materials: ['mat-123', 'mat-456'],
      folders: ['folder-789'],
      model: 'gpt-4o-mini-2024-07-18',
      systemPrompt: 'You are a helpful biology tutor. Answer questions based on the provided materials.',
      temperature: 0.7,
      maxTokens: 2048,
      enableWebSearch: true,
      enableRAGSearch: true,
      maxSteps: 5,
      enableHistory: false,
      enableVoice: false,
      enableFollowUps: false,
      enableComponentCreation: false,
      enableMessageGrading: false,
      enableReferenceMode: false,
      enableFeedback: true,
      // UI Customization (optional)
      hideTitle: false,
      hideEmptyState: false,
      emptyStateHTML: '<div style="text-align: center; padding: 2rem;"><h3>Welcome to Biology Assistant!</h3><p>Ask me anything about your course materials.</p></div>'
    }
  });

  console.log('Chat component created:', chatComponent._id);
  ```

  ```python Python theme={null}
  from studyfetch_sdk import StudyfetchSDK

  client = StudyfetchSDK(
      api_key="your-api-key",
      base_url="https://studyfetchapi.com",
  )

  chat_component = client.v1.components.create(
      name="Biology Study Assistant",
      type="chat",
      config={
          "materials": ["mat-123", "mat-456"],
          "folders": ["folder-789"],
          "model": "gpt-4o-mini-2024-07-18",
          "systemPrompt": "You are a helpful biology tutor. Answer questions based on the provided materials.",
          "temperature": 0.7,
          "maxTokens": 2048,
          "enableWebSearch": True,
          "enableRAGSearch": True,
          "maxSteps": 5,
          "enableHistory": False,
          "enableVoice": False,
          "enableFollowUps": False,
          "enableComponentCreation": False,
          "enableMessageGrading": False,
          "enableReferenceMode": False,
          "enableFeedback": True,
          # UI Customization (optional)
          "hideTitle": False,
          "hideEmptyState": False,
          "emptyStateHTML": '<div style="text-align: center; padding: 2rem;"><h3>Welcome to Biology Assistant!</h3><p>Ask me anything about your course materials.</p></div>'
      }
  )

  print(f"Chat component created: {chat_component._id}")
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.client.StudyfetchSdkClient;
  import com.studyfetch.javasdk.client.okhttp.StudyfetchSdkOkHttpClient;
  import com.studyfetch.javasdk.models.v1.components.ComponentResponse;
  import com.studyfetch.javasdk.models.v1.components.ComponentCreateParams;

  public class CreateChatComponent {
      public static void main(String[] args) {
          StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
              .fromEnv()
              .baseUrl("https://studyfetchapi.com")
              .build();

          ComponentCreateParams params = ComponentCreateParams.builder()
              .name("Biology Study Assistant")
              .type(ComponentCreateParams.Type.CHAT)
              .config(ComponentCreateParams.Config.ChatConfigDto.builder()
                  .materials(List.of("mat-123", "mat-456"))
                  .folders(List.of("folder-789"))
                  .model("gpt-4o-mini-2024-07-18")
                  .systemPrompt("You are a helpful biology tutor. Answer questions based on the provided materials.")
                  .temperature(0.7)
                  .maxTokens(2048)
                  .enableWebSearch(true)
                  .enableRagSearch(true)
                  .maxSteps(5)
                  .enableHistory(false)
                  .enableVoice(false)
                  .enableFollowUps(false)
                  .enableComponentCreation(false)
                  .enableMessageGrading(false)
                  .enableReferenceMode(false)
                  .enableFeedback(true)
                  // UI Customization (optional)
                  .hideTitle(false)
                  .hideEmptyState(false)
                  .emptyStateHTML("<div style='text-align: center; padding: 2rem;'><h3>Welcome to Biology Assistant!</h3><p>Ask me anything about your course materials.</p></div>")
                  .build())
              .build();

          ComponentResponse component = client.v1().components().create(params);
          System.out.println("Chat component created: " + component._id());
      }
  }
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Components;
  using System;
  using System.Collections.Generic;
  using System.Threading.Tasks;

  public class CreateChatComponent
  {
      public static async Task CreateChat()
      {
          var client = new StudyfetchSDKClient()
          {
              APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
              BaseUrl = new Uri("https://studyfetchapi.com")
          };

          var chatComponent = await client.V1.Components.Create(new()
          {
              Name = "Biology Study Assistant",
              Type = StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.Type.Chat,
              Config = new StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.ChatConfigDto()
              {
                  Model = "gemini-2.5-flash",
                  Materials = new List<string> { "mat-123" },
                  EnableFeedback = true,
                  // UI Customization (optional)
                  HideTitle = false,
                  HideEmptyState = false,
                  EmptyStateHTML = "<div style='text-align: center; padding: 2rem;'><h3>Welcome to Biology Assistant!</h3><p>Ask me anything about your course materials.</p></div>"
              }
          });

          Console.WriteLine($"Chat component created: {chatComponent._ID}");
      }
  }
  ```
</CodeGroup>

## Configuration Parameters

<ParamField body="name" type="string" required>
  Name of the chat component
</ParamField>

<ParamField body="type" type="string" required>
  Must be `"chat"`
</ParamField>

<ParamField body="config" type="object" required>
  Chat configuration object

  <Expandable title="Configuration Properties">
    <ParamField body="materials" type="array" required>
      Array of material IDs to use as context for the chat assistant
    </ParamField>

    <ParamField body="folders" type="array">
      Array of folder IDs containing materials
    </ParamField>

    <ParamField body="model" type="string" default="gpt-4o-mini-2024-07-18">
      AI model to use. Options:

      * `gpt-4o` - Most capable model
      * `gpt-4o-mini-2024-07-18` - Faster, cost-effective model
    </ParamField>

    <ParamField body="systemPrompt" type="string">
      System prompt to guide the AI assistant's behavior and personality
    </ParamField>

    <ParamField body="temperature" type="number" default="0.7">
      Temperature for response generation (0-2). Lower values make responses more focused and deterministic
    </ParamField>

    <ParamField body="maxTokens" type="integer" default="2048">
      Maximum tokens for AI responses
    </ParamField>

    <ParamField body="enableWebSearch" type="boolean" default="false">
      Enable web search capabilities for finding current information
    </ParamField>

    <ParamField body="enableRAGSearch" type="boolean" default="true">
      Enable RAG (Retrieval Augmented Generation) search within materials
    </ParamField>

    <ParamField body="maxSteps" type="integer">
      Maximum steps for multi-step tool calls and reasoning
    </ParamField>

    <ParamField body="enableHistory" type="boolean" default="false">
      Enable conversation history to allow users to continue previous chats
    </ParamField>

    <ParamField body="enableVoice" type="boolean" default="false">
      Enable voice input for hands-free interaction
    </ParamField>

    <ParamField body="enableFollowUps" type="boolean" default="false">
      Enable AI-suggested follow-up questions after responses
    </ParamField>

    <ParamField body="enableComponentCreation" type="boolean" default="false">
      Allow the AI to create study components (flashcards, tests, etc.) during conversation
    </ParamField>

    <ParamField body="enableMessageGrading" type="boolean" default="false">
      Enable message grading to track prompting quality and responsible AI usage. When enabled, user messages are scored on a 1-4 scale for prompting effectiveness and responsible interaction.
    </ParamField>

    <ParamField body="enableReferenceMode" type="boolean" default="false">
      Show reference titles and URLs instead of source content in citations. This provides a cleaner interface while maintaining source attribution.
    </ParamField>

    <ParamField body="enableFeedback" type="boolean" default="true">
      Enable thumbs up/down feedback with reason. When enabled, users can provide feedback on AI responses with optional text explanations. This data can be retrieved using the `chat.retrieveFeedback()` API for quality monitoring and improvement.
    </ParamField>

    <ParamField body="enableGuardrails" type="boolean" default="false">
      Enable guardrails to apply server-side content policy rules to AI responses. When enabled, the AI's responses will be evaluated against your configured rules before being returned to the user.
    </ParamField>

    <ParamField body="hideTitle" type="boolean" default="false">
      Hide the chat title and avatar in the embedded component
    </ParamField>

    <ParamField body="hideEmptyState" type="boolean" default="false">
      Hide the default empty state (icon and text) when no messages are present
    </ParamField>

    <ParamField body="emptyStateHTML" type="string">
      Provide custom HTML to replace the default icon and message when chat is empty.
    </ParamField>

    <ParamField body="guardrailRules" type="array">
      Array of guardrail rules to control AI behavior. Rules are evaluated on each response.

      <Expandable title="Guardrail Rule Properties">
        <ParamField body="id" type="string" required>
          Unique identifier for the rule
        </ParamField>

        <ParamField body="action" type="string" required>
          Action to take when rule is triggered:

          * `BLOCK` - Prevents the response and shows your custom message
          * `WARN` - Allows the response but adds a warning message
          * `MODIFY` - Allows the assistant to revise its response to comply with the rule
        </ParamField>

        <ParamField body="condition" type="string" required>
          Natural language description of when the rule should trigger. The AI evaluates if the response matches this condition.
        </ParamField>

        <ParamField body="description" type="string" required>
          Brief description of the rule's purpose
        </ParamField>

        <ParamField body="message" type="string">
          Custom message shown to the user when the rule triggers
        </ParamField>
      </Expandable>

      **Common Guardrail Use Cases:**

      * **Academic Integrity**: Prevent direct homework/test answers
      * **Safety**: Block harmful, medical, or legal advice
      * **Age-Appropriate Content**: Modify responses for younger audiences
      * **Brand Guidelines**: Ensure responses align with your organization's values
      * **Topic Boundaries**: Keep conversations focused on intended subject matter
    </ParamField>
  </Expandable>
</ParamField>

## Response

```json theme={null}
{
  "_id": "comp_123abc",
  "name": "Biology Study Assistant",
  "type": "chat",
  "status": "active",
  "config": {
    "materials": ["mat-123", "mat-456"],
    "folders": ["folder-789"],
    "model": "gpt-4o-mini-2024-07-18",
    "systemPrompt": "You are a helpful biology tutor...",
    "temperature": 0.7,
    "maxTokens": 2048,
    "enableWebSearch": true,
    "enableRAGSearch": true,
    "maxSteps": 5
  },
  "createdAt": "2024-01-15T10:00:00Z",
  "updatedAt": "2024-01-15T10:00:00Z",
  "organizationId": "org_456def",
  "usage": {
    "interactions": 0,
    "lastUsed": null
  }
}
```

## Adding Guardrails

Guardrails allow you to apply server-side content policy rules to AI responses. When enabled, the AI's responses are evaluated against your configured rules before being returned to the user.

### Example: Academic Integrity Guardrails

<CodeGroup>
  ```javascript JavaScript theme={null}
  const chatWithGuardrails = await client.v1.components.create({
    name: 'Math Tutor with Guardrails',
    type: 'chat',
    config: {
      materials: ['mat-789'],
      model: 'gpt-4o-mini-2024-07-18',
      enableFeedback: true,
      enableGuardrails: true,
      guardrailRules: [
        {
          id: 'no-direct-answers',
          action: 'modify',
          condition: 'Response provides direct answers to homework problems without explanation',
          description: 'Guide students to solve problems themselves',
          message: 'Modified to provide guidance instead of direct answers'
        },
        {
          id: 'academic-honesty',
          action: 'warn',
          condition: 'User asks for test or exam answers',
          description: 'Warn about academic integrity',
          message: 'Remember: This tool is for learning, not for completing graded assignments'
        }
      ]
    }
  });
  ```

  ```python Python theme={null}
  chat_with_guardrails = client.v1.components.create(
      name="Math Tutor with Guardrails",
      type="chat",
      config={
          "materials": ["mat-789"],
          "model": "gpt-4o-mini-2024-07-18",
          "enableFeedback": True,
          "enableGuardrails": True,
          "guardrailRules": [
              {
                  "id": "no-direct-answers",
                  "action": "MODIFY",
                  "condition": "Response provides direct answers to homework problems without explanation",
                  "description": "Guide students to solve problems themselves",
                  "message": "Modified to provide guidance instead of direct answers"
              },
              {
                  "id": "academic-honesty",
                  "action": "WARN",
                  "condition": "User asks for test or exam answers",
                  "description": "Warn about academic integrity",
                  "message": "Remember: This tool is for learning, not for completing graded assignments"
              }
          ]
      }
  )
  ```

  ```java Java theme={null}
  ComponentCreateParams guardrailParams = ComponentCreateParams.builder()
      .name("Math Tutor with Guardrails")
      .type(ComponentCreateParams.Type.CHAT)
      .config(ComponentCreateParams.Config.ChatConfigDto.builder()
          .materials(List.of("mat-789"))
          .model("gpt-4o-mini-2024-07-18")
          .enableFeedback(true)
          .enableGuardrails(true)
          .guardrailRules(List.of(
              ComponentCreateParams.Config.ChatConfigDto.GuardrailRule.builder()
                  .id("no-direct-answers")
                  .action(ComponentCreateParams.Config.ChatConfigDto.GuardrailRule.Action.MODIFY)
                  .condition("Response provides direct answers to homework problems without explanation")
                  .description("Guide students to solve problems themselves")
                  .message("Modified to provide guidance instead of direct answers")
                  .build(),
              ComponentCreateParams.Config.ChatConfigDto.GuardrailRule.builder()
                  .id("academic-honesty")
                  .action(ComponentCreateParams.Config.ChatConfigDto.GuardrailRule.Action.WARN)
                  .condition("User asks for test or exam answers")
                  .description("Warn about academic integrity")
                  .message("Remember: This tool is for learning, not for completing graded assignments")
                  .build()
          ))
          .build())
      .build();
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Components;
  using System;
  using System.Collections.Generic;
  using System.Threading.Tasks;
  using GuardrailRule = StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.ChatConfigDtoProperties.GuardrailRule;
  using GuardrailAction = StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.ChatConfigDtoProperties.GuardrailRuleProperties.Action;

  public class AcademicIntegrityGuardrails
  {
      public static async Task CreateChatWithGuardrails()
      {
          var client = new StudyfetchSDKClient()
          {
              APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
              BaseUrl = new Uri("https://studyfetchapi.com")
          };

          var guardrailComponent = await client.V1.Components.Create(new()
          {
              Name = "Math Tutor with Guardrails",
              Type = StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.Type.Chat,
              Config = new StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.ChatConfigDto()
              {
                  Model = "gemini-2.5-flash",
                  Materials = new List<string> { "mat-789" },
                  EnableFeedback = true,
                  EnableGuardrails = true,
                  GuardrailRules = new List<GuardrailRule>
                  {
                      new GuardrailRule()
                      {
                          ID = "academic-honesty",
                          Action = GuardrailAction.Warn,
                          Condition = "User asks for test or exam answers",
                          Description = "Warn about academic integrity",
                          Message = "Remember: This tool is for learning, not for completing graded assignments"
                      }
                  }
              }
          });

          Console.WriteLine($"Guardrail component created: {guardrailComponent._ID}");
      }
  }
  ```
</CodeGroup>

### Example: Safety and Content Moderation

<CodeGroup>
  ```javascript JavaScript theme={null}
  const safeChat = await client.v1.components.create({
    name: 'K-12 Science Assistant',
    type: 'chat',
    config: {
      materials: ['mat-science-k12'],
      enableFeedback: true,
      enableGuardrails: true,
      guardrailRules: [
        {
          id: 'no-medical-advice',
          action: 'block',
          condition: 'Response contains medical diagnosis or treatment advice',
          description: 'Prevent medical advice',
          message: 'I cannot provide medical advice. Please consult a healthcare professional.'
        },
        {
          id: 'age-appropriate',
          action: 'modify',
          condition: 'Response contains content not suitable for K-12 students',
          description: 'Ensure age-appropriate content',
          message: 'Content adjusted for educational purposes'
        },
        {
          id: 'no-dangerous-experiments',
          action: 'block',
          condition: 'Response describes dangerous chemical reactions or experiments',
          description: 'Prevent dangerous activities',
          message: 'For safety reasons, I cannot provide instructions for this type of experiment.'
        }
      ]
    }
  });
  ```

  ```python Python theme={null}
  safe_chat = client.v1.components.create(
      name="K-12 Science Assistant",
      type="chat",
      config={
          "materials": ["mat-science-k12"],
          "enableFeedback": True,
          "enableGuardrails": True,
          "guardrailRules": [
              {
                  "id": "no-medical-advice",
                  "action": "BLOCK",
                  "condition": "Response contains medical diagnosis or treatment advice",
                  "description": "Prevent medical advice",
                  "message": "I cannot provide medical advice. Please consult a healthcare professional."
              },
              {
                  "id": "age-appropriate",
                  "action": "MODIFY",
                  "condition": "Response contains content not suitable for K-12 students",
                  "description": "Ensure age-appropriate content",
                  "message": "Content adjusted for educational purposes"
              },
              {
                  "id": "no-dangerous-experiments",
                  "action": "BLOCK",
                  "condition": "Response describes dangerous chemical reactions or experiments",
                  "description": "Prevent dangerous activities",
                  "message": "For safety reasons, I cannot provide instructions for this type of experiment."
              }
          ]
      }
  )
  ```

  ```java Java theme={null}
  ComponentCreateParams safeParams = ComponentCreateParams.builder()
      .name("K-12 Science Assistant")
      .type(ComponentCreateParams.Type.CHAT)
      .config(ComponentCreateParams.Config.ChatConfigDto.builder()
          .materials(List.of("mat-science-k12"))
          .enableFeedback(true)
          .enableGuardrails(true)
          .guardrailRules(List.of(
              ComponentCreateParams.Config.ChatConfigDto.GuardrailRule.builder()
                  .id("no-medical-advice")
                  .action(ComponentCreateParams.Config.ChatConfigDto.GuardrailRule.Action.BLOCK)
                  .condition("Response contains medical diagnosis or treatment advice")
                  .description("Prevent medical advice")
                  .message("I cannot provide medical advice. Please consult a healthcare professional.")
                  .build(),
              ComponentCreateParams.Config.ChatConfigDto.GuardrailRule.builder()
                  .id("age-appropriate")
                  .action(ComponentCreateParams.Config.ChatConfigDto.GuardrailRule.Action.MODIFY)
                  .condition("Response contains content not suitable for K-12 students")
                  .description("Ensure age-appropriate content")
                  .message("Content adjusted for educational purposes")
                  .build(),
              ComponentCreateParams.Config.ChatConfigDto.GuardrailRule.builder()
                  .id("no-dangerous-experiments")
                  .action(ComponentCreateParams.Config.ChatConfigDto.GuardrailRule.Action.BLOCK)
                  .condition("Response describes dangerous chemical reactions or experiments")
                  .description("Prevent dangerous activities")
                  .message("For safety reasons, I cannot provide instructions for this type of experiment.")
                  .build()
          ))
          .build())
      .build();
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Components;
  using System;
  using System.Collections.Generic;
  using System.Threading.Tasks;
  using GuardrailRule = StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.ChatConfigDtoProperties.GuardrailRule;
  using GuardrailAction = StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.ChatConfigDtoProperties.GuardrailRuleProperties.Action;

  public class SafetyAndContentModeration
  {
      public static async Task CreateSafeChatComponent()
      {
          var client = new StudyfetchSDKClient()
          {
              APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
              BaseUrl = new Uri("https://studyfetchapi.com")
          };

          var safeChat = await client.V1.Components.Create(new()
          {
              Name = "K-12 Science Assistant",
              Type = StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.Type.Chat,
              Config = new StudyfetchSDK.Models.V1.Components.ComponentCreateParamsProperties.ConfigProperties.ChatConfigDto()
              {
                  Model = "gemini-2.5-flash",
                  Materials = new List<string> { "mat-science-k12" },
                  EnableFeedback = true,
                  EnableGuardrails = true,
                  GuardrailRules = new List<GuardrailRule>
                  {
                      new GuardrailRule()
                      {
                          ID = "no-medical-advice",
                          Action = GuardrailAction.Block,
                          Condition = "Response contains medical diagnosis or treatment advice",
                          Description = "Prevent medical advice",
                          Message = "I cannot provide medical advice. Please consult a healthcare professional."
                      },
                      new GuardrailRule()
                      {
                          ID = "age-appropriate",
                          Action = GuardrailAction.Modify,
                          Condition = "Response contains content not suitable for K-12 students",
                          Description = "Ensure age-appropriate content",
                          Message = "Content adjusted for educational purposes"
                      },
                      new GuardrailRule()
                      {
                          ID = "no-dangerous-experiments",
                          Action = GuardrailAction.Block,
                          Condition = "Response describes dangerous chemical reactions or experiments",
                          Description = "Prevent dangerous activities",
                          Message = "For safety reasons, I cannot provide instructions for this type of experiment."
                      }
                  }
              }
          });

          Console.WriteLine($"Safe chat component created: {safeChat._ID}");
      }
  }
  ```
</CodeGroup>

### Guardrail Actions Explained

* **BLOCK**: Completely prevents the response and shows your custom message to the user
* **WARN**: Allows the response but adds a warning message before or after it
* **MODIFY**: Instructs the AI to revise its response to comply with the rule

## Embedding This Component

Once you've created a Chat component, you can embed it on your website using the embedding API.

### Generate Embed URL

<CodeGroup>
  ```javascript JavaScript theme={null}
  const embedResponse = await client.v1.components.generateEmbed(chatComponent._id, {
    // User tracking
    userId: 'user-456',
    studentName: 'Jane Smith',  // Student name for display
    groupIds: ['class-101', 'class-102'],
    sessionId: 'session-789',
    
    // Chat-specific features
    features: {
      enableWebSearch: true,
      enableHistory: true,
      enableVoice: true,
      enableFollowUps: true,
      enableComponentCreation: false,
      placeholderText: 'Ask me anything about biology...',
      enableWebSearchSources: true,
      enableImageSources: true,
      enableBadWordsFilter: true,
      enablePromptingScore: true,
      enableResponsibilityScore: true,
      enableReferenceMode: false,
      enableGuardrails: true,
      enableOutline: false,
      enableTranscript: false
    },
    
    // Dimensions
    width: '100%',
    height: '600px',
    
    // Token expiry
    expiryHours: 24
  });
  ```

  ```python Python theme={null}
  embed_response = client.v1.components.generateEmbed(
      component_id=chat_component._id,
      userId="user-456",
      student_name="Jane Smith",  # Student name for display
      groupIds=["class-101", "class-102"],
      sessionId="session-789",
      features={
          "enableWebSearch": True,
          "enableHistory": True,
          "enableVoice": True,
          "enableFollowUps": True,
          "enableComponentCreation": False,
          "placeholderText": "Ask me anything about biology...",
          "enableWebSearchSources": True,
          "enableImageSources": True,
          "enableBadWordsFilter": True,
          "enablePromptingScore": True,
          "enableResponsibilityScore": True,
          "enableReferenceMode": False,
          "enableGuardrails": True,
          "enableOutline": False,
          "enableTranscript": False
      },
      width="100%",
      height="600px",
      expiryHours=24
  )
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.client.StudyfetchSdkClient;
  import com.studyfetch.javasdk.client.okhttp.StudyfetchSdkOkHttpClient;
  import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedParams;
  import com.studyfetch.javasdk.models.v1.components.ComponentGenerateEmbedResponse;

  StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
      .fromEnv()
      .baseUrl("https://studyfetchapi.com")
      .build();

  ComponentGenerateEmbedParams params = ComponentGenerateEmbedParams.builder()
      .id(chatComponent._id())
      // User tracking
      .userId("user-456")
      .studentName("Jane Smith")  // Student name for display
      .groupIds(List.of("class-101", "class-102"))
      .sessionId("session-789")
      
      // Chat-specific features
      .features(ComponentGenerateEmbedParams.Features.builder()
          .enableWebSearch(true)
          .enableHistory(true)
          .enableVoice(true)
          .enableFollowUps(true)
          .enableComponentCreation(false)
          .placeholderText("Ask me anything about biology...")
          .enableWebSearchSources(true)
          .enableImageSources(true)
          .enablePromptingScore(true)
          .enableResponsibilityScore(true)
          .enableReferenceMode(false)
          .enableGuardrails(true)
          .enableOutline(false)
          .enableTranscript(false)
          .build())
      
      // Dimensions
      .width("100%")
      .height("600px")
      
      // Token expiry
      .expiryHours(24)
      .build();

  ComponentGenerateEmbedResponse embedResponse = client.v1().components()
      .generateEmbed(params);
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Components;
  using StudyfetchSDK.Models.V1.Components.ComponentGenerateEmbedParamsProperties;
  using System;
  using System.Collections.Generic;
  using System.Threading.Tasks;

  public class GenerateChatEmbedAdvanced
  {
      public static async Task GenerateEmbed(string chatComponentId)
      {
          var client = new StudyfetchSDKClient()
          {
              APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
              BaseUrl = new Uri("https://studyfetchapi.com")
          };

          var embedResponse = await client.V1.Components.GenerateEmbed(new()
          {
              ID = chatComponentId,
              
              // User tracking
              UserID = "user-456",
              StudentName = "Jane Smith",  // Student name for display
              GroupIDs = new List<string> { "class-101", "class-102" },
              SessionID = "session-789",
              
              // Chat-specific features
              Features = new Features(enableBadWordsFilter: true)
              {
                  EnableWebSearch = true,
                  EnableHistory = true,
                  EnableVoice = true,
                  EnableFollowUps = true,
                  EnableComponentCreation = false,
                  PlaceholderText = "Ask me anything about biology...",
                  EnableWebSearchSources = true,
                  EnableImageSources = true,
                  EnablePromptingScore = true,
                  EnableResponsibilityScore = true,
                  EnableReferenceMode = false,
                  EnableGuardrails = true,
                  EnableOutline = false,
                  EnableTranscript = false
              },
              
              // Dimensions
              Width = "100%",
              Height = "600px",
              
              // Token expiry
              ExpiryHours = 24
          });

          Console.WriteLine($"Embed URL: {embedResponse.EmbedURL}");
          Console.WriteLine($"Token: {embedResponse.Token}");
      }
  }
  ```
</CodeGroup>

### Chat-Specific Embedding Features

<ParamField body="features.enableWebSearch" type="boolean" default="false">
  Allow the chat to search the web for current information
</ParamField>

<ParamField body="features.enableHistory" type="boolean" default="true">
  Show conversation history and allow users to continue previous chats
</ParamField>

<ParamField body="features.enableVoice" type="boolean" default="false">
  Enable voice input for asking questions
</ParamField>

<ParamField body="features.enableFollowUps" type="boolean" default="true">
  Show suggested follow-up questions after responses
</ParamField>

<ParamField body="features.enableComponentCreation" type="boolean" default="false">
  Allow users to create other components (flashcards, tests) from chat
</ParamField>

<ParamField body="features.placeholderText" type="string" default="Ask a question...">
  Custom placeholder text for the chat input
</ParamField>

<ParamField body="features.enableWebSearchSources" type="boolean" default="true">
  Show web search sources when web search is used
</ParamField>

<ParamField body="features.enableImageSources" type="boolean" default="true">
  Display image sources in responses when relevant
</ParamField>

<ParamField body="features.enableBadWordsFilter" type="boolean" default="true" required>
  Enable filtering of inappropriate language (required)
</ParamField>

<ParamField body="features.enablePromptingScore" type="boolean" default="false">
  Enable prompting quality scoring for user messages (1-4 scale)
</ParamField>

<ParamField body="features.enableResponsibilityScore" type="boolean" default="false">
  Enable responsibility scoring for user messages (1-4 scale)
</ParamField>

<ParamField body="features.enableReferenceMode" type="boolean" default="false">
  Show reference titles and URLs instead of source content in citations
</ParamField>

<ParamField body="features.enableGuardrails" type="boolean" default="false">
  Apply guardrail rules configured on the component to embedded chat
</ParamField>

<ParamField body="features.enableOutline" type="boolean" default="false">
  Enable document outline navigation (for document-based components)
</ParamField>

<ParamField body="features.enableTranscript" type="boolean" default="false">
  Enable transcript view (for video/audio-based components)
</ParamField>

### Embed in Your HTML

```html theme={null}
<iframe 
  src="https://embed.studyfetch.com/component/comp_123abc?token=..."
  width="100%"
  height="600px"
  frameborder="0"
  allow="microphone; clipboard-write"
  style="border: 1px solid #e5e5e5; border-radius: 8px;">
</iframe>
```

## Streaming Chat Responses

The Chat API supports real-time streaming responses using Server-Sent Events (SSE). This allows you to display responses as they're generated, providing a more interactive experience.

### Stream Chat Response

<CodeGroup>
  ```javascript JavaScript theme={null}
  // AI SDK format with messages array
  const streamResponse = await client.v1.chat.stream({
    componentId: 'comp_123abc',
    sessionId: 'session-789',
    userId: 'user-456',
    groupIds: ['class-101', 'class-102'],
    messages: [
      { role: 'system', content: 'You are a helpful biology tutor.' },
      { role: 'user', content: 'Explain photosynthesis in simple terms' }
    ]
  });

  // Process the stream
  for await (const chunk of streamResponse) {
    console.log(chunk.content);
  }

  // Custom format with single message
  const customStream = await client.v1.chat.stream({
    componentId: 'comp_123abc',
    sessionId: 'session-789',
    userId: 'user-456',
    message: {
      text: 'What is cellular respiration?',
      images: [
        {
          url: 'https://example.com/cell-diagram.png',
          caption: 'Cell structure diagram',
          mimeType: 'image/png'
        }
      ]
    }
  });
  ```

  ```python Python theme={null}
  # AI SDK format with messages array
  stream_response = client.v1.chat.stream(
      component_id="comp_123abc",
      session_id="session-789",
      user_id="user-456",
      group_ids=["class-101", "class-102"],
      messages=[
          {"role": "system", "content": "You are a helpful biology tutor."},
          {"role": "user", "content": "Explain photosynthesis in simple terms"}
      ]
  )

  # Process the stream
  for chunk in stream_response:
      print(chunk.content)

  # Custom format with single message
  custom_stream = client.v1.chat.stream(
      component_id="comp_123abc",
      session_id="session-789",
      user_id="user-456",
      message={
          "text": "What is cellular respiration?",
          "images": [
              {
                  "url": "https://example.com/cell-diagram.png",
                  "caption": "Cell structure diagram",
                  "mimeType": "image/png"
              }
          ]
      }
  )
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.client.StudyfetchSdkClient;
  import com.studyfetch.javasdk.client.okhttp.StudyfetchSdkOkHttpClient;
  import com.studyfetch.javasdk.models.v1.chat.ChatStreamParams;
  import java.util.List;

  StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
      .fromEnv()
      .build();

  // AI SDK format with messages array
  ChatStreamParams aiSdkParams = ChatStreamParams.builder()
      .componentId("comp_123abc")
      .sessionId("session-789")
      .userId("user-456")
      .groupIds(List.of("class-101", "class-102"))
      .messages(List.of(
          "{\"role\":\"system\",\"content\":\"You are a helpful biology tutor.\"}",
          "{\"role\":\"user\",\"content\":\"Explain photosynthesis in simple terms\"}"
      ))
      .build();

  client.v1().chat().stream(aiSdkParams);

  // Custom format with single message
  ChatStreamParams.Message message = ChatStreamParams.Message.builder()
      .text("What is cellular respiration?")
      .images(List.of(
          ChatStreamParams.Message.Image.builder()
              .url("https://example.com/cell-diagram.png")
              .caption("Cell structure diagram")
              .mimeType("image/png")
              .build()
      ))
      .build();

  ChatStreamParams customParams = ChatStreamParams.builder()
      .componentId("comp_123abc")
      .sessionId("session-789")
      .userId("user-456")
      .message(message)
      .build();

  client.v1().chat().stream(customParams);
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Chat;
  using StudyfetchSDK.Models.V1.Chat.ChatStreamParamsProperties;
  using StudyfetchSDK.Models.V1.Chat.ChatStreamParamsProperties.MessageProperties;
  using System;
  using System.Collections.Generic;
  using System.Threading.Tasks;

  public class StreamingChatExample
  {
      public static async Task StreamChat()
      {
          var client = new StudyfetchSDKClient()
          {
              APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
              BaseUrl = new Uri("https://studyfetchapi.com")
          };

          // AI SDK format with messages array
          var aiSdkParams = new ChatStreamParams()
          {
              ComponentID = "comp_123abc",
              SessionID = "session-789",
              UserID = "user-456",
              GroupIDs = new List<string> { "class-101", "class-102" },
              Messages = new List<string>
              {
                  "{\"role\": \"system\", \"content\": \"You are a helpful biology tutor.\"}",
                  "{\"role\": \"user\", \"content\": \"Explain photosynthesis in simple terms\"}"
              }
          };

          await client.V1.Chat.Stream(aiSdkParams);

          // Custom format with single message
          var customParams = new ChatStreamParams()
          {
              ComponentID = "comp_123abc",
              SessionID = "session-789",
              UserID = "user-456",
              Message = new Message()
              {
                  Text = "What is cellular respiration?",
                  Images = new List<Image>
                  {
                      new Image()
                      {
                          URL = "https://example.com/cell-diagram.png",
                          Caption = "Cell structure diagram",
                          MimeType = "image/png"
                      }
                  }
              }
          };

          await client.V1.Chat.Stream(customParams);
          Console.WriteLine("Chat streams completed");
      }
  }
  ```
</CodeGroup>

### Stream Parameters

<ParamField body="componentId" type="string">
  ID of the chat component to use
</ParamField>

<ParamField body="sessionId" type="string">
  Session ID to maintain conversation context
</ParamField>

<ParamField body="userId" type="string">
  User ID for tracking and personalization
</ParamField>

<ParamField body="groupIds" type="array">
  Array of group IDs for access control
</ParamField>

<ParamField body="context" type="object">
  Additional context to pass to the chat
</ParamField>

<ParamField body="messages" type="array">
  Messages array for AI SDK format. Each message should have:

  * `role`: "system", "user", or "assistant"
  * `content`: The message content
</ParamField>

<ParamField body="message" type="object">
  Single message for custom format

  <Expandable title="Message Properties">
    <ParamField body="text" type="string" required>
      Text content of the message
    </ParamField>

    <ParamField body="images" type="array">
      Array of images attached to the message

      <Expandable title="Image Properties">
        <ParamField body="url" type="string">
          URL of the image
        </ParamField>

        <ParamField body="base64" type="string">
          Base64 encoded image data (alternative to URL)
        </ParamField>

        <ParamField body="caption" type="string">
          Caption for the image
        </ParamField>

        <ParamField body="mimeType" type="string">
          MIME type of the image (e.g., "image/png", "image/jpeg")
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

### Stream Response Format

The streaming endpoint returns Server-Sent Events (SSE) with the following event types:

```
data: {"type":"content","content":"The process of photosynthesis..."}

data: {"type":"tool_call","tool":"web_search","args":{"query":"latest photosynthesis research"}}

data: {"type":"sources","sources":[{"title":"Source Title","url":"https://..."}]}

data: {"type":"done","usage":{"tokens":150}}
```

### Example: Building a Streaming Chat Interface

<CodeGroup>
  ```javascript JavaScript theme={null}
  // React example with streaming
  function ChatInterface({ componentId }) {
    const [messages, setMessages] = useState([]);
    const [streaming, setStreaming] = useState(false);

    const sendMessage = async (text) => {
      setStreaming(true);
      const userMessage = { role: 'user', content: text };
      setMessages(prev => [...prev, userMessage]);

      const assistantMessage = { role: 'assistant', content: '' };
      setMessages(prev => [...prev, assistantMessage]);

      try {
        const stream = await client.v1.chat.stream({
          componentId,
          sessionId: sessionStorage.getItem('chatSession'),
          messages: [...messages, userMessage]
        });

        for await (const chunk of stream) {
          if (chunk.type === 'content') {
            setMessages(prev => {
              const updated = [...prev];
              updated[updated.length - 1].content += chunk.content;
              return updated;
            });
          }
        }
      } finally {
        setStreaming(false);
      }
    };

    return (
      <div>
        {messages.map((msg, i) => (
          <div key={i} className={msg.role}>
            {msg.content}
          </div>
        ))}
        <input 
          onSubmit={(e) => sendMessage(e.target.value)}
          disabled={streaming}
        />
      </div>
    );
  }
  ```

  ```python Python theme={null}
  import asyncio
  import aiohttp

  async def stream_chat_response(client, component_id, message_text):
      """Stream chat responses with real-time display"""
      
      params = {
          "componentId": component_id,
          "sessionId": "session-789",
          "message": {
              "text": message_text
          }
      }
      
      async with client.v1.chat.stream_async(**params) as stream:
          full_response = ""
          
          async for chunk in stream:
              if chunk.type == "content":
                  print(chunk.content, end="", flush=True)
                  full_response += chunk.content
              elif chunk.type == "tool_call":
                  print(f"\n[Using tool: {chunk.tool}]")
              elif chunk.type == "done":
                  print(f"\n[Tokens used: {chunk.usage.tokens}]")
          
          return full_response

  # Usage
  async def main():
      response = await stream_chat_response(
          client, 
          "comp_123abc",
          "Explain the carbon cycle"
      )
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.models.v1.chat.ChatStreamParams;
  import java.io.BufferedReader;
  import java.io.InputStreamReader;
  import java.net.HttpURLConnection;
  import java.net.URL;

  public class StreamingChatExample {
      public void streamChat(String componentId, String messageText) {
          ChatStreamParams params = ChatStreamParams.builder()
              .componentId(componentId)
              .sessionId("session-789")
              .message(ChatStreamParams.Message.builder()
                  .text(messageText)
                  .build())
              .build();

          // Stream handling would typically be done through the SDK
          // This is a conceptual example
          client.v1().chat().stream(params, response -> {
              // Handle each chunk as it arrives
              if (response.getType().equals("content")) {
                  System.out.print(response.getContent());
              } else if (response.getType().equals("done")) {
                  System.out.println("\nChat completed");
              }
          });
      }
  }
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Chat;
  using StudyfetchSDK.Models.V1.Chat.ChatStreamParamsProperties;
  using System;
  using System.Threading.Tasks;

  public class StreamingChatExample
  {
      private readonly StudyfetchSDKClient _client;
      
      public StreamingChatExample()
      {
          _client = new StudyfetchSDKClient()
          {
              APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
              BaseUrl = new Uri("https://studyfetchapi.com")
          };
      }
      
      public async Task StreamChat(string componentId, string messageText)
      {
          var parameters = new ChatStreamParams()
          {
              ComponentID = componentId,
              SessionID = "session-789",
              Message = new Message()
              {
                  Text = messageText
              }
          };

          // Stream handling through the SDK
          await _client.V1.Chat.Stream(parameters);
          Console.WriteLine("Chat stream completed");
      }
  }
  ```
</CodeGroup>

## Managing Chat Embed Context

The context API allows you to dynamically push contextual information to specific embedded chat instances. This is particularly useful for applications where the chat component remains persistent while the surrounding content changes, such as:

* **Practice Tests**: Update context as users navigate between questions
* **Multi-page Tutorials**: Provide page-specific context without resetting chat history
* **Dynamic Content**: Keep the AI informed about what the user is currently viewing

### Push Context

Add context information to an embedded chat component:

<CodeGroup>
  ```javascript JavaScript theme={null}
  import StudyfetchSDK from '@studyfetch/sdk';

  const client = new StudyfetchSDK({
    apiKey: 'your-api-key',
    baseURL: 'https://studyfetchapi.com',
  });

  // Push context to a specific embed
  await client.v1.embed.context.push({
    token: 'embed-token-123',
    context: 'The user is now on Question 2 which discusses cellular respiration and the Krebs cycle.'
  });
  ```

  ```python Python theme={null}
  from studyfetch_sdk import StudyfetchSDK

  client = StudyfetchSDK(
      api_key="your-api-key",
      base_url="https://studyfetchapi.com",
  )

  # Push context to a specific embed
  client.v1.embed.context.push(
      token="embed-token-123",
      context="The user is now on Question 2 which discusses cellular respiration and the Krebs cycle."
  )
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.client.StudyfetchSdkClient;
  import com.studyfetch.javasdk.client.okhttp.StudyfetchSdkOkHttpClient;
  import com.studyfetch.javasdk.models.v1.embed.context.ContextPushParams;

  StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
      .fromEnv()
      .baseUrl("https://studyfetchapi.com")
      .build();

  // Push context to a specific embed
  ContextPushParams params = ContextPushParams.builder()
      .token("embed-token-123")
      .context("The user is now on Question 2 which discusses cellular respiration and the Krebs cycle.")
      .build();

  client.v1().embed().context().push(params);
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Embed.Context;
  using System;
  using System.Threading.Tasks;

  var client = new StudyfetchSDKClient()
  {
      APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
      BaseUrl = new Uri("https://studyfetchapi.com")
  };

  // Push context to a specific embed
  await client.V1.Embed.Context.Push(new ContextPushParams()
  {
      Token = "embed-token-123",
      Context = "The user is now on Question 2 which discusses cellular respiration and the Krebs cycle."
  });
  ```
</CodeGroup>

### Retrieve Context

Get the current context for an embedded chat component:

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Retrieve current context
  const currentContext = await client.v1.embed.context.retrieve({
    token: 'embed-token-123'
  });

  console.log('Current context:', currentContext);
  ```

  ```python Python theme={null}
  # Retrieve current context
  current_context = client.v1.embed.context.retrieve(
      token="embed-token-123"
  )

  print(f"Current context: {current_context}")
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.models.v1.embed.context.ContextRetrieveParams;

  // Retrieve current context
  ContextRetrieveParams retrieveParams = ContextRetrieveParams.builder()
      .token("embed-token-123")
      .build();

  client.v1().embed().context().retrieve(retrieveParams);
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK.Models.V1.Embed.Context;

  // Retrieve current context
  await client.V1.Embed.Context.Retrieve(new ContextRetrieveParams()
  {
      Token = "embed-token-123"
  });
  ```
</CodeGroup>

### Clear Context

Clear all context from an embedded chat component:

<CodeGroup>
  ```javascript JavaScript theme={null}
  // Clear all context
  await client.v1.embed.context.clear({
    token: 'embed-token-123'
  });
  ```

  ```python Python theme={null}
  # Clear all context
  client.v1.embed.context.clear(
      token="embed-token-123"
  )
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.models.v1.embed.context.ContextClearParams;

  // Clear all context
  ContextClearParams clearParams = ContextClearParams.builder()
      .token("embed-token-123")
      .build();

  client.v1().embed().context().clear(clearParams);
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK.Models.V1.Embed.Context;

  // Clear all context
  await client.V1.Embed.Context.Clear(new ContextClearParams()
  {
      Token = "embed-token-123"
  });
  ```
</CodeGroup>

### Complete Example: Practice Test with Context

Here's a complete example of using context management in a practice test application:

<CodeGroup>
  ```javascript JavaScript theme={null}
  class PracticeTestChat {
    constructor(client, embedToken) {
      this.client = client;
      this.embedToken = embedToken;
      this.currentQuestion = 0;
    }

    async navigateToQuestion(questionNumber, questionData) {
      // Clear previous context
      await this.client.v1.embed.context.clear({
        token: this.embedToken
      });

      // Push new context for current question
      const contextText = `The user is now on Question ${questionNumber}: ${questionData.title}. 
  Topic: ${questionData.topic}
  Content: ${questionData.content}`;

      await this.client.v1.embed.context.push({
        token: this.embedToken,
        context: contextText
      });

      this.currentQuestion = questionNumber;
    }

    async addSupplementalContext(additionalInfo) {
      // Add more context without clearing previous
      await this.client.v1.embed.context.push({
        token: this.embedToken,
        context: `Additional information: ${additionalInfo}`
      });
    }
  }

  // Usage
  const chat = new PracticeTestChat(client, 'embed-token-123');

  // User navigates to question 1
  await chat.navigateToQuestion(1, {
    title: 'Photosynthesis Process',
    topic: 'Biology - Cellular Processes',
    content: 'Explain the light-dependent reactions of photosynthesis...'
  });

  // User moves to question 2
  await chat.navigateToQuestion(2, {
    title: 'Cellular Respiration',
    topic: 'Biology - Cellular Processes',
    content: 'Describe the steps of the Krebs cycle...'
  });
  ```

  ```python Python theme={null}
  class PracticeTestChat:
      def __init__(self, client, embed_token):
          self.client = client
          self.embed_token = embed_token
          self.current_question = 0

      def navigate_to_question(self, question_number, question_data):
          # Clear previous context
          self.client.v1.embed.context.clear(token=self.embed_token)

          # Push new context for current question
          context_text = f"""The user is now on Question {question_number}: {question_data['title']}. 
  Topic: {question_data['topic']}
  Content: {question_data['content']}"""

          self.client.v1.embed.context.push(
              token=self.embed_token,
              context=context_text
          )

          self.current_question = question_number

      def add_supplemental_context(self, additional_info):
          # Add more context without clearing previous
          self.client.v1.embed.context.push(
              token=self.embed_token,
              context=f"Additional information: {additional_info}"
          )

  # Usage
  chat = PracticeTestChat(client, "embed-token-123")

  # User navigates to question 1
  chat.navigate_to_question(1, {
      "title": "Photosynthesis Process",
      "topic": "Biology - Cellular Processes",
      "content": "Explain the light-dependent reactions of photosynthesis..."
  })

  # User moves to question 2
  chat.navigate_to_question(2, {
      "title": "Cellular Respiration",
      "topic": "Biology - Cellular Processes",
      "content": "Describe the steps of the Krebs cycle..."
  })
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.client.StudyfetchSdkClient;
  import com.studyfetch.javasdk.models.v1.embed.context.*;

  public class PracticeTestChat {
      private final StudyfetchSdkClient client;
      private final String embedToken;
      private int currentQuestion;

      public PracticeTestChat(StudyfetchSdkClient client, String embedToken) {
          this.client = client;
          this.embedToken = embedToken;
          this.currentQuestion = 0;
      }

      public void navigateToQuestion(int questionNumber, QuestionData questionData) {
          // Clear previous context
          ContextClearParams clearParams = ContextClearParams.builder()
              .token(embedToken)
              .build();
          client.v1().embed().context().clear(clearParams);

          // Push new context for current question
          String contextText = String.format(
              "The user is now on Question %d: %s.%nTopic: %s%nContent: %s",
              questionNumber,
              questionData.title,
              questionData.topic,
              questionData.content
          );

          ContextPushParams pushParams = ContextPushParams.builder()
              .token(embedToken)
              .context(contextText)
              .build();
          client.v1().embed().context().push(pushParams);

          this.currentQuestion = questionNumber;
      }

      public void addSupplementalContext(String additionalInfo) {
          // Add more context without clearing previous
          ContextPushParams params = ContextPushParams.builder()
              .token(embedToken)
              .context("Additional information: " + additionalInfo)
              .build();
          client.v1().embed().context().push(params);
      }

      static class QuestionData {
          String title;
          String topic;
          String content;
      }
  }

  // Usage
  PracticeTestChat chat = new PracticeTestChat(client, "embed-token-123");

  PracticeTestChat.QuestionData q1 = new PracticeTestChat.QuestionData();
  q1.title = "Photosynthesis Process";
  q1.topic = "Biology - Cellular Processes";
  q1.content = "Explain the light-dependent reactions of photosynthesis...";

  chat.navigateToQuestion(1, q1);

  PracticeTestChat.QuestionData q2 = new PracticeTestChat.QuestionData();
  q2.title = "Cellular Respiration";
  q2.topic = "Biology - Cellular Processes";
  q2.content = "Describe the steps of the Krebs cycle...";

  chat.navigateToQuestion(2, q2);
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Embed.Context;
  using System;
  using System.Threading.Tasks;

  public class PracticeTestChat
  {
      private readonly StudyfetchSDKClient _client;
      private readonly string _embedToken;
      private int _currentQuestion;

      public PracticeTestChat(StudyfetchSDKClient client, string embedToken)
      {
          _client = client;
          _embedToken = embedToken;
          _currentQuestion = 0;
      }

      public async Task NavigateToQuestion(int questionNumber, QuestionData questionData)
      {
          // Clear previous context
          await _client.V1.Embed.Context.Clear(new ContextClearParams()
          {
              Token = _embedToken
          });

          // Push new context for current question
          var contextText = $@"The user is now on Question {questionNumber}: {questionData.Title}. 
  Topic: {questionData.Topic}
  Content: {questionData.Content}";

          await _client.V1.Embed.Context.Push(new ContextPushParams()
          {
              Token = _embedToken,
              Context = contextText
          });

          _currentQuestion = questionNumber;
      }

      public async Task AddSupplementalContext(string additionalInfo)
      {
          // Add more context without clearing previous
          await _client.V1.Embed.Context.Push(new ContextPushParams()
          {
              Token = _embedToken,
              Context = $"Additional information: {additionalInfo}"
          });
      }

      public class QuestionData
      {
          public string Title { get; set; }
          public string Topic { get; set; }
          public string Content { get; set; }
      }
  }

  // Usage
  var client = new StudyfetchSDKClient()
  {
      APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
      BaseUrl = new Uri("https://studyfetchapi.com")
  };

  var chat = new PracticeTestChat(client, "embed-token-123");

  // User navigates to question 1
  await chat.NavigateToQuestion(1, new PracticeTestChat.QuestionData
  {
      Title = "Photosynthesis Process",
      Topic = "Biology - Cellular Processes",
      Content = "Explain the light-dependent reactions of photosynthesis..."
  });

  // User moves to question 2
  await chat.NavigateToQuestion(2, new PracticeTestChat.QuestionData
  {
      Title = "Cellular Respiration",
      Topic = "Biology - Cellular Processes",
      Content = "Describe the steps of the Krebs cycle..."
  });
  ```
</CodeGroup>

### Context API Parameters

<ParamField body="token" type="string" required>
  The embed token for the specific chat instance. Obtained from `generateEmbed()` response.
</ParamField>

<ParamField body="context" type="string" required>
  The context string to add to the chat. Can include any relevant information about what the user is currently viewing or doing.
</ParamField>

## Retrieving Chat Feedback

You can retrieve feedback data (thumbs up/down) from users interacting with your chat components:

<CodeGroup>
  ```javascript JavaScript theme={null}
  import StudyfetchSDK from '@studyfetch/sdk';

  const client = new StudyfetchSDK({
    apiKey: 'your-api-key',
    baseURL: 'https://studyfetchapi.com',
  });

  // Retrieve all feedback
  await client.v1.chat.retrieveFeedback();

  // Filter feedback by component
  await client.v1.chat.retrieveFeedback({
    componentId: 'comp_123abc',
    startDate: '2025-01-01T00:00:00Z',
    endDate: '2025-12-31T23:59:59Z',
    feedbackType: 'thumbsUp',
    limit: '100',
    skip: '0'
  });
  ```

  ```python Python theme={null}
  from studyfetch_sdk import StudyfetchSDK

  client = StudyfetchSDK(
      api_key="your-api-key",
      base_url="https://studyfetchapi.com",
  )

  # Retrieve all feedback
  client.v1.chat.retrieve_feedback()

  # Filter feedback by component
  client.v1.chat.retrieve_feedback(
      component_id="comp_123abc",
      start_date="2025-01-01T00:00:00Z",
      end_date="2025-12-31T23:59:59Z",
      feedback_type="thumbsUp",
      limit="100",
      skip="0"
  )
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.client.StudyfetchSdkClient;
  import com.studyfetch.javasdk.client.okhttp.StudyfetchSdkOkHttpClient;
  import com.studyfetch.javasdk.models.v1.chat.ChatRetrieveFeedbackParams;

  StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
      .fromEnv()
      .baseUrl("https://studyfetchapi.com")
      .build();

  // Retrieve all feedback
  client.v1().chat().retrieveFeedback();

  // Filter feedback by component
  ChatRetrieveFeedbackParams params = ChatRetrieveFeedbackParams.builder()
      .componentId("comp_123abc")
      .startDate("2025-01-01T00:00:00Z")
      .endDate("2025-12-31T23:59:59Z")
      .feedbackType(ChatRetrieveFeedbackParams.FeedbackType.THUMBS_UP)
      .limit("100")
      .skip("0")
      .build();

  client.v1().chat().retrieveFeedback(params);
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Chat;
  using StudyfetchSDK.Models.V1.Chat.ChatRetrieveFeedbackParamsProperties;
  using System;
  using System.Threading.Tasks;

  var client = new StudyfetchSDKClient()
  {
      APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
      BaseUrl = new Uri("https://studyfetchapi.com")
  };

  // Retrieve all feedback
  await client.V1.Chat.RetrieveFeedback();

  // Filter feedback by component
  await client.V1.Chat.RetrieveFeedback(new ChatRetrieveFeedbackParams()
  {
      ComponentID = "comp_123abc",
      StartDate = "2025-01-01T00:00:00Z",
      EndDate = "2025-12-31T23:59:59Z",
      FeedbackType = FeedbackType.ThumbsUp,
      Limit = "100",
      Skip = "0"
  });
  ```
</CodeGroup>

### Feedback Parameters

<ParamField body="componentId" type="string">
  Filter feedback by specific component ID
</ParamField>

<ParamField body="userId" type="string">
  Filter feedback by specific user ID
</ParamField>

<ParamField body="startDate" type="string">
  Start date for feedback range (ISO 8601 format)
</ParamField>

<ParamField body="endDate" type="string">
  End date for feedback range (ISO 8601 format)
</ParamField>

<ParamField body="feedbackType" type="enum">
  Filter by feedback type:

  * `thumbsUp` - Positive feedback
  * `thumbsDown` - Negative feedback
</ParamField>

<ParamField body="limit" type="string" default="100">
  Number of records to return
</ParamField>

<ParamField body="skip" type="string" default="0">
  Number of records to skip (for pagination)
</ParamField>

## Retrieving Feedback Context

Get the specific message and full conversation for a feedback item to understand the context of user feedback:

<CodeGroup>
  ```javascript JavaScript theme={null}
  import StudyfetchSDK from '@studyfetch/sdk';

  const client = new StudyfetchSDK({
    apiKey: 'your-api-key',
    baseURL: 'https://studyfetchapi.com',
  });

  // Retrieve feedback context for a specific feedback ID
  await client.v1.chat.retrieveFeedbackContext({
    feedbackId: 'feedback_123abc'
  });
  ```

  ```python Python theme={null}
  from studyfetch_sdk import StudyfetchSDK

  client = StudyfetchSDK(
      api_key="your-api-key",
      base_url="https://studyfetchapi.com",
  )

  # Retrieve feedback context for a specific feedback ID
  client.v1.chat.retrieve_feedback_context(
      feedback_id="feedback_123abc"
  )
  ```

  ```java Java theme={null}
  import com.studyfetch.javasdk.client.StudyfetchSdkClient;
  import com.studyfetch.javasdk.client.okhttp.StudyfetchSdkOkHttpClient;
  import com.studyfetch.javasdk.models.v1.chat.ChatRetrieveFeedbackContextParams;

  StudyfetchSdkClient client = StudyfetchSdkOkHttpClient.builder()
      .fromEnv()
      .baseUrl("https://studyfetchapi.com")
      .build();

  // Retrieve feedback context for a specific feedback ID
  ChatRetrieveFeedbackContextParams params = ChatRetrieveFeedbackContextParams.builder()
      .feedbackId("feedback_123abc")
      .build();

  client.v1().chat().retrieveFeedbackContext(params);
  ```

  ```csharp C# theme={null}
  using StudyfetchSDK;
  using StudyfetchSDK.Models.V1.Chat;
  using System;
  using System.Threading.Tasks;

  var client = new StudyfetchSDKClient()
  {
      APIKey = Environment.GetEnvironmentVariable("STUDYFETCH_API_KEY"),
      BaseUrl = new Uri("https://studyfetchapi.com")
  };

  // Retrieve feedback context for a specific feedback ID
  await client.V1.Chat.RetrieveFeedbackContext(new ChatRetrieveFeedbackContextParams()
  {
      FeedbackID = "feedback_123abc"
  });
  ```
</CodeGroup>

### Feedback Context Parameters

<ParamField body="feedbackId" type="string" required>
  The ID of the feedback item to retrieve context for
</ParamField>
