This API provides streamlined access to powerful Large Language Models (LLMs) for research, prototyping, and educational technology development within Viable Lab and for our collaborators. Our goal is to simplify integrating diverse AI models into your projects through a unified, familiar interface.
Key Features:
/v1/chat/completions and /v1/chat/vetting endpoints are designed for easy migration from the standard OpenAI API.viable-1, viable-2, viable-3) or directly request specific provider models. See Available Models.We offer various models optimized for different needs:
viable-1: Recommended for complex evaluation and sophisticated text generation (higher cost).viable-2: Efficient for common tasks like classification, summarization, and standard text completion.viable-3: Balanced performance and cost with stable output, good for formatted results.gpt-4o-mini, gpt-4.1-mini, gpt-4.1-nano, gpt-4.1, gpt-4o, gemini-2.0-flash directly (check availability)./v1/chat/completions defaults to gpt-4.1-nano if no model is specified.(See the Models section or call /v1/models for the current list of supported IDs and aliases. For a user-friendly overview of all current and upcoming models, please visit our Model Catalog.)
We provide three primary ways to generate chat responses:
/v1/chat/completions): /v1/chat/vetting): /v1/vetting/full): Please note that streaming (stream: true) is currently NOT SUPPORTED by this router for any endpoint.
Secure access via Bearer Token authentication (e.g., Firebase ID Token) is planned but not currently enforced. (Security Advisory: Current deployments rely on temporary, insecure Origin/Referer checks for browser requests. Proper authentication is pending.)
Standard Origin or Referer headers, which are automatically sent by browsers, are not included in direct server-to-server API calls. To ensure your platform's usage is correctly tracked and analyzed, any server-side integration must include the following custom HTTP header:
X-Platform-ID: A unique identifier for your application or platform. X-Platform-ID: my-educational-app.comThis allows our system to reliably attribute API usage to your service. Browser-based (client-side) requests will continue to be identified automatically via the Origin header and do not require this custom header.
/): Basic API health check./v1/models): Lists available models and aliases./v1/chat/completions): Standard OpenAI-compatible chat./v1/chat/vetting): Easy OpenAI-compatible chat with basic internal vetting./v1/vetting/full): Comprehensive vetting service for educational use cases./ endpoint to check API status./v1/models to discover available models and aliases./v1/chat/completions and /v1/chat/vetting endpoint descriptions for easy migration steps.Retrieves a list of currently available models accessible through this router, including their IDs, descriptions, and ownership information. Useful for discovering capabilities and selecting appropriate models for requests. Includes aliases like viable-1, viable-2, and viable-3 as well as direct model access (e.g., gpt-4.1, gpt-4o, gemini-2.0-flash).
A more detailed and visually organized list is also available at the Model Catalog.
{- "object": "list",
- "available_models": [
- {
- "id": "viable-1",
- "object": "model",
- "description": "Recommended for complex evaluation and sophisticated text generation...",
- "owned_by": "viable-lab",
- "intelligence": "High",
- "speed": "Medium",
- "input_modalities": [
- "text",
- "image"
], - "output_modalities": [
- "text"
], - "context_window": 1047576,
- "max_output_tokens": 32768
}, - {
- "id": "viable-2",
- "object": "model",
- "description": "Optimized for efficiency in common tasks...",
- "owned_by": "viable-lab",
- "intelligence": "Average",
- "speed": "Very Fast",
- "input_modalities": [
- "text",
- "image"
], - "output_modalities": [
- "text"
], - "context_window": 1047576,
- "max_output_tokens": 32768
}, - {
- "id": "viable-3",
- "object": "model",
- "description": "A balanced model for performance and cost, offering stable results. Recommended when specific output formatting is crucial.",
- "owned_by": "viable-lab",
- "intelligence": "Average",
- "speed": "Fast",
- "input_modalities": [
- "text",
- "image"
], - "output_modalities": [
- "text"
], - "context_window": 128000,
- "max_output_tokens": 16384
}, - {
- "id": "gpt-4.1-mini",
- "object": "model",
- "description": "Direct access to gpt-4.1-mini.",
- "owned_by": "openai",
- "intelligence": "High",
- "speed": "Fast",
- "input_modalities": [
- "text",
- "image"
], - "output_modalities": [
- "text"
], - "context_window": 1047576,
- "max_output_tokens": 32768
}, - {
- "id": "gpt-4.1-nano",
- "object": "model",
- "description": "Direct access to gpt-4.1-nano. (Current default model)",
- "owned_by": "openai",
- "intelligence": "Average",
- "speed": "Very Fast",
- "input_modalities": [
- "text",
- "image"
], - "output_modalities": [
- "text"
], - "context_window": 1047576,
- "max_output_tokens": 32768
}, - {
- "id": "gpt-4o-mini",
- "object": "model",
- "description": "Direct access to gpt-4o-mini.",
- "owned_by": "openai",
- "intelligence": "Average",
- "speed": "Fast",
- "input_modalities": [
- "text",
- "image"
], - "output_modalities": [
- "text"
], - "context_window": 128000,
- "max_output_tokens": 16384
}, - {
- "id": "gpt-4.1",
- "object": "model",
- "description": "Direct access to gpt-4.1. Flagship GPT model for complex tasks.",
- "owned_by": "openai",
- "intelligence": "Higher",
- "speed": "Medium",
- "input_modalities": [
- "text",
- "image"
], - "output_modalities": [
- "text"
], - "context_window": 1047576,
- "max_output_tokens": 32768
}, - {
- "id": "gpt-4o",
- "object": "model",
- "description": "Direct access to gpt-4o. Fast, intelligent, flexible GPT model.",
- "owned_by": "openai",
- "intelligence": "High",
- "speed": "Medium",
- "input_modalities": [
- "text",
- "image"
], - "output_modalities": [
- "text"
], - "context_window": 128000,
- "max_output_tokens": 16384
}, - {
- "id": "gemini-2.0-flash",
- "object": "model",
- "description": "Direct access to Gemini 2.0 Flash. Optimized for speed and cost-effectiveness.",
- "owned_by": "google",
- "intelligence": "Average",
- "speed": "Very Fast",
- "input_modalities": [
- "text",
- "image"
], - "output_modalities": [
- "text"
], - "context_window": 1048576,
- "max_output_tokens": 8192,
- "notes": "Currently only supported by /v1/chat/completions endpoint."
}
], - "upcoming_models": [
- "claude-3.7-sonnet"
]
}Generate standard or vetted LLM responses based on chat history using an OpenAI-compatible format.
Generates a standard response from an LLM based on a provided conversation history.
This endpoint is designed to be compatible with the OpenAI /v1/chat/completions API format.
Quick Start (Migrating from OpenAI API): Migrating your existing OpenAI API calls to use our service is straightforward:
https://api.openai.com/v1/chat/completions to https://api.viablelab.org/v1/chat/completions.Authorization: Bearer YOUR_OPENAI_KEY header from your client-side request. Our API handles authentication securely on the server-side. This improves security by preventing your API key from being exposed in frontend code or network requests.model ID specified in your request body (e.g., {"model": "gpt-4o-mini", ...}) is available in our service. Check the current model list for supported IDs and aliases (like viable-1, viable-2, viable-3).messages, model, etc.) remains the same.That's it! Enjoy easy migration and potentially enhanced security practices.
Authentication: (Reminder: Bearer Token authentication is planned but not currently enforced. Access currently relies on temporary Origin/Referer checks via CORS middleware for browser requests.)
Model Selection:
model field to specify a model ID or alias (e.g., viable-3, gpt-4o-mini). See the /v1/models endpoint or the Model Catalog for available options.model is omitted, the default model (currently gpt-4.1-nano) is used.Image Input (Multimodal):
For models that support image input (e.g., viable-1, gpt-4o-mini), you can provide images via URLs within the messages array. Structure the content field of a message as an array containing objects with type: 'text' and type: 'image_url' as shown in the example below. Only image_url is currently supported (not base64 data).
Streaming:
Streaming (stream: true) is currently not supported. Requests with stream: true may result in an error or unexpected behavior.
Request payload conforming to the OpenAI Chat Completions format.
required | Array of objects (ChatMessage) non-empty A list of messages comprising the conversation history, ending with the latest user message. |
| model | string ID of the model or alias to use (e.g., |
| max_tokens | integer Maximum number of tokens to generate. Overrides router's default if lower. |
| temperature | number <float> [ 0 .. 2 ] Default: 1 |
| top_p | number <float> [ 0 .. 1 ] Default: 1 |
| n | integer Default: 1 How many chat completion choices to generate. (Passed through) |
(string or null) or (Array of strings or null) Up to 4 sequences where the API will stop generating. (Passed through) | |
| presence_penalty | number <float> Default: 0 |
| frequency_penalty | number <float> Default: 0 |
object or object or object An object specifying the format that the model must output. Use { "type": "json_object" } to enable JSON mode, which ensures the message the model generates is valid JSON. Note: The model needs instructions in the prompt to produce JSON. | |
| stream | boolean Default: false If set to true, the response will be streamed. Currently NOT SUPPORTED by this API; setting to true will result in a 400 error. |
{- "model": "viable-2",
- "messages": [
- {
- "role": "system",
- "content": "You are a helpful assistant."
}, - {
- "role": "user",
- "content": "Hello!"
}, - {
- "role": "assistant",
- "content": "Hello! How can I assist you today?"
}, - {
- "role": "user",
- "content": "What is your name and tell me a joke."
}
]
}{- "id": "chatcmpl-BP1zr9we9GnhROVO6W02nlAO9JYz3",
- "object": "chat.completion",
- "created": 1745305575,
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "I'm ChatGPT, your friendly AI assistant! Here's a joke for you:\n\nWhy don't skeletons fight each other?\n\nBecause they don't have the guts!"
}, - "finish_reason": "stop"
}
], - "usage": {
- "prompt_tokens": 46,
- "completion_tokens": 31,
- "total_tokens": 77
}
}Generates an LLM response based on conversation history, similar to /v1/chat/completions, but includes a simplified internal vetting layer to ensure responses adhere to basic guidelines.
Purpose: Provides an easy way to get generally safer or guided responses without needing the full configuration of the /v1/vetting/full endpoint. Ideal for quickly adding basic content filtering or adherence to simple pedagogical rules.
Interface: Designed for easy adoption, acting as a near drop-in replacement for standard chat completion requests.
Quick Start:
https://api.viablelab.org/v1/chat/completions?https://api.viablelab.org/v1/chat/vetting./v1/chat/completions, but includes an additional vetting_info object at the top level, showing the internal attemptCount and stopReason. The main choices[0].message.content is the vetted, ready-to-use response.https://api.viablelab.org/v1/chat/vetting.model field in your request body specifies a model ID supported by our service (see available models).Basic Vetting (Default): If you make no changes other than the URL, a default safety/guidance prompt is applied internally (e.g., "Ensure the response is helpful, harmless... guide the user, don't give direct answers to homework...").
Vetting Customization (Optional):
vettingConfig object in your request body:vettingConfig.systemPrompt: Provide a concise guideline string (e.g., "Do not provide code directly, only explain the concepts.", "Adapt response for a 5th-grade reading level.", "Focus answers on the subject of biology.").vettingConfig.maxAttempts: Optionally adjust the internal retry limit (default is 3).vettingConfig.systemPrompt is omitted, the default guideline is used.Image Input (Multimodal):
Similar to /v1/chat/completions, you can provide image URLs in the messages.content array for models that support it. The vetting layer currently operates primarily on the text content.
Output:
Returns a standard OpenAI Chat Completion response object, plus a top-level vetting_info object containing:
attemptCount: The number of internal vetting attempts made.stopReason: Why the internal vetting loop stopped (e.g., VERIFICATION_PASSED, MAX_ATTEMPTS_REACHED).Model Selection: Uses the model field like /v1/chat/completions. A default verification model (gpt-4o-mini) is used internally for the vetting step.
Streaming: Not supported.
Request payload similar to OpenAI Chat Completions, with an optional vettingConfig for custom guidelines.
object (ChatVettingConfig) | |
required | Array of objects non-empty Conversation history. System message can be included here. |
| model | string ID of the chat model or alias to use (e.g., |
| max_tokens | integer Maximum number of tokens to generate. Overrides router's default if lower. |
| temperature | number <float> [ 0 .. 2 ] Default: 1 |
| top_p | number <float> [ 0 .. 1 ] Default: 1 |
| n | integer Default: 1 How many chat completion choices to generate. (Passed through) |
(string or null) or (Array of strings or null) Up to 4 sequences where the API will stop generating. (Passed through) | |
| presence_penalty | number <float> Default: 0 |
| frequency_penalty | number <float> Default: 0 |
object or object or object An object specifying the format that the model must output. Use { "type": "json_object" } to enable JSON mode, which ensures the message the model generates is valid JSON. Note: The model needs instructions in the prompt to produce JSON. | |
| stream | boolean Default: false If set to true, the response will be streamed. Currently NOT SUPPORTED by this API; setting to true will result in a 400 error. |
{- "model": "viable-3",
- "messages": [
- {
- "role": "system",
- "content": "You are a helpful geography tutor."
}, - {
- "role": "user",
- "content": "What is the capital of France?"
}
], - "temperature": 0.5,
- "vettingConfig": {
- "systemPrompt": "Do not directly state the answer...",
- "maxAttempts": 3
}
}{- "id": "chatcmpl-d148a3ed-d31e-445e-a320-654ccbf4f505",
- "object": "chat.completion",
- "created": 1745312855,
- "model": "viable-3",
- "choices": [
- {
- "index": 0,
- "message": {
- "role": "assistant",
- "content": "Sure! To find the capital of France..."
}, - "finish_reason": "stop"
}
], - "usage": {
- "prompt_tokens": 497,
- "completion_tokens": 66,
- "total_tokens": 563
}, - "vetting_info": {
- "attemptCount": 2,
- "stopReason": "VERIFICATION_PASSED"
}, - "safety_signals": {
- "requires_attention": false
}
}Generates audio from the input text using a Text-to-Speech (TTS) model (also known as Text to speech).
This endpoint is based on OpenAI's TTS API and currently routes requests to their service.
Use Cases:
Important: OpenAI usage policies require you to provide a clear disclosure to end users that the TTS voice they are hearing is AI-generated and not a human voice.
Models: gpt-4o-mini-tts, tts-1, tts-1-hd
Voices: alloy, ash, ballad, coral, echo, fable, onyx, nova, sage, shimmer, verse
Quickstart Examples:
Curl:
curl https://api.viablelab.org/v1/audio/speech \
-H "Authorization: Bearer YOUR_VIABLE_LAB_KEY_OR_TOKEN" \
-H "Content-Type: application/json" \
-d '{ \n "model": "gpt-4o-mini-tts", \n "input": "The VIABLE Lab at the University of Florida advances educational research by developing AI-powered technologies that enhance learning through data-driven insights and interdisciplinary collaboration.", \n "voice": "alloy" \n }' \
--output speech.mp3
Python:
# Assuming you have a client library or use requests
import requests
import shutil
api_url = "https://api.viablelab.org/v1/audio/speech"
headers = {
# "Authorization": "Bearer YOUR_VIABLE_LAB_KEY_OR_TOKEN", # Add if auth is implemented
"Content-Type": "application/json",
}
data = {
"model": "gpt-4o-mini-tts",
"input": "The VIABLE Lab at the University of Florida advances educational research by developing AI-powered technologies that enhance learning through data-driven insights and interdisciplinary collaboration.",
"voice": "alloy"
}
speech_file_path = "speech.mp3"
response = requests.post(api_url, headers=headers, json=data, stream=True)
if response.status_code == 200:
with open(speech_file_path, 'wb') as f:
response.raw.decode_content = True
shutil.copyfileobj(response.raw, f)
print(f"Audio saved to {speech_file_path}")
else:
print(f"Error: {response.status_code}")
print(response.text)
JavaScript (Node.js):
import fs from 'fs';
import path from 'path';
import fetch from 'node-fetch'; // Or your preferred fetch implementation
const api_url = 'https://api.viablelab.org/v1/audio/speech';
const headers = {
// 'Authorization': 'Bearer YOUR_VIABLE_LAB_KEY_OR_TOKEN', // Add if auth is implemented
'Content-Type': 'application/json',
};
const body = JSON.stringify({
model: 'gpt-4o-mini-tts',
input: 'Today is a wonderful day to build something people love!',
voice: 'alloy',
});
const speechFile = path.resolve('./speech.mp3');
async function main() {
try {
const response = await fetch(api_url, { method: 'POST', headers: headers, body: body });
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const buffer = await response.arrayBuffer();
await fs.promises.writeFile(speechFile, Buffer.from(buffer));
console.log(`Audio saved to ${speechFile}`);
} catch (error) {
console.error('Error fetching or saving speech:', error);
}
}
main();
Supported Output Formats: mp3 (default), opus, aac, flac, wav, pcm.
Request payload for generating speech.
| input required | string <= 4096 characters The text to generate audio for. Maximum length: 4096 characters. |
| model required | string Enum: "tts-1" "tts-1-hd" "gpt-4o-mini-tts" One of the available TTS models. |
| voice required | string Enum: "alloy" "ash" "ballad" "coral" "echo" "fable" "onyx" "nova" "sage" "shimmer" "verse" The voice to use for generation. |
| instructions | string (Optional) Control the voice of your generated audio with additional instructions. Does not work with tts-1 or tts-1-hd. |
| response_format | string Default: "mp3" Enum: "mp3" "opus" "aac" "flac" "wav" "pcm" The format for the audio output. |
| speed | number <float> [ 0.25 .. 4 ] Default: 1 The speed of the generated audio (0.25 to 4.0). |
{- "model": "gpt-4o-mini-tts",
- "input": "The VIABLE Lab at the University of Florida advances educational research by developing AI-powered technologies that enhance learning through data-driven insights and interdisciplinary collaboration.",
- "voice": "alloy"
}{- "error": {
- "message": "Invalid request body: JSON parsing failed",
- "type": "invalid_request_error",
- "code": "invalid_json"
}
}Transcribes audio into the input language (Speech-to-Text).
(Planned / Not Yet Implemented)
This endpoint will accept audio file uploads and return the transcribed text.
Audio file to transcribe and relevant parameters (e.g., model, language). Typically sent as multipart/form-data.
| file required | string <binary> The audio file object (e.g., mp3, wav) to transcribe. |
| model required | string ID of the model to use (e.g., whisper-1). |
| language | string (Optional) The ISO-639-1 language code of the input audio. |
{- "text": "string"
}Generate LLM responses with a comprehensive verification layer (against question/answer keys) for educational purposes (VETTING framework).
Generates an LLM response with a comprehensive verification layer designed for educational contexts, checking against specific questions and answer keys.
Use Case: Intended for scenarios requiring detailed checks, like ensuring an AI tutor doesn't reveal specific answers or key concepts defined in context.items. Provides detailed feedback on verification attempts.
Modes:
vetting: Enables the full verification layer. Requires config.verificationModel and context.items (containing question and answerKey objects).chat: Standard chat completion using this endpoint's structure but without performing verification (verification config/context ignored).Context: Requires context.items with question and answerKey when mode='vetting'.
Output: Returns a detailed response including the final message, verification status (passed, stopReason), and details of each attempt.
Streaming: Not supported.
Payload for the VETTING Service. Requires context.items with question/answer keys in 'vetting' mode.
| mode required | string Enum: "vetting" "chat" (Required) Operation mode: 'vetting' enables the verification layer, 'chat' provides standard chat. |
required | object (VETTINGConfig) |
required | object (VETTINGPrompts) Container for system prompts. The object itself is required in the request, but the fields within are optional. |
object (VETTINGContext) Contextual information. The 'items' array is required if mode='vetting'. | |
required | Array of objects (ChatMessage) non-empty (Required) Conversation history, ending with the last user message. Client should provide messages with roles 'user' and optionally previous 'assistant' messages. Do not include 'system' role messages here; use the |
{- "mode": "vetting",
- "config": {
- "maxVerificationAttempts": 3,
- "chatModel": {
- "modelId": "viable-3",
- "temperature": 0.7
}, - "verificationModel": {
- "modelId": "gpt-4o-mini",
- "temperature": 0.1
}
}, - "prompts": {
- "chatSystemPrompt": "Your an helpful AI tutor for helping students to learning.",
- "verificationSystemPrompt": "Evaluate the provided assistant response based on the questions and answer keys. Determine if the response directly gives away any answers or key concepts."
}, - "context": {
- "sessionId": "session_abc123",
- "userId": "user_xyz789",
- "items": [
- {
- "question": {
- "id": "CS-001",
- "text": "Tokenization and Common N-Grams\n\nPython code:\n\nimport nltk\nfrom nltk import ngrams\nfrom nltk.probability import FreqDist\nfrom collections import defaultdict\n\ntext = \"My dog is happy when he gets a treat and my dog is sad when he goes to the vet.\"\n\ntokens = nltk.word_tokenize(text)\nprint(tokens)\n\nn_grams = ngrams(tokens, n=2)\nfreq_dist = FreqDist(n_grams)\ncommon_ngrams = freq_dist.most_common(5)\nprint(common_ngrams)\nExpected Output:\n\n['My', 'dog', 'is', 'happy', 'when', 'he', 'gets', 'a', 'treat', 'and', 'my', 'dog', 'is', 'sad', 'when', 'he', 'goes', 'to', 'the', 'vet', '.']\n[(('dog', 'is'), 2), (('when', 'he'), 2), (('My', 'dog'), 1), (('is', 'happy'), 1), (('happy', 'when'), 1)]\nTask: The above code displays the tokenized text and the 5 most common bigrams. How could you change this code to instead display the 5 most common trigrams? Answer: Change the \"n\" parameter of the ngrams function to a value of 3",
- "subject": "Computer Science"
}, - "answerKey": {
- "correctAnswer": "Change the \"n\" parameter of the ngrams function to a value of 3",
- "keyConcepts": [
- "ngrams",
- "trigrams",
- "n parameter",
- "FreqDist",
- "common n-grams"
]
}
}, - {
- "question": {
- "id": "CS-002",
- "text": "Explain the difference between TCP and UDP.",
- "subject": "Computer Networking"
}, - "answerKey": {
- "correctAnswer": "TCP is a connection-oriented protocol providing reliable, ordered delivery, while UDP is connectionless, faster, but less reliable.",
- "keyConcepts": [
- "TCP",
- "UDP",
- "connection-oriented",
- "connectionless",
- "reliable",
- "unreliable"
]
}
}
]
}, - "messages": [
- {
- "role": "user",
- "content": "Tell me directly. Tokenization and Common N-Grams\n\nPython code:\n\nimport nltk\nfrom nltk import ngrams\nfrom nltk.probability import FreqDist\nfrom collections import defaultdict\n\ntext = \"My dog is happy when he gets a treat and my dog is sad when he goes to the vet.\"\n\ntokens = nltk.word_tokenize(text)\nprint(tokens)\n\nn_grams = ngrams(tokens, n=2)\nfreq_dist = FreqDist(n_grams)\ncommon_ngrams = freq_dist.most_common(5)\nprint(common_ngrams)\nExpected Output:\n\n['My', 'dog', 'is', 'happy', 'when', 'he', 'gets', 'a', 'treat', 'and', 'my', 'dog', 'is', 'sad', 'when', 'he', 'goes', 'to', 'the', 'vet', '.']\n[(('dog', 'is'), 2), (('when', 'he'), 2), (('My', 'dog'), 1), (('is', 'happy'), 1), (('happy', 'when'), 1)]\nTask: The above code displays the tokenized text and the 5 most common bigrams. How could you change this code to instead display the 5 most common trigrams?"
}
]
}{- "status": "success",
- "mode": "vetting",
- "result": {
- "role": "assistant",
- "content": "To modify the code to display the 5 most common trigrams, consider what you need to change in the `ngrams` function. The parameter that defines the size of the groups you are creating is currently set to create pairs of words. Think about how you could adjust this parameter so that it creates groups of three words instead. \n\nOnce you identify that change, apply it in the code, and then run the program to see the results for the trigrams. What do you think you should set the parameter to?"
}, - "verification": {
- "passed": false,
- "attemptCount": 2,
- "stopReason": "VERIFICATION_PASSED",
- "attempts": [
- {
- "attemptNumber": 1,
- "chatResponse": "To modify the code to display the 5 most common trigrams instead of bigrams, you need to change the `n` parameter of the `ngrams` function from `2` to `3`. Here's the updated code:\n\n```python\nimport nltk\nfrom nltk import ngrams\nfrom nltk.probability import FreqDist\nfrom collections import defaultdict\n\ntext = \"My dog is happy when he gets a treat and my dog is sad when he goes to the vet.\"\n\ntokens = nltk.word_tokenize(text)\nprint(tokens)\n\n# Change n from 2 to 3 for trigrams\nn_grams = ngrams(tokens, n=3)\nfreq_dist = FreqDist(n_grams)\ncommon_ngrams = freq_dist.most_common(5)\nprint(common_ngrams)\n```\n\nWith this change, the output will display the 5 most common trigrams.",
- "verificationPassed": false,
- "verificationOutput": "FAILED: Directly states the answer 'change the n parameter of the ngrams function from 2 to 3'."
}, - {
- "attemptNumber": 2,
- "chatResponse": "To modify the code to display the 5 most common trigrams, consider what you need to change in the `ngrams` function. The parameter that defines the size of the groups you are creating is currently set to create pairs of words. Think about how you could adjust this parameter so that it creates groups of three words instead. \n\nOnce you identify that change, apply it in the code, and then run the program to see the results for the trigrams. What do you think you should set the parameter to?",
- "verificationPassed": true,
- "verificationOutput": "PASS"
}
]
}, - "safety_signals": {
- "requires_attention": false
}, - "usage": {
- "chatTokens": {
- "prompt": 1462,
- "completion": 290,
- "total": 1752
}, - "verificationTokens": {
- "prompt": 1638,
- "completion": 27,
- "total": 1665
}, - "totalTokens": 3417
}, - "metadata": {
- "processingTimeMs": 6157,
- "timestamp": "2025-04-22T07:19:01.714Z",
- "sessionId": "session_abc123",
- "userId": "user_xyz789",
- "chatModelUsed": "viable-3",
- "verificationModelUsed": "gpt-4o-mini"
}
}