PageSourceSearch

https://www.lelo.com/modules/lelo/lelo_agentic/js/webmcp-tools.js?v=1

js lelo.com collected 2026-09-24 17:41:59 UTC 3,445 bytes, 103 lines download raw bytes

1/**
2 * @file
3 * WebMCP tool registration — exposes anonymous site actions to in-browser
4 * AI agents via navigator.modelContext (https://webmachinelearning.github.io/webmcp/).
5 *
6 * Tool surface mirrors the published Tier-1 agent skills (anonymous,
7 * read-only + newsletter opt-in). Nothing here performs checkout, cart or
8 * account mutations.
9 */
10(function () {
11  'use strict';
12
13  if (!('modelContext' in navigator) || typeof navigator.modelContext.registerTool !== 'function') {
14    return;
15  }
16
17  var controller = new AbortController();
18  var origin = window.location.origin;
19
20  function getJson(path) {
21    return fetch(origin + path, { headers: { Accept: 'application/vnd.api+json' } })
22      .then(function (r) {
23        if (!r.ok) { throw new Error('HTTP ' + r.status); }
24        return r.json();
25      });
26  }
27
28  var tools = [
29    {
30      name: 'list-product-categories',
31      description: 'List all LELO product categories with their taxonomy ids. Use to discover what product ranges exist before drilling into one.',
32      inputSchema: { type: 'object', properties: {}, additionalProperties: false },
33      execute: function () {
34        return getJson('/jsonapi/product-categories');
35      }
36    },
37    {
38      name: 'get-category',
39      description: 'Fetch one product category (products, description) by taxonomy id from list-product-categories.',
40      inputSchema: {
41        type: 'object',
42        properties: {
43          taxonomy_id: { type: 'string', description: 'Taxonomy term id of the category.' }
44        },
45        required: ['taxonomy_id'],
46        additionalProperties: false
47      },
48      execute: function (input) {
49        return getJson('/jsonapi/category-details/' + encodeURIComponent(input.taxonomy_id));
50      }
51    },
52    {
53      name: 'get-product-details',
54      description: 'Fetch name, price, variations and availability for a LELO product by its numeric product id.',
55      inputSchema: {
56        type: 'object',
57        properties: {
58          product_id: { type: 'string', description: 'Numeric commerce product id.' }
59        },
60        required: ['product_id'],
61        additionalProperties: false
62      },
63      execute: function (input) {
64        return getJson('/jsonapi/ctaproducts/' + encodeURIComponent(input.product_id));
65      }
66    },
67    {
68      name: 'get-page-as-markdown',
69      description: 'Fetch any lelo.com page as clean Markdown (content negotiation). Use for reading product, category or editorial pages without HTML chrome.',
70      inputSchema: {
71        type: 'object',
72        properties: {
73          path: { type: 'string', description: 'Root-relative page path, e.g. /gigi-2.' }
74        },
75        required: ['path'],
76        additionalProperties: false
77      },
78      execute: function (input) {
79        var path = String(input.path);
80        if (path.charAt(0) !== '/') { path = '/' + path; }
81        return fetch(origin + path, { headers: { Accept: 'text/markdown' } })
82          .then(function (r) {
83            if (!r.ok) { throw new Error('HTTP ' + r.status); }
84            return r.text();
85          });
86      }
87    }
88  ];
89
90  tools.forEach(function (tool) {
91    navigator.modelContext.registerTool({
92      name: tool.name,
93      description: tool.description,
94      inputSchema: tool.inputSchema,
95      execute: tool.execute,
96      signal: controller.signal
97    });
98  });
99
100  window.addEventListener('pagehide', function () {
101    controller.abort();
102  });
103})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.