mirror of
https://github.com/simstudioai/sim.git
synced 2026-02-19 02:34:37 -05:00
feat(slack): ability to have DM channels as destination for slack tools (#2388)
* feat(slack): tool to allow dms * don't make new tool but separate out destination * add log for message limit * consolidate slack selector code * add scopes correctly * fix zod validation * update message logs * add console logs * fix * remove from tools where feature not needed * add correct condition * fix type * fix cond eval logic
This commit is contained in:
committed by
GitHub
parent
bdcc42e566
commit
300aaa5368
@@ -38,6 +38,57 @@ function shouldIncludeField(subBlockConfig: SubBlockConfig, isAdvancedMode: bool
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates a condition object against current field values.
|
||||
* Used to determine if a conditionally-visible field should be included in params.
|
||||
*/
|
||||
function evaluateCondition(
|
||||
condition:
|
||||
| {
|
||||
field: string
|
||||
value: any
|
||||
not?: boolean
|
||||
and?: { field: string; value: any; not?: boolean }
|
||||
}
|
||||
| (() => {
|
||||
field: string
|
||||
value: any
|
||||
not?: boolean
|
||||
and?: { field: string; value: any; not?: boolean }
|
||||
})
|
||||
| undefined,
|
||||
values: Record<string, any>
|
||||
): boolean {
|
||||
if (!condition) return true
|
||||
|
||||
const actual = typeof condition === 'function' ? condition() : condition
|
||||
const fieldValue = values[actual.field]
|
||||
|
||||
const valueMatch = Array.isArray(actual.value)
|
||||
? fieldValue != null &&
|
||||
(actual.not ? !actual.value.includes(fieldValue) : actual.value.includes(fieldValue))
|
||||
: actual.not
|
||||
? fieldValue !== actual.value
|
||||
: fieldValue === actual.value
|
||||
|
||||
const andMatch = !actual.and
|
||||
? true
|
||||
: (() => {
|
||||
const andFieldValue = values[actual.and!.field]
|
||||
const andValueMatch = Array.isArray(actual.and!.value)
|
||||
? andFieldValue != null &&
|
||||
(actual.and!.not
|
||||
? !actual.and!.value.includes(andFieldValue)
|
||||
: actual.and!.value.includes(andFieldValue))
|
||||
: actual.and!.not
|
||||
? andFieldValue !== actual.and!.value
|
||||
: andFieldValue === actual.and!.value
|
||||
return andValueMatch
|
||||
})()
|
||||
|
||||
return valueMatch && andMatch
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to migrate agent block params from old format to messages array
|
||||
* Transforms systemPrompt/userPrompt into messages array format
|
||||
@@ -343,9 +394,15 @@ export class Serializer {
|
||||
const isStarterBlock = block.type === 'starter'
|
||||
const isAgentBlock = block.type === 'agent'
|
||||
|
||||
// First collect all current values from subBlocks, filtering by mode
|
||||
// First pass: collect ALL raw values for condition evaluation
|
||||
const allValues: Record<string, any> = {}
|
||||
Object.entries(block.subBlocks).forEach(([id, subBlock]) => {
|
||||
// Find the corresponding subblock config to check its mode
|
||||
allValues[id] = subBlock.value
|
||||
})
|
||||
|
||||
// Second pass: filter by mode and conditions
|
||||
Object.entries(block.subBlocks).forEach(([id, subBlock]) => {
|
||||
// Find the corresponding subblock config to check its mode and condition
|
||||
const subBlockConfig = blockConfig.subBlocks.find((config) => config.id === id)
|
||||
|
||||
// Include field if it matches current mode OR if it's the starter inputFormat with values
|
||||
@@ -360,9 +417,14 @@ export class Serializer {
|
||||
const isLegacyAgentField =
|
||||
isAgentBlock && ['systemPrompt', 'userPrompt', 'memories'].includes(id)
|
||||
|
||||
// Check if field's condition is met (conditionally-hidden fields should be excluded)
|
||||
const conditionMet = subBlockConfig
|
||||
? evaluateCondition(subBlockConfig.condition, allValues)
|
||||
: true
|
||||
|
||||
if (
|
||||
(subBlockConfig &&
|
||||
(shouldIncludeField(subBlockConfig, isAdvancedMode) || hasStarterInputFormatValues)) ||
|
||||
(subBlockConfig && shouldIncludeField(subBlockConfig, isAdvancedMode) && conditionMet) ||
|
||||
hasStarterInputFormatValues ||
|
||||
isLegacyAgentField
|
||||
) {
|
||||
params[id] = subBlock.value
|
||||
@@ -475,52 +537,6 @@ export class Serializer {
|
||||
// Check required user-only parameters for the current tool
|
||||
const missingFields: string[] = []
|
||||
|
||||
// Helper function to evaluate conditions
|
||||
const evalCond = (
|
||||
condition:
|
||||
| {
|
||||
field: string
|
||||
value: any
|
||||
not?: boolean
|
||||
and?: { field: string; value: any; not?: boolean }
|
||||
}
|
||||
| (() => {
|
||||
field: string
|
||||
value: any
|
||||
not?: boolean
|
||||
and?: { field: string; value: any; not?: boolean }
|
||||
})
|
||||
| undefined,
|
||||
values: Record<string, any>
|
||||
): boolean => {
|
||||
if (!condition) return true
|
||||
const actual = typeof condition === 'function' ? condition() : condition
|
||||
const fieldValue = values[actual.field]
|
||||
|
||||
const valueMatch = Array.isArray(actual.value)
|
||||
? fieldValue != null &&
|
||||
(actual.not ? !actual.value.includes(fieldValue) : actual.value.includes(fieldValue))
|
||||
: actual.not
|
||||
? fieldValue !== actual.value
|
||||
: fieldValue === actual.value
|
||||
|
||||
const andMatch = !actual.and
|
||||
? true
|
||||
: (() => {
|
||||
const andFieldValue = values[actual.and!.field]
|
||||
return Array.isArray(actual.and!.value)
|
||||
? andFieldValue != null &&
|
||||
(actual.and!.not
|
||||
? !actual.and!.value.includes(andFieldValue)
|
||||
: actual.and!.value.includes(andFieldValue))
|
||||
: actual.and!.not
|
||||
? andFieldValue !== actual.and!.value
|
||||
: andFieldValue === actual.and!.value
|
||||
})()
|
||||
|
||||
return valueMatch && andMatch
|
||||
}
|
||||
|
||||
// Iterate through the tool's parameters, not the block's subBlocks
|
||||
Object.entries(currentTool.params || {}).forEach(([paramId, paramConfig]) => {
|
||||
if (paramConfig.required && paramConfig.visibility === 'user-only') {
|
||||
@@ -533,14 +549,14 @@ export class Serializer {
|
||||
const includedByMode = shouldIncludeField(subBlockConfig, isAdvancedMode)
|
||||
|
||||
// Check visibility condition
|
||||
const includedByCondition = evalCond(subBlockConfig.condition, params)
|
||||
const includedByCondition = evaluateCondition(subBlockConfig.condition, params)
|
||||
|
||||
// Check if field is required based on its required condition (if it's a condition object)
|
||||
const isRequired = (() => {
|
||||
if (!subBlockConfig.required) return false
|
||||
if (typeof subBlockConfig.required === 'boolean') return subBlockConfig.required
|
||||
// If required is a condition object, evaluate it
|
||||
return evalCond(subBlockConfig.required, params)
|
||||
return evaluateCondition(subBlockConfig.required, params)
|
||||
})()
|
||||
|
||||
shouldValidateParam = includedByMode && includedByCondition && isRequired
|
||||
|
||||
Reference in New Issue
Block a user