thinkpool-pair 0.7.256 → 0.7.257
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/hermes-acp-bootstrap.py +51 -0
- package/hermes-event-mapper.mjs +11 -10
- package/package.json +1 -1
package/hermes-acp-bootstrap.py
CHANGED
|
@@ -145,6 +145,57 @@ def constrained_expand(toolsets_arg=None, mcp_server_names=None):
|
|
|
145
145
|
acp_adapter.session._expand_acp_enabled_toolsets = constrained_expand
|
|
146
146
|
|
|
147
147
|
import acp_adapter.server
|
|
148
|
+
|
|
149
|
+
# Hermes 0.18.2 emits the real result through ``tool.completed`` immediately,
|
|
150
|
+
# but its ACP callback ignores that event and waits for the next model-step
|
|
151
|
+
# summary. Parallel Read/search calls are not always present in that summary,
|
|
152
|
+
# leaving clients with a ToolCallStart and no ToolCallUpdate forever. Complete
|
|
153
|
+
# from the authoritative execution callback and consume the same per-name FIFO;
|
|
154
|
+
# the later step callback then sees an empty queue and cannot double-emit. If a
|
|
155
|
+
# future Hermes release handles completion itself, it consumes the queue before
|
|
156
|
+
# this wrapper runs and this compatibility branch becomes a no-op.
|
|
157
|
+
from collections import deque
|
|
158
|
+
import acp_adapter.events
|
|
159
|
+
import acp_adapter.tools
|
|
160
|
+
|
|
161
|
+
_tool_progress_factory = acp_adapter.server.make_tool_progress_cb
|
|
162
|
+
def completion_aware_tool_progress_factory(
|
|
163
|
+
conn, session_id, loop, tool_call_ids, tool_call_meta,
|
|
164
|
+
edit_approval_policy_getter=None,
|
|
165
|
+
):
|
|
166
|
+
upstream = _tool_progress_factory(
|
|
167
|
+
conn, session_id, loop, tool_call_ids, tool_call_meta,
|
|
168
|
+
edit_approval_policy_getter=edit_approval_policy_getter,
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
def progress(event_type, name=None, preview=None, args=None, **kwargs):
|
|
172
|
+
upstream(event_type, name, preview, args, **kwargs)
|
|
173
|
+
if event_type != "tool.completed" or not name:
|
|
174
|
+
return
|
|
175
|
+
queue = tool_call_ids.get(name)
|
|
176
|
+
if isinstance(queue, str):
|
|
177
|
+
queue = deque([queue])
|
|
178
|
+
tool_call_ids[name] = queue
|
|
179
|
+
if not queue:
|
|
180
|
+
return
|
|
181
|
+
tool_call_id = queue.popleft()
|
|
182
|
+
meta = tool_call_meta.pop(tool_call_id, {})
|
|
183
|
+
result = kwargs.get("result")
|
|
184
|
+
update = acp_adapter.tools.build_tool_complete(
|
|
185
|
+
tool_call_id,
|
|
186
|
+
name,
|
|
187
|
+
result=str(result) if result is not None else None,
|
|
188
|
+
function_args=meta.get("args"),
|
|
189
|
+
snapshot=meta.get("snapshot"),
|
|
190
|
+
)
|
|
191
|
+
acp_adapter.events._send_update(conn, session_id, loop, update)
|
|
192
|
+
if not queue:
|
|
193
|
+
tool_call_ids.pop(name, None)
|
|
194
|
+
|
|
195
|
+
return progress
|
|
196
|
+
|
|
197
|
+
acp_adapter.server.make_tool_progress_cb = completion_aware_tool_progress_factory
|
|
198
|
+
|
|
148
199
|
_register = acp_adapter.server.HermesACPAgent._register_session_mcp_servers
|
|
149
200
|
async def constrained_register(self, state, mcp_servers):
|
|
150
201
|
if any(getattr(server, "name", None) != "thinkpool" for server in (mcp_servers or [])):
|
package/hermes-event-mapper.mjs
CHANGED
|
@@ -128,16 +128,17 @@ export class HermesEventMapper {
|
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
finishTurn({ stopReason = 'end_turn', usage = null } = {}) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
131
|
+
for (const [toolCallId, tool] of this.tools) {
|
|
132
|
+
const cancelled = stopReason === 'cancelled'
|
|
133
|
+
this._emit({
|
|
134
|
+
kind: 'tool_result', toolUseId: toolCallId,
|
|
135
|
+
content: [{ type: 'text', text: cancelled ? '[cancelled]' : 'Hermes ended the turn without reporting this tool result.' }],
|
|
136
|
+
toolInput: tool.input || undefined,
|
|
137
|
+
isError: !cancelled && stopReason !== 'end_turn',
|
|
138
|
+
missing: !cancelled,
|
|
139
|
+
durationMs: tool.startedAt ? Date.now() - tool.startedAt : undefined,
|
|
140
|
+
parentToolUseId: null,
|
|
141
|
+
})
|
|
141
142
|
}
|
|
142
143
|
this.tools.clear()
|
|
143
144
|
const blocks = []
|