cave-supervisor-demo.json 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. {
  2. "version": "3.16",
  3. "name": "CaveSupervisorDemo",
  4. "description": "Supervisor workflow that runs two scout subflows in parallel, pauses for review, then generates a deep-scout child workflow and resumes exploration.",
  5. "steps": [
  6. {
  7. "id": "Set_010_OutputRoot",
  8. "target": "$outputRoot",
  9. "value": "=\".codex/demo-artifacts/cave-workflow-demo\"",
  10. "next": "Set_020_DeepFlowFile"
  11. },
  12. {
  13. "id": "Set_020_DeepFlowFile",
  14. "target": "$deepFlowFile",
  15. "value": "=\".vl-code/workflows/cave-deep-scout-generated.json\"",
  16. "next": "Fork_030_InitialScouts"
  17. },
  18. {
  19. "id": "Fork_030_InitialScouts",
  20. "children": [
  21. "Subflow_040_NorthScout",
  22. "Subflow_050_SouthScout"
  23. ],
  24. "next": "Pause_060_ManagerReview"
  25. },
  26. {
  27. "id": "Subflow_040_NorthScout",
  28. "workflow_path": "cave-zone-scout",
  29. "mode": "sync",
  30. "work_dir": "=$outputRoot + \"/north\"",
  31. "params": {
  32. "zoneName": "=\"north-rim\"",
  33. "mapJson": "{\n \"zone\": \"North Rim\",\n \"start\": \"N0\",\n \"goal\": \"N7\",\n \"energy\": 10,\n \"rooms\": {\n \"N0\": {\n \"crystals\": 0\n },\n \"N1\": {\n \"crystals\": 2\n },\n \"N2\": {\n \"crystals\": 1,\n \"recharge\": 1\n },\n \"N3\": {\n \"crystals\": 3\n },\n \"N4\": {\n \"crystals\": 2\n },\n \"N5\": {\n \"crystals\": 4,\n \"recharge\": 2\n },\n \"N6\": {\n \"crystals\": 1\n },\n \"N7\": {\n \"crystals\": 6\n }\n },\n \"tunnels\": {\n \"N0\": [\n {\n \"to\": \"N1\",\n \"cost\": 2\n },\n {\n \"to\": \"N2\",\n \"cost\": 3\n }\n ],\n \"N1\": [\n {\n \"to\": \"N3\",\n \"cost\": 2\n },\n {\n \"to\": \"N4\",\n \"cost\": 3\n }\n ],\n \"N2\": [\n {\n \"to\": \"N4\",\n \"cost\": 2\n },\n {\n \"to\": \"N5\",\n \"cost\": 4\n }\n ],\n \"N3\": [\n {\n \"to\": \"N6\",\n \"cost\": 2\n }\n ],\n \"N4\": [\n {\n \"to\": \"N6\",\n \"cost\": 1\n },\n {\n \"to\": \"N5\",\n \"cost\": 2\n }\n ],\n \"N5\": [\n {\n \"to\": \"N7\",\n \"cost\": 2\n }\n ],\n \"N6\": [\n {\n \"to\": \"N7\",\n \"cost\": 1\n }\n ]\n }\n}"
  34. },
  35. "out": {
  36. "$northSummary": "=_result.variables[\"$zoneSummary\"]",
  37. "$northReport": "=_result.variables[\"$reportText\"]"
  38. }
  39. },
  40. {
  41. "id": "Subflow_050_SouthScout",
  42. "workflow_path": "cave-zone-scout",
  43. "mode": "sync",
  44. "work_dir": "=$outputRoot + \"/south\"",
  45. "params": {
  46. "zoneName": "=\"south-spiral\"",
  47. "mapJson": "{\n \"zone\": \"South Spiral\",\n \"start\": \"S0\",\n \"goal\": \"S8\",\n \"energy\": 11,\n \"rooms\": {\n \"S0\": {\n \"crystals\": 0\n },\n \"S1\": {\n \"crystals\": 1\n },\n \"S2\": {\n \"crystals\": 3\n },\n \"S3\": {\n \"crystals\": 2,\n \"recharge\": 1\n },\n \"S4\": {\n \"crystals\": 4\n },\n \"S5\": {\n \"crystals\": 1\n },\n \"S6\": {\n \"crystals\": 5,\n \"recharge\": 2\n },\n \"S7\": {\n \"crystals\": 2\n },\n \"S8\": {\n \"crystals\": 7\n }\n },\n \"tunnels\": {\n \"S0\": [\n {\n \"to\": \"S1\",\n \"cost\": 1\n },\n {\n \"to\": \"S2\",\n \"cost\": 3\n }\n ],\n \"S1\": [\n {\n \"to\": \"S3\",\n \"cost\": 2\n },\n {\n \"to\": \"S4\",\n \"cost\": 4\n }\n ],\n \"S2\": [\n {\n \"to\": \"S4\",\n \"cost\": 2\n },\n {\n \"to\": \"S5\",\n \"cost\": 3\n }\n ],\n \"S3\": [\n {\n \"to\": \"S6\",\n \"cost\": 2\n }\n ],\n \"S4\": [\n {\n \"to\": \"S6\",\n \"cost\": 1\n },\n {\n \"to\": \"S7\",\n \"cost\": 2\n }\n ],\n \"S5\": [\n {\n \"to\": \"S7\",\n \"cost\": 2\n }\n ],\n \"S6\": [\n {\n \"to\": \"S8\",\n \"cost\": 2\n }\n ],\n \"S7\": [\n {\n \"to\": \"S8\",\n \"cost\": 1\n }\n ]\n }\n}"
  48. },
  49. "out": {
  50. "$southSummary": "=_result.variables[\"$zoneSummary\"]",
  51. "$southReport": "=_result.variables[\"$reportText\"]"
  52. }
  53. },
  54. {
  55. "id": "Pause_060_ManagerReview",
  56. "reason": "Manager review: compare north/south scout reports before dispatching a deep anomaly probe.",
  57. "next": "Tool_070_WriteDeepScoutWorkflow"
  58. },
  59. {
  60. "id": "Tool_070_WriteDeepScoutWorkflow",
  61. "tool": "WriteFile",
  62. "input": {
  63. "file_path": "=$deepFlowFile",
  64. "content": "{\n \"version\": \"3.16\",\n \"name\": \"GeneratedDeepScout\",\n \"description\": \"Writes a cave-search program into an isolated child space, runs it, and captures the trace/report.\",\n \"steps\": [\n {\n \"id\": \"Tool_010_WriteMap\",\n \"tool\": \"WriteFile\",\n \"input\": {\n \"file_path\": \"=\\\"cave.json\\\"\",\n \"content\": \"=mapJson\"\n },\n \"next\": \"Tool_020_WriteSolver\"\n },\n {\n \"id\": \"Tool_020_WriteSolver\",\n \"tool\": \"WriteFile\",\n \"input\": {\n \"file_path\": \"=\\\"explore-cave.mjs\\\"\",\n \"content\": \"import fs from 'fs';\\n\\nconst cavePath = process.argv[2] || 'cave.json';\\nconst cave = JSON.parse(fs.readFileSync(cavePath, 'utf8'));\\nconst trace = [];\\nconst seen = new Map();\\nlet best = null;\\n\\nfunction scoreState(node, energy, crystals, path) {\\n return (node === cave.goal ? 500 : 0) + (crystals * 11) + energy - path.length;\\n}\\n\\nfunction remember(signature, score) {\\n const prev = seen.get(signature) ?? -Infinity;\\n if (prev >= score) return false;\\n seen.set(signature, score);\\n return true;\\n}\\n\\nfunction explore(node, energy, crystals, path, visitedRooms) {\\n const room = cave.rooms[node] || {};\\n const nextVisitedRooms = new Set(visitedRooms);\\n const gained = nextVisitedRooms.has(node) ? 0 : (room.crystals || 0);\\n nextVisitedRooms.add(node);\\n const nextCrystals = crystals + gained;\\n const nextPath = [...path, node];\\n const signature = [node, energy, nextCrystals, [...nextVisitedRooms].sort().join(',')].join('|');\\n const score = scoreState(node, energy, nextCrystals, nextPath);\\n if (!remember(signature, score)) return;\\n\\n trace.push(`visit=${node}; energy=${energy}; crystals=${nextCrystals}; path=${nextPath.join('>')}`);\\n if (!best || score > best.score) {\\n best = { node, energy, crystals: nextCrystals, path: nextPath, score };\\n }\\n if (node === cave.goal) return;\\n\\n const edges = (cave.tunnels[node] || []).slice().sort((a, b) => {\\n const aReward = (cave.rooms[a.to]?.crystals || 0) - a.cost;\\n const bReward = (cave.rooms[b.to]?.crystals || 0) - b.cost;\\n return bReward - aReward;\\n });\\n\\n for (const edge of edges) {\\n if (energy < edge.cost) {\\n trace.push(`skip=${node}->${edge.to}; reason=energy; need=${edge.cost}; have=${energy}`);\\n continue;\\n }\\n const recharge = cave.rooms[edge.to]?.recharge || 0;\\n explore(edge.to, energy - edge.cost + recharge, nextCrystals, nextPath, nextVisitedRooms);\\n }\\n}\\n\\nexplore(cave.start, cave.energy, 0, [], new Set());\\n\\nconst reportLines = [\\n `zone=${cave.zone}`,\\n `goal=${cave.goal}`,\\n `bestNode=${best?.node || 'unknown'}`,\\n `score=${best?.score ?? 0}`,\\n `energyLeft=${best?.energy ?? 0}`,\\n `crystals=${best?.crystals ?? 0}`,\\n `route=${best?.path?.join('>') || ''}`\\n];\\n\\nfs.writeFileSync('report.txt', reportLines.join('\\\\n'));\\nfs.writeFileSync('trace.txt', trace.join('\\\\n'));\\nconsole.log(`best=${best?.node || 'unknown'}; score=${best?.score ?? 0}; route=${best?.path?.join('>') || ''}; crystals=${best?.crystals ?? 0}`);\\n\"\n },\n \"next\": \"Tool_030_RunSolver\"\n },\n {\n \"id\": \"Tool_030_RunSolver\",\n \"tool\": \"Bash\",\n \"input\": {\n \"command\": \"=\\\"node explore-cave.mjs cave.json\\\"\"\n },\n \"out\": {\n \"$solverStdout\": \"=_result\"\n },\n \"next\": \"Tool_040_ReadReport\"\n },\n {\n \"id\": \"Tool_040_ReadReport\",\n \"tool\": \"ReadFile\",\n \"input\": {\n \"file_path\": \"=\\\"report.txt\\\"\"\n },\n \"out\": {\n \"$reportText\": \"=_result\"\n },\n \"next\": \"Tool_050_ReadTrace\"\n },\n {\n \"id\": \"Tool_050_ReadTrace\",\n \"tool\": \"ReadFile\",\n \"input\": {\n \"file_path\": \"=\\\"trace.txt\\\"\",\n \"limit\": 80\n },\n \"out\": {\n \"$traceText\": \"=_result\"\n },\n \"next\": \"Set_060_Summary\"\n },\n {\n \"id\": \"Set_060_Summary\",\n \"target\": \"$zoneSummary\",\n \"value\": \"=zoneName + \\\" => \\\" + $solverStdout\",\n \"next\": \"Write_070_Summary\"\n },\n {\n \"id\": \"Write_070_Summary\",\n \"target\": \"=\\\"Artifacts/zone-summary.txt\\\"\",\n \"value\": \"=$zoneSummary\",\n \"mode\": \"overwrite\",\n \"next\": \"Stop_End\"\n },\n {\n \"id\": \"Stop_End\"\n }\n ]\n}"
  65. },
  66. "next": "Subflow_080_DeepScout"
  67. },
  68. {
  69. "id": "Subflow_080_DeepScout",
  70. "workflow_path": "cave-deep-scout-generated",
  71. "mode": "sync",
  72. "work_dir": "=$outputRoot + \"/deep-scout\"",
  73. "params": {
  74. "zoneName": "=\"deep-anomaly\"",
  75. "mapJson": "{\n \"zone\": \"Deep Anomaly\",\n \"start\": \"D0\",\n \"goal\": \"D9\",\n \"energy\": 14,\n \"rooms\": {\n \"D0\": {\n \"crystals\": 0\n },\n \"D1\": {\n \"crystals\": 2\n },\n \"D2\": {\n \"crystals\": 3\n },\n \"D3\": {\n \"crystals\": 1,\n \"recharge\": 1\n },\n \"D4\": {\n \"crystals\": 4\n },\n \"D5\": {\n \"crystals\": 2,\n \"recharge\": 2\n },\n \"D6\": {\n \"crystals\": 6\n },\n \"D7\": {\n \"crystals\": 3\n },\n \"D8\": {\n \"crystals\": 5\n },\n \"D9\": {\n \"crystals\": 9\n }\n },\n \"tunnels\": {\n \"D0\": [\n {\n \"to\": \"D1\",\n \"cost\": 2\n },\n {\n \"to\": \"D2\",\n \"cost\": 2\n }\n ],\n \"D1\": [\n {\n \"to\": \"D3\",\n \"cost\": 2\n },\n {\n \"to\": \"D4\",\n \"cost\": 4\n }\n ],\n \"D2\": [\n {\n \"to\": \"D4\",\n \"cost\": 2\n },\n {\n \"to\": \"D5\",\n \"cost\": 3\n }\n ],\n \"D3\": [\n {\n \"to\": \"D6\",\n \"cost\": 3\n }\n ],\n \"D4\": [\n {\n \"to\": \"D6\",\n \"cost\": 2\n },\n {\n \"to\": \"D7\",\n \"cost\": 2\n }\n ],\n \"D5\": [\n {\n \"to\": \"D7\",\n \"cost\": 1\n },\n {\n \"to\": \"D8\",\n \"cost\": 3\n }\n ],\n \"D6\": [\n {\n \"to\": \"D9\",\n \"cost\": 2\n }\n ],\n \"D7\": [\n {\n \"to\": \"D9\",\n \"cost\": 2\n }\n ],\n \"D8\": [\n {\n \"to\": \"D9\",\n \"cost\": 1\n }\n ]\n }\n}"
  76. },
  77. "out": {
  78. "$deepSummary": "=_result.variables[\"$zoneSummary\"]",
  79. "$deepReport": "=_result.variables[\"$reportText\"]"
  80. },
  81. "next": "Set_090_FinalNarrative"
  82. },
  83. {
  84. "id": "Set_090_FinalNarrative",
  85. "target": "$finalNarrative",
  86. "value": "=\"North\\n\" + $northSummary + \"\\n\\nSouth\\n\" + $southSummary + \"\\n\\nDeep\\n\" + $deepSummary",
  87. "next": "Write_100_ManagerReport"
  88. },
  89. {
  90. "id": "Write_100_ManagerReport",
  91. "target": "=$outputRoot + \"/manager-report.txt\"",
  92. "value": "=$finalNarrative",
  93. "mode": "overwrite",
  94. "next": "Stop_End"
  95. },
  96. {
  97. "id": "Stop_End"
  98. }
  99. ]
  100. }