How Bootspring's AI expert agents work.
The agent system provides specialized AI personas for different development tasks. Each agent has expertise in a specific domain and collaborates with others.
┌─────────────────────────────────────────────────────────────────────┐
│ AGENT SYSTEM │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Agent │ │ Context │ │ LLM │ │
│ │ Registry │───▶│ Builder │───▶│ Provider │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Profile │ │ Project │ │ Response │ │
│ │ Loader │ │ Context │ │ Processor │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
1 interface AgentProfile {
2 // Identity
3 name : string ;
4 displayName : string ;
5 description : string ;
6 avatar ? : string ;
7
8 // Classification
9 category : AgentCategory ;
10 tier : Tier ;
11 tags : string [ ] ;
12
13 // Behavior
14 systemPrompt : string ;
15 capabilities : string [ ] ;
16 limitations : string [ ] ;
17
18 // Collaboration
19 collaborates : string [ ] ;
20 delegates : DelegationRule [ ] ;
21
22 // Configuration
23 model ? : string ;
24 temperature ? : number ;
25 maxTokens ? : number ;
26
27 // Extensions
28 tools ? : Tool [ ] ;
29 examples ? : Example [ ] ;
30 }
31
32 type AgentCategory =
33 | 'development'
34 | 'quality'
35 | 'architecture'
36 | 'business'
37 | 'design' ;
38
39 type Tier = 'free' | 'pro' | 'team' | 'enterprise' ;
1 # agents/frontend-expert.yaml
2
3 name : frontend - expert
4 displayName : Frontend Expert
5 description : Expert in React , Next.js , and modern frontend development
6
7 category : development
8 tier : free
9 tags : [ react , nextjs , typescript , css , tailwind ]
10
11 systemPrompt : |
12 You are a senior frontend developer with deep expertise in:
13 - React 18+ with Server Components
14 - Next.js 14+ App Router
15 - TypeScript best practices
16 - Tailwind CSS and modern styling
17 - Performance optimization
18 - Accessibility (WCAG 2.1)
19
20 When helping users :
21 1. Prefer Server Components when possible
22 2. Use TypeScript with strict mode
23 3. Follow React best practices (hooks , composition)
24 4. Consider performance and accessibility
25 5. Provide complete , working code examples
26
27 capabilities :
28 - React component development
29 - Next.js App Router patterns
30 - Tailwind CSS styling
31 - Form handling and validation
32 - State management
33 - API integration
34 - Performance optimization
35 - Accessibility implementation
36
37 limitations :
38 - Backend/database design (delegate to backend - expert)
39 - Infrastructure/DevOps (delegate to devops - expert)
40 - Security audits (delegate to security - expert)
41
42 collaborates :
43 - ui - ux - expert
44 - testing - expert
45 - performance - expert
46 - backend - expert
47
48 delegates :
49 - pattern : "database|schema|prisma"
50 to : database - expert
51 - pattern : "api|endpoint|route"
52 to : api - expert
53 - pattern : "security|auth|permission"
54 to : security - expert
55
56 examples :
57 - prompt : "Create a data table component"
58 response : |
59 Here's a reusable data table component...
1 // core/agents/registry.ts
2
3 export class AgentRegistry {
4 private agents : Map < string , AgentProfile > = new Map ( ) ;
5 private categories : Map < AgentCategory , string [ ] > = new Map ( ) ;
6
7 async loadAll ( agentsPath : string ) : Promise < void > {
8 const files = await glob ( '*.yaml' , { cwd : agentsPath } ) ;
9
10 for ( const file of files ) {
11 const content = await readFile ( join ( agentsPath , file ) , 'utf-8' ) ;
12 const profile = parseYaml < AgentProfile > ( content ) ;
13
14 this . register ( profile ) ;
15 }
16 }
17
18 register ( profile : AgentProfile ) : void {
19 // Validate profile
20 this . validate ( profile ) ;
21
22 // Store in registry
23 this . agents . set ( profile . name , profile ) ;
24
25 // Index by category
26 const categoryAgents = this . categories . get ( profile . category ) || [ ] ;
27 categoryAgents . push ( profile . name ) ;
28 this . categories . set ( profile . category , categoryAgents ) ;
29 }
30
31 get ( name : string ) : AgentProfile | undefined {
32 return this . agents . get ( name ) ;
33 }
34
35 list ( filter ? : AgentFilter ) : AgentProfile [ ] {
36 let results = Array . from ( this . agents . values ( ) ) ;
37
38 if ( filter ?. category ) {
39 results = results . filter ( a => a . category === filter . category ) ;
40 }
41 if ( filter ?. tier ) {
42 results = results . filter ( a => TIER_ORDER [ a . tier ] <= TIER_ORDER [ filter . tier ! ] ) ;
43 }
44 if ( filter ?. tags ) {
45 results = results . filter ( a =>
46 filter . tags ! . some ( t => a . tags . includes ( t ) )
47 ) ;
48 }
49
50 return results ;
51 }
52 }
1 // core/agents/invoker.ts
2
3 export class AgentInvoker {
4 private registry : AgentRegistry ;
5 private contextBuilder : ContextBuilder ;
6 private llmProvider : LLMProvider ;
7 private entitlements : EntitlementChecker ;
8
9 async invoke (
10 agentName : string ,
11 prompt : string ,
12 options : InvokeOptions = { }
13 ) : Promise < AgentResponse > {
14 // 1. Load agent profile
15 const agent = this . registry . get ( agentName ) ;
16 if ( ! agent ) {
17 throw new AgentNotFoundError ( agentName ) ;
18 }
19
20 // 2. Check entitlements
21 await this . checkEntitlements ( agent , options . userId ) ;
22
23 // 3. Build context
24 const context = await this . buildContext ( agent , options ) ;
25
26 // 4. Prepare messages
27 const messages = this . prepareMessages ( agent , prompt , context ) ;
28
29 // 5. Invoke LLM
30 const startTime = Date . now ( ) ;
31 const response = await this . llmProvider . complete ( messages , {
32 model : agent . model || 'claude-3-5-sonnet' ,
33 temperature : agent . temperature ?? 0.7 ,
34 maxTokens : options . maxTokens || agent . maxTokens || 4096 ,
35 } ) ;
36
37 // 6. Process response
38 const processed = await this . processResponse ( response , agent ) ;
39
40 // 7. Track usage
41 await this . trackUsage ( {
42 agent : agentName ,
43 duration : Date . now ( ) - startTime ,
44 tokens : response . usage ,
45 userId : options . userId ,
46 } ) ;
47
48 return processed ;
49 }
50
51 private async buildContext (
52 agent : AgentProfile ,
53 options : InvokeOptions
54 ) : Promise < InvocationContext > {
55 const context : InvocationContext = {
56 agent : {
57 name : agent . name ,
58 capabilities : agent . capabilities ,
59 } ,
60 } ;
61
62 // Add project context
63 if ( options . projectId ) {
64 context . project = await this . contextBuilder . getProjectContext (
65 options . projectId
66 ) ;
67 }
68
69 // Add file context
70 if ( options . files ?. length ) {
71 context . files = await this . contextBuilder . getFileContents (
72 options . files
73 ) ;
74 }
75
76 // Add conversation history
77 if ( options . history ?. length ) {
78 context . history = options . history ;
79 }
80
81 return context ;
82 }
83
84 private prepareMessages (
85 agent : AgentProfile ,
86 prompt : string ,
87 context : InvocationContext
88 ) : Message [ ] {
89 const messages : Message [ ] = [ ] ;
90
91 // System message with agent persona
92 messages . push ( {
93 role : 'system' ,
94 content : this . buildSystemPrompt ( agent , context ) ,
95 } ) ;
96
97 // Add history if present
98 if ( context . history ) {
99 messages . push ( ... context . history ) ;
100 }
101
102 // User prompt
103 messages . push ( {
104 role : 'user' ,
105 content : this . buildUserPrompt ( prompt , context ) ,
106 } ) ;
107
108 return messages ;
109 }
110 }
1 // core/agents/context-builder.ts
2
3 export class ContextBuilder {
4 async build ( options : ContextOptions ) : Promise < string > {
5 const sections : string [ ] = [ ] ;
6
7 // Agent context
8 sections . push ( this . formatAgentContext ( options . agent ) ) ;
9
10 // Project context
11 if ( options . project ) {
12 sections . push ( await this . formatProjectContext ( options . project ) ) ;
13 }
14
15 // File contents
16 if ( options . files ?. length ) {
17 sections . push ( await this . formatFileContents ( options . files ) ) ;
18 }
19
20 // Custom context
21 if ( options . custom ) {
22 sections . push ( options . custom ) ;
23 }
24
25 return sections . join ( '\n\n---\n\n' ) ;
26 }
27
28 private formatAgentContext ( agent : AgentProfile ) : string {
29 return `
30 ## Agent: ${ agent . displayName }
31
32 **Capabilities:**
33 ${ agent . capabilities . map ( c => ` - ${ c } ` ) . join ( '\n' ) }
34
35 **Collaboration:**
36 When appropriate, suggest involving:
37 ${ agent . collaborates . map ( c => ` - ${ c } ` ) . join ( '\n' ) }
38 ` . trim ( ) ;
39 }
40
41 private async formatProjectContext ( projectId : string ) : Promise < string > {
42 const context = await this . loadProjectContext ( projectId ) ;
43
44 return `
45 ## Project Context
46
47 ${ context . summary }
48
49 **Tech Stack:** ${ context . stack . join ( ', ' ) }
50 **Key Files:**
51 ${ context . keyFiles . map ( f => ` - ${ f . path } : ${ f . description } ` ) . join ( '\n' ) }
52 ` . trim ( ) ;
53 }
54 }
1 // core/agents/delegation.ts
2
3 export class DelegationManager {
4 private registry : AgentRegistry ;
5
6 shouldDelegate (
7 agent : AgentProfile ,
8 prompt : string
9 ) : DelegationSuggestion | null {
10 for ( const rule of agent . delegates || [ ] ) {
11 const regex = new RegExp ( rule . pattern , 'i' ) ;
12
13 if ( regex . test ( prompt ) ) {
14 const targetAgent = this . registry . get ( rule . to ) ;
15
16 if ( targetAgent ) {
17 return {
18 from : agent . name ,
19 to : rule . to ,
20 reason : ` This task involves ${ rule . pattern } , which is better handled by ${ targetAgent . displayName } ` ,
21 confidence : this . calculateConfidence ( prompt , rule ) ,
22 } ;
23 }
24 }
25 }
26
27 return null ;
28 }
29
30 suggestCollaborators (
31 agent : AgentProfile ,
32 prompt : string
33 ) : CollaborationSuggestion [ ] {
34 const suggestions : CollaborationSuggestion [ ] = [ ] ;
35
36 for ( const collaborator of agent . collaborates ) {
37 const collaboratorProfile = this . registry . get ( collaborator ) ;
38
39 if ( collaboratorProfile && this . isRelevant ( prompt , collaboratorProfile ) ) {
40 suggestions . push ( {
41 agent : collaborator ,
42 reason : ` ${ collaboratorProfile . displayName } could help with ${ this . getRelevantCapability ( prompt , collaboratorProfile ) } ` ,
43 } ) ;
44 }
45 }
46
47 return suggestions ;
48 }
49 }
1 // core/agents/orchestration.ts
2
3 export class MultiAgentOrchestrator {
4 async orchestrate (
5 task : Task ,
6 agents : string [ ]
7 ) : Promise < OrchestrationResult > {
8 const results : AgentResult [ ] = [ ] ;
9
10 for ( const agentName of agents ) {
11 // Get previous results as context
12 const previousContext = this . formatPreviousResults ( results ) ;
13
14 // Invoke agent with context
15 const result = await this . invoker . invoke ( agentName , task . prompt , {
16 context : previousContext ,
17 task : task . id ,
18 } ) ;
19
20 results . push ( {
21 agent : agentName ,
22 response : result ,
23 } ) ;
24
25 // Check if task is complete
26 if ( this . isTaskComplete ( task , results ) ) {
27 break ;
28 }
29 }
30
31 return {
32 task : task . id ,
33 agents : results . map ( r => r . agent ) ,
34 finalResponse : this . synthesizeResults ( results ) ,
35 } ;
36 }
37 }
1 // core/agents/processor.ts
2
3 export class ResponseProcessor {
4 process ( response : LLMResponse , agent : AgentProfile ) : AgentResponse {
5 const content = response . content ;
6
7 return {
8 id : generateId ( ) ,
9 agent : agent . name ,
10 content : content ,
11 type : this . detectResponseType ( content ) ,
12 codeBlocks : this . extractCodeBlocks ( content ) ,
13 suggestions : this . extractSuggestions ( content , agent ) ,
14 usage : response . usage ,
15 timestamp : new Date ( ) ,
16 } ;
17 }
18
19 private detectResponseType ( content : string ) : ResponseType {
20 if ( content . includes ( '```' ) ) return 'code' ;
21 if ( content . includes ( '##' ) ) return 'documentation' ;
22 if ( content . includes ( '- [ ]' ) ) return 'checklist' ;
23 return 'text' ;
24 }
25
26 private extractCodeBlocks ( content : string ) : CodeBlock [ ] {
27 const regex = / ``` ( \w + ) ? \n ( [ \s \S ] *? ) ``` / g ;
28 const blocks : CodeBlock [ ] = [ ] ;
29 let match ;
30
31 while ( ( match = regex . exec ( content ) ) !== null ) {
32 blocks . push ( {
33 language : match [ 1 ] || 'text' ,
34 code : match [ 2 ] . trim ( ) ,
35 } ) ;
36 }
37
38 return blocks ;
39 }
40 }
Agent Expertise frontend-expertReact, Next.js, CSS backend-expertAPIs, servers, logic database-expertSchemas, queries, optimization api-expertREST, GraphQL, design mobile-expertReact Native, iOS, Android
Agent Expertise testing-expertUnit, integration, E2E security-expertAuth, vulnerabilities, compliance performance-expertOptimization, profiling code-review-expertBest practices, patterns
Agent Expertise architecture-expertSystem design, patterns devops-expertCI/CD, infrastructure cloud-expertAWS, GCP, Azure
Agent Expertise business-strategy-expertStrategy, planning fundraising-expertInvestors, pitching growth-expertMetrics, acquisition