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"),
|
("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="getting-started", title="Getting Started", children=[
|
||||||
SimpleNamespace(slug="installation", title="Installation"),
|
SimpleNamespace(slug="installation", title="Installation"),
|
||||||
SimpleNamespace(slug="first-tool", title="Your First Tool"),
|
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="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")
|
@web_bp.route("/tutorials/<path:path>", endpoint="tutorials_path")
|
||||||
def tutorials_path(path: str):
|
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(
|
return render_template(
|
||||||
"pages/content.html",
|
"pages/content.html",
|
||||||
title=_title_case(path),
|
title=_title_case(path),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue