Claude Component
The <Claude> component is the core of Smithers. It executes Claude via Claude Code CLI with full tool access, database logging, and structured output support.
Basic Usage
import { Claude } from "smithers/smithers-orchestrator/src/components/Claude" ;
< Claude
model = "sonnet"
maxTurns = { 10 }
onFinished = { ( result ) => console . log ( result . output ) }
>
Analyze this codebase and suggest improvements.
</ Claude >
Props
Model Configuration
model
'opus' | 'sonnet' | 'haiku'
default: "sonnet"
The Claude model to use. < Claude model = "opus" > Complex reasoning task </ Claude >
< Claude model = "sonnet" > Standard task </ Claude >
< Claude model = "haiku" > Quick, simple task </ Claude >
Maximum number of agentic turns (tool use cycles). < Claude maxTurns = { 5 } > Limited iteration task </ Claude >
Maximum tokens for the response.
Timeout in milliseconds. < Claude timeout = { 60000 } > Task with 1 minute timeout </ Claude >
System Prompt
Custom system prompt for Claude. < Claude systemPrompt = "You are a security expert. Focus on vulnerabilities." >
Review this code.
</ Claude >
Custom tools to provide to Claude. < Claude tools = { [ myCustomTool ] } >
Use the custom tool.
</ Claude >
Restrict Claude to only these built-in tools. < Claude allowedTools = { [ "Read" , "Glob" , "Grep" ] } >
Research only - no edits.
</ Claude >
Prevent Claude from using these tools. < Claude disallowedTools = { [ "Bash" ] } >
No shell commands.
</ Claude >
permissionMode
'default' | 'acceptEdits' | 'plan'
Permission handling mode. < Claude permissionMode = "acceptEdits" >
Auto-accept file edits.
</ Claude >
Structured Output
Zod schema for structured output validation. const ResultSchema = z . object ({
summary: z . string (),
issues: z . array ( z . string ()),
});
< Claude schema = { ResultSchema } >
Return structured analysis.
</ Claude >
Custom validation function. < Claude validate = { ( r ) => r . issues . length > 0 } >
Must find at least one issue.
</ Claude >
Retry if validation fails.
Maximum validation retries.
Callbacks
onFinished
(result: AgentResult) => void
Called when execution completes. < Claude onFinished = { ( result ) => {
console . log ( result . output );
console . log ( result . structured ); // If schema provided
console . log ( result . tokensUsed );
} } >
Task
</ Claude >
Called on execution error. < Claude onError = { ( err ) => console . error ( err ) } >
Risky task
</ Claude >
onProgress
(message: string) => void
Called with progress updates.
onToolCall
(tool: string, input: any) => void
Called when Claude uses a tool.
Stop Conditions
Conditions that can stop execution early. < Claude
stopConditions = { [
{ type: "token_limit" , value: 10000 },
{ type: "pattern" , value: /DONE/ i },
] }
>
Task with stop conditions
</ Claude >
AgentResult Type
interface AgentResult < T = any > {
output : string ; // Raw text output
structured ?: T ; // Validated structured output
tokensUsed : {
input : number ;
output : number ;
};
turnsUsed : number ;
stopReason : 'completed' | 'stop_condition' | 'error' | 'cancelled' ;
durationMs : number ;
exitCode ?: number ;
sessionId ?: string ;
}
Structured Output with Zod
Get typed, validated responses:
import { z } from 'zod' ;
const AnalysisSchema = z . object ({
summary: z . string (),
issues: z . array ( z . object ({
severity: z . enum ([ 'low' , 'medium' , 'high' , 'critical' ]),
file: z . string (),
description: z . string (),
})),
recommendations: z . array ( z . string ()),
});
< Claude
model = "sonnet"
schema = { AnalysisSchema }
maxRetries = { 2 }
onFinished = { ( result ) => {
// result.structured is typed as z.infer<typeof AnalysisSchema>
for ( const issue of result . structured . issues ) {
console . log ( `[ ${ issue . severity } ] ${ issue . file } : ${ issue . description } ` );
}
} }
>
Analyze this codebase for security issues.
Return a structured analysis.
</ Claude >
Control what Claude can do:
// Research only - no modifications
< Claude allowedTools = { [ "Read" , "Glob" , "Grep" ] } >
Find all files that import the auth module.
</ Claude >
// Full edit access
< Claude
allowedTools = { [ "Read" , "Edit" , "Write" , "Bash" ] }
permissionMode = "acceptEdits"
>
Implement the feature.
</ Claude >
// No shell access
< Claude disallowedTools = { [ "Bash" ] } >
Analyze the code (no commands).
</ Claude >
Conditional Rendering
Use signals to control when Claude runs:
function ConditionalClaude () {
const [ phase , setPhase ] = createSignal ( "research" );
return (
< Ralph maxIterations = { 5 } >
{ phase () === "research" && (
< Claude
allowedTools = { [ "Read" , "Glob" ] }
onFinished = { () => setPhase ( "implement" ) }
>
Research the codebase.
</ Claude >
) }
{ phase () === "implement" && (
< Claude
allowedTools = { [ "Edit" , "Write" ] }
onFinished = { () => setPhase ( "done" ) }
>
Implement the solution.
</ Claude >
) }
</ Ralph >
);
}
Nested Prompt Components
Compose prompts with child components:
< Claude model = "sonnet" >
< Sqlite path = "./data.db" >
Database contains users and orders tables.
</ Sqlite >
Find the top 10 customers by order value.
Export results to a CSV file.
</ Claude >
Error Handling
function ResilientClaude () {
const [ attempts , setAttempts ] = createSignal ( 0 );
const [ error , setError ] = createSignal < Error | null >( null );
return (
< Ralph maxIterations = { 3 } >
{ error () && attempts () < 3 && (
< Claude
onFinished = { () => setError ( null ) }
onError = { ( err ) => {
setError ( err );
setAttempts ( a => a + 1 );
} }
>
Previous attempt failed: { error ()?. message }
Try a different approach.
</ Claude >
) }
{ ! error () && (
< Claude
onFinished = { ( r ) => console . log ( "Success:" , r . output ) }
onError = { setError }
>
Complete the task.
</ Claude >
) }
</ Ralph >
);
}
Best Practices
Always set maxTurns for agentic tasks
Prevent runaway iterations: < Claude maxTurns = { 10 } > ... </ Claude >
Use allowedTools to restrict access
Use schemas for predictable output
Validate responses with Zod: < Claude schema = { MySchema } maxRetries = { 2 } >