@visorcraft/idlehands 2.2.10 → 2.2.12

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/agent.js CHANGED
@@ -1676,10 +1676,10 @@ export async function createSession(opts) {
1676
1676
  const hasOnToolResult = Boolean(hookObj.onToolResult);
1677
1677
  const hasOnToolLoop = Boolean(hookObj.onToolLoop);
1678
1678
  const hasOnTurnEnd = Boolean(hookObj.onTurnEnd);
1679
- const emitToolCall = async (id, name, args) => {
1679
+ const emitToolCall = async (id, name, args, phase = 'executing') => {
1680
1680
  if (!hasOnToolCall && !hooksEnabled)
1681
1681
  return;
1682
- const call = { id, name, args };
1682
+ const call = { id, name, args, phase };
1683
1683
  if (hasOnToolCall)
1684
1684
  hookObj.onToolCall?.(call);
1685
1685
  if (hooksEnabled) {
@@ -1993,6 +1993,7 @@ export async function createSession(opts) {
1993
1993
  const toolLoopWarningKeys = new Set();
1994
1994
  let forceToollessRecoveryTurn = false;
1995
1995
  let toollessRecoveryUsed = false;
1996
+ const streamedToolCallPreviews = new Set();
1996
1997
  // ── Security: credential leak detection + prompt injection guard ──
1997
1998
  const leakDetector = new LeakDetector();
1998
1999
  const promptGuard = new PromptGuard('warn');
@@ -2356,6 +2357,32 @@ export async function createSession(opts) {
2356
2357
  requestId: `r${reqCounter}`,
2357
2358
  onToken: hookObj.onToken,
2358
2359
  onFirstDelta,
2360
+ onToolCallDelta: (delta) => {
2361
+ const name = typeof delta?.name === 'string' ? delta.name : '';
2362
+ if (!name)
2363
+ return;
2364
+ const id = typeof delta?.id === 'string' && delta.id.trim().length
2365
+ ? delta.id
2366
+ : `stream_call_${delta.index}`;
2367
+ const previewKey = `${turns}:${id}:${name}`;
2368
+ if (streamedToolCallPreviews.has(previewKey))
2369
+ return;
2370
+ streamedToolCallPreviews.add(previewKey);
2371
+ let parsedArgs = {};
2372
+ const rawArgs = typeof delta.argumentsSoFar === 'string' ? delta.argumentsSoFar.trim() : '';
2373
+ if (rawArgs) {
2374
+ try {
2375
+ const parsed = parseJsonArgs(rawArgs);
2376
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
2377
+ parsedArgs = parsed;
2378
+ }
2379
+ }
2380
+ catch {
2381
+ // partial JSON chunks are expected during streaming
2382
+ }
2383
+ }
2384
+ void emitToolCall(id, name, parsedArgs, 'planned');
2385
+ },
2359
2386
  };
2360
2387
  if (primaryUsesRuntimeModel && primaryRoute?.model) {
2361
2388
  // Runtime-native routing: lane model/fallbacks reference runtime model IDs.