{"version":3,"sources":["/Users/shyun/comcom/ain-enterprise/ain-adk/dist/cjs/chunk-7KW3WUN6.cjs","../../src/services/workflow-graph.service.ts"],"names":["spec","mermaid"],"mappings":"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","file":"/Users/shyun/comcom/ain-enterprise/ain-adk/dist/cjs/chunk-7KW3WUN6.cjs","sourcesContent":[null,"import type {\n\tWorkflowGraphBlock,\n\tWorkflowPieChartBlock,\n\tWorkflowRenderedGraphData,\n\tWorkflowRenderedPieChartData,\n\tWorkflowRenderedXYChartData,\n\tWorkflowXYChartBlock,\n\tWorkflowXYChartSeriesData,\n} from \"@/types/memory.js\";\n\nexport type WorkflowGraphRenderResult = {\n\tcontent: string;\n\tdata: WorkflowRenderedGraphData;\n};\n\nexport class WorkflowGraphService {\n\tbuildExtractionPrompt(\n\t\tblock: WorkflowGraphBlock,\n\t\tresultsText: string,\n\t\trenderedBlocksText = \"\",\n\t): string {\n\t\treturn block.graphType === \"xychart-beta\"\n\t\t\t? this.buildXYChartExtractionPrompt(\n\t\t\t\t\tblock,\n\t\t\t\t\tresultsText,\n\t\t\t\t\trenderedBlocksText,\n\t\t\t\t)\n\t\t\t: this.buildPieChartExtractionPrompt(\n\t\t\t\t\tblock,\n\t\t\t\t\tresultsText,\n\t\t\t\t\trenderedBlocksText,\n\t\t\t\t);\n\t}\n\n\trenderGraph(\n\t\tblock: WorkflowGraphBlock,\n\t\trawContent: string,\n\t): WorkflowGraphRenderResult {\n\t\tif (block.graphType === \"xychart-beta\") {\n\t\t\tconst spec = this.parseXYChartSpec(block, rawContent);\n\t\t\tconst mermaid = this.renderXYChart(spec);\n\t\t\treturn {\n\t\t\t\tcontent: `\\`\\`\\`mermaid\\n${mermaid}\\n\\`\\`\\`\\n\\n`,\n\t\t\t\tdata: {\n\t\t\t\t\tspec,\n\t\t\t\t\tmermaid,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\tconst spec = this.parsePieChartSpec(block, rawContent);\n\t\tconst mermaid = this.renderPieChart(spec);\n\t\treturn {\n\t\t\tcontent: `\\`\\`\\`mermaid\\n${mermaid}\\n\\`\\`\\`\\n\\n`,\n\t\t\tdata: {\n\t\t\t\tspec,\n\t\t\t\tmermaid,\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate buildXYChartExtractionPrompt(\n\t\tblock: WorkflowXYChartBlock,\n\t\tresultsText: string,\n\t\trenderedBlocksText: string,\n\t): string {\n\t\treturn `Task results:\n${resultsText}\n\nRendered response blocks:\n${renderedBlocksText || \"(none)\"}\n\nExtract only the data needed to render a Mermaid xychart-beta graph.\nReturn only a valid JSON object with this shape:\n{\n  \"title\": \"string (optional)\",\n  \"xAxis\": [\"category label\", \"...\"],\n  \"yAxis\": {\n    \"label\": \"string (optional)\",\n    \"min\": \"number (optional)\",\n    \"max\": \"number (optional)\"\n  },\n  \"series\": [\n    {\n      \"kind\": \"bar or line\",\n      \"label\": \"string (optional)\",\n      \"data\": [1, 2, 3]\n    }\n  ]\n}\n\nRules:\n- xAxis must be a non-empty array of strings.\n- series must be a non-empty array.\n- Every series.data array must contain only numbers.\n- Every series.data length must exactly match xAxis length.\n- Use \"bar\" or \"line\" for series.kind.\n- Omit yAxis.min / yAxis.max if they cannot be determined confidently.\n- Prefer the workflow block title when it is already provided.\n\nWorkflow block title:\n${block.title || \"(none)\"}\n\nWorkflow graph instructions:\n${block.prompt}`;\n\t}\n\n\tprivate buildPieChartExtractionPrompt(\n\t\tblock: WorkflowPieChartBlock,\n\t\tresultsText: string,\n\t\trenderedBlocksText: string,\n\t): string {\n\t\treturn `Task results:\n${resultsText}\n\nRendered response blocks:\n${renderedBlocksText || \"(none)\"}\n\nExtract only the data needed to render a Mermaid pie graph.\nReturn only a valid JSON object with this shape:\n{\n  \"title\": \"string (optional)\",\n  \"showData\": \"boolean (optional)\",\n  \"slices\": [\n    {\n      \"label\": \"string\",\n      \"value\": 1\n    }\n  ]\n}\n\nRules:\n- slices must be a non-empty array.\n- Every slice.label must be a non-empty string.\n- Every slice.value must be a positive number greater than zero.\n- Prefer the workflow block title when it is already provided.\n- Respect the block-level showData flag when it is provided.\n\nWorkflow block title:\n${block.title || \"(none)\"}\n\nWorkflow block showData:\n${block.showData === undefined ? \"(unspecified)\" : String(block.showData)}\n\nWorkflow graph instructions:\n${block.prompt}`;\n\t}\n\n\tprivate parseXYChartSpec(\n\t\tblock: WorkflowXYChartBlock,\n\t\trawContent: string,\n\t): WorkflowRenderedXYChartData {\n\t\tconst parsed = this.parseJsonObject(rawContent);\n\t\tconst xAxis = Array.isArray(parsed.xAxis)\n\t\t\t? parsed.xAxis\n\t\t\t\t\t.map((value) => this.toNonEmptyString(value))\n\t\t\t\t\t.filter((value): value is string => Boolean(value))\n\t\t\t: [];\n\t\tif (xAxis.length === 0) {\n\t\t\tthrow new Error(\"XY chart extraction must return xAxis: string[].\");\n\t\t}\n\n\t\tconst rawSeries = Array.isArray(parsed.series) ? parsed.series : [];\n\t\tif (rawSeries.length === 0) {\n\t\t\tthrow new Error(\"XY chart extraction must return a non-empty series[].\");\n\t\t}\n\n\t\tconst series = rawSeries.map((entry, index) =>\n\t\t\tthis.parseXYChartSeries(entry, xAxis.length, index),\n\t\t);\n\t\tconst title = this.toNonEmptyString(parsed.title) || block.title;\n\t\tconst rawYAxis = this.asRecord(parsed.yAxis);\n\t\tconst yAxis = rawYAxis ? this.buildXYAxisConfig(rawYAxis) : undefined;\n\n\t\treturn {\n\t\t\tgraphType: \"xychart-beta\",\n\t\t\t...(title ? { title } : {}),\n\t\t\txAxis,\n\t\t\t...(yAxis ? { yAxis } : {}),\n\t\t\tseries,\n\t\t};\n\t}\n\n\tprivate parsePieChartSpec(\n\t\tblock: WorkflowPieChartBlock,\n\t\trawContent: string,\n\t): WorkflowRenderedPieChartData {\n\t\tconst parsed = this.parseJsonObject(rawContent);\n\t\tconst rawSlices = Array.isArray(parsed.slices) ? parsed.slices : [];\n\t\tif (rawSlices.length === 0) {\n\t\t\tthrow new Error(\"Pie chart extraction must return a non-empty slices[].\");\n\t\t}\n\n\t\tconst slices = rawSlices.map((entry, index) => {\n\t\t\tconst slice = this.asRecord(entry);\n\t\t\tconst label = this.toNonEmptyString(slice?.label);\n\t\t\tconst value = this.toFiniteNumber(slice?.value);\n\t\t\tif (!label) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Pie chart slice at index ${index} must include a non-empty label.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (value === undefined || value <= 0) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Pie chart slice \"${label}\" must use a positive numeric value.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn { label, value };\n\t\t});\n\n\t\tconst title = this.toNonEmptyString(parsed.title) || block.title;\n\t\tconst showData =\n\t\t\tblock.showData ??\n\t\t\t(typeof parsed.showData === \"boolean\" ? parsed.showData : undefined);\n\n\t\treturn {\n\t\t\tgraphType: \"pie\",\n\t\t\t...(title ? { title } : {}),\n\t\t\t...(showData === undefined ? {} : { showData }),\n\t\t\tslices,\n\t\t};\n\t}\n\n\tprivate renderXYChart(spec: WorkflowRenderedXYChartData): string {\n\t\tconst lines = [\"xychart-beta\"];\n\t\tif (spec.title) {\n\t\t\tlines.push(`  title ${JSON.stringify(spec.title)}`);\n\t\t}\n\n\t\tlines.push(\n\t\t\t`  x-axis [${spec.xAxis.map((value) => JSON.stringify(value)).join(\", \")}]`,\n\t\t);\n\n\t\tconst yAxisLine = this.buildXYAxisLine(spec);\n\t\tif (yAxisLine) {\n\t\t\tlines.push(yAxisLine);\n\t\t}\n\n\t\tfor (const series of spec.series) {\n\t\t\tconst labelPrefix = series.label\n\t\t\t\t? ` ${JSON.stringify(series.label)}`\n\t\t\t\t: \"\";\n\t\t\tlines.push(`  ${series.kind}${labelPrefix} [${series.data.join(\", \")}]`);\n\t\t}\n\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tprivate renderPieChart(spec: WorkflowRenderedPieChartData): string {\n\t\tconst lines = [spec.showData ? \"pie showData\" : \"pie\"];\n\t\tif (spec.title) {\n\t\t\tlines.push(`  title ${JSON.stringify(spec.title)}`);\n\t\t}\n\n\t\tfor (const slice of spec.slices) {\n\t\t\tlines.push(`  ${JSON.stringify(slice.label)} : ${slice.value}`);\n\t\t}\n\n\t\treturn lines.join(\"\\n\");\n\t}\n\n\tprivate buildXYAxisLine(\n\t\tspec: WorkflowRenderedXYChartData,\n\t): string | undefined {\n\t\tif (!spec.yAxis) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst label = spec.yAxis.label || \"value\";\n\t\tif (spec.yAxis.min !== undefined && spec.yAxis.max !== undefined) {\n\t\t\treturn `  y-axis ${JSON.stringify(label)} ${spec.yAxis.min} --> ${spec.yAxis.max}`;\n\t\t}\n\n\t\treturn spec.yAxis.label\n\t\t\t? `  y-axis ${JSON.stringify(spec.yAxis.label)}`\n\t\t\t: undefined;\n\t}\n\n\tprivate parseXYChartSeries(\n\t\tentry: unknown,\n\t\texpectedLength: number,\n\t\tindex: number,\n\t): WorkflowXYChartSeriesData {\n\t\tconst record = this.asRecord(entry);\n\t\tif (!record) {\n\t\t\tthrow new Error(`XY chart series at index ${index} must be an object.`);\n\t\t}\n\t\tconst kind = record?.kind;\n\t\tif (kind !== \"bar\" && kind !== \"line\") {\n\t\t\tthrow new Error(\n\t\t\t\t`XY chart series at index ${index} must use kind \"bar\" or \"line\".`,\n\t\t\t);\n\t\t}\n\n\t\tconst data = Array.isArray(record.data)\n\t\t\t? record.data\n\t\t\t\t\t.map((value) => this.toFiniteNumber(value))\n\t\t\t\t\t.filter((value): value is number => value !== undefined)\n\t\t\t: [];\n\t\tif (data.length !== expectedLength) {\n\t\t\tthrow new Error(\n\t\t\t\t`XY chart series at index ${index} must contain exactly ${expectedLength} numeric values.`,\n\t\t\t);\n\t\t}\n\n\t\tconst label = this.toNonEmptyString(record.label);\n\t\treturn {\n\t\t\tkind,\n\t\t\t...(label ? { label } : {}),\n\t\t\tdata,\n\t\t};\n\t}\n\n\tprivate buildXYAxisConfig(\n\t\tyAxis: Record<string, unknown>,\n\t): WorkflowRenderedXYChartData[\"yAxis\"] | undefined {\n\t\tconst label = this.toNonEmptyString(yAxis.label);\n\t\tconst min = this.toFiniteNumber(yAxis.min);\n\t\tconst max = this.toFiniteNumber(yAxis.max);\n\t\tif (label === undefined && min === undefined && max === undefined) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\treturn {\n\t\t\t...(label ? { label } : {}),\n\t\t\t...(min === undefined ? {} : { min }),\n\t\t\t...(max === undefined ? {} : { max }),\n\t\t};\n\t}\n\n\tprivate parseJsonObject(rawContent: string): Record<string, unknown> {\n\t\tconst jsonText = this.extractJsonValue(rawContent);\n\t\tconst parsed = JSON.parse(jsonText) as unknown;\n\t\tif (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n\t\t\tthrow new Error(\"Graph extraction did not return a JSON object.\");\n\t\t}\n\t\treturn parsed as Record<string, unknown>;\n\t}\n\n\tprivate extractJsonValue(rawContent: string): string {\n\t\tconst trimmed = rawContent.trim();\n\t\tconst unfenced = trimmed.startsWith(\"```\")\n\t\t\t? trimmed\n\t\t\t\t\t.replace(/^```[a-zA-Z]*\\n?/, \"\")\n\t\t\t\t\t.replace(/\\n?```$/, \"\")\n\t\t\t\t\t.trim()\n\t\t\t: trimmed;\n\t\tconst firstBrace = unfenced.indexOf(\"{\");\n\t\tconst lastBrace = unfenced.lastIndexOf(\"}\");\n\t\tif (firstBrace === -1 || lastBrace === -1 || lastBrace < firstBrace) {\n\t\t\tthrow new Error(\"Graph extraction did not return a JSON object.\");\n\t\t}\n\t\treturn unfenced.slice(firstBrace, lastBrace + 1);\n\t}\n\n\tprivate asRecord(value: unknown): Record<string, unknown> | undefined {\n\t\treturn value && typeof value === \"object\" && !Array.isArray(value)\n\t\t\t? (value as Record<string, unknown>)\n\t\t\t: undefined;\n\t}\n\n\tprivate toNonEmptyString(value: unknown): string | undefined {\n\t\treturn typeof value === \"string\" && value.trim().length > 0\n\t\t\t? value.trim()\n\t\t\t: undefined;\n\t}\n\n\tprivate toFiniteNumber(value: unknown): number | undefined {\n\t\tif (typeof value === \"number\" && Number.isFinite(value)) {\n\t\t\treturn value;\n\t\t}\n\t\tif (typeof value === \"string\" && value.trim().length > 0) {\n\t\t\tconst parsed = Number(value.trim().replace(/,/g, \"\"));\n\t\t\treturn Number.isFinite(parsed) ? parsed : undefined;\n\t\t}\n\t\treturn undefined;\n\t}\n}\n"]}