@melaya/runner 1.0.87 → 1.0.89
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/dist/assistantHost.py +55 -7
- package/package.json +1 -1
package/dist/assistantHost.py
CHANGED
|
@@ -169,6 +169,11 @@ def _build_agent():
|
|
|
169
169
|
# explodes context. Bounded to the selected services so the model can't reach
|
|
170
170
|
# a connector the user didn't enable / has no creds for.
|
|
171
171
|
connector_services = [s.strip().lower() for s in os.environ.get("MEL_ASSISTANT_CONNECTORS", "").split(",") if s.strip()]
|
|
172
|
+
# Self-arm the write-approval gate whenever connectors are active, so it can't
|
|
173
|
+
# be silently OFF on an older runner build that didn't set this env. Writes
|
|
174
|
+
# then ALWAYS require the in-chat approval card (fail-safe).
|
|
175
|
+
if connector_services and not os.environ.get("MEL_ASSISTANT_CONNECTOR_HITL"):
|
|
176
|
+
os.environ["MEL_ASSISTANT_CONNECTOR_HITL"] = "1"
|
|
172
177
|
try:
|
|
173
178
|
if connector_services:
|
|
174
179
|
from shared.orchestration.lazy_registry import build_lazy_toolkit
|
|
@@ -251,15 +256,39 @@ def _build_agent():
|
|
|
251
256
|
return agent
|
|
252
257
|
|
|
253
258
|
|
|
259
|
+
_HOOKS_REGISTERED = False
|
|
260
|
+
|
|
261
|
+
|
|
254
262
|
def _register_stream_hooks(agent) -> None:
|
|
255
|
-
"""Emit delta / tool events live as the agent produces output
|
|
256
|
-
|
|
263
|
+
"""Emit delta / tool events live as the agent produces output.
|
|
264
|
+
|
|
265
|
+
Registers agentscope CLASS hooks on ReActAgent — NOT instance hooks on the
|
|
266
|
+
object make_agent returned. With reliability=True (and bounded_memory) that
|
|
267
|
+
object is a WRAPPER around the real ReActAgent, so an instance hook on it
|
|
268
|
+
never fires when the inner agent runs its acting / print steps: the FE then
|
|
269
|
+
only ever saw the `round` event ("thinking…") and never the tool / delta
|
|
270
|
+
stream. Class hooks fire for the inner agent regardless of wrapping — the
|
|
271
|
+
exact mechanism the pipeline event bus uses (shared.runtime.events
|
|
272
|
+
.wire_agentscope_hooks). There's one agent per host process, so a class hook
|
|
273
|
+
is effectively instance-scoped here; it keys output to the in-flight turn via
|
|
274
|
+
_stream and no-ops between turns (turnId == "").
|
|
275
|
+
|
|
276
|
+
pre_print gives cumulative snapshots per message; we forward the new suffix
|
|
277
|
+
as a delta. post_acting gives the tool-call batch; one `tool` event each.
|
|
278
|
+
"""
|
|
279
|
+
global _HOOKS_REGISTERED
|
|
280
|
+
if _HOOKS_REGISTERED:
|
|
281
|
+
return
|
|
257
282
|
try:
|
|
258
283
|
from shared.runtime.events import _flatten_agent_text
|
|
259
284
|
except Exception:
|
|
260
285
|
return
|
|
286
|
+
try:
|
|
287
|
+
from agentscope.agent import ReActAgent
|
|
288
|
+
except Exception:
|
|
289
|
+
return
|
|
261
290
|
|
|
262
|
-
def
|
|
291
|
+
def _pre_print_hook(_agent, **kwargs) -> None:
|
|
263
292
|
try:
|
|
264
293
|
tid = _stream.get("turnId")
|
|
265
294
|
if not tid:
|
|
@@ -278,7 +307,7 @@ def _register_stream_hooks(agent) -> None:
|
|
|
278
307
|
except Exception:
|
|
279
308
|
pass
|
|
280
309
|
|
|
281
|
-
def
|
|
310
|
+
def _post_acting_hook(_agent, **kwargs) -> None:
|
|
282
311
|
try:
|
|
283
312
|
tid = _stream.get("turnId")
|
|
284
313
|
if not tid:
|
|
@@ -290,11 +319,30 @@ def _register_stream_hooks(agent) -> None:
|
|
|
290
319
|
except Exception:
|
|
291
320
|
pass
|
|
292
321
|
|
|
293
|
-
|
|
322
|
+
# Our agentscope's hook registration is 3-arg: (hook_type, hook_name, hook).
|
|
323
|
+
# The ORIGINAL code here called register_INSTANCE_hook(hook_type, fn) — 2 args
|
|
324
|
+
# against a 3-arg method AND on the reliability WRAPPER rather than the inner
|
|
325
|
+
# ReActAgent → TypeError, silently swallowed → the hooks were NEVER registered.
|
|
326
|
+
# That is why the FE only ever saw the `round` event ("thinking…") and none of
|
|
327
|
+
# the tool / delta stream. Register CLASS hooks with the correct arity (2-arg
|
|
328
|
+
# kept as a defensive fallback in case the signature ever changes).
|
|
329
|
+
def _reg(hook_type: str, name: str, fn) -> bool:
|
|
294
330
|
try:
|
|
295
|
-
|
|
331
|
+
ReActAgent.register_class_hook(hook_type, name, fn) # 3-arg (vendored)
|
|
332
|
+
return True
|
|
333
|
+
except TypeError:
|
|
334
|
+
try:
|
|
335
|
+
ReActAgent.register_class_hook(hook_type, fn) # 2-arg (pip build)
|
|
336
|
+
return True
|
|
337
|
+
except Exception:
|
|
338
|
+
return False
|
|
296
339
|
except Exception:
|
|
297
|
-
|
|
340
|
+
return False
|
|
341
|
+
|
|
342
|
+
ok_a = _reg("pre_print", "mel_assistant_delta", _pre_print_hook)
|
|
343
|
+
ok_b = _reg("post_acting", "mel_assistant_tool", _post_acting_hook)
|
|
344
|
+
_HOOKS_REGISTERED = ok_a or ok_b
|
|
345
|
+
_log(f"stream hooks registered (delta={ok_a} tool={ok_b})")
|
|
298
346
|
|
|
299
347
|
|
|
300
348
|
def _run_turn(agent, turn_id: str, message: str) -> None:
|