mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-28 03:00:29 -04:00
feat(tools): added thinking tool, hiddenFromSidebar param (#230)
* add thinking tool and block * add hiddenFromSidebar for blocks that we want to be accessible to agents but hidden as standalone blocks
This commit is contained in:
@@ -19,7 +19,8 @@ export function Toolbar() {
|
||||
const filteredBlocks = !searchQuery.trim() ? getBlocksByCategory(activeTab) : getAllBlocks()
|
||||
|
||||
return filteredBlocks.filter((block) => {
|
||||
if (block.type === 'starter') return false
|
||||
if (block.type === 'starter' || block.hiddenFromSidebar) return false
|
||||
|
||||
return (
|
||||
!searchQuery.trim() ||
|
||||
block.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
|
||||
52
sim/blocks/blocks/thinking.ts
Normal file
52
sim/blocks/blocks/thinking.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { BrainIcon } from '@/components/icons'
|
||||
import { ToolResponse } from '@/tools/types'
|
||||
import { BlockConfig } from '../types'
|
||||
|
||||
interface ThinkingToolResponse extends ToolResponse {
|
||||
output: {
|
||||
acknowledgedThought: string
|
||||
}
|
||||
}
|
||||
|
||||
export const ThinkingBlock: BlockConfig<ThinkingToolResponse> = {
|
||||
type: 'thinking',
|
||||
name: 'Thinking',
|
||||
description: 'Forces model to outline its thought process.',
|
||||
longDescription:
|
||||
'Adds a step where the model explicitly outlines its thought process before proceeding. This can improve reasoning quality by encouraging step-by-step analysis.',
|
||||
category: 'tools',
|
||||
bgColor: '#181C1E',
|
||||
icon: BrainIcon,
|
||||
hiddenFromSidebar: true,
|
||||
|
||||
subBlocks: [
|
||||
{
|
||||
id: 'thought',
|
||||
title: 'Thought Process / Instruction',
|
||||
type: 'long-input',
|
||||
layout: 'full',
|
||||
placeholder: 'Describe the step-by-step thinking process here...',
|
||||
hidden: true,
|
||||
},
|
||||
],
|
||||
|
||||
inputs: {
|
||||
thought: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'The detailed thought process or instruction for the model.',
|
||||
},
|
||||
},
|
||||
|
||||
outputs: {
|
||||
response: {
|
||||
type: {
|
||||
acknowledgedThought: 'string',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
tools: {
|
||||
access: ['thinking_tool'],
|
||||
},
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import { GoogleDocsBlock } from './blocks/docs'
|
||||
import { GoogleDriveBlock } from './blocks/drive'
|
||||
import { EvaluatorBlock } from './blocks/evaluator'
|
||||
import { ExaBlock } from './blocks/exa'
|
||||
import { MistralParseBlock } from './blocks/mistral-parse'
|
||||
import { FileBlock } from './blocks/file'
|
||||
import { FirecrawlBlock } from './blocks/firecrawl'
|
||||
import { FunctionBlock } from './blocks/function'
|
||||
@@ -17,6 +16,7 @@ import { GmailBlock } from './blocks/gmail'
|
||||
// import { GuestyBlock } from './blocks/guesty'
|
||||
import { ImageGeneratorBlock } from './blocks/image-generator'
|
||||
import { JinaBlock } from './blocks/jina'
|
||||
import { MistralParseBlock } from './blocks/mistral-parse'
|
||||
import { NotionBlock } from './blocks/notion'
|
||||
import { OpenAIBlock } from './blocks/openai'
|
||||
import { PerplexityBlock } from './blocks/perplexity'
|
||||
@@ -29,6 +29,7 @@ import { SlackBlock } from './blocks/slack'
|
||||
import { StarterBlock } from './blocks/starter'
|
||||
import { SupabaseBlock } from './blocks/supabase'
|
||||
import { TavilyBlock } from './blocks/tavily'
|
||||
import { ThinkingBlock } from './blocks/thinking'
|
||||
import { TranslateBlock } from './blocks/translate'
|
||||
import { TwilioSMSBlock } from './blocks/twilio'
|
||||
import { TypeformBlock } from './blocks/typeform'
|
||||
@@ -77,6 +78,7 @@ export {
|
||||
TwilioSMSBlock,
|
||||
ImageGeneratorBlock,
|
||||
TypeformBlock,
|
||||
ThinkingBlock,
|
||||
}
|
||||
|
||||
// Registry of all block configurations, alphabetically sorted
|
||||
@@ -88,7 +90,6 @@ const blocks: Record<string, BlockConfig> = {
|
||||
confluence: ConfluenceBlock,
|
||||
evaluator: EvaluatorBlock,
|
||||
exa: ExaBlock,
|
||||
mistral_parse: MistralParseBlock,
|
||||
firecrawl: FirecrawlBlock,
|
||||
file: FileBlock,
|
||||
function: FunctionBlock,
|
||||
@@ -100,6 +101,7 @@ const blocks: Record<string, BlockConfig> = {
|
||||
// guesty: GuestyBlock,
|
||||
image_generator: ImageGeneratorBlock,
|
||||
jina: JinaBlock,
|
||||
mistral_parse: MistralParseBlock,
|
||||
notion: NotionBlock,
|
||||
openai: OpenAIBlock,
|
||||
perplexity: PerplexityBlock,
|
||||
@@ -111,6 +113,7 @@ const blocks: Record<string, BlockConfig> = {
|
||||
starter: StarterBlock,
|
||||
supabase: SupabaseBlock,
|
||||
tavily: TavilyBlock,
|
||||
thinking: ThinkingBlock,
|
||||
translate: TranslateBlock,
|
||||
twilio_sms: TwilioSMSBlock,
|
||||
typeform: TypeformBlock,
|
||||
|
||||
@@ -152,6 +152,7 @@ export interface BlockConfig<T extends ToolResponse = ToolResponse> {
|
||||
}
|
||||
}
|
||||
}
|
||||
hiddenFromSidebar?: boolean
|
||||
}
|
||||
|
||||
// Output configuration rules
|
||||
|
||||
@@ -1359,48 +1359,6 @@ export const CrunchbaseIcon = (props: SVGProps<SVGSVGElement>) => (
|
||||
</svg>
|
||||
)
|
||||
|
||||
export function BrainIcon(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
{...props}
|
||||
width="30"
|
||||
height="30"
|
||||
viewBox="0 0 30 30"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M20.0553 16.4443C18.7145 16.4443 17.4286 16.977 16.4805 17.9251C15.5324 18.8732 14.9998 20.1591 14.9998 21.4999M14.9998 21.4999V22.9443M14.9998 21.4999C14.9998 20.1591 14.4671 18.8732 13.519 17.9251C12.5709 16.977 11.285 16.4443 9.94423 16.4443M14.9998 22.9443C14.9998 24.2852 15.5324 25.5711 16.4805 26.5192C17.4286 27.4673 18.7145 27.9999 20.0553 27.9999C21.3962 27.9999 22.6821 27.4673 23.6302 26.5192C24.5783 25.5711 25.1109 24.2852 25.1109 22.9443V20.3443M14.9998 22.9443C14.9998 24.2852 14.4671 25.5711 13.519 26.5192C12.5709 27.4673 11.285 27.9999 9.94423 27.9999C8.60341 27.9999 7.31751 27.4673 6.36941 26.5192C5.42131 25.5711 4.88867 24.2852 4.88867 22.9443V20.3443"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M22.9449 20.7779C24.2857 20.7779 25.5716 20.2452 26.5197 19.2971C27.4678 18.349 28.0004 17.0631 28.0004 15.7223C28.0004 14.3815 27.4678 13.0956 26.5197 12.1475C25.5716 11.1994 24.2857 10.6667 22.9449 10.6667H22.2227"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M25.1111 11.1V7.05556C25.1111 5.71474 24.5785 4.42884 23.6304 3.48074C22.6823 2.53264 21.3964 2 20.0556 2C18.7147 2 17.4288 2.53264 16.4807 3.48074C15.5326 4.42884 14.9998 5.71474 14.9998 7.05556V21.5"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M4.88867 11.1V7.05556C4.88867 5.71474 5.42131 4.42884 6.36941 3.48074C7.31751 2.53264 8.60341 2 9.94423 2C11.285 2 12.5709 2.53264 13.519 3.48074C14.4671 4.42884 14.9998 5.71474 14.9998 7.05556V21.5"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function InputIcon(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg
|
||||
@@ -1866,3 +1824,19 @@ export function MistralIcon(props: SVGProps<SVGSVGElement>) {
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function BrainIcon(props: SVGProps<SVGSVGElement>) {
|
||||
return (
|
||||
<svg {...props} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" fill="currentColor">
|
||||
<title>Brain</title>
|
||||
<g id="Brain">
|
||||
<path d="M11,5.34c-.12,1,.26.66-1,.66A7,7,0,0,0,4.85,17.75,7,7,0,0,0,2.62,28.48,12.14,12.14,0,0,0,.06,37.22C1,46.59,12.33,51.56,19.31,45A11.66,11.66,0,0,0,23,36.51V6.22C23-1.57,11.86-2.14,11,5.34Zm-.55,40.55a8.89,8.89,0,0,1-4.78-2.18l.42-.42a2.1,2.1,0,0,1,2.42-.4,1,1,0,0,0,.9-1.78c-2-1-1.24.83-2-3.11-.61-3,1.55-4.14,0-4.89-1.79-.9-2.38,3.32-2,5.28.79,4,.85,1.7-1.19,3.94a10,10,0,0,1-.13-12.5c1.51,1,4.86,2,4.86.17a1,1,0,0,0-1-1c-5.79,0-6.94-8.33-1.27-9.82C8,19.87,11,20.73,11,19a1,1,0,0,0-1-1,5,5,0,1,1,1.44-9.77C13,12,18,13,18,11a1,1,0,0,0-1-1,4,4,0,1,1,4-3.78v9.37l-1.16,1.15a3.42,3.42,0,0,1-4.29.43,1,1,0,0,0-1.38.28c-1.12,1.68,3.7,3.68,6.83.92V36.51A9.3,9.3,0,0,1,10.49,45.89Z" />
|
||||
<path d="M16.21,23.79a3.14,3.14,0,0,0-4.42,0c-1,1-2-.42-3.08-1.5a1,1,0,0,0-1.42,1.42l.86.85-1.47.49A1,1,0,0,0,7.32,27L10.18,26c2.71.74,3.26-2.15,4.61-.79l2.5,2.5a1,1,0,0,0,1.42-1.42Z" />
|
||||
<path d="M17,33H16a3,3,0,0,0-3,3,1,1,0,0,1-1,1H11a1,1,0,0,0,0,2h1a3,3,0,0,0,3-3,1,1,0,0,1,1-1h1A1,1,0,0,0,17,33Z" />
|
||||
<path d="M45.36,28.49a7,7,0,0,0-2.21-10.74A7,7,0,0,0,38,6c-1.28,0-.93.35-1-.63A6,6,0,0,0,31,0a6.13,6.13,0,0,0-6,6.22V36.51C25,42.89,30.26,48.4,36.82,48A12,12,0,0,0,45.36,28.49Zm-1.65,13.8A4.92,4.92,0,0,0,42,41c.55-2.79,1.21-4.79-.13-7.47a1,1,0,0,0-1.78.9c1,2.06.45,3.65-.07,6.25-3.33.28-1.92,2.85-.59,2.19s2.33.34,2.88.84A9.28,9.28,0,0,1,27,36.51V18.37c3.12,2.75,8,.76,6.83-.92a1,1,0,0,0-1.38-.28,3.42,3.42,0,0,1-4.29-.43L27,15.59V6.22A4,4,0,1,1,31,10a1,1,0,0,0-1,1c0,2.05,5.07,1,6.57-2.78A5,5,0,1,1,38,18a1,1,0,0,0,0,2,7,7,0,0,0,3.27-.82C47,20.68,45.73,29,40,29a1,1,0,0,0,0,2,6.89,6.89,0,0,0,3.86-1.17C48.62,35.85,44,42.55,43.71,42.29Z" />
|
||||
<path d="M41,27a1,1,0,0,0,.32-1.95l-1.47-.49.86-.85a1,1,0,0,0-1.42-1.42c-1.09,1.09-2.07,2.51-3.08,1.5a3.14,3.14,0,0,0-4.42,0l-2.5,2.5A1,1,0,0,0,30,28c.56,0,.54-.13,3.21-2.79,1.38-1.38,1.86,1.54,4.61.79C40.92,27,40.78,27,41,27Z" />
|
||||
<path d="M37,37H36a1,1,0,0,1-1-1,3,3,0,0,0-3-3H31a1,1,0,0,0,0,2h1a1,1,0,0,1,1,1,3,3,0,0,0,3,3h1A1,1,0,0,0,37,37Z" />
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -44,10 +44,11 @@ import { sheetsReadTool, sheetsUpdateTool, sheetsWriteTool } from './sheets'
|
||||
import { slackMessageTool } from './slack/message'
|
||||
import { supabaseInsertTool, supabaseQueryTool } from './supabase'
|
||||
import { tavilyExtractTool, tavilySearchTool } from './tavily'
|
||||
import { thinkingTool } from './thinking/thinking'
|
||||
import { sendSMSTool } from './twilio/send'
|
||||
import { typeformFilesTool, typeformInsightsTool, typeformResponsesTool } from './typeform'
|
||||
import { OAuthTokenPayload, ToolConfig, ToolResponse } from './types'
|
||||
import { formatRequestParams, validateToolRequest, transformTable } from './utils'
|
||||
import { formatRequestParams, transformTable, validateToolRequest } from './utils'
|
||||
import { visionTool } from './vision/vision'
|
||||
import { whatsappSendMessageTool } from './whatsapp'
|
||||
import { xReadTool, xSearchTool, xUserTool, xWriteTool } from './x'
|
||||
@@ -122,6 +123,7 @@ export const tools: Record<string, ToolConfig> = {
|
||||
airtable_list_records: airtableListRecordsTool,
|
||||
airtable_update_record: airtableUpdateRecordTool,
|
||||
mistral_parser: mistralParserTool,
|
||||
thinking_tool: thinkingTool,
|
||||
}
|
||||
|
||||
// Get a tool by its ID
|
||||
@@ -345,7 +347,7 @@ export async function executeTool(
|
||||
const endTime = new Date()
|
||||
const endTimeISO = endTime.toISOString()
|
||||
const duration = endTime.getTime() - startTime.getTime()
|
||||
|
||||
|
||||
// Apply post-processing if available and not skipped
|
||||
if (tool.postProcess && directResult.success && !skipPostProcess) {
|
||||
try {
|
||||
@@ -370,7 +372,7 @@ export async function executeTool(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
...directResult,
|
||||
timing: {
|
||||
|
||||
3
sim/tools/thinking/index.ts
Normal file
3
sim/tools/thinking/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { thinkingTool } from './thinking'
|
||||
|
||||
export { thinkingTool }
|
||||
39
sim/tools/thinking/thinking.ts
Normal file
39
sim/tools/thinking/thinking.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import { ToolConfig } from '../types'
|
||||
import { ThinkingToolParams, ThinkingToolResponse } from './types'
|
||||
|
||||
export const thinkingTool: ToolConfig<ThinkingToolParams, ThinkingToolResponse> = {
|
||||
id: 'thinking_tool',
|
||||
name: 'Thinking Tool',
|
||||
description:
|
||||
'Processes a provided thought/instruction, making it available for subsequent steps.',
|
||||
version: '1.0.0',
|
||||
|
||||
// Define the input parameter
|
||||
params: {
|
||||
thought: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
description:
|
||||
'The thought process or instruction provided by the user in the Thinking Step block.',
|
||||
},
|
||||
},
|
||||
|
||||
// Use directExecution as no external HTTP call is needed
|
||||
directExecution: async (params: ThinkingToolParams): Promise<ThinkingToolResponse> => {
|
||||
// Simply acknowledge the thought by returning it in the output
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
acknowledgedThought: params.thought,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
// Request configuration is not needed due to directExecution, but the type requires it.
|
||||
// Provide minimal valid configuration.
|
||||
request: {
|
||||
url: '', // Not used
|
||||
method: 'POST', // Not used
|
||||
headers: () => ({}), // Not used
|
||||
},
|
||||
}
|
||||
11
sim/tools/thinking/types.ts
Normal file
11
sim/tools/thinking/types.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { ToolResponse } from '../types'
|
||||
|
||||
export interface ThinkingToolParams {
|
||||
thought: string
|
||||
}
|
||||
|
||||
export interface ThinkingToolResponse extends ToolResponse {
|
||||
output: {
|
||||
acknowledgedThought: string
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user