@oh-my-pi/pi-agent-core 16.5.1 → 16.5.2

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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [16.5.2] - 2026-07-14
6
+
7
+ ### Fixed
8
+
9
+ - Improved session deadline abort signals to carry structured cancellation reasons, enabling timeout-aware tools to correctly classify deadline cancellations.
10
+ - Fixed an issue where completed tool executions were incorrectly marked as skipped (clobbering their actual results) if a user message was queued while the tool was in flight.
11
+
5
12
  ## [16.5.1] - 2026-07-14
6
13
 
7
14
  ### Fixed
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-agent-core",
4
- "version": "16.5.1",
4
+ "version": "16.5.2",
5
5
  "description": "General-purpose agent with transport abstraction, state management, and attachment support",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -35,12 +35,12 @@
35
35
  "fmt": "biome format --write ."
36
36
  },
37
37
  "dependencies": {
38
- "@oh-my-pi/pi-ai": "16.5.1",
39
- "@oh-my-pi/pi-catalog": "16.5.1",
40
- "@oh-my-pi/pi-natives": "16.5.1",
41
- "@oh-my-pi/pi-utils": "16.5.1",
42
- "@oh-my-pi/pi-wire": "16.5.1",
43
- "@oh-my-pi/snapcompact": "16.5.1",
38
+ "@oh-my-pi/pi-ai": "16.5.2",
39
+ "@oh-my-pi/pi-catalog": "16.5.2",
40
+ "@oh-my-pi/pi-natives": "16.5.2",
41
+ "@oh-my-pi/pi-utils": "16.5.2",
42
+ "@oh-my-pi/pi-wire": "16.5.2",
43
+ "@oh-my-pi/snapcompact": "16.5.2",
44
44
  "@opentelemetry/api": "^1.9.1"
45
45
  },
46
46
  "devDependencies": {
package/src/agent-loop.ts CHANGED
@@ -766,12 +766,13 @@ async function runLoopBody(
766
766
  let deadlineTimer: Timer | undefined;
767
767
  if (config.deadline !== undefined) {
768
768
  const deadlineAbortController = new AbortController();
769
+ const deadlineReason = new DOMException("Deadline exceeded", "TimeoutError");
769
770
  const delay = config.deadline - Date.now();
770
771
  if (delay <= 0) {
771
- deadlineAbortController.abort("Deadline exceeded");
772
+ deadlineAbortController.abort(deadlineReason);
772
773
  } else {
773
774
  deadlineTimer = setTimeout(() => {
774
- deadlineAbortController.abort("Deadline exceeded");
775
+ deadlineAbortController.abort(deadlineReason);
775
776
  }, delay);
776
777
  }
777
778
  signal = signal ? AbortSignal.any([signal, deadlineAbortController.signal]) : deadlineAbortController.signal;
@@ -2132,19 +2133,21 @@ async function executeToolCalls(
2132
2133
 
2133
2134
  const interrupted = interruptState.triggered;
2134
2135
  const perToolAborted = record.signal.aborted;
2135
- const abortedDuringExecution = perToolAborted && isError;
2136
- if (interrupted && perToolAborted && isError) {
2137
- // This tool's own signal fired AND it failed it was cut off before producing
2138
- // a usable result, so report it as skipped.
2136
+ const abortedDuringExecution = perToolAborted && isError && !completedToolExecution;
2137
+ if (interrupted && perToolAborted && isError && !completedToolExecution) {
2138
+ // This tool's own signal fired AND it failed to produce a result: `tool.execute()`
2139
+ // never returned (it threw on the abort), so it was genuinely cut off before
2140
+ // producing usable output. Report it as skipped.
2139
2141
  record.skipped = true;
2140
2142
  emitToolResult(record, createSkippedToolResult(interruptState.source), true);
2141
2143
  } else {
2142
- // No interrupt on this signal, or the tool finished (successfully or with a
2143
- // genuine error) before the interrupt landed. Keep its real result: a completed
2144
- // tool already ran its side effects, so the model must see what actually
2145
- // happened rather than a false "skipped". A peer-IRC interrupt on the batch
2146
- // leaves non-interruptible tools' signals untouched their genuine errors
2147
- // survive here instead of being clobbered into "skipped".
2144
+ // No interrupt on this signal, or the tool finished before the interrupt landed
2145
+ // (`completedToolExecution`) even if the signal aborted around completion. Keep
2146
+ // its real result: a completed tool already ran its side effects, so the model must
2147
+ // see what actually happened (a genuine non-zero exit / error result) rather than a
2148
+ // false "skipped" that discards work the tool performed (#4752). A peer-IRC interrupt
2149
+ // on the batch leaves non-interruptible tools' signals untouched — their genuine
2150
+ // errors survive here too.
2148
2151
  emitToolResult(record, result, isError);
2149
2152
  }
2150
2153