feat(codecompanion): add format_action - #188
Conversation
bf6b95f to
0048769
Compare
|
@powerman Thank you for the PR. Sorry for the delay in response. We have done a lot of refactoring at #169 with respect to tools. I think it's best we add this along with that. I'm thinking of replacing |
I don't think so - both because of auto_approve for some/all tools, and because of re-reading chat history later. So, tool args (cleaned from too large args like text diff/new file content) in a chat looks useful to me. Can be optionally enabled, of course, or this (show args or not) can be controlled by generic args cleaning hook (which may return nothing if user don't wanna see any args).
It turns out I'm now also working on tool calling issues with CodeCompanion/MCPHub:
I was planning to open a discussion with you about it, but if you don't mind we can continue here. I've just started, so some questions might be basic or invalid (sorry about that):
Probably after #169 it will makes sense to describe all tools in API functions format instead of Markdown (and send this either in system prompt if CodeCompanion won't support actual functions API or append it as is into functions API value). |
Yeah this makes sense.
Thanks and agree, some models do that like passing arguments in
I'm not sure I get this right but I'm thinking you are asking if we can create function tools from MCP server tools that work with codecompanion? If so, yes! We can just use the inputSchema of a tool as parameters for a function tool. This is code that handles converting each server tool into a codecompanion tool. -- Add individual tool
tools[namespaced_tool_name] = {
id = "mcp_dynamic:" .. safe_name .. ":" .. tool_name,
description = tool.description,
hide_in_help_window = true,
visible = opts.show_server_tools_in_chat == true,
callback = {
name = namespaced_tool_name,
cmds = { create_individual_tool_handler(server.name, tool_name, namespaced_tool_name) },
output = core.create_output_handlers(namespaced_tool_name, true, opts),
schema = {
type = "function",
["function"] = {
name = namespaced_tool_name,
description = tool.description,
parameters = tool.inputSchema,
},
},
},
}I majorly work with copilot adapter and so far I didn't run into any issues. Some old models might have an issue with tools having lengthy descriptions but I've not encountered in my testing. We can use system_prompt field if the need arises.
Agree with all these. Haven't focused much on them. Would really appreciate fixing these.
This was intentional because using actual JSON examples in the prompt surprisingly for some reason didn't work as expected. It was a hit and miss for different models. I thought that if we are expecting structured output, JSON examples work best but not for function calling. There seems to be some different internal schema these models are trained on and they are getting confused between the JSON examples and their internal examples I think. |
Yeah, that's the plan for today. 😄
No, I was talking about sending available functions to API in a separate "functions" key instead of usual system prompt in a "messages" key. Check this example with both keys: https://gist.github.com/hansvdam/8b9269390e16fa0bf394d7656bec1ea5 (that's just a random gist I just found, can't guarantee it's valid, but at a glance it is valid). Moving this way will result in removing markdown system prompt with tools at all. Or maybe transform it to contain same JSON as value of "functions" API param to use for providers which does not support "functions" param in API (if such providers still exists). |
Actually I've completely disabled both MCPHub and Neovim groups (and also I don't use any of CodeCompanion tools). I'm using 3rd-party MCP servers like The rationale for this:
|
Yeah,
We now manage our own registry https://github.com/ravitemer/mcp-registry with static configs. See #192
Make sure to auto approve the |
@ravitemer It turns out Neovim has no pretty-print for JSON. I still think using JSON here is better, but I'm not sure which option to choose:
|
|
We have a M.pretty_json function in utils/init.lua which is how we render the json in the :MCPHub |
Cool! I'm going to make a PR with switching Schema to JSON, and then look how to adapt current PR (format_action) for the make-tools branch and probably will open another one targeted to make-tools branch. |
|
Thanks for the new PR. Closing this |
Description
When tools is executed CodeCompanion does not show anything useful - all it says is "use_mcp_tool" has failed or succeeded. As "use_mcp_tool" is a meta-command, user do not see neither which tool was called, nor it args.
For successful execution it might be not critical and mostly just a curiosity to follow what LLM does.
But for failed runs it became a real UX issues, because in most cases failure happens because LLM uses wrong args, and now user needs to open a CodeCompanion debug output and try hard to find args used by LLM to spot an error and provide LLM with a hint how to fix it.
This PR adds support for a hook to let user format tool name and args to make them looks nice and useful.
Screenshots
Before this PR:

After this PR, using example configuration:

Checklist
make testto ensure all tests passmake formatto format the codemake docsto update the vimdoc pagesI've skipped
make docsbecause it makes irrelevant changes - but it works ok for relevant changes.