@skydiveai/pi-extensions 0.1.0-beta.2103 → 0.1.0-beta.2104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +56 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1400,6 +1400,57 @@ function mcpResultToPiContent(result) {
|
|
|
1400
1400
|
text: "MCP tool returned no content."
|
|
1401
1401
|
}];
|
|
1402
1402
|
}
|
|
1403
|
+
const MAX_ENUM_VALUES_LISTED = 12;
|
|
1404
|
+
function formatEnumValues(values) {
|
|
1405
|
+
const shown = values.slice(0, MAX_ENUM_VALUES_LISTED).map((v) => JSON.stringify(v));
|
|
1406
|
+
if (values.length > MAX_ENUM_VALUES_LISTED) shown.push(`… (${values.length} total)`);
|
|
1407
|
+
return shown.join(", ");
|
|
1408
|
+
}
|
|
1409
|
+
function extractEnum(propSchema) {
|
|
1410
|
+
if (Array.isArray(propSchema.enum) && propSchema.enum.length > 0) return propSchema.enum;
|
|
1411
|
+
const items = propSchema.items;
|
|
1412
|
+
if (items !== null && typeof items === "object" && Array.isArray(items.enum) && items.enum.length > 0) return items.enum;
|
|
1413
|
+
return null;
|
|
1414
|
+
}
|
|
1415
|
+
/**
|
|
1416
|
+
* Build a compact, human-readable constraint hint from an MCP tool's raw JSON
|
|
1417
|
+
* schema so the model sees required fields and each param's allowed enum values
|
|
1418
|
+
* inline in the tool description — the schema pass-through hands pi the server's
|
|
1419
|
+
* schema verbatim, but the model attends to the prose far more than the raw
|
|
1420
|
+
* `enum`/`required` keys. Returns '' when there is nothing worth surfacing.
|
|
1421
|
+
*/
|
|
1422
|
+
function describeToolConstraints(inputSchema) {
|
|
1423
|
+
if (inputSchema === null || typeof inputSchema !== "object") return "";
|
|
1424
|
+
const schema = inputSchema;
|
|
1425
|
+
const required = Array.isArray(schema.required) ? schema.required.filter((r) => typeof r === "string") : [];
|
|
1426
|
+
const properties = schema.properties !== null && typeof schema.properties === "object" ? schema.properties : {};
|
|
1427
|
+
const enumLines = [];
|
|
1428
|
+
for (const [propName, rawProp] of Object.entries(properties)) {
|
|
1429
|
+
if (rawProp === null || typeof rawProp !== "object") continue;
|
|
1430
|
+
const values = extractEnum(rawProp);
|
|
1431
|
+
if (values) enumLines.push(`- \`${propName}\` must be one of: ${formatEnumValues(values)}`);
|
|
1432
|
+
}
|
|
1433
|
+
if (required.length === 0 && enumLines.length === 0) return "";
|
|
1434
|
+
const lines = ["Argument constraints:"];
|
|
1435
|
+
if (required.length > 0) lines.push(`- required: ${required.map((r) => `\`${r}\``).join(", ")}`);
|
|
1436
|
+
lines.push(...enumLines);
|
|
1437
|
+
return lines.join("\n");
|
|
1438
|
+
}
|
|
1439
|
+
/**
|
|
1440
|
+
* Build the `promptSnippet` a registered MCP tool exposes to the model: the
|
|
1441
|
+
* server's description with the argument-constraint hint appended, falling back
|
|
1442
|
+
* to a labelled placeholder when the server omitted a description AND the schema
|
|
1443
|
+
* carries no constraints (pi's system-prompt builder hides tools whose snippet
|
|
1444
|
+
* is empty — system-prompt.js:49). This is the layer where `describeToolConstraints`
|
|
1445
|
+
* actually reaches the model, so it is exported and tested directly: the pure
|
|
1446
|
+
* hint being correct is necessary but not sufficient; what the model sees is
|
|
1447
|
+
* this composed snippet.
|
|
1448
|
+
*/
|
|
1449
|
+
function buildToolPromptSnippet({ description, inputSchema, serverId }) {
|
|
1450
|
+
const constraintHint = describeToolConstraints(inputSchema);
|
|
1451
|
+
const enriched = constraintHint.length > 0 ? `${description}${description.length > 0 ? "\n\n" : ""}${constraintHint}` : description;
|
|
1452
|
+
return enriched.length > 0 ? enriched : `MCP tool from server "${serverId}".`;
|
|
1453
|
+
}
|
|
1403
1454
|
var McpExtension = class {
|
|
1404
1455
|
mcpClients = /* @__PURE__ */ new Map();
|
|
1405
1456
|
registeredMcpToolNames = /* @__PURE__ */ new Set();
|
|
@@ -1419,7 +1470,11 @@ var McpExtension = class {
|
|
|
1419
1470
|
const name = makeToolName(serverId, tool.name);
|
|
1420
1471
|
const parameters = Type.Unsafe(tool.inputSchema);
|
|
1421
1472
|
const description = tool.description?.trim() ?? "";
|
|
1422
|
-
const promptSnippet =
|
|
1473
|
+
const promptSnippet = buildToolPromptSnippet({
|
|
1474
|
+
description,
|
|
1475
|
+
inputSchema: tool.inputSchema,
|
|
1476
|
+
serverId
|
|
1477
|
+
});
|
|
1423
1478
|
pi.registerTool(withSummaryStrippedBeforeValidation({
|
|
1424
1479
|
name,
|
|
1425
1480
|
label: `MCP: ${serverId}/${tool.name}`,
|