@@ -28,7 +28,7 @@ import type {
2828} from '@slack/bolt/dist/Assistant' ;
2929import type { Router } from 'express' ;
3030import { logger } from '../logger.js' ;
31- import { AddieClaudeClient } from './claude-client.js' ;
31+ import { AddieClaudeClient , ADMIN_MAX_ITERATIONS , type UserScopedToolsResult } from './claude-client.js' ;
3232import { AddieDatabase } from '../db/addie-db.js' ;
3333import {
3434 initializeKnowledgeSearch ,
@@ -456,13 +456,15 @@ async function buildMessageWithMemberContext(
456456async function createUserScopedTools (
457457 memberContext : MemberContext | null ,
458458 slackUserId ?: string
459- ) : Promise < RequestTools > {
459+ ) : Promise < UserScopedToolsResult > {
460460 const memberHandlers = createMemberToolHandlers ( memberContext ) ;
461461 const allTools = [ ...MEMBER_TOOLS ] ;
462462 const allHandlers = new Map ( memberHandlers ) ;
463463
464+ const userIsAdmin = isAdmin ( memberContext ) ;
465+
464466 // Add admin tools if user is admin
465- if ( isAdmin ( memberContext ) ) {
467+ if ( userIsAdmin ) {
466468 const adminHandlers = createAdminToolHandlers ( memberContext ) ;
467469 allTools . push ( ...ADMIN_TOOLS ) ;
468470 for ( const [ name , handler ] of adminHandlers ) {
@@ -472,7 +474,7 @@ async function createUserScopedTools(
472474 }
473475
474476 // Add event tools if user can create events (admin or committee lead)
475- const canCreate = slackUserId ? await canCreateEvents ( slackUserId ) : isAdmin ( memberContext ) ;
477+ const canCreate = slackUserId ? await canCreateEvents ( slackUserId ) : userIsAdmin ;
476478 if ( canCreate ) {
477479 const eventHandlers = createEventToolHandlers ( memberContext , slackUserId ) ;
478480 allTools . push ( ...EVENT_TOOLS ) ;
@@ -483,8 +485,11 @@ async function createUserScopedTools(
483485 }
484486
485487 return {
486- tools : allTools ,
487- handlers : allHandlers ,
488+ tools : {
489+ tools : allTools ,
490+ handlers : allHandlers ,
491+ } ,
492+ isAdmin : userIsAdmin ,
488493 } ;
489494}
490495
@@ -702,7 +707,10 @@ async function handleUserMessage({
702707 } ) ;
703708
704709 // Create user-scoped tools (includes admin tools if user is admin)
705- const userTools = await createUserScopedTools ( memberContext , userId ) ;
710+ const { tools : userTools , isAdmin : userIsAdmin } = await createUserScopedTools ( memberContext , userId ) ;
711+
712+ // Admin users get higher iteration limit for bulk operations
713+ const processOptions = userIsAdmin ? { maxIterations : ADMIN_MAX_ITERATIONS } : undefined ;
706714
707715 // Process with Claude using streaming
708716 let response ;
@@ -735,7 +743,7 @@ async function handleUserMessage({
735743 } ) ;
736744
737745 // Process Claude response stream (pass conversation history for context)
738- for await ( const event of claudeClient . processMessageStream ( messageWithContext , conversationHistory , userTools ) ) {
746+ for await ( const event of claudeClient . processMessageStream ( messageWithContext , conversationHistory , userTools , processOptions ) ) {
739747 if ( event . type === 'text' ) {
740748 fullText += event . text ;
741749 // Append text chunk to Slack stream
@@ -776,7 +784,7 @@ async function handleUserMessage({
776784 } else {
777785 // Fall back to non-streaming for compatibility
778786 logger . debug ( 'Addie Bolt: Using non-streaming response (streaming not available)' ) ;
779- response = await claudeClient . processMessage ( messageWithContext , conversationHistory , userTools ) ;
787+ response = await claudeClient . processMessage ( messageWithContext , conversationHistory , userTools , undefined , processOptions ) ;
780788 fullText = response . text ;
781789
782790 // Send response via say() with feedback buttons
@@ -1078,12 +1086,15 @@ async function handleAppMention({
10781086 } ) ;
10791087
10801088 // Create user-scoped tools (includes admin tools if user is admin)
1081- const userTools = await createUserScopedTools ( memberContext , userId ) ;
1089+ const { tools : userTools , isAdmin : userIsAdmin } = await createUserScopedTools ( memberContext , userId ) ;
1090+
1091+ // Admin users get higher iteration limit for bulk operations
1092+ const processOptions = userIsAdmin ? { maxIterations : ADMIN_MAX_ITERATIONS } : undefined ;
10821093
10831094 // Process with Claude
10841095 let response ;
10851096 try {
1086- response = await claudeClient . processMessage ( messageWithContext , undefined , userTools ) ;
1097+ response = await claudeClient . processMessage ( messageWithContext , undefined , userTools , undefined , processOptions ) ;
10871098 } catch ( error ) {
10881099 logger . error ( { error } , 'Addie Bolt: Error processing mention' ) ;
10891100 response = {
@@ -1483,12 +1494,15 @@ async function handleDirectMessage(
14831494 } ) ;
14841495
14851496 // Create user-scoped tools
1486- const userTools = await createUserScopedTools ( memberContext , userId ) ;
1497+ const { tools : userTools , isAdmin : userIsAdmin } = await createUserScopedTools ( memberContext , userId ) ;
1498+
1499+ // Admin users get higher iteration limit for bulk operations
1500+ const processOptions = userIsAdmin ? { maxIterations : ADMIN_MAX_ITERATIONS } : undefined ;
14871501
14881502 // Process with Claude
14891503 let response ;
14901504 try {
1491- response = await claudeClient . processMessage ( messageWithContext , conversationHistory , userTools ) ;
1505+ response = await claudeClient . processMessage ( messageWithContext , conversationHistory , userTools , undefined , processOptions ) ;
14921506 } catch ( error ) {
14931507 logger . error ( { error } , 'Addie Bolt: Error processing DM' ) ;
14941508 response = {
@@ -1814,8 +1828,9 @@ async function handleChannelMessage({
18141828 ) ;
18151829
18161830 // Generate a response with the specified tools (includes admin tools if user is admin)
1817- const userTools = await createUserScopedTools ( memberContext , userId ) ;
1818- const response = await claudeClient . processMessage ( messageWithContext , undefined , userTools ) ;
1831+ const { tools : userTools , isAdmin : userIsAdmin } = await createUserScopedTools ( memberContext , userId ) ;
1832+ const processOptions = userIsAdmin ? { maxIterations : ADMIN_MAX_ITERATIONS } : undefined ;
1833+ const response = await claudeClient . processMessage ( messageWithContext , undefined , userTools , undefined , processOptions ) ;
18191834
18201835 if ( ! response . text || response . text . trim ( ) . length === 0 ) {
18211836 logger . debug ( { channelId } , 'Addie Bolt: No response generated' ) ;
@@ -2272,12 +2287,15 @@ async function handleReactionAdded({
22722287 ) ;
22732288
22742289 // Create user-scoped tools
2275- const userTools = await createUserScopedTools ( memberContext , reactingUserId ) ;
2290+ const { tools : userTools , isAdmin : userIsAdmin } = await createUserScopedTools ( memberContext , reactingUserId ) ;
2291+
2292+ // Admin users get higher iteration limit for bulk operations
2293+ const processOptions = userIsAdmin ? { maxIterations : ADMIN_MAX_ITERATIONS } : undefined ;
22762294
22772295 // Process with Claude
22782296 let response ;
22792297 try {
2280- response = await claudeClient . processMessage ( messageWithContext , undefined , userTools ) ;
2298+ response = await claudeClient . processMessage ( messageWithContext , undefined , userTools , undefined , processOptions ) ;
22812299 } catch ( error ) {
22822300 logger . error ( { error } , 'Addie Bolt: Error processing reaction response' ) ;
22832301 response = {
0 commit comments