diff --git a/packages/server/marketplaces/tools/Bilig WorkPaper Formula Readback.json b/packages/server/marketplaces/tools/Bilig WorkPaper Formula Readback.json new file mode 100644 index 00000000000..596a7899875 --- /dev/null +++ b/packages/server/marketplaces/tools/Bilig WorkPaper Formula Readback.json @@ -0,0 +1,8 @@ +{ + "name": "bilig_workpaper_formula_readback", + "description": "Useful when an agent needs to edit one spreadsheet input, recalculate formulas, and verify the computed readback without Excel or browser automation.", + "color": "linear-gradient(rgb(24,96,122), rgb(48,159,108))", + "iconSrc": "https://github.com/proompteng.png", + "schema": "[{\"id\":0,\"property\":\"baseUrl\",\"description\":\"Bilig base URL. Use https://bilig.proompteng.ai for the hosted demo or your self-hosted Bilig URL.\",\"type\":\"string\",\"required\":false},{\"id\":1,\"property\":\"sheetName\",\"description\":\"Worksheet containing the editable forecast input. Default: Inputs\",\"type\":\"string\",\"required\":false},{\"id\":2,\"property\":\"address\",\"description\":\"A1-style input cell address to edit. Default: B3\",\"type\":\"string\",\"required\":false},{\"id\":3,\"property\":\"value\",\"description\":\"Numeric value to write before formula readback. Default: 0.4\",\"type\":\"number\",\"required\":false}]", + "func": "const fetch = require('node-fetch');\n\nconst baseUrl = String($baseUrl || 'https://bilig.proompteng.ai').replace(/\\/$/, '');\nconst sheetName = String($sheetName || 'Inputs');\nconst address = String($address || 'B3').toUpperCase();\nconst value = $value == null || $value === '' ? 0.4 : Number($value);\n\nif (!baseUrl.startsWith('http://') && !baseUrl.startsWith('https://')) {\n return 'Bilig WorkPaper formula readback failed: baseUrl must start with http:// or https://';\n}\n\nif (!Number.isFinite(value)) {\n return `Bilig WorkPaper formula readback failed: value must be numeric, received ${JSON.stringify($value)}`;\n}\n\nconst response = await fetch(`${baseUrl}/api/workpaper/n8n/forecast`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'User-Agent': 'Flowise-Bilig-WorkPaper-Tool/0.1'\n },\n body: JSON.stringify({ sheetName, address, value })\n});\n\nconst text = await response.text();\nlet proof;\ntry {\n proof = JSON.parse(text);\n} catch (error) {\n return `Bilig WorkPaper formula readback failed: expected JSON but received ${text.slice(0, 500)}`;\n}\n\nif (proof == null || typeof proof !== 'object' || Array.isArray(proof)) {\n return `Bilig WorkPaper formula readback failed: expected JSON object response, received ${Array.isArray(proof) ? 'array' : typeof proof}`;\n}\n\nif (!response.ok) {\n return `Bilig WorkPaper formula readback failed: HTTP ${response.status} ${response.statusText} - ${JSON.stringify(proof)}`;\n}\n\nif (proof.verified !== true) {\n const proofId = proof.workpaper_id || proof.id || 'unknown';\n return `Bilig WorkPaper formula readback failed: unverified response (verified=${proof.verified}) for workpaper_id=${proofId}`;\n}\n\nconst checks = proof.checks && typeof proof.checks === 'object' && !Array.isArray(proof.checks) ? proof.checks : {};\nconst before = proof.before && typeof proof.before === 'object' && !Array.isArray(proof.before) ? proof.before : {};\nconst after = proof.after && typeof proof.after === 'object' && !Array.isArray(proof.after) ? proof.after : {};\nconst compactProof = {\n verified: true,\n editedCell: proof.editedCell,\n before: {\n expectedArr: before.expectedArr,\n targetGap: before.targetGap\n },\n after: {\n expectedArr: after.expectedArr,\n targetGap: after.targetGap\n },\n checks: {\n formulasPersisted: checks.formulasPersisted === true,\n restoredMatchesAfter: checks.restoredMatchesAfter === true,\n computedOutputChanged: checks.computedOutputChanged === true\n },\n source: 'Bilig WorkPaper',\n github: 'https://github.com/proompteng/bilig'\n};\n\nreturn JSON.stringify(compactProof, null, 2);" +}