Spaces:
Runtime error
Runtime error
| /** | |
| * /comparison β plain-English comparison of how four teams built the same PO chatbot. | |
| * | |
| * Four questions, one figure + one small table + one takeaway each. | |
| */ | |
| export function ComparisonView() { | |
| return ( | |
| <div className="cmp"> | |
| <div className="cmp__hero"> | |
| <h1>Four teams. One chatbot. Four different ways to build it.</h1> | |
| <p className="cmp__lede"> | |
| Rajat, Naman, Sreedath, Pritam and ourselves each built a chatbot for Ramco's | |
| Procure-to-Pay using the same source data drop. This page answers four simple | |
| questions about how the approaches differ. | |
| </p> | |
| <ol className="cmp__toc"> | |
| <li>What Ramco files does each team read?</li> | |
| <li>Where does the slot list come from?</li> | |
| <li>Does the bot have journey steps?</li> | |
| <li>Does the bot actually call Ramco APIs?</li> | |
| </ol> | |
| <div className="cmp__lede-meta"> | |
| Numbers come from reading each repo directly. Pritam's repo is private, so his | |
| column is filled in from the live deployed app where possible. | |
| </div> | |
| </div> | |
| {/* ============================ 1. DATA SOURCES ============================ */} | |
| <section className="cmp__section"> | |
| <h2>1 Β· What Ramco files does each team read?</h2> | |
| <p> | |
| Ramco's data drop has about a dozen kinds of files. Each team picks a different | |
| subset. Rajat reads the most kinds of file (11), Sreedath reads the fewest (4) | |
| but covers all five Procure-to-Pay sub-modules. Naman and ours sit in the | |
| middle. | |
| </p> | |
| <div className="cmp__figure"> | |
| <img src="/figures/fig1_data.jpg" alt="Matrix of source files vs teams" /> | |
| <div className="cmp__figure-caption"> | |
| Figure 1 β Filled cell means that team's pipeline reads that file. | |
| </div> | |
| </div> | |
| <table className="cmp__table cmp__table--simple"> | |
| <thead> | |
| <tr> | |
| <th>Team</th> | |
| <th># source types</th> | |
| <th>Coverage</th> | |
| <th>The thing only they read</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td><strong>Rajat</strong></td> | |
| <td>11</td> | |
| <td>PO only Β· 13 journeys</td> | |
| <td>OLH HTML, ARM PDF, FSC sheets, step sheets, test cases, PO_info.xml</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Naman</strong></td> | |
| <td>6</td> | |
| <td>PO only Β· 17 journeys</td> | |
| <td>BPC component registry</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Sreedath</strong></td> | |
| <td>4</td> | |
| <td><strong>All 5 P2P sub-modules Β· 91 journeys</strong></td> | |
| <td>β</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Ours</strong></td> | |
| <td>5</td> | |
| <td>PO pilot, deep</td> | |
| <td>β</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <p className="cmp__takeaway"> | |
| <strong>Takeaway:</strong> different teams optimised for different things. Rajat | |
| went wide on source variety, Sreedath went wide across sub-modules, Naman and | |
| ours went deep on a single journey. Only Rajat reads the Online Help HTML β | |
| the file that tells you which fields Ramco's real users see marked as | |
| "mandatory". | |
| </p> | |
| </section> | |
| {/* ============================ 2. SLOTS ============================ */} | |
| <section className="cmp__section"> | |
| <h2>2 Β· Where does the slot list come from?</h2> | |
| <p> | |
| "Slots" are the fields the bot asks the user for β supplier, item, quantity, | |
| and so on. The interesting question is: <em>which Ramco file did each team | |
| treat as the source of truth for that list?</em> | |
| </p> | |
| <div className="cmp__figure"> | |
| <img src="/figures/fig2_slots.jpg" alt="Slot extraction pipelines per team" /> | |
| <div className="cmp__figure-caption"> | |
| Figure 2 β Four different sources of truth for "what should the bot ask?" | |
| </div> | |
| </div> | |
| <table className="cmp__table cmp__table--simple"> | |
| <thead> | |
| <tr> | |
| <th>Team</th> | |
| <th>Source of slot list</th> | |
| <th>What that means</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td><strong>Rajat</strong></td> | |
| <td>OLH HTML "mandatory" markers</td> | |
| <td>Matches what real Ramco users see on screen.</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Naman</strong></td> | |
| <td>OpenAPI request schema</td> | |
| <td>Matches what the API will accept; may miss UI-only fields.</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Sreedath</strong></td> | |
| <td>A hand-written JSON file</td> | |
| <td>~6 fields a developer typed in. Goes stale if Ramco changes anything.</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Ours</strong></td> | |
| <td>API alias map + variant graph</td> | |
| <td>Variant-aware priority list; lives behind the alias map of API β UI β SP names.</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <p className="cmp__takeaway"> | |
| <strong>Takeaway:</strong> five teams, five different answers to "what should | |
| the bot ask for?" On the same prompt, our bots will request different fields | |
| until we agree on one source of truth. | |
| </p> | |
| </section> | |
| {/* ============================ 3. STEPS ============================ */} | |
| <section className="cmp__section"> | |
| <h2>3 Β· Does the bot have journey steps?</h2> | |
| <p> | |
| Three of the five bots have an explicit notion of "step 1 β step 2 β step 3". | |
| One uses screens-as-steps. <strong>Ours has no steps at all</strong> β every | |
| turn just picks the next slot to ask. It's a slot machine. | |
| </p> | |
| <div className="cmp__figure"> | |
| <img src="/figures/fig3_steps.jpg" alt="Journey step representation per team" /> | |
| <div className="cmp__figure-caption"> | |
| Figure 3 β Three teams have linear step sequences. Ours has a loop. | |
| </div> | |
| </div> | |
| <table className="cmp__table cmp__table--simple"> | |
| <thead> | |
| <tr> | |
| <th>Team</th> | |
| <th>Has steps?</th> | |
| <th>Where steps come from</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td><strong>Rajat</strong></td> | |
| <td className="cmp__yes">Yes</td> | |
| <td>One step per OLH group-box on screen.</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Naman</strong></td> | |
| <td className="cmp__yes">Yes</td> | |
| <td>One step per UI screen (PoCrtMain, PoCrtDrpshp, β¦).</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Sreedath</strong></td> | |
| <td className="cmp__yes">Yes</td> | |
| <td>Developer-aggregated "user beats" in journeys.json.</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Pritam</strong></td> | |
| <td className="cmp__yes">Yes</td> | |
| <td>Server-side step machine (code private).</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Ours</strong></td> | |
| <td className="cmp__no">No β slot machine</td> | |
| <td>Resolver picks the next missing slot each turn.</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <p className="cmp__takeaway"> | |
| <strong>Takeaway:</strong> steps match Ramco's screen layout. A slot machine | |
| matches natural conversation. Both are reasonable β they're different design | |
| philosophies, not a right/wrong choice. | |
| </p> | |
| </section> | |
| {/* ============================ 4. APIs ============================ */} | |
| <section className="cmp__section"> | |
| <h2>4 Β· Does the bot actually call Ramco APIs?</h2> | |
| <p> | |
| Eventually a real chatbot has to call Ramco's APIs to create the PO. So which | |
| bots actually do that, and which just stop at naming the API that <em>would</em> | |
| be called? | |
| </p> | |
| <div className="cmp__figure"> | |
| <img src="/figures/fig4_apis.jpg" alt="API wiring per team" /> | |
| <div className="cmp__figure-caption"> | |
| Figure 4 β Three teams stop at "API named". Pritam is unclear (private). Ours | |
| actually fires the call (mocked) and surfaces real Ramco-style errors. | |
| </div> | |
| </div> | |
| <table className="cmp__table cmp__table--simple"> | |
| <thead> | |
| <tr> | |
| <th>Team</th> | |
| <th>API actually fires?</th> | |
| <th>How API is referenced</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <tr> | |
| <td><strong>Rajat</strong></td> | |
| <td className="cmp__no">No</td> | |
| <td>Each slot carries its API binding. Static HTML demo.</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Naman</strong></td> | |
| <td className="cmp__no">No</td> | |
| <td>Per-step API list from the CSV. Demo is scripted.</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Sreedath</strong></td> | |
| <td className="cmp__no">No</td> | |
| <td>Each step references its CSV row. No dispatch.</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Pritam</strong></td> | |
| <td className="cmp__warn">Unclear (private)</td> | |
| <td>Audit pane suggests real calls for some journeys.</td> | |
| </tr> | |
| <tr> | |
| <td><strong>Ours</strong></td> | |
| <td className="cmp__yes">Yes β mocked</td> | |
| <td>Variant lock β build payload β POST β real Ramco-style errors / PO/MOCK/<id>.</td> | |
| </tr> | |
| </tbody> | |
| </table> | |
| <p className="cmp__takeaway"> | |
| <strong>Takeaway:</strong> only our bot reaches the point of actually firing a | |
| request. Everyone else's demo stops one step short of the API call. To compare | |
| fairly we'd need a shared mock environment that replays each team's "I would | |
| have called X with payload Y". | |
| </p> | |
| </section> | |
| {/* ============================ SUMMARY ============================ */} | |
| <section className="cmp__section cmp__summary"> | |
| <h2>One-paragraph summary</h2> | |
| <p> | |
| Each team made a different trade. <strong>Rajat</strong> went deep on source | |
| variety β he's the only one reading the Online Help HTML where Ramco marks | |
| mandatory fields. <strong>Sreedath</strong> went wide across sub-modules β 91 | |
| journeys covering all five P2P modules. <strong>Naman</strong> built the | |
| tightest API audit trail per step. <strong>Pritam</strong> is the only other | |
| team with a server-side stack, but his repo is private. <strong>Ours</strong> | |
| is the only bot that actually fires (mocked) API calls and returns real | |
| Ramco-style errors at variant lock. None of these is wrong; they're four | |
| different design philosophies for the same problem. | |
| </p> | |
| </section> | |
| {/* ============================ FOOTER ============================ */} | |
| <section className="cmp__section cmp__footer"> | |
| <h2>What's not verified here</h2> | |
| <ul className="cmp__list"> | |
| <li>Pritam's code is private β his rows are inferred from the deployed app.</li> | |
| <li> | |
| The figures are generated diagrams (Gemini 3 Pro Image Preview, 2 refinement | |
| iterations) β they illustrate structural differences, not architecture from | |
| each team's own documentation. | |
| </li> | |
| <li> | |
| Only L0 (routing) was probed live across teams. L1βL7 of the eval framework | |
| would need a per-team adapter to compare rigorously. | |
| </li> | |
| </ul> | |
| </section> | |
| </div> | |
| ); | |
| } | |