/ src / tools / ThinkTool / ThinkTool.tsx
ThinkTool.tsx
 1  import { z } from 'zod'
 2  import React from 'react'
 3  import { Text } from 'ink'
 4  import { Tool } from '../../Tool.js'
 5  import { DESCRIPTION, PROMPT } from './prompt.js'
 6  import { getTheme } from '../../utils/theme.js'
 7  import { MessageResponse } from '../../components/MessageResponse.js'
 8  import { checkGate, logEvent } from '../../services/statsig.js'
 9  import { USE_BEDROCK, USE_VERTEX } from '../../utils/model.js'
10  
11  const thinkToolSchema = z.object({
12    thought: z.string().describe('Your thoughts.'),
13  })
14  
15  export const ThinkTool = {
16    name: 'Think',
17    userFacingName: () => 'Think',
18    description: async () => DESCRIPTION,
19    inputSchema: thinkToolSchema,
20    isEnabled: async () =>
21      Boolean(process.env.THINK_TOOL) && (await checkGate('tengu_think_tool')),
22    isReadOnly: () => true,
23    needsPermissions: () => false,
24    prompt: async () => PROMPT,
25  
26    async *call(input, { messageId }) {
27      logEvent('tengu_thinking', {
28        messageId,
29        thoughtLength: input.thought.length.toString(),
30        method: 'tool',
31        provider: USE_BEDROCK ? 'bedrock' : USE_VERTEX ? 'vertex' : '1p',
32      })
33  
34      yield {
35        type: 'result',
36        resultForAssistant: 'Your thought has been logged.',
37        data: { thought: input.thought },
38      }
39    },
40  
41    // This is never called -- it's special-cased in AssistantToolUseMessage
42    renderToolUseMessage(input) {
43      return input.thought
44    },
45  
46    renderToolUseRejectedMessage() {
47      return (
48        <MessageResponse>
49          <Text color={getTheme().error}>Thought cancelled</Text>
50        </MessageResponse>
51      )
52    },
53  
54    renderResultForAssistant: () => 'Your thought has been logged.',
55  } satisfies Tool<typeof thinkToolSchema>