version mise à jour par claude , à tester
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
/**
|
||||
* Metadata & GenericSearch Tools
|
||||
* - get_entity_metadata : list queryable entities and their properties (Metadata API)
|
||||
* - generic_search : full-text search across indexed WMS documents (GenericSearch API)
|
||||
*/
|
||||
|
||||
const apiService = require('../services/api-service').getInstance();
|
||||
|
||||
function listTools() {
|
||||
return [
|
||||
{
|
||||
name: 'get_entity_metadata',
|
||||
description: `Get metadata for WMS entities — field names, types, and assembly info — without querying actual data.
|
||||
Use this to discover the exact field names and types for any entity before building a filter.
|
||||
- Without entity_name: lists all queryable entities
|
||||
- With entity_name (partial match ok, case-insensitive): returns field names + types for that entity`,
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
entity_name: {
|
||||
type: 'string',
|
||||
description: 'Partial entity name to look up (e.g. "OutboundOrder", "Task", "Stock"). Omit to list all entities.',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'generic_search',
|
||||
description: `Full-text search across indexed WMS documents (faster than LINQ for keyword searches).
|
||||
First call without arguments to get available categories, then search within them.
|
||||
Examples:
|
||||
- generic_search(query="ORD-2024-001") — find an order by code
|
||||
- generic_search(query="picking error", categories=["Tasks"]) — search tasks
|
||||
- generic_search() — list available search categories`,
|
||||
inputSchema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
query: {
|
||||
type: 'string',
|
||||
description: 'Search keyword or phrase',
|
||||
},
|
||||
categories: {
|
||||
type: 'array',
|
||||
items: { type: 'string' },
|
||||
description: 'Document categories to search (omit to search all). Get available categories by calling without query.',
|
||||
},
|
||||
limit: {
|
||||
type: 'number',
|
||||
description: 'Max results (default: 20)',
|
||||
default: 20,
|
||||
},
|
||||
skip: {
|
||||
type: 'number',
|
||||
description: 'Offset for pagination (default: 0)',
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
async function executeTool(name, args) {
|
||||
switch (name) {
|
||||
case 'get_entity_metadata':
|
||||
return await getEntityMetadata(args);
|
||||
case 'generic_search':
|
||||
return await genericSearch(args);
|
||||
default:
|
||||
throw new Error(`Unknown metadata tool: ${name}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function getEntityMetadata(args) {
|
||||
const { entity_name } = args || {};
|
||||
|
||||
try {
|
||||
const entities = await apiService.getMetadataEntities();
|
||||
|
||||
if (!entity_name) {
|
||||
// Return full entity list
|
||||
return {
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: JSON.stringify({
|
||||
success: true,
|
||||
totalEntities: Array.isArray(entities) ? entities.length : '?',
|
||||
entities,
|
||||
}, null, 2),
|
||||
}],
|
||||
};
|
||||
}
|
||||
|
||||
// Find matching entities (case-insensitive partial match)
|
||||
const search = entity_name.toLowerCase();
|
||||
const matches = Array.isArray(entities)
|
||||
? entities.filter(e => {
|
||||
const name = (e.FullName || e.Name || e.fullName || e.name || JSON.stringify(e)).toLowerCase();
|
||||
return name.includes(search);
|
||||
})
|
||||
: [];
|
||||
|
||||
if (matches.length === 0) {
|
||||
return {
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: JSON.stringify({
|
||||
success: false,
|
||||
error: `No entity matching "${entity_name}" found`,
|
||||
availableCount: Array.isArray(entities) ? entities.length : '?',
|
||||
hint: 'Call get_entity_metadata without entity_name to see all entities',
|
||||
}, null, 2),
|
||||
}],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
|
||||
// Fetch properties for each match (up to 3)
|
||||
const results = [];
|
||||
for (const entity of matches.slice(0, 3)) {
|
||||
const assemblyFullName = entity.AssemblyFullName || entity.assemblyFullName;
|
||||
const fullName = entity.FullName || entity.fullName;
|
||||
|
||||
let properties = null;
|
||||
if (assemblyFullName && fullName) {
|
||||
try {
|
||||
properties = await apiService.getEntityProperties(assemblyFullName, fullName);
|
||||
} catch (err) {
|
||||
console.error(`[Metadata] Could not fetch properties for ${fullName}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
results.push({ entity, properties });
|
||||
}
|
||||
|
||||
return {
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: JSON.stringify({
|
||||
success: true,
|
||||
query: entity_name,
|
||||
matchCount: matches.length,
|
||||
results,
|
||||
}, null, 2),
|
||||
}],
|
||||
};
|
||||
} catch (err) {
|
||||
return {
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: JSON.stringify({ success: false, error: err.message }, null, 2),
|
||||
}],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async function genericSearch(args) {
|
||||
const { query, categories = [], limit = 20, skip = 0 } = args || {};
|
||||
|
||||
try {
|
||||
// No query: return available categories
|
||||
if (!query) {
|
||||
const cats = await apiService.getSearchCategories();
|
||||
return {
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: JSON.stringify({
|
||||
success: true,
|
||||
availableCategories: cats,
|
||||
hint: 'Pass query + optional categories[] to search',
|
||||
}, null, 2),
|
||||
}],
|
||||
};
|
||||
}
|
||||
|
||||
const result = await apiService.genericSearch(query, categories, limit, skip);
|
||||
|
||||
return {
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: JSON.stringify({
|
||||
success: true,
|
||||
query,
|
||||
categories: categories.length > 0 ? categories : 'all',
|
||||
result,
|
||||
}, null, 2),
|
||||
}],
|
||||
};
|
||||
} catch (err) {
|
||||
return {
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: JSON.stringify({ success: false, error: err.message }, null, 2),
|
||||
}],
|
||||
isError: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { listTools, executeTool };
|
||||
Reference in New Issue
Block a user