Add comprehensive tutorial content
- yaml-config: Complete YAML structure reference - arguments: Custom CLI flags and patterns - multi-step: Chaining prompts and code steps - code-steps: Python processing between AI calls - advanced-workflows: Multi-provider, conditionals, pipelines Update tutorials route to use docs content system Expand table of contents with new sections 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
c1eb425457
commit
d072d7ccad
|
|
@ -607,6 +607,643 @@ project. It implements:</p>
|
|||
("example-project", "Full Example Project"),
|
||||
],
|
||||
},
|
||||
|
||||
"yaml-config": {
|
||||
"title": "Understanding YAML Config",
|
||||
"description": "Learn the structure of SmartTools configuration files",
|
||||
"content": """
|
||||
<p class="lead">Every SmartTool is defined by a YAML configuration file. This guide covers the complete
|
||||
structure and all available options.</p>
|
||||
|
||||
<h2 id="file-location">File Location</h2>
|
||||
<p>Tool configs are stored in <code>~/.smarttools/<tool-name>/config.yaml</code>.</p>
|
||||
|
||||
<h2 id="complete-structure">Complete Structure</h2>
|
||||
<pre><code class="language-yaml"># Required fields
|
||||
name: my-tool # Tool name (lowercase, hyphens)
|
||||
version: "1.0.0" # Semver version string
|
||||
|
||||
# Recommended fields
|
||||
description: "What this tool does"
|
||||
category: text-processing # For registry organization
|
||||
tags: # Searchable tags
|
||||
- text
|
||||
- formatting
|
||||
|
||||
# Optional metadata
|
||||
author: your-name
|
||||
license: MIT
|
||||
homepage: https://github.com/you/my-tool
|
||||
|
||||
# Arguments (custom CLI flags)
|
||||
arguments:
|
||||
- flag: --format
|
||||
variable: format
|
||||
default: "markdown"
|
||||
description: Output format
|
||||
|
||||
# Processing steps
|
||||
steps:
|
||||
- type: prompt
|
||||
provider: claude
|
||||
prompt: |
|
||||
Process this: {input}
|
||||
output_var: result
|
||||
|
||||
# Final output template
|
||||
output: "{result}"</code></pre>
|
||||
|
||||
<h2 id="required-fields">Required Fields</h2>
|
||||
|
||||
<h3>name</h3>
|
||||
<p>The tool's identifier. Must be lowercase with hyphens only:</p>
|
||||
<pre><code class="language-yaml">name: my-cool-tool # Good
|
||||
name: MyCoolTool # Bad - no uppercase
|
||||
name: my_cool_tool # Bad - no underscores</code></pre>
|
||||
|
||||
<h3>version</h3>
|
||||
<p>Semantic version string. Always quote it to prevent YAML parsing issues:</p>
|
||||
<pre><code class="language-yaml">version: "1.0.0" # Good
|
||||
version: 1.0 # Bad - YAML parses as float</code></pre>
|
||||
|
||||
<h2 id="variable-substitution">Variable Substitution</h2>
|
||||
<p>Use <code>{variable}</code> syntax in prompts and output:</p>
|
||||
<ul>
|
||||
<li><code>{input}</code> - Content piped to the tool</li>
|
||||
<li><code>{variable_name}</code> - From arguments or previous steps</li>
|
||||
</ul>
|
||||
|
||||
<p>To include literal braces, double them:</p>
|
||||
<pre><code class="language-yaml">prompt: |
|
||||
Format as JSON: {{\"key\": \"value\"}}
|
||||
Input: {input}</code></pre>
|
||||
|
||||
<h2 id="categories">Categories</h2>
|
||||
<p>Standard categories for the registry:</p>
|
||||
<ul>
|
||||
<li><code>text-processing</code> - Summarize, translate, format</li>
|
||||
<li><code>code-analysis</code> - Review, explain, generate</li>
|
||||
<li><code>data-extraction</code> - Parse, extract, convert</li>
|
||||
<li><code>content-creation</code> - Write, expand, draft</li>
|
||||
<li><code>productivity</code> - Automate, organize</li>
|
||||
<li><code>education</code> - Explain, teach, simplify</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="validation">Validation</h2>
|
||||
<p>Test your config without running:</p>
|
||||
<pre><code class="language-bash"># Validate syntax
|
||||
smarttools test my-tool --dry-run
|
||||
|
||||
# Check for common issues
|
||||
smarttools registry publish --dry-run</code></pre>
|
||||
""",
|
||||
"headings": [
|
||||
("file-location", "File Location"),
|
||||
("complete-structure", "Complete Structure"),
|
||||
("required-fields", "Required Fields"),
|
||||
("variable-substitution", "Variable Substitution"),
|
||||
("categories", "Categories"),
|
||||
("validation", "Validation"),
|
||||
],
|
||||
},
|
||||
|
||||
"arguments": {
|
||||
"title": "Custom Arguments",
|
||||
"description": "Add flags and options to make your tools flexible",
|
||||
"content": """
|
||||
<p class="lead">Arguments let users customize tool behavior with CLI flags like <code>--format json</code>
|
||||
or <code>--verbose</code>.</p>
|
||||
|
||||
<h2 id="basic-syntax">Basic Syntax</h2>
|
||||
<pre><code class="language-yaml">arguments:
|
||||
- flag: --format # The CLI flag
|
||||
variable: format # Variable name in templates
|
||||
default: "text" # Default value if not provided
|
||||
description: "Output format (text, json, markdown)"</code></pre>
|
||||
|
||||
<h2 id="using-arguments">Using Arguments</h2>
|
||||
<p>Reference arguments in prompts using <code>{variable_name}</code>:</p>
|
||||
<pre><code class="language-yaml">arguments:
|
||||
- flag: --tone
|
||||
variable: tone
|
||||
default: "professional"
|
||||
|
||||
steps:
|
||||
- type: prompt
|
||||
provider: claude
|
||||
prompt: |
|
||||
Rewrite this text with a {tone} tone:
|
||||
|
||||
{input}
|
||||
output_var: result</code></pre>
|
||||
|
||||
<p>Users can then run:</p>
|
||||
<pre><code class="language-bash">echo "Hey, fix this bug ASAP!" | tone-shift --tone friendly</code></pre>
|
||||
|
||||
<h2 id="multiple-arguments">Multiple Arguments</h2>
|
||||
<pre><code class="language-yaml">arguments:
|
||||
- flag: --lang
|
||||
variable: language
|
||||
default: "English"
|
||||
description: "Target language"
|
||||
|
||||
- flag: --formality
|
||||
variable: formality
|
||||
default: "neutral"
|
||||
description: "Formality level (casual, neutral, formal)"
|
||||
|
||||
- flag: --max-length
|
||||
variable: max_length
|
||||
default: "500"
|
||||
description: "Maximum output length in words"</code></pre>
|
||||
|
||||
<h2 id="argument-types">Argument Patterns</h2>
|
||||
|
||||
<h3>Choice Arguments</h3>
|
||||
<p>Document valid choices in the description:</p>
|
||||
<pre><code class="language-yaml">- flag: --style
|
||||
variable: style
|
||||
default: "concise"
|
||||
description: "Writing style: concise, detailed, or academic"</code></pre>
|
||||
|
||||
<h3>Numeric Arguments</h3>
|
||||
<p>Always quote defaults to avoid YAML issues:</p>
|
||||
<pre><code class="language-yaml">- flag: --max-tokens
|
||||
variable: max_tokens
|
||||
default: "1000" # Quoted string, not integer</code></pre>
|
||||
|
||||
<h3>Boolean-like Arguments</h3>
|
||||
<p>Use string values for conditional prompts:</p>
|
||||
<pre><code class="language-yaml">- flag: --verbose
|
||||
variable: verbose
|
||||
default: "no"
|
||||
description: "Include detailed explanations (yes/no)"</code></pre>
|
||||
|
||||
<h2 id="in-prompts">Using in Prompts</h2>
|
||||
<p>Combine multiple arguments in your prompt template:</p>
|
||||
<pre><code class="language-yaml">steps:
|
||||
- type: prompt
|
||||
provider: claude
|
||||
prompt: |
|
||||
Translate the following text to {language}.
|
||||
Use a {formality} register.
|
||||
Keep the response under {max_length} words.
|
||||
|
||||
Text to translate:
|
||||
{input}
|
||||
output_var: translation</code></pre>
|
||||
|
||||
<h2 id="best-practices">Best Practices</h2>
|
||||
<ul>
|
||||
<li><strong>Use descriptive variable names</strong> - <code>target_language</code> not <code>tl</code></li>
|
||||
<li><strong>Provide sensible defaults</strong> - Tools should work without any flags</li>
|
||||
<li><strong>Document choices</strong> - List valid options in the description</li>
|
||||
<li><strong>Keep flags short</strong> - Use <code>--lang</code> not <code>--target-language</code></li>
|
||||
</ul>
|
||||
""",
|
||||
"headings": [
|
||||
("basic-syntax", "Basic Syntax"),
|
||||
("using-arguments", "Using Arguments"),
|
||||
("multiple-arguments", "Multiple Arguments"),
|
||||
("argument-types", "Argument Patterns"),
|
||||
("in-prompts", "Using in Prompts"),
|
||||
("best-practices", "Best Practices"),
|
||||
],
|
||||
},
|
||||
|
||||
"multi-step": {
|
||||
"title": "Multi-Step Workflows",
|
||||
"description": "Chain prompts and code steps together",
|
||||
"content": """
|
||||
<p class="lead">Complex tools can chain multiple steps together. Each step's output becomes available
|
||||
to subsequent steps.</p>
|
||||
|
||||
<h2 id="step-flow">How Steps Flow</h2>
|
||||
<pre><code class="language-yaml">steps:
|
||||
# Step 1: Extract key points
|
||||
- type: prompt
|
||||
provider: claude
|
||||
prompt: "Extract 5 key points from: {input}"
|
||||
output_var: key_points
|
||||
|
||||
# Step 2: Use step 1's output
|
||||
- type: prompt
|
||||
provider: claude
|
||||
prompt: |
|
||||
Create a summary from these points:
|
||||
{key_points}
|
||||
output_var: summary
|
||||
|
||||
output: "{summary}"</code></pre>
|
||||
|
||||
<p>Variables flow through the pipeline:</p>
|
||||
<ul>
|
||||
<li><code>{input}</code> → available in all steps</li>
|
||||
<li><code>{key_points}</code> → available after step 1</li>
|
||||
<li><code>{summary}</code> → available after step 2</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="mixed-steps">Mixing Prompt and Code Steps</h2>
|
||||
<p>Combine AI calls with Python processing:</p>
|
||||
<pre><code class="language-yaml">steps:
|
||||
# Step 1: AI extracts data
|
||||
- type: prompt
|
||||
provider: claude
|
||||
prompt: |
|
||||
Extract all email addresses from this text as a comma-separated list:
|
||||
{input}
|
||||
output_var: emails_raw
|
||||
|
||||
# Step 2: Python cleans the data
|
||||
- type: code
|
||||
code: |
|
||||
emails = [e.strip() for e in emails_raw.split(',')]
|
||||
emails = [e for e in emails if '@' in e]
|
||||
email_count = len(emails)
|
||||
cleaned_emails = '\\n'.join(sorted(set(emails)))
|
||||
output_var: cleaned_emails, email_count
|
||||
|
||||
# Step 3: AI formats output
|
||||
- type: prompt
|
||||
provider: claude
|
||||
prompt: |
|
||||
Format these {email_count} emails as a nice list:
|
||||
{cleaned_emails}
|
||||
output_var: formatted
|
||||
|
||||
output: "{formatted}"</code></pre>
|
||||
|
||||
<h2 id="error-handling">Step Dependencies</h2>
|
||||
<p>If any step fails, execution stops. Design steps to handle edge cases:</p>
|
||||
<pre><code class="language-yaml">steps:
|
||||
- type: code
|
||||
code: |
|
||||
# Handle empty input gracefully
|
||||
if not input.strip():
|
||||
result = "No input provided"
|
||||
skip_ai = "yes"
|
||||
else:
|
||||
result = input
|
||||
skip_ai = "no"
|
||||
output_var: result, skip_ai
|
||||
|
||||
- type: prompt
|
||||
provider: claude
|
||||
prompt: |
|
||||
{result}
|
||||
# AI prompt only runs if skip_ai is "no"
|
||||
output_var: ai_response</code></pre>
|
||||
|
||||
<h2 id="common-patterns">Common Patterns</h2>
|
||||
|
||||
<h3>Extract → Transform → Format</h3>
|
||||
<pre><code class="language-yaml">steps:
|
||||
- type: prompt # Extract structured data
|
||||
- type: code # Transform/filter
|
||||
- type: prompt # Format for output</code></pre>
|
||||
|
||||
<h3>Analyze → Synthesize</h3>
|
||||
<pre><code class="language-yaml">steps:
|
||||
- type: prompt # Break down into parts
|
||||
- type: prompt # Combine insights</code></pre>
|
||||
|
||||
<h3>Validate → Process</h3>
|
||||
<pre><code class="language-yaml">steps:
|
||||
- type: code # Validate input format
|
||||
- type: prompt # Process if valid</code></pre>
|
||||
|
||||
<h2 id="debugging">Debugging Multi-Step Tools</h2>
|
||||
<pre><code class="language-bash"># Show prompts without running
|
||||
cat test.txt | my-tool --dry-run
|
||||
|
||||
# See verbose output
|
||||
cat test.txt | my-tool --verbose</code></pre>
|
||||
""",
|
||||
"headings": [
|
||||
("step-flow", "How Steps Flow"),
|
||||
("mixed-steps", "Mixing Prompt and Code Steps"),
|
||||
("error-handling", "Step Dependencies"),
|
||||
("common-patterns", "Common Patterns"),
|
||||
("debugging", "Debugging Multi-Step Tools"),
|
||||
],
|
||||
},
|
||||
|
||||
"code-steps": {
|
||||
"title": "Code Steps",
|
||||
"description": "Add Python code processing between AI calls",
|
||||
"content": """
|
||||
<p class="lead">Code steps let you run Python code to process data, validate input, or transform
|
||||
AI outputs between prompts.</p>
|
||||
|
||||
<h2 id="basic-syntax">Basic Syntax</h2>
|
||||
<pre><code class="language-yaml">steps:
|
||||
- type: code
|
||||
code: |
|
||||
# Python code here
|
||||
result = input.upper()
|
||||
output_var: result</code></pre>
|
||||
|
||||
<h2 id="available-variables">Available Variables</h2>
|
||||
<p>Code steps have access to:</p>
|
||||
<ul>
|
||||
<li><code>input</code> - The original input text</li>
|
||||
<li>All argument variables</li>
|
||||
<li>Output variables from previous steps</li>
|
||||
</ul>
|
||||
|
||||
<pre><code class="language-yaml">arguments:
|
||||
- flag: --max
|
||||
variable: max_items
|
||||
default: "10"
|
||||
|
||||
steps:
|
||||
- type: prompt
|
||||
prompt: "List items from: {input}"
|
||||
output_var: items_raw
|
||||
|
||||
- type: code
|
||||
code: |
|
||||
# Access argument and previous step output
|
||||
items = items_raw.strip().split('\\n')
|
||||
limited = items[:int(max_items)]
|
||||
result = '\\n'.join(limited)
|
||||
output_var: result</code></pre>
|
||||
|
||||
<h2 id="multiple-outputs">Multiple Output Variables</h2>
|
||||
<p>Return multiple values with comma-separated output_var:</p>
|
||||
<pre><code class="language-yaml">- type: code
|
||||
code: |
|
||||
lines = input.strip().split('\\n')
|
||||
line_count = len(lines)
|
||||
word_count = len(input.split())
|
||||
char_count = len(input)
|
||||
output_var: line_count, word_count, char_count</code></pre>
|
||||
|
||||
<h2 id="common-operations">Common Operations</h2>
|
||||
|
||||
<h3>Text Processing</h3>
|
||||
<pre><code class="language-yaml">- type: code
|
||||
code: |
|
||||
# Remove empty lines
|
||||
lines = [l for l in input.split('\\n') if l.strip()]
|
||||
cleaned = '\\n'.join(lines)
|
||||
output_var: cleaned</code></pre>
|
||||
|
||||
<h3>JSON Parsing</h3>
|
||||
<pre><code class="language-yaml">- type: code
|
||||
code: |
|
||||
import json
|
||||
data = json.loads(ai_response)
|
||||
formatted = json.dumps(data, indent=2)
|
||||
output_var: formatted</code></pre>
|
||||
|
||||
<h3>Data Validation</h3>
|
||||
<pre><code class="language-yaml">- type: code
|
||||
code: |
|
||||
import re
|
||||
emails = re.findall(r'[\\w.-]+@[\\w.-]+', input)
|
||||
valid_emails = '\\n'.join(emails) if emails else "No emails found"
|
||||
output_var: valid_emails</code></pre>
|
||||
|
||||
<h3>File Operations</h3>
|
||||
<pre><code class="language-yaml">- type: code
|
||||
code: |
|
||||
from pathlib import Path
|
||||
# Write to temp file
|
||||
output_path = Path('/tmp/output.txt')
|
||||
output_path.write_text(processed_text)
|
||||
result = f"Saved to {output_path}"
|
||||
output_var: result</code></pre>
|
||||
|
||||
<h2 id="using-imports">Using Imports</h2>
|
||||
<p>Standard library imports work in code steps:</p>
|
||||
<pre><code class="language-yaml">- type: code
|
||||
code: |
|
||||
import json
|
||||
import re
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
timestamp = datetime.now().isoformat()
|
||||
result = f"Processed at {timestamp}"
|
||||
output_var: result</code></pre>
|
||||
|
||||
<h2 id="error-handling">Error Handling</h2>
|
||||
<p>Handle exceptions to prevent tool failures:</p>
|
||||
<pre><code class="language-yaml">- type: code
|
||||
code: |
|
||||
import json
|
||||
try:
|
||||
data = json.loads(ai_response)
|
||||
result = data.get('summary', 'No summary found')
|
||||
except json.JSONDecodeError:
|
||||
result = ai_response # Fall back to raw response
|
||||
output_var: result</code></pre>
|
||||
|
||||
<h2 id="security">Security Notes</h2>
|
||||
<ul>
|
||||
<li>Code runs with your user permissions</li>
|
||||
<li>Don't use <code>eval()</code> on untrusted input</li>
|
||||
<li>Be careful with file operations</li>
|
||||
<li>Third-party packages must be installed separately</li>
|
||||
</ul>
|
||||
""",
|
||||
"headings": [
|
||||
("basic-syntax", "Basic Syntax"),
|
||||
("available-variables", "Available Variables"),
|
||||
("multiple-outputs", "Multiple Output Variables"),
|
||||
("common-operations", "Common Operations"),
|
||||
("using-imports", "Using Imports"),
|
||||
("error-handling", "Error Handling"),
|
||||
("security", "Security Notes"),
|
||||
],
|
||||
},
|
||||
|
||||
"advanced-workflows": {
|
||||
"title": "Advanced Workflows",
|
||||
"description": "Complex multi-provider and advanced tool patterns",
|
||||
"content": """
|
||||
<p class="lead">Take your tools to the next level with advanced patterns like multi-provider
|
||||
workflows, dynamic prompts, and complex data pipelines.</p>
|
||||
|
||||
<h2 id="multi-provider">Multi-Provider Workflows</h2>
|
||||
<p>Use different AI providers for different tasks:</p>
|
||||
<pre><code class="language-yaml">steps:
|
||||
# Fast model for extraction
|
||||
- type: prompt
|
||||
provider: opencode-grok
|
||||
prompt: "Extract key facts from: {input}"
|
||||
output_var: facts
|
||||
|
||||
# Powerful model for synthesis
|
||||
- type: prompt
|
||||
provider: claude-opus
|
||||
prompt: |
|
||||
Create a comprehensive analysis from these facts:
|
||||
{facts}
|
||||
output_var: analysis</code></pre>
|
||||
|
||||
<h2 id="conditional-logic">Conditional Logic with Code</h2>
|
||||
<p>Use code steps to implement branching:</p>
|
||||
<pre><code class="language-yaml">steps:
|
||||
# Analyze input type
|
||||
- type: code
|
||||
code: |
|
||||
if input.strip().startswith('{'):
|
||||
input_type = "json"
|
||||
processed = input
|
||||
elif ',' in input and '\\n' in input:
|
||||
input_type = "csv"
|
||||
processed = input
|
||||
else:
|
||||
input_type = "text"
|
||||
processed = input
|
||||
output_var: input_type, processed
|
||||
|
||||
# Different prompt based on type
|
||||
- type: prompt
|
||||
provider: claude
|
||||
prompt: |
|
||||
This is {input_type} data. Analyze it appropriately:
|
||||
{processed}
|
||||
output_var: result</code></pre>
|
||||
|
||||
<h2 id="iterative-refinement">Iterative Refinement</h2>
|
||||
<p>Multiple passes for quality improvement:</p>
|
||||
<pre><code class="language-yaml">steps:
|
||||
# First draft
|
||||
- type: prompt
|
||||
provider: opencode-deepseek
|
||||
prompt: "Write a summary of: {input}"
|
||||
output_var: draft
|
||||
|
||||
# Critique
|
||||
- type: prompt
|
||||
provider: claude-haiku
|
||||
prompt: |
|
||||
Review this summary for accuracy and clarity.
|
||||
List specific improvements needed:
|
||||
{draft}
|
||||
output_var: critique
|
||||
|
||||
# Final version
|
||||
- type: prompt
|
||||
provider: claude-sonnet
|
||||
prompt: |
|
||||
Improve this summary based on the feedback:
|
||||
|
||||
Original: {draft}
|
||||
|
||||
Feedback: {critique}
|
||||
output_var: final</code></pre>
|
||||
|
||||
<h2 id="data-pipelines">Data Processing Pipelines</h2>
|
||||
<pre><code class="language-yaml">name: csv-analyzer
|
||||
steps:
|
||||
# Parse CSV
|
||||
- type: code
|
||||
code: |
|
||||
import csv
|
||||
from io import StringIO
|
||||
reader = csv.DictReader(StringIO(input))
|
||||
rows = list(reader)
|
||||
headers = list(rows[0].keys()) if rows else []
|
||||
row_count = len(rows)
|
||||
sample = rows[:5]
|
||||
output_var: headers, row_count, sample
|
||||
|
||||
# AI analysis
|
||||
- type: prompt
|
||||
provider: claude
|
||||
prompt: |
|
||||
Analyze this CSV data:
|
||||
- Columns: {headers}
|
||||
- Row count: {row_count}
|
||||
- Sample rows: {sample}
|
||||
|
||||
Provide insights about the data structure and patterns.
|
||||
output_var: analysis
|
||||
|
||||
# Generate code
|
||||
- type: prompt
|
||||
provider: claude
|
||||
prompt: |
|
||||
Based on this analysis: {analysis}
|
||||
|
||||
Write Python code to process this CSV and extract key metrics.
|
||||
output_var: code</code></pre>
|
||||
|
||||
<h2 id="template-composition">Template Composition</h2>
|
||||
<p>Build prompts dynamically:</p>
|
||||
<pre><code class="language-yaml">arguments:
|
||||
- flag: --task
|
||||
variable: task
|
||||
default: "summarize"
|
||||
|
||||
steps:
|
||||
- type: code
|
||||
code: |
|
||||
templates = {
|
||||
"summarize": "Summarize this concisely:",
|
||||
"explain": "Explain this for a beginner:",
|
||||
"critique": "Provide constructive criticism of:",
|
||||
"expand": "Expand on this with more detail:"
|
||||
}
|
||||
instruction = templates.get(task, templates["summarize"])
|
||||
output_var: instruction
|
||||
|
||||
- type: prompt
|
||||
provider: claude
|
||||
prompt: |
|
||||
{instruction}
|
||||
|
||||
{input}
|
||||
output_var: result</code></pre>
|
||||
|
||||
<h2 id="external-tools">Integrating External Tools</h2>
|
||||
<pre><code class="language-yaml">steps:
|
||||
# Use code to call external commands
|
||||
- type: code
|
||||
code: |
|
||||
import subprocess
|
||||
# Run linter
|
||||
result = subprocess.run(
|
||||
['pylint', '--output-format=json', '-'],
|
||||
input=input,
|
||||
capture_output=True,
|
||||
text=True
|
||||
)
|
||||
lint_output = result.stdout
|
||||
output_var: lint_output
|
||||
|
||||
# AI interprets results
|
||||
- type: prompt
|
||||
provider: claude
|
||||
prompt: |
|
||||
Explain these linting results in plain English
|
||||
and suggest fixes:
|
||||
|
||||
{lint_output}
|
||||
output_var: explanation</code></pre>
|
||||
|
||||
<h2 id="performance-tips">Performance Tips</h2>
|
||||
<ul>
|
||||
<li><strong>Use fast models for simple tasks</strong> - grok for extraction, haiku for formatting</li>
|
||||
<li><strong>Minimize API calls</strong> - Combine related tasks in one prompt</li>
|
||||
<li><strong>Cache with code steps</strong> - Store intermediate results</li>
|
||||
<li><strong>Parallel execution</strong> - See <a href="/docs/parallel-orchestration">Parallel Orchestration</a></li>
|
||||
</ul>
|
||||
""",
|
||||
"headings": [
|
||||
("multi-provider", "Multi-Provider Workflows"),
|
||||
("conditional-logic", "Conditional Logic with Code"),
|
||||
("iterative-refinement", "Iterative Refinement"),
|
||||
("data-pipelines", "Data Processing Pipelines"),
|
||||
("template-composition", "Template Composition"),
|
||||
("external-tools", "Integrating External Tools"),
|
||||
("performance-tips", "Performance Tips"),
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -624,8 +1261,15 @@ def get_toc():
|
|||
SimpleNamespace(slug="getting-started", title="Getting Started", children=[
|
||||
SimpleNamespace(slug="installation", title="Installation"),
|
||||
SimpleNamespace(slug="first-tool", title="Your First Tool"),
|
||||
SimpleNamespace(slug="yaml-config", title="YAML Config"),
|
||||
]),
|
||||
SimpleNamespace(slug="arguments", title="Custom Arguments", children=[]),
|
||||
SimpleNamespace(slug="multi-step", title="Multi-Step Workflows", children=[
|
||||
SimpleNamespace(slug="code-steps", title="Code Steps"),
|
||||
]),
|
||||
SimpleNamespace(slug="publishing", title="Publishing", children=[]),
|
||||
SimpleNamespace(slug="providers", title="Providers", children=[]),
|
||||
SimpleNamespace(slug="parallel-orchestration", title="Parallel Orchestration", children=[]),
|
||||
SimpleNamespace(slug="publishing", title="Publishing", children=[]),
|
||||
SimpleNamespace(slug="advanced-workflows", title="Advanced Workflows", children=[
|
||||
SimpleNamespace(slug="parallel-orchestration", title="Parallel Orchestration"),
|
||||
]),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -528,6 +528,14 @@ def tutorials():
|
|||
|
||||
@web_bp.route("/tutorials/<path:path>", endpoint="tutorials_path")
|
||||
def tutorials_path(path: str):
|
||||
from .docs_content import get_doc
|
||||
doc = get_doc(path)
|
||||
if doc:
|
||||
return render_template(
|
||||
"pages/docs.html",
|
||||
doc=doc,
|
||||
toc=None, # No sidebar for tutorial pages
|
||||
)
|
||||
return render_template(
|
||||
"pages/content.html",
|
||||
title=_title_case(path),
|
||||
|
|
|
|||
Loading…
Reference in New Issue