@strayl/agent 0.1.21 → 0.1.23

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.
Files changed (2) hide show
  1. package/dist/agent.js +22 -3
  2. package/package.json +1 -1
package/dist/agent.js CHANGED
@@ -12380,6 +12380,10 @@ var StdinListener = class {
12380
12380
  isCancelled() {
12381
12381
  return this.cancelled;
12382
12382
  }
12383
+ /** Put commands back at the front of the queue (for re-queuing unhandled commands) */
12384
+ requeue(...cmds) {
12385
+ this.queue.unshift(...cmds);
12386
+ }
12383
12387
  stop() {
12384
12388
  this.rl?.close();
12385
12389
  this.rl = null;
@@ -13564,6 +13568,7 @@ async function runAgent(config) {
13564
13568
  let consecutiveLLMErrors = 0;
13565
13569
  const MAX_CONSECUTIVE_LLM_ERRORS = 5;
13566
13570
  let nudgedToContinue = false;
13571
+ let hasUsedTools = false;
13567
13572
  if (config.restoreCheckpoint) {
13568
13573
  const cp = config.restoreCheckpoint;
13569
13574
  context.restoreMessages(cp.messages);
@@ -13582,6 +13587,7 @@ ${config.previousSummary}`);
13582
13587
  }
13583
13588
  while (iteration < maxIterations) {
13584
13589
  iteration++;
13590
+ emitter.emit({ type: "debug", message: `[LOOP] iteration=${iteration}/${maxIterations} mode=${currentMode} nudgedToContinue=${nudgedToContinue}` });
13585
13591
  for (const cmd of stdin.drain()) {
13586
13592
  switch (cmd.type) {
13587
13593
  case "inject":
@@ -13750,13 +13756,19 @@ ${IMPLEMENTATION_MODE_PROMPT2}`);
13750
13756
  });
13751
13757
  }
13752
13758
  if (completedToolCalls.length === 0) {
13753
- if (!nudgedToContinue) {
13759
+ emitter.emit({ type: "debug", message: `[LOOP] No tool calls. textLen=${assistantText.length} nudgedToContinue=${nudgedToContinue} hasUsedTools=${hasUsedTools} mode=${currentMode} text="${assistantText.slice(0, 200)}"` });
13760
+ const shouldNudge = !nudgedToContinue && (hasUsedTools || currentMode === "implement");
13761
+ if (shouldNudge) {
13754
13762
  nudgedToContinue = true;
13755
- context.addUser("[System: You responded with text but did not call any tools. If you are done, respond with your final message. Otherwise, use your tools to continue working.]");
13763
+ emitter.emit({ type: "debug", message: `[LOOP] Sending nudge to continue...` });
13764
+ context.addUser("[System: You responded with text but did not call any tools. If your task is complete, say so briefly. If there is unfinished work from the user's original request, continue using tools.]");
13756
13765
  continue;
13757
13766
  }
13767
+ emitter.emit({ type: "debug", message: `[LOOP] No nudge needed (hasUsedTools=${hasUsedTools}), breaking loop. Agent will terminate.` });
13758
13768
  break;
13759
13769
  }
13770
+ emitter.emit({ type: "debug", message: `[LOOP] Tool calls: ${completedToolCalls.map((tc) => tc.function.name).join(", ")}` });
13771
+ hasUsedTools = true;
13760
13772
  nudgedToContinue = false;
13761
13773
  for (const tc of completedToolCalls) {
13762
13774
  if (stdin.isCancelled()) {
@@ -13777,12 +13789,15 @@ ${IMPLEMENTATION_MODE_PROMPT2}`);
13777
13789
  emitter.emit({ type: "tool-call-start", id: tc.id, name: tc.function.name, args: parsedArgs });
13778
13790
  const toolDef = registry.get(tc.function.name);
13779
13791
  if (toolDef?.hitl) {
13792
+ emitter.emit({ type: "debug", message: `[HITL] Requesting HITL for tool=${tc.function.name} safeId=${hitl.safeId(tc.id)}` });
13780
13793
  emitter.emit({ type: "hitl-request", id: tc.id, safe_id: hitl.safeId(tc.id), tool: tc.function.name, args: parsedArgs });
13781
13794
  const response = await hitl.waitForResponse(tc.id, async () => {
13782
13795
  for (const cmd of stdin.drain()) {
13783
13796
  if (cmd.type === "hitl-response") {
13784
13797
  await hitl.writeResponse(cmd.id, { decision: cmd.decision, data: cmd.data });
13785
13798
  } else if (cmd.type === "cancel") {
13799
+ } else {
13800
+ stdin.requeue(cmd);
13786
13801
  }
13787
13802
  }
13788
13803
  });
@@ -13795,7 +13810,9 @@ ${IMPLEMENTATION_MODE_PROMPT2}`);
13795
13810
  if (response.decision === "edit" && response.data && typeof response.data === "object") {
13796
13811
  parsedArgs = { ...parsedArgs, ...response.data };
13797
13812
  }
13813
+ emitter.emit({ type: "debug", message: `[HITL] Got response: decision=${response.decision} dataKeys=${response.data ? Object.keys(response.data).join(",") : "none"}` });
13798
13814
  emitter.emit({ type: "hitl-response", id: tc.id, decision: response.decision, data: response.data });
13815
+ nudgedToContinue = false;
13799
13816
  }
13800
13817
  const toolCtx = {
13801
13818
  emitter,
@@ -13831,10 +13848,12 @@ ${PLAN_MODE_SYSTEM_PROMPT2}`);
13831
13848
  });
13832
13849
  }
13833
13850
  stdin.stop();
13851
+ const exitReason = iteration >= maxIterations ? "max_iterations" : "complete";
13852
+ emitter.emit({ type: "debug", message: `[SESSION-END] reason=${exitReason} iteration=${iteration}/${maxIterations} mode=${currentMode}` });
13834
13853
  emitter.emit({
13835
13854
  type: "session-end",
13836
13855
  usage: context.totalUsage(),
13837
- exit_reason: iteration >= maxIterations ? "max_iterations" : "complete"
13856
+ exit_reason: exitReason
13838
13857
  });
13839
13858
  }
13840
13859
  function toolToActivity(name, args) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strayl/agent",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"