Skip to content

Commit 9ce4fd1

Browse files
committed
fix(gauge): scope inputs to the selected operation
1 parent 898ccb1 commit 9ce4fd1

7 files changed

Lines changed: 166 additions & 14 deletions

File tree

‎apps/sim/blocks/blocks/gauge.ts‎

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,7 @@ export const GaugeBlock: BlockConfig = {
664664
id: 'topic',
665665
title: 'Topic Filters',
666666
type: 'code',
667+
dependsOn: ['operation'],
667668
condition: { field: 'operation', value: ['gauge_list_answers', 'gauge_list_citations'] },
668669
language: 'json',
669670
placeholder: '["top_..."]',
@@ -970,21 +971,29 @@ export const GaugeBlock: BlockConfig = {
970971
],
971972
config: {
972973
tool: (params) => params.operation,
973-
params: (params) => {
974+
params: (params, context) => {
975+
const operation = context?.operation ?? params.operation
976+
const patch = ['gauge_bulk_update_prompts', 'gauge_update_prompt'].includes(operation)
974977
return {
975978
...params,
976979
limit: params.limit === '' || params.limit == null ? undefined : Number(params.limit),
977-
topic: params.topicFilter ?? params.topic,
980+
topic:
981+
operation === 'gauge_list_prompts'
982+
? (params.topicFilter ?? (context?.operation ? params.topic : undefined))
983+
: params.topic,
978984
topicId: params.topicId === '' ? undefined : params.topicId,
979-
trackingType:
980-
params.promptTrackingType === 'unchanged'
985+
trackingType: patch
986+
? params.promptTrackingType === 'unchanged'
981987
? undefined
982-
: (params.promptTrackingType ?? params.trackingType),
988+
: (params.promptTrackingType ?? params.trackingType)
989+
: params.trackingType,
983990
name: params.name === '' ? undefined : params.name,
984991
dataset:
985-
params.metadataDataset === 'all'
986-
? undefined
987-
: (params.metadataDataset ?? params.dataset),
992+
operation === 'gauge_get_query_metadata'
993+
? params.metadataDataset === 'all'
994+
? undefined
995+
: (params.metadataDataset ?? params.dataset)
996+
: params.dataset,
988997
}
989998
},
990999
},

‎apps/sim/blocks/types.ts‎

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,12 @@ export type CanvasSentenceClause =
597597
/** An ordered set of clauses forming one card summary sentence. */
598598
export type CanvasSentence = readonly CanvasSentenceClause[]
599599

600+
/** Trusted mapper context kept separate from user-configured and model-supplied arguments. */
601+
export interface BlockToolParamsContext {
602+
/** Operation selected by the configuring surface. */
603+
operation?: string
604+
}
605+
600606
export interface BlockConfig {
601607
type: string
602608
name: string
@@ -669,7 +675,10 @@ export interface BlockConfig {
669675
access: string[]
670676
config?: {
671677
tool: (params: Record<string, any>) => string
672-
params?: (params: Record<string, any>) => Record<string, any>
678+
params?: (
679+
params: Record<string, any>,
680+
context?: BlockToolParamsContext
681+
) => Record<string, any>
673682
}
674683
}
675684
inputs: Record<string, ParamConfig>

‎apps/sim/executor/handlers/human-in-the-loop/handler.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,9 @@ export class HumanInTheLoopBlockHandler implements BlockHandler {
423423
).filter(isCanonicalPair)
424424

425425
const { paramsTransform } = buildBlockToolParamsTransform({
426+
operation:
427+
toolConfig.operation ??
428+
(typeof storedParams.operation === 'string' ? storedParams.operation : undefined),
426429
blockSubBlocks: subBlocks,
427430
blockParamsFn: notificationBlock?.tools?.config?.params,
428431
blockInputDefs: notificationBlock?.inputs,

‎apps/sim/providers/utils.test.ts‎

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,15 @@ import {
4848
} from '@/providers/utils'
4949
import { useProvidersStore } from '@/stores/providers/store'
5050
import { gaugeGetQueryMetadataTool } from '@/tools/gauge/get_query_metadata'
51+
import { gaugeListAnswersTool } from '@/tools/gauge/list_answers'
52+
import { gaugeListCitationsTool } from '@/tools/gauge/list_citations'
5153
import { gaugeListPromptsTool } from '@/tools/gauge/list_prompts'
54+
import { gaugeQueryTool } from '@/tools/gauge/query'
5255
import type {
5356
GaugeGetQueryMetadataParams,
57+
GaugeListAnswersParams,
5458
GaugeListPromptsParams,
59+
GaugeQueryParams,
5560
GaugeUpdatePromptParams,
5661
} from '@/tools/gauge/types'
5762
import { gaugeUpdatePromptTool } from '@/tools/gauge/update_prompt'
@@ -88,6 +93,84 @@ const mockGetRotatingApiKey = vi.fn().mockReturnValue('rotating-server-key')
8893
const originalRequire = module.require
8994

9095
describe('integration filters through agent execution', () => {
96+
it.each([
97+
{ tool: gaugeListAnswersTool, field: 'topicFilterSelector' },
98+
{ tool: gaugeListAnswersTool, field: 'manualTopicFilter' },
99+
{ tool: gaugeListCitationsTool, field: 'topicFilterSelector' },
100+
{ tool: gaugeListCitationsTool, field: 'manualTopicFilter' },
101+
])('ignores stale $field aliases for $tool.id', async ({ tool, field }) => {
102+
const providerTool = await transformBlockTool(
103+
{
104+
type: 'gauge',
105+
params: {
106+
org: 'example',
107+
category: 'example',
108+
[field]: 'top_stale',
109+
topic: '["top_active"]',
110+
promptTrackingType: 'branded_own',
111+
trackingType: 'all',
112+
},
113+
},
114+
{ selectedOperation: tool.id, getAllBlocks: () => [GaugeBlock], getTool: () => tool }
115+
)
116+
if (!providerTool) throw new Error('Gauge agent tool was not created')
117+
const { executionParams } = prepareToolExecution(providerTool, {}, {}, undefined)
118+
const params = { ...executionParams, accessToken: 'fixture-token' } as GaugeListAnswersParams
119+
const url = typeof tool.request.url === 'function' ? tool.request.url(params) : tool.request.url
120+
expect(new URL(url).searchParams.getAll('topic')).toEqual(['top_active'])
121+
expect(new URL(url).searchParams.get('trackingType')).toBe('all')
122+
})
123+
124+
it.each(['answers', 'all'])(
125+
'ignores a stale %s metadata selection when querying a different dataset',
126+
async (metadataDataset) => {
127+
const tool = gaugeQueryTool
128+
const providerTool = await transformBlockTool(
129+
{
130+
type: 'gauge',
131+
params: {
132+
org: 'example',
133+
dataset: 'citations',
134+
metrics: '["citations"]',
135+
metadataDataset,
136+
},
137+
},
138+
{ selectedOperation: tool.id, getAllBlocks: () => [GaugeBlock], getTool: () => tool }
139+
)
140+
if (!providerTool) throw new Error('Gauge agent tool was not created')
141+
const { executionParams } = prepareToolExecution(providerTool, {}, {}, undefined)
142+
const params = { ...executionParams, accessToken: 'fixture-token' } as GaugeQueryParams
143+
expect(tool.request.body?.(params)).toMatchObject({ dataset: 'citations' })
144+
}
145+
)
146+
147+
it('clears an incompatible Gauge topic array when switching an agent to List Prompts', async () => {
148+
const tool = gaugeListPromptsTool
149+
vi.spyOn(blockRegistry, 'getBlock').mockReturnValue(GaugeBlock)
150+
const params = getParamsForToolOperation(
151+
{ type: 'gauge', params: { org: 'example', category: 'example', topic: '["top_stale"]' } },
152+
tool
153+
)
154+
const providerTool = await transformBlockTool(
155+
{ type: 'gauge', params },
156+
{ selectedOperation: tool.id, getAllBlocks: () => [GaugeBlock], getTool: () => tool }
157+
)
158+
if (!providerTool) throw new Error('Gauge agent tool was not created')
159+
const { executionParams } = prepareToolExecution(
160+
providerTool,
161+
{ topic: 'top_model' },
162+
{},
163+
undefined
164+
)
165+
const requestParams = {
166+
...executionParams,
167+
accessToken: 'fixture-token',
168+
} as GaugeListPromptsParams
169+
const url =
170+
typeof tool.request.url === 'function' ? tool.request.url(requestParams) : tool.request.url
171+
expect(new URL(url).searchParams.get('topic')).toBe('top_model')
172+
})
173+
91174
it.each(['configured', 'model'] as const)(
92175
'retains the %s Gauge topic filter without a stored operation',
93176
async (source) => {

‎apps/sim/providers/utils.ts‎

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
} from '@/lib/workflows/subblocks/visibility'
2424
import { resolveBlockToolId } from '@/lib/workflows/tool-input/identity'
2525
import { assembleCustomBlockInputMapping, isCustomBlockType } from '@/blocks/custom/build-config'
26-
import type { SubBlockConfig } from '@/blocks/types'
26+
import type { BlockToolParamsContext, SubBlockConfig } from '@/blocks/types'
2727
import { isCustomTool } from '@/executor/constants'
2828
import {
2929
findProviderFromModel,
@@ -523,7 +523,10 @@ function buildCustomBlockInputMappingSchema(
523523
}
524524
}
525525

526-
type BlockToolParamsFn = (params: Record<string, any>) => Record<string, any>
526+
type BlockToolParamsFn = (
527+
params: Record<string, any>,
528+
context?: BlockToolParamsContext
529+
) => Record<string, any>
527530

528531
/**
529532
* Builds the transform that turns a tool row's stored sub-block values into the
@@ -547,6 +550,7 @@ type BlockToolParamsFn = (params: Record<string, any>) => Record<string, any>
547550
* none of it, which is why it needed a new version rather than a fix in place.
548551
*/
549552
export function buildBlockToolParamsTransform(config: {
553+
operation?: string
550554
blockSubBlocks: SubBlockConfig[] | undefined
551555
blockParamsFn: BlockToolParamsFn | undefined
552556
blockInputDefs: Record<string, unknown> | undefined
@@ -558,6 +562,7 @@ export function buildBlockToolParamsTransform(config: {
558562
jsonShapedParamKeys: string[]
559563
} {
560564
const {
565+
operation,
561566
blockSubBlocks,
562567
blockParamsFn,
563568
blockInputDefs,
@@ -613,7 +618,7 @@ export function buildBlockToolParamsTransform(config: {
613618
}
614619

615620
if (blockParamsFn) {
616-
const transformed = blockParamsFn(result)
621+
const transformed = blockParamsFn(result, { operation })
617622
result = { ...result, ...transformed }
618623
}
619624

@@ -893,6 +898,9 @@ export async function transformBlockTool(
893898
}
894899

895900
const { paramsTransform, jsonShapedParamKeys } = buildBlockToolParamsTransform({
901+
operation:
902+
selectedOperation ??
903+
(typeof userProvidedParams.operation === 'string' ? userProvidedParams.operation : undefined),
896904
blockSubBlocks: blockDef?.subBlocks,
897905
blockParamsFn: blockDef?.tools?.config?.params as BlockToolParamsFn | undefined,
898906
blockInputDefs: blockDef?.inputs as Record<string, unknown> | undefined,

‎apps/sim/serializer/gauge.test.ts‎

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { beforeEach, describe, expect, it, vi } from 'vitest'
2+
import { getBlock } from '@/blocks'
3+
import { GaugeBlock } from '@/blocks/blocks/gauge'
4+
import { extractBlockParams } from '@/serializer/index'
5+
import { prepareBlockState } from '@/stores/workflows/prepare-block-state'
6+
import { gaugeListPromptsTool } from '@/tools/gauge/list_prompts'
7+
import type { GaugeListPromptsParams } from '@/tools/gauge/types'
8+
import { prepareToolRequest } from '@/tools/request-transport'
9+
10+
describe('Gauge canvas operation changes', () => {
11+
beforeEach(() => {
12+
vi.mocked(getBlock).mockReturnValue(GaugeBlock)
13+
})
14+
15+
it.each([false, true])(
16+
'does not reuse an old topic array after clearing the prompt filter (advanced: %s)',
17+
(advancedMode) => {
18+
const block = prepareBlockState({
19+
id: 'gauge_fixture',
20+
type: 'gauge',
21+
name: 'Gauge',
22+
position: { x: 0, y: 0 },
23+
})
24+
block.advancedMode = advancedMode
25+
block.subBlocks.operation.value = 'gauge_list_prompts'
26+
block.subBlocks.manualOrg.value = 'example'
27+
block.subBlocks.manualCategory.value = 'example'
28+
block.subBlocks.topic.value = '["top_stale"]'
29+
const params = extractBlockParams(block)
30+
const mapped = GaugeBlock.tools.config?.params?.(params)
31+
if (!mapped) throw new Error('Gauge parameter mapping is unavailable')
32+
const request = prepareToolRequest(gaugeListPromptsTool, {
33+
...mapped,
34+
org: 'example',
35+
category: 'example',
36+
accessToken: 'fixture-token',
37+
} as GaugeListPromptsParams)
38+
expect(new URL(request.url).searchParams.has('topic')).toBe(false)
39+
}
40+
)
41+
})

‎scripts/check-test-types.baseline.json‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,8 +657,7 @@
657657
"TS18048": 7
658658
},
659659
"apps/sim/blocks/blocks/google_drive.test.ts": {
660-
"TS18048": 1,
661-
"TS2554": 4
660+
"TS18048": 1
662661
},
663662
"apps/sim/blocks/blocks/instagram.test.ts": {
664663
"TS18048": 1

0 commit comments

Comments
 (0)