docs: add scenarios user guide and API reference

- Add /docs/scenarios page with comprehensive user guide
  - Overview of what scenarios are
  - Common archetypes for different tool types
  - CLI commands: generate, list, run, test, info
  - Quality scoring explanation
  - CI/CD integration examples
  - Rate limits documentation

- Add /docs/api/scenarios page with API reference
  - List scenarios endpoint
  - Get scenario details
  - List collection scenarios
  - Create scenario
  - Generate scenarios with AI
  - Run scenario
  - Get run history
  - Check prompt similarity
  - Featured scenarios
  - Error responses
This commit is contained in:
Ajax Davis 2026-01-18 09:53:36 +10:00
parent ea742c9386
commit c52e6eaf24
2 changed files with 1293 additions and 0 deletions

View file

@ -0,0 +1,679 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@tpmjs/ui/Card/Card';
import { CodeBlock } from '@tpmjs/ui/CodeBlock/CodeBlock';
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Scenarios API | TPMJS Docs',
description: 'API reference for TPMJS scenarios endpoints',
};
export default function ScenariosApiPage(): React.ReactElement {
return (
<div className="space-y-8">
<div>
<h1 className="text-3xl font-bold mb-4">Scenarios API</h1>
<p className="text-foreground-secondary text-lg">
The Scenarios API allows you to create, run, and manage test scenarios for your tool
collections.
</p>
</div>
{/* List Scenarios */}
<Card>
<CardHeader>
<CardTitle>List Scenarios</CardTitle>
<CardDescription>GET /api/scenarios</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
Retrieve a paginated list of public scenarios with optional filtering.
</p>
<h4 className="font-semibold">Query Parameters</h4>
<ul className="list-disc list-inside space-y-1 text-foreground-secondary">
<li>
<code>limit</code> - Number of results (default: 20, max: 50)
</li>
<li>
<code>offset</code> - Pagination offset
</li>
<li>
<code>collectionId</code> - Filter by collection ID
</li>
<li>
<code>tags</code> - Filter by tags (comma-separated)
</li>
<li>
<code>sortBy</code> - Sort field: <code>qualityScore</code>, <code>totalRuns</code>,{' '}
<code>createdAt</code>, <code>lastRunAt</code>
</li>
</ul>
<h4 className="font-semibold">Example Request</h4>
<CodeBlock
code={`curl "https://tpmjs.com/api/scenarios?limit=10&sortBy=qualityScore"`}
language="bash"
showCopy={true}
/>
<h4 className="font-semibold">Example Response</h4>
<CodeBlock
code={`{
"data": [
{
"id": "clu123abc456",
"collectionId": "clx789def",
"prompt": "Scrape the main article content from a news website...",
"name": "Scrape article content",
"description": "Tests web scraping capability on news sites",
"tags": ["web-scraping", "content-extraction"],
"qualityScore": 0.85,
"totalRuns": 12,
"lastRunAt": "2024-01-20T10:30:00Z",
"lastRunStatus": "pass",
"consecutivePasses": 5,
"consecutiveFails": 0,
"createdAt": "2024-01-01T00:00:00Z",
"collection": {
"id": "clx789def",
"name": "Web Scraping Toolkit",
"slug": "web-scraping-toolkit",
"username": "johndoe"
}
}
],
"pagination": {
"limit": 10,
"offset": 0,
"hasMore": true
}
}`}
language="json"
showCopy={true}
/>
</CardContent>
</Card>
{/* Get Scenario */}
<Card>
<CardHeader>
<CardTitle>Get Scenario</CardTitle>
<CardDescription>GET /api/scenarios/:id</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
Retrieve detailed information about a specific scenario.
</p>
<h4 className="font-semibold">Path Parameters</h4>
<ul className="list-disc list-inside space-y-1 text-foreground-secondary">
<li>
<code>id</code> - Scenario ID
</li>
</ul>
<h4 className="font-semibold">Example Request</h4>
<CodeBlock
code={`curl "https://tpmjs.com/api/scenarios/clu123abc456"`}
language="bash"
showCopy={true}
/>
<h4 className="font-semibold">Example Response</h4>
<CodeBlock
code={`{
"success": true,
"data": {
"id": "clu123abc456",
"collectionId": "clx789def",
"prompt": "Scrape the main article content from a news website and extract the headline, author, publication date, and body text.",
"name": "Scrape article content",
"description": "Tests web scraping capability on news sites",
"tags": ["web-scraping", "content-extraction", "news"],
"assertions": null,
"qualityScore": 0.85,
"totalRuns": 12,
"lastRunAt": "2024-01-20T10:30:00Z",
"lastRunStatus": "pass",
"consecutivePasses": 5,
"consecutiveFails": 0,
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-20T10:30:00Z",
"collection": {
"id": "clx789def",
"name": "Web Scraping Toolkit",
"slug": "web-scraping-toolkit"
}
}
}`}
language="json"
showCopy={true}
/>
</CardContent>
</Card>
{/* List Collection Scenarios */}
<Card>
<CardHeader>
<CardTitle>List Collection Scenarios</CardTitle>
<CardDescription>GET /api/collections/:id/scenarios</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
Retrieve all scenarios for a specific collection.
</p>
<h4 className="font-semibold">Path Parameters</h4>
<ul className="list-disc list-inside space-y-1 text-foreground-secondary">
<li>
<code>id</code> - Collection ID
</li>
</ul>
<h4 className="font-semibold">Query Parameters</h4>
<ul className="list-disc list-inside space-y-1 text-foreground-secondary">
<li>
<code>limit</code> - Number of results (default: 20, max: 50)
</li>
<li>
<code>offset</code> - Pagination offset
</li>
</ul>
<h4 className="font-semibold">Example Request</h4>
<CodeBlock
code={`curl "https://tpmjs.com/api/collections/clx789def/scenarios"`}
language="bash"
showCopy={true}
/>
<h4 className="font-semibold">Example Response</h4>
<CodeBlock
code={`{
"success": true,
"data": {
"scenarios": [
{
"id": "clu123abc456",
"name": "Scrape article content",
"prompt": "Scrape the main article content...",
"qualityScore": 0.85,
"totalRuns": 12,
"lastRunStatus": "pass",
"tags": ["web-scraping"]
}
]
}
}`}
language="json"
showCopy={true}
/>
</CardContent>
</Card>
{/* Create Scenario */}
<Card>
<CardHeader>
<CardTitle>Create Scenario</CardTitle>
<CardDescription>POST /api/scenarios</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
Create a new scenario manually. Requires authentication and collection ownership.
</p>
<h4 className="font-semibold">Request Body</h4>
<CodeBlock
code={`{
"collectionId": "clx789def",
"prompt": "Search for weather information in Tokyo and return the current temperature",
"name": "Tokyo weather lookup",
"description": "Tests weather search functionality",
"tags": ["weather", "search", "api"]
}`}
language="json"
showCopy={true}
/>
<h4 className="font-semibold">TypeScript Example</h4>
<CodeBlock
code={`const response = await fetch('https://tpmjs.com/api/scenarios', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
collectionId: 'clx789def',
prompt: 'Search for weather information in Tokyo',
name: 'Tokyo weather lookup',
tags: ['weather', 'search']
})
});
const { data: scenario } = await response.json();
console.log('Created scenario:', scenario.id);`}
language="typescript"
showCopy={true}
/>
</CardContent>
</Card>
{/* Generate Scenarios */}
<Card>
<CardHeader>
<CardTitle>Generate Scenarios</CardTitle>
<CardDescription>POST /api/collections/:id/scenarios/generate</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
AI-generate scenarios based on the collection&apos;s tools. Requires authentication and
collection ownership.
</p>
<h4 className="font-semibold">Path Parameters</h4>
<ul className="list-disc list-inside space-y-1 text-foreground-secondary">
<li>
<code>id</code> - Collection ID
</li>
</ul>
<h4 className="font-semibold">Request Body</h4>
<CodeBlock
code={`{
"count": 3,
"skipSimilarityCheck": false
}`}
language="json"
showCopy={true}
/>
<h4 className="font-semibold">Example Request</h4>
<CodeBlock
code={`curl -X POST "https://tpmjs.com/api/collections/clx789def/scenarios/generate" \\
-H "Authorization: Bearer YOUR_API_KEY" \\
-H "Content-Type: application/json" \\
-d '{"count": 3}'`}
language="bash"
showCopy={true}
/>
<h4 className="font-semibold">Example Response</h4>
<CodeBlock
code={`{
"success": true,
"data": {
"scenarios": [
{
"scenario": {
"id": "clu111aaa",
"prompt": "Scrape the main article content from a news website...",
"name": "News article extraction",
"tags": ["web-scraping", "content-extraction"]
},
"similarity": {
"maxSimilarity": 0.15,
"mostSimilar": null
}
},
{
"scenario": {
"id": "clu222bbb",
"prompt": "Extract all product images from an e-commerce page...",
"name": "E-commerce image extraction",
"tags": ["web-scraping", "images", "e-commerce"]
},
"similarity": {
"maxSimilarity": 0.72,
"mostSimilar": {
"id": "clu000xxx",
"name": "Product page scraping"
}
}
}
]
}
}`}
language="json"
showCopy={true}
/>
<div className="bg-background-secondary p-4 rounded-lg">
<h4 className="font-semibold text-sm mb-2">Similarity Warning</h4>
<p className="text-foreground-secondary text-sm">
When <code>similarity.maxSimilarity</code> exceeds 0.7, the scenario is similar to an
existing one. The <code>mostSimilar</code> field shows which scenario it overlaps
with.
</p>
</div>
</CardContent>
</Card>
{/* Run Scenario */}
<Card>
<CardHeader>
<CardTitle>Run Scenario</CardTitle>
<CardDescription>POST /api/scenarios/:id/run</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
Execute a scenario and return the results. Requires authentication. Consumes one run
from your daily quota.
</p>
<h4 className="font-semibold">Path Parameters</h4>
<ul className="list-disc list-inside space-y-1 text-foreground-secondary">
<li>
<code>id</code> - Scenario ID
</li>
</ul>
<h4 className="font-semibold">Example Request</h4>
<CodeBlock
code={`curl -X POST "https://tpmjs.com/api/scenarios/clu123abc456/run" \\
-H "Authorization: Bearer YOUR_API_KEY"`}
language="bash"
showCopy={true}
/>
<h4 className="font-semibold">Example Response</h4>
<CodeBlock
code={`{
"success": true,
"data": {
"runId": "run_abc123def456",
"status": "completed",
"success": true,
"evaluator": {
"model": "claude-3-5-sonnet-latest",
"verdict": "pass",
"reason": "The agent successfully extracted the article headline, author name, publication date, and full body text from the news website. All required fields were present and correctly formatted."
},
"usage": {
"inputTokens": 892,
"outputTokens": 353,
"totalTokens": 1245,
"executionTimeMs": 2341
},
"timestamps": {
"startedAt": "2024-01-20T10:30:00Z",
"completedAt": "2024-01-20T10:30:02Z",
"createdAt": "2024-01-20T10:30:00Z"
},
"quotaRemaining": 46
}
}`}
language="json"
showCopy={true}
/>
<h4 className="font-semibold">Failure Response</h4>
<CodeBlock
code={`{
"success": true,
"data": {
"runId": "run_xyz789",
"status": "completed",
"success": false,
"evaluator": {
"model": "claude-3-5-sonnet-latest",
"verdict": "fail",
"reason": "The agent was unable to complete the task. The target website returned a 403 Forbidden error, preventing the scraping operation."
},
"usage": {
"inputTokens": 456,
"outputTokens": 123,
"totalTokens": 579,
"executionTimeMs": 3102
},
"quotaRemaining": 45
}
}`}
language="json"
showCopy={true}
/>
</CardContent>
</Card>
{/* Get Scenario Runs */}
<Card>
<CardHeader>
<CardTitle>Get Scenario Run History</CardTitle>
<CardDescription>GET /api/scenarios/:id/runs</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
Retrieve the run history for a scenario. Requires authentication if the scenario belongs
to a private collection.
</p>
<h4 className="font-semibold">Path Parameters</h4>
<ul className="list-disc list-inside space-y-1 text-foreground-secondary">
<li>
<code>id</code> - Scenario ID
</li>
</ul>
<h4 className="font-semibold">Query Parameters</h4>
<ul className="list-disc list-inside space-y-1 text-foreground-secondary">
<li>
<code>limit</code> - Number of results (default: 10, max: 50)
</li>
<li>
<code>offset</code> - Pagination offset
</li>
</ul>
<h4 className="font-semibold">Example Request</h4>
<CodeBlock
code={`curl "https://tpmjs.com/api/scenarios/clu123abc456/runs?limit=5" \\
-H "Authorization: Bearer YOUR_API_KEY"`}
language="bash"
showCopy={true}
/>
<h4 className="font-semibold">Example Response</h4>
<CodeBlock
code={`{
"data": [
{
"id": "run_abc123",
"status": "completed",
"success": true,
"evaluator": {
"model": "claude-3-5-sonnet-latest",
"verdict": "pass",
"reason": "Successfully extracted article content"
},
"assertions": null,
"usage": {
"inputTokens": 892,
"outputTokens": 353,
"totalTokens": 1245,
"executionTimeMs": 2341
},
"timestamps": {
"startedAt": "2024-01-20T10:30:00Z",
"completedAt": "2024-01-20T10:30:02Z",
"createdAt": "2024-01-20T10:30:00Z"
}
}
],
"pagination": {
"limit": 5,
"offset": 0,
"hasMore": true
}
}`}
language="json"
showCopy={true}
/>
</CardContent>
</Card>
{/* Check Similarity */}
<Card>
<CardHeader>
<CardTitle>Check Prompt Similarity</CardTitle>
<CardDescription>POST /api/scenarios/check-similarity</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
Check if a prompt is similar to existing scenarios in a collection. Useful before
creating manual scenarios to avoid duplicates.
</p>
<h4 className="font-semibold">Request Body</h4>
<CodeBlock
code={`{
"prompt": "Scrape article headlines from a news website",
"collectionId": "clx789def"
}`}
language="json"
showCopy={true}
/>
<h4 className="font-semibold">Example Response</h4>
<CodeBlock
code={`{
"success": true,
"data": {
"maxSimilarity": 0.78,
"similar": [
{
"id": "clu123abc456",
"name": "Scrape article content",
"prompt": "Scrape the main article content from a news website...",
"similarity": 0.78
},
{
"id": "clu789xyz",
"name": "Extract news headlines",
"prompt": "Get all headlines from the front page of a news site...",
"similarity": 0.65
}
]
}
}`}
language="json"
showCopy={true}
/>
<div className="bg-background-secondary p-4 rounded-lg">
<h4 className="font-semibold text-sm mb-2">Similarity Threshold</h4>
<p className="text-foreground-secondary text-sm">
A <code>maxSimilarity</code> above 0.7 indicates significant overlap with existing
scenarios. Consider modifying your prompt to test different aspects of your tools.
</p>
</div>
</CardContent>
</Card>
{/* Featured Scenarios */}
<Card>
<CardHeader>
<CardTitle>Get Featured Scenarios</CardTitle>
<CardDescription>GET /api/scenarios/featured</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
Retrieve featured scenarios for the homepage showcase. Returns a mix of high-quality,
diverse, and recently successful scenarios.
</p>
<h4 className="font-semibold">Query Parameters</h4>
<ul className="list-disc list-inside space-y-1 text-foreground-secondary">
<li>
<code>limit</code> - Number of results (default: 10, max: 20)
</li>
</ul>
<h4 className="font-semibold">Example Request</h4>
<CodeBlock
code={`curl "https://tpmjs.com/api/scenarios/featured?limit=5"`}
language="bash"
showCopy={true}
/>
<h4 className="font-semibold">Example Response</h4>
<CodeBlock
code={`{
"success": true,
"data": [
{
"id": "clu123abc456",
"name": "Scrape article content",
"qualityScore": 0.95,
"totalRuns": 50,
"lastRunStatus": "pass",
"collection": {
"name": "Web Scraping Toolkit",
"slug": "web-scraping-toolkit",
"username": "johndoe"
}
}
]
}`}
language="json"
showCopy={true}
/>
</CardContent>
</Card>
{/* Error Responses */}
<Card>
<CardHeader>
<CardTitle>Error Responses</CardTitle>
<CardDescription>Common error codes and responses</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<h4 className="font-semibold">401 Unauthorized</h4>
<CodeBlock
code={`{
"success": false,
"error": "Unauthorized",
"message": "API key is required for this endpoint"
}`}
language="json"
showCopy={true}
/>
<h4 className="font-semibold">403 Forbidden</h4>
<CodeBlock
code={`{
"success": false,
"error": "Forbidden",
"message": "You don't have permission to access this scenario"
}`}
language="json"
showCopy={true}
/>
<h4 className="font-semibold">404 Not Found</h4>
<CodeBlock
code={`{
"success": false,
"error": "Not Found",
"message": "Scenario not found"
}`}
language="json"
showCopy={true}
/>
<h4 className="font-semibold">429 Rate Limited</h4>
<CodeBlock
code={`{
"success": false,
"error": "Rate Limit Exceeded",
"message": "Daily scenario run quota exceeded. Resets at midnight UTC.",
"quotaRemaining": 0,
"resetAt": "2024-01-21T00:00:00Z"
}`}
language="json"
showCopy={true}
/>
</CardContent>
</Card>
</div>
);
}

View file

@ -0,0 +1,614 @@
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@tpmjs/ui/Card/Card';
import { CodeBlock } from '@tpmjs/ui/CodeBlock/CodeBlock';
import type { Metadata } from 'next';
import Link from 'next/link';
export const metadata: Metadata = {
title: 'Scenarios Guide | TPMJS Docs',
description: 'Test your tool collections with AI-generated scenarios and automated evaluation',
};
export default function ScenariosPage(): React.ReactElement {
return (
<div className="space-y-8">
<div>
<h1 className="text-3xl font-bold mb-4">Scenarios</h1>
<p className="text-foreground-secondary text-lg">
Scenarios are AI-generated test cases for your tool collections. They automatically verify
that your tools work correctly and provide quality metrics over time.
</p>
</div>
{/* Overview */}
<Card>
<CardHeader>
<CardTitle>What are Scenarios?</CardTitle>
<CardDescription>Automated testing for tool collections</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
A Scenario is a test case that exercises your tool collection with a realistic user
prompt. When you run a scenario:
</p>
<ol className="list-decimal list-inside space-y-2 text-foreground-secondary">
<li>An ephemeral agent is created with your collection&apos;s tools</li>
<li>The agent executes the scenario&apos;s prompt</li>
<li>An LLM evaluates whether the task was completed successfully</li>
<li>Results are recorded and quality scores are updated</li>
</ol>
<p className="text-foreground-secondary">
This enables continuous testing of your tool collections, similar to unit tests for
code.
</p>
</CardContent>
</Card>
{/* Use Cases */}
<Card>
<CardHeader>
<CardTitle>Common Archetypes</CardTitle>
<CardDescription>Typical scenarios for different tool types</CardDescription>
</CardHeader>
<CardContent className="space-y-6">
<div>
<h4 className="font-semibold mb-2">Web Scraping Tools</h4>
<p className="text-foreground-secondary text-sm mb-2">
Test data extraction from various webpage structures:
</p>
<CodeBlock
code={`"Scrape the main heading and first paragraph from https://example.com"
"Extract all links from a news article page"
"Get the price and description from an e-commerce product page"`}
language="text"
showCopy={false}
/>
</div>
<div>
<h4 className="font-semibold mb-2">Search Tools</h4>
<p className="text-foreground-secondary text-sm mb-2">
Verify search accuracy and relevance:
</p>
<CodeBlock
code={`"Search for recent news about climate change and summarize the top 3 results"
"Find documentation for the React useState hook"
"Search for restaurants near Times Square, New York"`}
language="text"
showCopy={false}
/>
</div>
<div>
<h4 className="font-semibold mb-2">Data Processing Tools</h4>
<p className="text-foreground-secondary text-sm mb-2">
Test transformations and calculations:
</p>
<CodeBlock
code={`"Convert 100 USD to EUR using current exchange rates"
"Parse this JSON and extract the user email addresses"
"Calculate the average of these numbers: 10, 20, 30, 40, 50"`}
language="text"
showCopy={false}
/>
</div>
<div>
<h4 className="font-semibold mb-2">File/Document Tools</h4>
<p className="text-foreground-secondary text-sm mb-2">
Verify file operations and content extraction:
</p>
<CodeBlock
code={`"Generate a PDF report with the title 'Monthly Summary'"
"Extract text content from a markdown document"
"Create a CSV file with sample user data"`}
language="text"
showCopy={false}
/>
</div>
</CardContent>
</Card>
{/* CLI Installation */}
<Card>
<CardHeader>
<CardTitle>Getting Started</CardTitle>
<CardDescription>Install the CLI and authenticate</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<h4 className="font-semibold">Install the TPMJS CLI</h4>
<CodeBlock code="npm install -g @tpmjs/cli" language="bash" showCopy={true} />
<h4 className="font-semibold">Authenticate</h4>
<p className="text-foreground-secondary text-sm">
You need a TPMJS API key to run scenarios. Get one from your{' '}
<Link
href="/dashboard/settings/tpmjs-api-keys"
className="text-primary hover:underline"
>
dashboard settings
</Link>
.
</p>
<CodeBlock code="tpm auth login" language="bash" showCopy={true} />
</CardContent>
</Card>
{/* Generate Scenarios */}
<Card>
<CardHeader>
<CardTitle>Generate Scenarios</CardTitle>
<CardDescription>tpm scenario generate</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
AI-generate test scenarios based on your collection&apos;s tools. The generator analyzes
your tools and creates realistic prompts.
</p>
<h4 className="font-semibold">Basic Usage</h4>
<CodeBlock
code={`# Generate 1 scenario (default)
tpm scenario generate my-collection
# Generate multiple scenarios
tpm scenario generate my-collection --count 5
# Skip similarity check (allow duplicates)
tpm scenario generate my-collection --count 3 --skip-similarity`}
language="bash"
showCopy={true}
/>
<h4 className="font-semibold">Example Output</h4>
<CodeBlock
code={`Generating 3 scenarios for "Web Scraping Toolkit"...
Generated 3 scenarios:
1. "Scrape the main article content from a news website and extract..."
Similarity: 0% (unique)
Tags: web-scraping, content-extraction
2. "Extract all image URLs from an e-commerce product gallery..."
Similarity: 15% (unique)
Tags: web-scraping, images, e-commerce
3. "Get the current weather data from a weather service page..."
Similarity: 8% (unique)
Tags: web-scraping, weather, data-extraction
Use 'tpm scenario list my-collection' to view all scenarios.`}
language="text"
showCopy={false}
/>
<div className="bg-background-secondary p-4 rounded-lg">
<h4 className="font-semibold text-sm mb-2">Similarity Detection</h4>
<p className="text-foreground-secondary text-sm">
Generated scenarios are checked against existing ones using vector similarity. If a
scenario is &gt;70% similar to an existing one, you&apos;ll see a warning. This helps
maintain diverse test coverage.
</p>
</div>
</CardContent>
</Card>
{/* List Scenarios */}
<Card>
<CardHeader>
<CardTitle>List Scenarios</CardTitle>
<CardDescription>tpm scenario list</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
View all scenarios for a collection or browse public scenarios.
</p>
<h4 className="font-semibold">Usage</h4>
<CodeBlock
code={`# List scenarios for a specific collection
tpm scenario list my-collection
# List all public scenarios
tpm scenario list
# With pagination
tpm scenario list --limit 50 --offset 20
# Filter by tags
tpm scenario list --tags web-scraping,api
# Output as JSON
tpm scenario list my-collection --json`}
language="bash"
showCopy={true}
/>
<h4 className="font-semibold">Example Output</h4>
<CodeBlock
code={`Scenarios for Web Scraping Toolkit
Name Quality Runs Status Tags
Scrape main article content... 85% 12 pass web-scraping
Extract image URLs from gallery 92% 8 pass images, e-commerce
Get weather data from service... 45% 5 fail weather, data
Showing 3 scenario(s)`}
language="text"
showCopy={false}
/>
</CardContent>
</Card>
{/* Run Scenarios */}
<Card>
<CardHeader>
<CardTitle>Run All Scenarios</CardTitle>
<CardDescription>tpm scenario run</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
Execute all scenarios for a collection. This is ideal for CI/CD pipelines or batch
testing.
</p>
<h4 className="font-semibold">Usage</h4>
<CodeBlock
code={`# Run all scenarios for a collection
tpm scenario run my-collection
# Verbose output with detailed progress
tpm scenario run my-collection --verbose
# JSON output for CI integration
tpm scenario run my-collection --json`}
language="bash"
showCopy={true}
/>
<h4 className="font-semibold">Example Output</h4>
<CodeBlock
code={`Running 3 scenarios for "Web Scraping Toolkit"...
[1/3] Scrape main article content...
PASSED (2.3s) - Successfully extracted article content
[2/3] Extract image URLs from gallery
PASSED (1.8s) - Found and returned 12 image URLs
[3/3] Get weather data from service...
FAILED (3.1s) - Weather service returned 403 error
Results: 2 passed, 1 failed, 0 errors
Total time: 7.2s
Quota remaining: 47 runs/day`}
language="text"
showCopy={false}
/>
<h4 className="font-semibold">Exit Codes</h4>
<ul className="list-disc list-inside space-y-1 text-foreground-secondary text-sm">
<li>
<code>0</code> - All scenarios passed
</li>
<li>
<code>1</code> - One or more scenarios failed
</li>
</ul>
</CardContent>
</Card>
{/* Test Single Scenario */}
<Card>
<CardHeader>
<CardTitle>Test Single Scenario</CardTitle>
<CardDescription>tpm scenario test</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
Run a single scenario by its ID. Useful for debugging or re-testing specific failures.
</p>
<h4 className="font-semibold">Usage</h4>
<CodeBlock
code={`# Run a single scenario
tpm scenario test clu123abc456
# With verbose output
tpm scenario test clu123abc456 --verbose
# JSON output
tpm scenario test clu123abc456 --json`}
language="bash"
showCopy={true}
/>
<h4 className="font-semibold">Example Output</h4>
<CodeBlock
code={`Scenario: Scrape main article content from a news website
Collection: Web Scraping Toolkit
Scenario PASSED
Results
Status: completed
Verdict: pass
Reason: The agent successfully extracted the main article heading and...
Usage
Duration: 2,341ms
Tokens: 1,245 (in: 892, out: 353)
Run ID: run_abc123def456
Quota remaining: 46 runs/day`}
language="text"
showCopy={false}
/>
</CardContent>
</Card>
{/* Scenario Info */}
<Card>
<CardHeader>
<CardTitle>View Scenario Details</CardTitle>
<CardDescription>tpm scenario info</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
View detailed information about a scenario including its run history and quality
metrics.
</p>
<h4 className="font-semibold">Usage</h4>
<CodeBlock
code={`# View scenario details
tpm scenario info clu123abc456
# Include run history
tpm scenario info clu123abc456 --runs 10
# JSON output
tpm scenario info clu123abc456 --json`}
language="bash"
showCopy={true}
/>
<h4 className="font-semibold">Example Output</h4>
<CodeBlock
code={`Scenario: Scrape main article content from a news website
ID: clu123abc456
Collection: Web Scraping Toolkit
Created: 2 weeks ago
Prompt:
Scrape the main article content from a news website and extract
the headline, author, publication date, and body text.
Quality Metrics:
Score: 85%
Total Runs: 12
Consecutive Passes: 5
Last Run: 2 hours ago (pass)
Tags: web-scraping, content-extraction, news
Recent Runs:
#12 pass 2h ago 2,341ms "Successfully extracted article content"
#11 pass 1d ago 2,156ms "Successfully extracted article content"
#10 pass 2d ago 2,892ms "Successfully extracted article content"
#9 fail 3d ago 4,521ms "Timeout waiting for page load"
#8 pass 4d ago 2,234ms "Successfully extracted article content"`}
language="text"
showCopy={false}
/>
</CardContent>
</Card>
{/* Quality Scoring */}
<Card>
<CardHeader>
<CardTitle>Quality Scoring</CardTitle>
<CardDescription>How scenario quality is calculated</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
Quality scores help identify reliable scenarios and track improvement over time. Scores
range from 0% to 100%.
</p>
<h4 className="font-semibold">Streak-Based Scoring</h4>
<p className="text-foreground-secondary text-sm">
Scenarios earn bonus points for consecutive passes and lose points for consecutive
failures:
</p>
<div className="grid grid-cols-2 gap-4 mt-4">
<div className="bg-green-500/10 p-4 rounded-lg">
<h5 className="font-semibold text-green-600 dark:text-green-400 text-sm mb-2">
On Pass
</h5>
<ul className="text-foreground-secondary text-sm space-y-1">
<li>+5% base score</li>
<li>+1% per consecutive pass</li>
<li>Maximum score: 100%</li>
</ul>
</div>
<div className="bg-red-500/10 p-4 rounded-lg">
<h5 className="font-semibold text-red-600 dark:text-red-400 text-sm mb-2">
On Failure
</h5>
<ul className="text-foreground-secondary text-sm space-y-1">
<li>-10% base penalty</li>
<li>-2% per consecutive fail</li>
<li>Minimum score: 0%</li>
</ul>
</div>
</div>
<div className="bg-background-secondary p-4 rounded-lg mt-4">
<h4 className="font-semibold text-sm mb-2">Example</h4>
<p className="text-foreground-secondary text-sm">
A scenario with 5 consecutive passes would have a quality score of approximately 85%
(5% × 5 + 1% × (1+2+3+4+5) = 25% + 15% = 40%, plus base score). High-quality scenarios
are featured on the TPMJS homepage showcase.
</p>
</div>
</CardContent>
</Card>
{/* CI/CD Integration */}
<Card>
<CardHeader>
<CardTitle>CI/CD Integration</CardTitle>
<CardDescription>Automate scenario testing in your pipeline</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
Integrate scenario testing into your CI/CD pipeline to catch regressions early.
</p>
<h4 className="font-semibold">GitHub Actions Example</h4>
<CodeBlock
code={`name: TPMJS Scenario Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test-scenarios:
runs-on: ubuntu-latest
steps:
- name: Install TPMJS CLI
run: npm install -g @tpmjs/cli
- name: Configure API Key
run: |
mkdir -p ~/.config/tpmjs
echo '{"apiKey":"$\{{ secrets.TPMJS_API_KEY }}"}' > ~/.config/tpmjs/config.json
- name: Run Scenarios
run: tpm scenario run my-collection --json > results.json
- name: Check Results
run: |
FAILED=$(jq '.failed' results.json)
if [ "$FAILED" -gt 0 ]; then
echo "❌ $FAILED scenario(s) failed"
exit 1
fi
echo "✅ All scenarios passed"`}
language="yaml"
showCopy={true}
/>
<h4 className="font-semibold">JSON Output Format</h4>
<CodeBlock
code={`{
"collection": "my-collection",
"total": 5,
"passed": 4,
"failed": 1,
"errors": 0,
"duration": 12345,
"results": [
{
"scenarioId": "clu123abc456",
"name": "Scrape main article content",
"status": "pass",
"duration": 2341,
"verdict": "pass",
"reason": "Successfully extracted article content"
}
]
}`}
language="json"
showCopy={true}
/>
</CardContent>
</Card>
{/* Rate Limits */}
<Card>
<CardHeader>
<CardTitle>Rate Limits</CardTitle>
<CardDescription>Daily quota and usage tracking</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<p className="text-foreground-secondary">
Scenario execution is subject to daily rate limits to ensure fair usage:
</p>
<ul className="list-disc list-inside space-y-2 text-foreground-secondary">
<li>
<strong>Free tier:</strong> 50 scenario runs per day
</li>
<li>
<strong>Pro tier:</strong> 500 scenario runs per day
</li>
<li>Quotas reset at midnight UTC</li>
<li>Failed runs count toward the quota</li>
</ul>
<p className="text-foreground-secondary text-sm mt-4">
The remaining quota is shown after each scenario run. Plan your CI/CD schedules
accordingly to stay within limits.
</p>
</CardContent>
</Card>
{/* Next Steps */}
<Card>
<CardHeader>
<CardTitle>Next Steps</CardTitle>
<CardDescription>Continue learning about TPMJS</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<ul className="space-y-3">
<li>
<Link href="/docs/api/scenarios" className="text-primary hover:underline font-medium">
Scenarios API Reference
</Link>
<p className="text-foreground-secondary text-sm">
REST API endpoints for programmatic scenario management
</p>
</li>
<li>
<Link
href="/docs/api/collections"
className="text-primary hover:underline font-medium"
>
Collections API
</Link>
<p className="text-foreground-secondary text-sm">
Create and manage tool collections for your scenarios
</p>
</li>
<li>
<Link href="/docs/agents" className="text-primary hover:underline font-medium">
Agents Documentation
</Link>
<p className="text-foreground-secondary text-sm">
Learn how scenarios use agents for execution
</p>
</li>
<li>
<Link href="/" className="text-primary hover:underline font-medium">
Browse Tool Registry
</Link>
<p className="text-foreground-secondary text-sm">
Discover tools to add to your collections
</p>
</li>
</ul>
</CardContent>
</Card>
</div>
);
}