mirror of
https://github.com/langgenius/dify.git
synced 2026-05-06 02:18:08 +08:00
feat: add iteration id
This commit is contained in:
@ -20,8 +20,8 @@ describe('parseDSL', () => {
|
|||||||
nodeId: 'a',
|
nodeId: 'a',
|
||||||
params: [
|
params: [
|
||||||
[
|
[
|
||||||
{ nodeType: 'plain', nodeId: 'b' },
|
{ nodeType: 'plain', nodeId: 'b', iterationId: 'a', iterationIndex: 0 },
|
||||||
{ nodeType: 'plain', nodeId: 'c' },
|
{ nodeType: 'plain', nodeId: 'c', iterationId: 'a', iterationIndex: 0 },
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@ -72,17 +72,19 @@ describe('parseDSL', () => {
|
|||||||
nodeId: 'a',
|
nodeId: 'a',
|
||||||
params: [
|
params: [
|
||||||
[
|
[
|
||||||
{ nodeType: 'plain', nodeId: 'b' },
|
{ nodeType: 'plain', nodeId: 'b', iterationId: 'a', iterationIndex: 0 },
|
||||||
{
|
{
|
||||||
nodeType: 'parallel',
|
nodeType: 'parallel',
|
||||||
nodeId: 'e',
|
nodeId: 'e',
|
||||||
|
iterationId: 'a',
|
||||||
|
iterationIndex: 0,
|
||||||
params: [
|
params: [
|
||||||
[
|
[
|
||||||
{ nodeType: 'plain', nodeId: 'f' },
|
{ nodeType: 'plain', nodeId: 'f', iterationId: 'a', iterationIndex: 0 },
|
||||||
{ nodeType: 'plain', nodeId: 'g' },
|
{ nodeType: 'plain', nodeId: 'g', iterationId: 'a', iterationIndex: 0 },
|
||||||
],
|
],
|
||||||
// single node don't need to be wrapped in an array
|
// single node don't need to be wrapped in an array
|
||||||
{ nodeType: 'plain', nodeId: 'h' },
|
{ nodeType: 'plain', nodeId: 'h', iterationId: 'a', iterationIndex: 0 },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
type NodePlain = { nodeType: 'plain'; nodeId: string }
|
type IterationInfo = { iterationId: string; iterationIndex: number }
|
||||||
type NodeComplex = { nodeType: string; nodeId: string; params: (NodePlain | NodeComplex | Node[])[] }
|
type NodePlain = { nodeType: 'plain'; nodeId: string; } & Partial<IterationInfo>
|
||||||
|
type NodeComplex = { nodeType: string; nodeId: string; params: (NodePlain | (NodeComplex & Partial<IterationInfo>) | Node[] | number)[] } & Partial<IterationInfo>
|
||||||
type Node = NodePlain | NodeComplex
|
type Node = NodePlain | NodeComplex
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -8,7 +9,7 @@ type Node = NodePlain | NodeComplex
|
|||||||
* @returns An array of parsed nodes.
|
* @returns An array of parsed nodes.
|
||||||
*/
|
*/
|
||||||
function parseDSL(dsl: string): Node[] {
|
function parseDSL(dsl: string): Node[] {
|
||||||
return parseTopLevelFlow(dsl).map(parseNode)
|
return parseTopLevelFlow(dsl).map(nodeStr => parseNode(nodeStr))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,9 +45,10 @@ function parseTopLevelFlow(dsl: string): string[] {
|
|||||||
* Parses a single node string.
|
* Parses a single node string.
|
||||||
* If the node is complex (e.g., has parentheses), it extracts the node type, node ID, and parameters.
|
* If the node is complex (e.g., has parentheses), it extracts the node type, node ID, and parameters.
|
||||||
* @param nodeStr - The node string to parse.
|
* @param nodeStr - The node string to parse.
|
||||||
|
* @param parentIterationId - The ID of the parent iteration node (if applicable).
|
||||||
* @returns A parsed node object.
|
* @returns A parsed node object.
|
||||||
*/
|
*/
|
||||||
function parseNode(nodeStr: string): Node {
|
function parseNode(nodeStr: string, parentIterationId?: string): Node {
|
||||||
// Check if the node is a complex node
|
// Check if the node is a complex node
|
||||||
if (nodeStr.startsWith('(') && nodeStr.endsWith(')')) {
|
if (nodeStr.startsWith('(') && nodeStr.endsWith(')')) {
|
||||||
const innerContent = nodeStr.slice(1, -1).trim() // Remove outer parentheses
|
const innerContent = nodeStr.slice(1, -1).trim() // Remove outer parentheses
|
||||||
@ -72,42 +74,53 @@ function parseNode(nodeStr: string): Node {
|
|||||||
|
|
||||||
// Extract nodeType, nodeId, and params
|
// Extract nodeType, nodeId, and params
|
||||||
const [nodeType, nodeId, ...paramsRaw] = parts
|
const [nodeType, nodeId, ...paramsRaw] = parts
|
||||||
const params = parseParams(paramsRaw)
|
const params = parseParams(paramsRaw, nodeType === 'iteration' ? nodeId.trim() : parentIterationId)
|
||||||
|
const complexNode = {
|
||||||
return {
|
|
||||||
nodeType: nodeType.trim(),
|
nodeType: nodeType.trim(),
|
||||||
nodeId: nodeId.trim(),
|
nodeId: nodeId.trim(),
|
||||||
params,
|
params,
|
||||||
}
|
}
|
||||||
|
if (parentIterationId) {
|
||||||
|
complexNode.iterationId = parentIterationId
|
||||||
|
complexNode.iterationIndex = 0 // Fixed as 0
|
||||||
|
}
|
||||||
|
return complexNode
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it's not a complex node, treat it as a plain node
|
// If it's not a complex node, treat it as a plain node
|
||||||
return { nodeType: 'plain', nodeId: nodeStr.trim() }
|
const plainNode: NodePlain = { nodeType: 'plain', nodeId: nodeStr.trim() }
|
||||||
|
if (parentIterationId) {
|
||||||
|
plainNode.iterationId = parentIterationId
|
||||||
|
plainNode.iterationIndex = 0 // Fixed as 0
|
||||||
|
}
|
||||||
|
return plainNode
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses parameters of a complex node.
|
* Parses parameters of a complex node.
|
||||||
* Supports nested flows and complex sub-nodes.
|
* Supports nested flows and complex sub-nodes.
|
||||||
|
* Adds iteration-specific metadata recursively.
|
||||||
* @param paramParts - The parameters string split by commas.
|
* @param paramParts - The parameters string split by commas.
|
||||||
|
* @param iterationId - The ID of the iteration node, if applicable.
|
||||||
* @returns An array of parsed parameters (plain nodes, nested nodes, or flows).
|
* @returns An array of parsed parameters (plain nodes, nested nodes, or flows).
|
||||||
*/
|
*/
|
||||||
function parseParams(paramParts: string[]): (Node | Node[])[] {
|
function parseParams(paramParts: string[], iterationId?: string): (Node | Node[] | number)[] {
|
||||||
return paramParts.map((part) => {
|
return paramParts.map((part) => {
|
||||||
if (part.includes('->')) {
|
if (part.includes('->')) {
|
||||||
// Parse as a flow and return an array of nodes
|
// Parse as a flow and return an array of nodes
|
||||||
return parseTopLevelFlow(part).map(parseNode)
|
return parseTopLevelFlow(part).map(node => parseNode(node, iterationId))
|
||||||
}
|
}
|
||||||
else if (part.startsWith('(')) {
|
else if (part.startsWith('(')) {
|
||||||
// Parse as a nested complex node
|
// Parse as a nested complex node
|
||||||
return parseNode(part)
|
return parseNode(part, iterationId)
|
||||||
}
|
}
|
||||||
else if (!isNaN(Number(part.trim()))) {
|
else if (!Number.isNaN(Number(part.trim()))) {
|
||||||
// Parse as a numeric parameter
|
// Parse as a numeric parameter
|
||||||
return Number(part.trim())
|
return Number(part.trim())
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Parse as a plain node
|
// Parse as a plain node
|
||||||
return parseNode(part)
|
return parseNode(part, iterationId)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user