Skip to content

feat: Insertion functionality #45

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: main
Choose a base branch
from

Conversation

Ryfernandes
Copy link
Contributor

@Ryfernandes Ryfernandes commented Jul 15, 2025

Issue resolved by this Pull Request:
Resolves #43

The primary feature of this pull request is to refactor most of the tools in generation.py. Before, these tools allowed node items to be appended to the end of the document. Now, they have been refactored to enable both append and insert operations. This is achieved through two parameters: sibling_anchor and parent_anchor. The control flow works as follows:

  • If a sibling_anchor is provided, the node item will be inserted before/after the sibling anchor, depending on the boolean insert_after parameter
  • If no sibling_anchor is provided, the tool will default to append functionality. In this case, if a parent_anchor is provided, the node item will be appended as a child of the parent_anchor. If no parent_anchor is provided, the node item will be added to the end of the document.

This is more complex than the old tools, but it allows for much more functionality without extra tool definitions. Based on tests with Claude as a client, frontier LLMs are able to comprehend the following directions in the tool docstring:

"""Insert a paragraph by specifying sibling_anchor or append a paragraph by specifying parent_anchor in a Docling Document object.

If sibling_anchor is provided, the value of parent_anchor does not matter. Only omit sibling_anchor and specify parent_anchor when appending a paragraph to the end of a group. To append a paragraph to the end of the entire document, do not specify either anchor.
"""

In addition to the insertion functionality, I have also refactored the way that lists work in docling-mcp. This refactor was proposed in the original issue and is what I implemented for my Docling MCP client, but I am happy to discuss further. Essentially, the old list system used local_stack_cache to track open/closed lists. Instead of having this auxiliary system, which only functions for one list at a time at the end of the document, I changed the code to be more consistent with the ways that lists work in docling-core: enabling list items to be added as children of specified list group parents. With this, I turned the open/close list group tools into a single add_list_group_to_docling_document tool. Additionally, all of the stack checks and furniture items have been removed. The safeguards to prevent things like titles in list groups and list items outside of list groups still exist.

Lastly, for all tools that insert/append node items, I added an additional value to the returned object: the document anchor(s) of the newly created object(s). From limited testing (moreso speculation) this should help the client to place multiple new items consecutively, without having to make intermediate get_overview_of_document_anchors calls.

These changes have been tested with Claude as a client, but still should be tested on LlamaStack. Once we confirm that this new format is not too complex, I can quickly add some regression tests before merge.

Claude Tests (New features and "regression" from #40)

Test 1: Confirm that previous conversation flows still work and insert a new paragraph (test robustness by not giving the exact position/document anchor, instead referring to a relational position)

Screenshot 2025-07-31 at 11 30 34 AM Screenshot 2025-07-31 at 11 30 48 AM Screenshot 2025-07-31 at 11 31 11 AM

Markdown file:
example_editing_converted.md


Test 2: Confirm that documents can still be created sequentially, test the insertion of multiple items at once (prompts purposefully conversational/ambiguous at times)

Screenshot 2025-07-31 at 11 33 33 AM Screenshot 2025-07-31 at 11 34 25 AM Screenshot 2025-07-31 at 11 34 46 AM 3b-8fb5-be2964dbf0df" />

Markdown file:
example_justin_bieber.md


Test 3: Confirm that lists can still be created and have items inserted after creation

Screenshot 2025-07-31 at 4 25 03 PM Screenshot 2025-07-31 at 4 25 13 PM Screenshot 2025-07-31 at 4 25 20 PM

Markdown file:
example_list_operations.md

@Ryfernandes Ryfernandes marked this pull request as draft July 15, 2025 17:46
Copy link
Contributor

github-actions bot commented Jul 15, 2025

DCO Check Passed

Thanks @Ryfernandes, all your commits are properly signed off. 🎉

Copy link

mergify bot commented Jul 15, 2025

Merge Protections

Your pull request matches the following merge protections and will not be merged until they are valid.

🟢 Enforce conventional commit

Wonderful, this rule succeeded.

Make sure that we follow https://www.conventionalcommits.org/en/v1.0.0/

  • title ~= ^(fix|feat|docs|style|refactor|perf|test|build|ci|chore|revert)(?:\(.+\))?(!)?:

@Ryfernandes Ryfernandes changed the title feat: Insertion tools feat: Insertion functionality Jul 15, 2025
@Ryfernandes
Copy link
Contributor Author

@ceberam This latest commit is the way I structured the insertion tools for the local fork that I used in the Docling-Client demo. It's structured in a way to minimize the number of tools by combining the insertion and addition functionalities into one tool. This does make the parameters more complex, but Claude was able to handle it fine after some tweaking of the docstring/parameter annotations. I haven't tested with smaller models, so do you think they would be able to handle this type of tool calling reliably?

I, Ryan Fernandes <[email protected]>, hereby add my Signed-off-by to this commit: 24b5ae7
I, Ryan Fernandes <[email protected]>, hereby add my Signed-off-by to this commit: 3297d17

Signed-off-by: Ryan Fernandes <[email protected]>
I, Ryan Fernandes <[email protected]>, hereby add my Signed-off-by to this commit: 24b5ae7
I, Ryan Fernandes <[email protected]>, hereby add my Signed-off-by to this commit: 3297d17
I, Ryan Fernandes <[email protected]>, hereby add my Signed-off-by to this commit: 10c7588

Signed-off-by: Ryan Fernandes <[email protected]>
I, Ryan Fernandes <[email protected]>, hereby add my Signed-off-by to this commit: 14af47a
I, Ryan Fernandes <[email protected]>, hereby add my Signed-off-by to this commit: 17de1fc
I, Ryan Fernandes <[email protected]>, hereby add my Signed-off-by to this commit: 58760e1

Signed-off-by: Ryan Fernandes <[email protected]>
I, Ryan Fernandes <[email protected]>, hereby add my Signed-off-by to this commit: 14af47a
I, Ryan Fernandes <[email protected]>, hereby add my Signed-off-by to this commit: 17de1fc
I, Ryan Fernandes <[email protected]>, hereby add my Signed-off-by to this commit: 58760e1
I, Ryan Fernandes <[email protected]>, hereby add my Signed-off-by to this commit: ee1b802

Signed-off-by: Ryan Fernandes <[email protected]>
Signed-off-by: Ryan Fernandes <[email protected]>
@Ryfernandes Ryfernandes marked this pull request as ready for review July 31, 2025 20:27
Copy link

codecov bot commented Aug 1, 2025

Codecov Report

❌ Patch coverage is 11.60221% with 160 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
docling_mcp/tools/generation.py 11.66% 159 Missing ⚠️
docling_mcp/tools/conversion.py 0.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Contributor

@ceberam ceberam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! 🏆

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Change Generation Tools to Allow Insertion of Items
2 participants