dist-mcp / mcp / sourceNotation.js
dist-mcp / mcp / sourceNotation.js
export const ATTACHMENT_NOTATION = /^a([1-9]\d*|n)?$/i;
export class UnsupportedAttachmentNotationError extends Error {
constructor(value) {
super(`Source "${value}" uses LM-Studio attachment notation (aN), which is not supported here. ` +
`Use load_file_attachment first, then pass the resulting scratchpad notation (iN/pN) as a target instead.`);
this.name = "UnsupportedAttachmentNotationError";
}
}
function rejectIfAttachmentNotation(value) {
if (typeof value !== "string")
return;
const trimmed = value.trim();
if (ATTACHMENT_NOTATION.test(trimmed)) {
throw new UnsupportedAttachmentNotationError(trimmed);
}
}
/**
* analyse_image/detect_object/annotate_image all use a single `targets` field (array of
* aN/iN/vN/pN notations, or a comma/space-separated string — see FlexibleTargetsList in
* core/tools.ts) instead of generate-image/process-image's separate canvas/moodboard fields.
* No-ops entirely for the unsloth preset (see module doc comment above).
*/
export function assertNoAttachmentNotation(args, preset) {
if (preset.name === "unsloth")
return;
const { targets } = args;
if (Array.isArray(targets)) {
targets.forEach(rejectIfAttachmentNotation);
}
else if (typeof targets === "string") {
targets.split(/[\s,]+/).forEach(rejectIfAttachmentNotation);
}
}
/** Collects every aN-shaped token out of `targets`, deduplicated — used to feed
* McpResultPreset.beforeToolCall()'s `attachmentTokens` (unsloth only). */
export function collectAttachmentTokens(args) {
const { targets } = args;
const tokens = new Set();
const consider = (value) => {
if (typeof value !== "string")
return;
const trimmed = value.trim();
if (ATTACHMENT_NOTATION.test(trimmed))
tokens.add(trimmed);
};
if (Array.isArray(targets))
targets.forEach(consider);
else if (typeof targets === "string")
targets.split(/[\s,]+/).forEach(consider);
return [...tokens];
}
// No separate path-resolution step here: core/tools.ts's own handlers (handleAnalyseImage,
// handleDetectObject, handleAnnotateImage) already parse and resolve every `targets` shape
// themselves — native array, comma/space-separated string, and JSON-array-shaped string alike —
// including the scratchpad-basename/absolute-path fallback. Re-resolving here duplicated that
// logic with a second, less complete implementation and broke on JSON-array-shaped strings.
export const ATTACHMENT_NOTATION = /^a([1-9]\d*|n)?$/i;
export class UnsupportedAttachmentNotationError extends Error {
constructor(value) {
super(`Source "${value}" uses LM-Studio attachment notation (aN), which is not supported here. ` +
`Use load_file_attachment first, then pass the resulting scratchpad notation (iN/pN) as a target instead.`);
this.name = "UnsupportedAttachmentNotationError";
}
}
function rejectIfAttachmentNotation(value) {
if (typeof value !== "string")
return;
const trimmed = value.trim();
if (ATTACHMENT_NOTATION.test(trimmed)) {
throw new UnsupportedAttachmentNotationError(trimmed);
}
}
/**
* analyse_image/detect_object/annotate_image all use a single `targets` field (array of
* aN/iN/vN/pN notations, or a comma/space-separated string — see FlexibleTargetsList in
* core/tools.ts) instead of generate-image/process-image's separate canvas/moodboard fields.
* No-ops entirely for the unsloth preset (see module doc comment above).
*/
export function assertNoAttachmentNotation(args, preset) {
if (preset.name === "unsloth")
return;
const { targets } = args;
if (Array.isArray(targets)) {
targets.forEach(rejectIfAttachmentNotation);
}
else if (typeof targets === "string") {
targets.split(/[\s,]+/).forEach(rejectIfAttachmentNotation);
}
}
/** Collects every aN-shaped token out of `targets`, deduplicated — used to feed
* McpResultPreset.beforeToolCall()'s `attachmentTokens` (unsloth only). */
export function collectAttachmentTokens(args) {
const { targets } = args;
const tokens = new Set();
const consider = (value) => {
if (typeof value !== "string")
return;
const trimmed = value.trim();
if (ATTACHMENT_NOTATION.test(trimmed))
tokens.add(trimmed);
};
if (Array.isArray(targets))
targets.forEach(consider);
else if (typeof targets === "string")
targets.split(/[\s,]+/).forEach(consider);
return [...tokens];
}
// No separate path-resolution step here: core/tools.ts's own handlers (handleAnalyseImage,
// handleDetectObject, handleAnnotateImage) already parse and resolve every `targets` shape
// themselves — native array, comma/space-separated string, and JSON-array-shaped string alike —
// including the scratchpad-basename/absolute-path fallback. Re-resolving here duplicated that
// logic with a second, less complete implementation and broke on JSON-array-shaped strings.