mirror of
https://github.com/DayuanJiang/next-ai-draw-io.git
synced 2026-10-12 04:29:51 +08:00
fix(mcp-server): get_selection lists every selected id, with detail for the first 100
This commit is contained in:
@@ -69,14 +69,15 @@ export function parseSelectionAnswer(value: unknown): SelectionAnswer | null {
|
||||
return { pageId: text(given.pageId), pageName: text(given.pageName), cells }
|
||||
}
|
||||
|
||||
/** describeSelection lists at most this many cells; the rest are counted */
|
||||
/** describeSelection details at most this many cells; the rest by id only */
|
||||
export const MAX_LISTED_CELLS = 100
|
||||
|
||||
/**
|
||||
* The get_selection result text. `externalDrawio` names the draw.io origin
|
||||
* when the preview loads it from another origin, where the page cannot
|
||||
* read the editor. A selection of a whole large diagram is counted, not
|
||||
* listed in full: the model needs the ids of a few hundred cells at most.
|
||||
* read the editor. A selection of a whole large diagram would fill the
|
||||
* model's context with labels and geometry: the first cells get them, the
|
||||
* rest are listed by id alone (an edit on the selection needs every id).
|
||||
*/
|
||||
export function describeSelection(
|
||||
answer: SelectionAnswer,
|
||||
@@ -110,10 +111,10 @@ export function describeSelection(
|
||||
const parent = cell.parent ? ` inside "${cell.parent}"` : ""
|
||||
return `- id="${cell.id}" shape ${label}${where}${parent}`
|
||||
})
|
||||
const more = answer.cells.length - listed.length
|
||||
if (more > 0) {
|
||||
const rest = answer.cells.slice(MAX_LISTED_CELLS)
|
||||
if (rest.length > 0) {
|
||||
lines.push(
|
||||
`- and ${more} more cells not listed here; call get_diagram for the rest`,
|
||||
`- and ${rest.length} more cells, listed by id only: ${rest.map((c) => `"${c.id}"`).join(", ")}`,
|
||||
)
|
||||
}
|
||||
const count =
|
||||
|
||||
@@ -53,7 +53,7 @@ describe("get_selection text", () => {
|
||||
expect(text).toContain('edit_diagram (page_id="p1")')
|
||||
})
|
||||
|
||||
it("counts a large selection instead of listing every cell", () => {
|
||||
it("details the first cells of a large selection and lists the rest by id", () => {
|
||||
const cells = (n: number) =>
|
||||
Array.from({ length: n }, (_, i) => ({
|
||||
id: `c${i + 1}`,
|
||||
@@ -67,8 +67,13 @@ describe("get_selection text", () => {
|
||||
)
|
||||
expect(text).toContain(`${MAX_LISTED_CELLS + 5} cells selected`)
|
||||
expect(text).toContain(`id="c${MAX_LISTED_CELLS}"`)
|
||||
// No detail past the cap, but every id: the model acts on all of
|
||||
// them, and get_diagram cannot tell which cells were selected
|
||||
expect(text).not.toContain(`id="c${MAX_LISTED_CELLS + 1}"`)
|
||||
expect(text).toContain("and 5 more cells not listed here")
|
||||
expect(text).not.toContain(`shape "Cell ${MAX_LISTED_CELLS + 1}"`)
|
||||
expect(text).toContain(
|
||||
`- and 5 more cells, listed by id only: "c${MAX_LISTED_CELLS + 1}", "c${MAX_LISTED_CELLS + 2}", "c${MAX_LISTED_CELLS + 3}", "c${MAX_LISTED_CELLS + 4}", "c${MAX_LISTED_CELLS + 5}"`,
|
||||
)
|
||||
const exact = describeSelection(
|
||||
{ ...page, cells: cells(MAX_LISTED_CELLS) },
|
||||
null,
|
||||
|
||||
Reference in New Issue
Block a user