@oh-my-pi/pi-agent-core 17.2.12 → 17.2.13

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,12 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [17.2.13] - 2026-08-11
6
+
7
+ ### Fixed
8
+
9
+ - Fixed Cursor sessions re-executing settled tools when an owned dialect projector rebuilds toolCall blocks: `snapshotAssistantContentBlock` now copies `kCursorExecResolved` explicitly so agent-loop still skips already-settled calls.
10
+
5
11
  ## [17.2.10] - 2026-08-06
6
12
 
7
13
  ### Fixed
@@ -639,6 +639,11 @@ export type ToolApprovalDecision = ToolTier | {
639
639
  reason?: string;
640
640
  override?: boolean;
641
641
  policy?: "allow" | "deny" | "prompt";
642
+ /** User-policy key for this decision. When set, `tools.approval.<policyKey>`
643
+ * is consulted instead of `tools.approval.<tool.name>`. Lets a dispatcher
644
+ * tool (e.g. `write` for an `xd://` device call) scope user allow/deny/
645
+ * prompt policies to the tool it dispatches into. */
646
+ policyKey?: string;
642
647
  };
643
648
  export type ToolApproval = ToolApprovalDecision | ((args: unknown) => ToolApprovalDecision);
644
649
  /**
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": "17.2.12",
4
+ "version": "17.2.13",
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,16 +35,16 @@
35
35
  "fmt": "biome format --write ."
36
36
  },
37
37
  "dependencies": {
38
- "@oh-my-pi/pi-ai": "17.2.12",
39
- "@oh-my-pi/pi-catalog": "17.2.12",
40
- "@oh-my-pi/pi-natives": "17.2.12",
41
- "@oh-my-pi/pi-utils": "17.2.12",
42
- "@oh-my-pi/pi-wire": "17.2.12",
43
- "@oh-my-pi/snapcompact": "17.2.12",
38
+ "@oh-my-pi/pi-ai": "17.2.13",
39
+ "@oh-my-pi/pi-catalog": "17.2.13",
40
+ "@oh-my-pi/pi-natives": "17.2.13",
41
+ "@oh-my-pi/pi-utils": "17.2.13",
42
+ "@oh-my-pi/pi-wire": "17.2.13",
43
+ "@oh-my-pi/snapcompact": "17.2.13",
44
44
  "@opentelemetry/api": "^1.9.1"
45
45
  },
46
46
  "devDependencies": {
47
- "@oh-my-pi/omptype": "17.2.12",
47
+ "@oh-my-pi/omptype": "17.2.13",
48
48
  "@opentelemetry/context-async-hooks": "^2.9.0",
49
49
  "@opentelemetry/sdk-trace-base": "^2.9.0",
50
50
  "@types/bun": "^1.3.14"
package/src/agent-loop.ts CHANGED
@@ -31,7 +31,11 @@ import {
31
31
  wrapInbandToolStream,
32
32
  } from "@oh-my-pi/pi-ai/dialect";
33
33
  import * as AIError from "@oh-my-pi/pi-ai/error";
34
- import { type CursorExecResolvedCarrier, kCursorExecResolved } from "@oh-my-pi/pi-ai/utils/block-symbols";
34
+ import {
35
+ type CursorExecResolvedCarrier,
36
+ copyCursorExecResolved,
37
+ kCursorExecResolved,
38
+ } from "@oh-my-pi/pi-ai/utils/block-symbols";
35
39
  import {
36
40
  createHarmonyAuditEvent,
37
41
  detectHarmonyLeakInAssistantMessage,
@@ -356,12 +360,18 @@ function snapshotAssistantContentBlock(block: AssistantContentBlock): AssistantC
356
360
  return { ...block, block: structuredCloneJSON(block.block) };
357
361
  case "fallback":
358
362
  return { ...block, from: { ...block.from }, to: { ...block.to } };
359
- case "toolCall":
360
- return {
363
+ case "toolCall": {
364
+ const snap = {
361
365
  ...block,
362
366
  arguments: structuredCloneJSON(block.arguments),
363
367
  providerMetadata: snapshotToolCallProviderMetadata(block.providerMetadata),
364
368
  };
369
+ // Object spread copies enumerable symbols in Bun, but the Cursor
370
+ // exec-resolved marker is load-bearing for skip-on-dispatch — copy
371
+ // it explicitly so a projector/snapshot path cannot drop it.
372
+ copyCursorExecResolved(snap, block);
373
+ return snap;
374
+ }
365
375
  }
366
376
  }
367
377
 
package/src/types.ts CHANGED
@@ -728,7 +728,17 @@ export type ToolLoadMode = "essential" | "discoverable";
728
728
  */
729
729
  export type ToolApprovalDecision =
730
730
  | ToolTier
731
- | { tier: ToolTier; reason?: string; override?: boolean; policy?: "allow" | "deny" | "prompt" };
731
+ | {
732
+ tier: ToolTier;
733
+ reason?: string;
734
+ override?: boolean;
735
+ policy?: "allow" | "deny" | "prompt";
736
+ /** User-policy key for this decision. When set, `tools.approval.<policyKey>`
737
+ * is consulted instead of `tools.approval.<tool.name>`. Lets a dispatcher
738
+ * tool (e.g. `write` for an `xd://` device call) scope user allow/deny/
739
+ * prompt policies to the tool it dispatches into. */
740
+ policyKey?: string;
741
+ };
732
742
  export type ToolApproval = ToolApprovalDecision | ((args: unknown) => ToolApprovalDecision);
733
743
 
734
744
  /**