11import { ServiceNowIcon } from '@/components/icons'
2- import type { BlockConfig , BlockMeta } from '@/blocks/types'
2+ import type { BlockConfig , BlockMeta , BlockToolParamsContext } from '@/blocks/types'
33import { AuthMode , IntegrationType } from '@/blocks/types'
4- import { normalizeFileInput , withSavedCredential } from '@/blocks/utils'
4+ import { isToolCall , normalizeFileInput , toolCallArg , withSavedCredential } from '@/blocks/utils'
55import {
66 APPROVAL_DECISION_OPTIONS ,
77 APPROVAL_STATE ,
@@ -1622,9 +1622,9 @@ Output: {"state": "2", "assigned_to": "john.doe", "work_notes": "Assigned and st
16221622 ] ,
16231623 config : {
16241624 tool : ( params ) => params . operation ,
1625- params : ( params ) => {
1625+ params : ( params , context ?: BlockToolParamsContext ) => {
16261626 const {
1627- operation,
1627+ operation : storedOperation ,
16281628 fields,
16291629 readFields,
16301630 returnFields,
@@ -1644,11 +1644,23 @@ Output: {"state": "2", "assigned_to": "john.doe", "work_notes": "Assigned and st
16441644 knowledgeQuery,
16451645 ...rest
16461646 } = params
1647+ const operation = context ?. operation ?? storedOperation
1648+ /**
1649+ * A dedicated subblock's value, or on a tool call where it is blank, the
1650+ * model's arg under the tool param name. Without a model arg the subblock
1651+ * value stands exactly, so an explicit "Any" (`''`) is not replaced.
1652+ */
1653+ const dedicatedOrToolArg = ( dedicated : unknown , toolArg : unknown ) =>
1654+ isToolCall ( context ) &&
1655+ toolArg !== undefined &&
1656+ ( dedicated === undefined || dedicated === null || dedicated === '' )
1657+ ? toolArg
1658+ : dedicated
16471659 const isCreateOrUpdate =
16481660 operation === 'servicenow_create_record' || operation === 'servicenow_update_record'
16491661
16501662 if ( SEMANTIC_DISPLAY_VALUE_OPS . has ( operation ) ) {
1651- rest . displayValue = semanticDisplayValue
1663+ rest . displayValue = dedicatedOrToolArg ( semanticDisplayValue , rest . displayValue )
16521664 }
16531665
16541666 /**
@@ -1659,7 +1671,9 @@ Output: {"state": "2", "assigned_to": "john.doe", "work_notes": "Assigned and st
16591671 * query — so each gets its own subblock and is republished here for the
16601672 * operations that own it. Assign explicitly rather than conditionally:
16611673 * `finalInputs` merges this result over the raw inputs, so a key left
1662- * off is not dropped, it keeps whatever the raw input held.
1674+ * off is not dropped, it keeps whatever the raw input held. On a tool
1675+ * call the model supplies these under the tool param names, so a blank
1676+ * dedicated subblock falls back to the model's value instead of wiping it.
16631677 */
16641678 const stateSource =
16651679 operation === 'servicenow_update_change_state'
@@ -1669,12 +1683,24 @@ Output: {"state": "2", "assigned_to": "john.doe", "work_notes": "Assigned and st
16691683 : CHANGE_STATE_OPS . has ( operation )
16701684 ? changeState
16711685 : incidentState
1672- rest . state = SEMANTIC_STATE_OPS . has ( operation ) ? stateSource : undefined
1673- rest . comments =
1674- operation === 'servicenow_update_approval' ? approvalComments : incidentComments
1675- rest . closeCode = CHANGE_CLOSE_OPS . has ( operation ) ? changeCloseCode : resolutionCode
1676- rest . closeNotes = CHANGE_CLOSE_OPS . has ( operation ) ? changeCloseNotes : resolutionNotes
1677- if ( operation === 'servicenow_search_knowledge' ) rest . query = knowledgeQuery
1686+ rest . state = SEMANTIC_STATE_OPS . has ( operation )
1687+ ? dedicatedOrToolArg ( stateSource , rest . state )
1688+ : undefined
1689+ rest . comments = dedicatedOrToolArg (
1690+ operation === 'servicenow_update_approval' ? approvalComments : incidentComments ,
1691+ rest . comments
1692+ )
1693+ rest . closeCode = dedicatedOrToolArg (
1694+ CHANGE_CLOSE_OPS . has ( operation ) ? changeCloseCode : resolutionCode ,
1695+ rest . closeCode
1696+ )
1697+ rest . closeNotes = dedicatedOrToolArg (
1698+ CHANGE_CLOSE_OPS . has ( operation ) ? changeCloseNotes : resolutionNotes ,
1699+ rest . closeNotes
1700+ )
1701+ if ( operation === 'servicenow_search_knowledge' ) {
1702+ rest . query = dedicatedOrToolArg ( knowledgeQuery , rest . query )
1703+ }
16781704
16791705 /**
16801706 * `attachmentLimit` exists as a separate subblock precisely so a limit
@@ -1684,8 +1710,8 @@ Output: {"state": "2", "assigned_to": "john.doe", "work_notes": "Assigned and st
16841710 * Every paginated operation reads exactly one of the two.
16851711 */
16861712 if ( operation === 'servicenow_list_attachments' ) {
1687- rest . limit =
1688- attachmentLimit != null && attachmentLimit !== '' ? Number ( attachmentLimit ) : undefined
1713+ const limit = dedicatedOrToolArg ( attachmentLimit , rest . limit )
1714+ rest . limit = limit != null && limit !== '' ? Number ( limit ) : undefined
16891715 } else if ( rest . limit != null ) {
16901716 rest . limit = rest . limit === '' ? undefined : Number ( rest . limit )
16911717 }
@@ -1741,7 +1767,12 @@ Output: {"state": "2", "assigned_to": "john.doe", "work_notes": "Assigned and st
17411767 }
17421768
17431769 const projection = operation === 'servicenow_read_record' ? readFields : returnFields
1744- return { ...rest , fields : projection || undefined }
1770+ const toolFields = toolCallArg ( context , fields )
1771+ const toolProjection =
1772+ typeof toolFields === 'string' && ! toolFields . trim ( ) . startsWith ( '{' )
1773+ ? toolFields
1774+ : undefined
1775+ return { ...rest , fields : projection || toolProjection || undefined }
17451776 } ,
17461777 } ,
17471778 } ,
0 commit comments