mirror of
https://github.com/simstudioai/sim.git
synced 2026-02-14 08:25:03 -05:00
* fix(billing): should allow restoring subscription (#1728) * fix(already-cancelled-sub): UI should allow restoring subscription * restore functionality fixed * fix * improvement(start): revert to start block * make it work with start block * fix start block persistence * cleanup triggers * debounce status checks * update docs * improvement(start): revert to start block * make it work with start block * fix start block persistence * cleanup triggers * debounce status checks * update docs * SSE v0.1 * v0.2 * v0.3 * v0.4 * v0.5 * v0.6 * broken checkpoint * Executor progress - everything preliminarily tested except while loops and triggers * Executor fixes * Fix var typing * Implement while loop execution * Loop and parallel result agg * Refactor v1 - loops work * Fix var resolution in for each loop * Fix while loop condition and variable resolution * Fix loop iteration counts * Fix loop badges * Clean logs * Fix variable references from start block * Fix condition block * Fix conditional convergence * Dont execute orphaned nodse * Code cleanup 1 and error surfacing * compile time try catch * Some fixes * Fix error throwing * Sentinels v1 * Fix multiple start and end nodes in loop * Edge restoration * Fix reachable nodes execution * Parallel subflows * Fix loop/parallel sentinel convergence * Loops and parallels orchestrator * Split executor * Variable resolution split * Dag phase * Refactor * Refactor * Refactor 3 * Lint + refactor * Lint + cleanup + refactor * Readability * Initial logs * Fix trace spans * Console pills for iters * Add input/output pills * Checkpoint * remove unused code * THIS IS THE COMMIT THAT CAN BREAK A LOT OF THINGS * ANOTHER BIG REFACTOR * Lint + fix tests * Fix webhook * Remove comment * Merge stash * Fix triggers? * Stuff * Fix error port * Lint * Consolidate state * Clean up some var resolution * Remove some var resolution logs * Fix chat * Fix chat triggers * Fix chat trigger fully * Snapshot refactor * Fix mcp and custom tools * Lint * Fix parallel default count and trace span overlay * Agent purple * Fix test * Fix test --------- Co-authored-by: Waleed <walif6@gmail.com> Co-authored-by: Vikhyath Mondreti <vikhyathvikku@gmail.com> Co-authored-by: Vikhyath Mondreti <vikhyath@simstudio.ai>
101 lines
3.3 KiB
TypeScript
101 lines
3.3 KiB
TypeScript
import { createLogger } from '@/lib/logs/console/logger'
|
|
import { isReference, parseReferencePath, REFERENCE } from '@/executor/consts'
|
|
import { extractBaseBlockId, extractBranchIndex } from '@/executor/utils/subflow-utils'
|
|
import type { SerializedWorkflow } from '@/serializer/types'
|
|
import type { ResolutionContext, Resolver } from './reference'
|
|
|
|
const logger = createLogger('ParallelResolver')
|
|
|
|
export class ParallelResolver implements Resolver {
|
|
constructor(private workflow: SerializedWorkflow) {}
|
|
|
|
canResolve(reference: string): boolean {
|
|
if (!isReference(reference)) {
|
|
return false
|
|
}
|
|
const parts = parseReferencePath(reference)
|
|
if (parts.length === 0) {
|
|
return false
|
|
}
|
|
const [type] = parts
|
|
return type === REFERENCE.PREFIX.PARALLEL
|
|
}
|
|
|
|
resolve(reference: string, context: ResolutionContext): any {
|
|
const parts = parseReferencePath(reference)
|
|
if (parts.length < 2) {
|
|
logger.warn('Invalid parallel reference - missing property', { reference })
|
|
return undefined
|
|
}
|
|
|
|
const [_, property] = parts
|
|
const parallelId = this.findParallelForBlock(context.currentNodeId)
|
|
if (!parallelId) {
|
|
logger.debug('Block not in a parallel', { nodeId: context.currentNodeId })
|
|
return undefined
|
|
}
|
|
|
|
const parallelConfig = this.workflow.parallels?.[parallelId]
|
|
if (!parallelConfig) {
|
|
logger.warn('Parallel config not found', { parallelId })
|
|
return undefined
|
|
}
|
|
|
|
const branchIndex = extractBranchIndex(context.currentNodeId)
|
|
if (branchIndex === null) {
|
|
logger.debug('Node ID does not have branch index', { nodeId: context.currentNodeId })
|
|
return undefined
|
|
}
|
|
|
|
const distributionItems = this.getDistributionItems(parallelConfig)
|
|
|
|
switch (property) {
|
|
case 'index':
|
|
return branchIndex
|
|
case 'currentItem':
|
|
if (Array.isArray(distributionItems)) {
|
|
return distributionItems[branchIndex]
|
|
}
|
|
if (typeof distributionItems === 'object' && distributionItems !== null) {
|
|
const keys = Object.keys(distributionItems)
|
|
const key = keys[branchIndex]
|
|
return key !== undefined ? distributionItems[key] : undefined
|
|
}
|
|
return undefined
|
|
case 'items':
|
|
return distributionItems
|
|
default:
|
|
logger.warn('Unknown parallel property', { property })
|
|
return undefined
|
|
}
|
|
}
|
|
|
|
private findParallelForBlock(blockId: string): string | undefined {
|
|
const baseId = extractBaseBlockId(blockId)
|
|
if (!this.workflow.parallels) {
|
|
return undefined
|
|
}
|
|
for (const parallelId of Object.keys(this.workflow.parallels)) {
|
|
const parallelConfig = this.workflow.parallels[parallelId]
|
|
if (parallelConfig?.nodes.includes(baseId)) {
|
|
return parallelId
|
|
}
|
|
}
|
|
|
|
return undefined
|
|
}
|
|
|
|
private getDistributionItems(parallelConfig: any): any {
|
|
let distributionItems = parallelConfig.distributionItems || parallelConfig.distribution || []
|
|
if (typeof distributionItems === 'string' && !distributionItems.startsWith('<')) {
|
|
try {
|
|
distributionItems = JSON.parse(distributionItems.replace(/'/g, '"'))
|
|
} catch (e) {
|
|
logger.error('Failed to parse distribution items', { distributionItems })
|
|
return []
|
|
}
|
|
}
|
|
return distributionItems
|
|
}
|
|
}
|