From 3a0b234669995507c59fc3d7083e2b02caae5065 Mon Sep 17 00:00:00 2001 From: hksdpc255 <43977088+hksdpc255@users.noreply.github.com> Date: Wed, 14 Jan 2026 03:08:59 +1100 Subject: [PATCH] Add context management to the MiroThinker template (simulate official agent behavior) (#1143) --- models/templates/MiroThinker.jinja | 76 +++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 6 deletions(-) diff --git a/models/templates/MiroThinker.jinja b/models/templates/MiroThinker.jinja index 306dc95b..fee4a57d 100644 --- a/models/templates/MiroThinker.jinja +++ b/models/templates/MiroThinker.jinja @@ -8,23 +8,33 @@ {%- endif %} {%- if tools %} {%- set system_message.content = "In this environment you have access to a set of tools you can use to answer the user's question. \n\nYou only have access to the tools provided below. You can only use one tool per message, and will receive the result of that tool in the user's next response. You use tools step-by-step to accomplish a given task, with each tool-use informed by the result of the previous tool-use. " + date_string + "\n\n# Tool-Use Formatting Instructions \n\nTool-use is formatted using XML-style tags. The tool-use is enclosed in and each parameter is similarly enclosed within its own set of tags.\n\nThe Model Context Protocol (MCP) connects to servers that provide additional tools and resources to extend your capabilities. You can use the server's tools via the `use_mcp_tool`.\n\nDescription: \nRequest to use a tool provided by a MCP server. Each MCP server can provide multiple tools with different capabilities. Tools have defined input schemas that specify required and optional parameters.\n\nParameters:\n- server_name: (required) The name of the MCP server providing the tool\n- tool_name: (required) The name of the tool to execute\n- arguments: (required) A JSON object containing the tool's input parameters, following the tool's input schema, quotes within string must be properly escaped, ensure it's valid JSON\n\nUsage:\n\nserver name here\ntool name here\n\n{\n\"param1\": \"value1\",\n\"param2\": \"value2 \\\"escaped string\\\"\"\n}\n\n\n\nImportant Notes:\n- Tool-use must be placed **at the end** of your response, **top-level**, and not nested within other tags.\n- Always adhere to this format for the tool use to ensure proper parsing and execution.\n\nString and scalar parameters should be specified as is, while lists and objects should use JSON format. Note that spaces for string values are not stripped. The output is not expected to be valid XML and is parsed with regular expressions.\nHere are the functions available in JSONSchema format:\n\n" %} - {%- set ns = namespace(formatted_tools='', last_server='') %} + {%- set ns = namespace(formatted_tools='', last_server=None) %} {%- for tool in tools %} - {%- set tool_name = tool.function.name.split('_') %} - {%- if tool_name | length > 1 %} + {%- set function = namespace(name=None, description=None, parameters=None) %} + {%- if tool.function is defined %} + {%- set function.name = tool.function.name %} + {%- set function.description = tool.function.description %} + {%- set function.parameters = tool.function.parameters %} + {%- elif tool.name is defined and tool.description is defined %} + {%- set function.name = tool.name %} + {%- set function.description = tool.description %} + {%- set function.parameters = tool.parameters %} + {%- endif %} + {%- set tool_name = function.name.split('_') %} + {%- if tool_name | length > 2 %} {%- set curr_server = tool_name[0] %} {%- set tool_name = tool_name[1:] | join('_') %} {%- else %} {%- set curr_server = 'system_default' %} - {%- set tool_name = tool.function.name %} + {%- set tool_name = function.name %} {%- endif %} {%- if curr_server != ns.last_server %} {%- set ns.formatted_tools = ns.formatted_tools + "\n## Server name: " + curr_server + "\n" %} {%- set ns.last_server = curr_server %} {%- endif %} {%- set ns.formatted_tools = ns.formatted_tools + "### Tool name: " + tool_name + "\n" %} - {%- set ns.formatted_tools = ns.formatted_tools + "Description: " + tool.function.description + "\n" %} - {%- set ns.formatted_tools = ns.formatted_tools + "Input JSON schema: " + ( tool.parameters | tojson(ensure_ascii=False) ) + "\n" %} + {%- set ns.formatted_tools = ns.formatted_tools + "Description: " + function.description + "\n" %} + {%- set ns.formatted_tools = ns.formatted_tools + "Input JSON schema: " + ( function.parameters | tojson(ensure_ascii=False) ) + "\n" %} {%- set ns.formatted_tools = ns.formatted_tools + '\n' %} {%- endfor %} {%- set system_message.content = system_message.content + ns.formatted_tools + "\n# General Objective\n\nYou accomplish a given task iteratively, breaking it down into clear steps and working through them methodically.\n\n" %} @@ -47,6 +57,57 @@ {%- endif %} {%- set messages = [system_message] + messages %} +{#- ========== MiroThinker Context Management ========== #} + +{%- set tool_count = namespace(keep=5, total=0) %} +{%- if keep_tool_result is defined %} + {%- set tool_count.keep = keep_tool_result %} +{%- endif %} +{%- if tool_count.keep != -1 %} + {%- for message in messages %} + {%- if message.role == 'assistant' %} + {%- if message.tool_calls %} + {%- set message.have_tools = message.tool_calls | length %} + {%- set tool_count.total = tool_count.total + message.have_tools %} + {%- else %} + {%- set msg = message.content %} + {%- if msg.endswith('\n') %} + {%- set msg = msg[:-16] %} + {%- set msg = msg.split('\n') %} + {%- if msg | length > 1 %} + {%- set message.have_tools = (msg[-1].split('\n') | length) - 1 %} + {%- set tool_count.total = tool_count.total + message.have_tools %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endif %} + {%- endfor %} + {%- if tool_count.total > tool_count.keep %} + {%- set tool_count.total = tool_count.total - tool_count.keep %} + {%- else %} + {%- set tool_count.total = 0 %} + {%- endif %} + {%- set should_consume = namespace(count=0) %} + {%- for message in messages %} + {%- if message.role == 'assistant' %} + {%- if message.have_tools is defined %} + {%- if message.have_tools < tool_count.total %} + {%- set should_consume.count = should_consume.count + message.have_tools %} + {%- set tool_count.total = tool_count.total - message.have_tools %} + {%- else %} + {%- set should_consume.count = should_consume.count + tool_count.total %} + {%- set tool_count.total = 0 %} + {%- endif %} + {%- endif %} + {%- elif message.role == 'user' or message.role == 'tool' %} + {%- if should_consume.count > 0 %} + {%- set message.content = 'Tool result is omitted to save tokens.' %} + {%- set should_consume.count = should_consume.count - 1 %} + {%- endif %} + {%- endif %} + {%- endfor %} +{%- endif %} + {#- ========== MiroThinker Tool Response ========== #} {%- for message in messages %} @@ -71,6 +132,9 @@ {%- elif message.role == 'user' %} {%- if message.content.startswith('') %} {%- set message.content = message.content[15:] | trim %} + {%- if message.content.endswith('') %} + {%- set message.content = message.content[:-16] | trim %} + {%- endif %} {%- endif %} {%- elif message.role == 'tool' %} {%- set message.role = 'user' %}