@oh-my-pi/pi-agent-core 15.10.11 → 15.10.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/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [15.10.12] - 2026-06-10
6
+
7
+ ### Added
8
+
9
+ - Added `AgentLoopConfig.getDisableReasoning` so callers can override `disableReasoning` per LLM call, mirroring `getReasoning`.
10
+ - Added `transformProviderContext` to `AgentOptions`/`AgentLoopConfig`: an optional hook applied to the assembled provider context after conversion, normalization, and append-only handling, but before telemetry capture and provider send.
11
+
12
+ ### Fixed
13
+
14
+ - Fixed `Agent` runs so explicit reasoning disablement is forwarded to provider stream options and re-resolved per continuation, keeping mid-run thinking-off changes in sync with the next provider request.
15
+
5
16
  ## [15.10.11] - 2026-06-10
6
17
 
7
18
  ### Changed
@@ -10,6 +21,7 @@
10
21
  - Catalog imports moved to the new `@oh-my-pi/pi-catalog` package: subpath imports (`calculateCost`, Codex wire constants) plus catalog values previously taken from the `@oh-my-pi/pi-ai` root (`getBundledModel`, `clampThinkingLevelForModel`), which pi-ai no longer re-exports; type-only `Model`/`Api`/`Effort` imports from pi-ai are unchanged
11
22
 
12
23
  ## [15.10.8] - 2026-06-09
24
+
13
25
  ### Added
14
26
 
15
27
  - Added optional `fetch` overrides to `SummaryOptions` and `compact`/`generateSummary` so remote compaction can use custom HTTP clients
@@ -18,6 +30,7 @@
18
30
  - Added the upstream provider that served a request (`AssistantMessage.upstreamProvider`, e.g. OpenRouter's routed provider) as a `pi.gen_ai.response.upstream_provider` chat-span telemetry attribute, alongside the existing response id and time-to-first-chunk.
19
31
 
20
32
  ## [15.10.5] - 2026-06-08
33
+
21
34
  ### Removed
22
35
 
23
36
  - Removed the `maxToolCallsPerTurn` option from `AgentOptions` and `AgentLoopConfig`, so assistant turns are no longer capped after a configured number of completed tool calls
@@ -55,7 +68,6 @@
55
68
  - Removed stale synthetic user-message tag filters from OpenAI remote compaction output preservation; developer messages are now dropped by role instead.
56
69
  - Tool executions now receive the active turn `AbortSignal` unconditionally.
57
70
 
58
-
59
71
  ## [15.10.2] - 2026-06-08
60
72
 
61
73
  ### Fixed
@@ -87,6 +99,7 @@
87
99
  - Surfaced Anthropic stream failures whose message starts with `Output blocked by conten` as normal assistant error lifecycle events, so interactive clients render content-filter blocks instead of silently dropping the streaming bubble at `agent_end`.
88
100
 
89
101
  ## [15.8.3] - 2026-06-03
102
+
90
103
  ### Added
91
104
 
92
105
  - Added `getReadToolPath(context)` to `@oh-my-pi/pi-agent-core/compaction/tool-protection` to extract a paired `read` tool call's `path` for embedders building read-targeted protection matchers
@@ -651,4 +664,4 @@ Initial release under @oh-my-pi scope. See previous releases at [badlogic/pi-mon
651
664
 
652
665
  - `Agent` constructor now has all options optional (empty options use defaults).
653
666
 
654
- - `queueMessage()` is now synchronous (no longer returns a Promise).
667
+ - `queueMessage()` is now synchronous (no longer returns a Promise).
@@ -1,4 +1,4 @@
1
- import { type ApiKeyResolveContext, type AssistantMessage, type AssistantMessageEvent, type CursorExecHandlers, type CursorToolResultHandler, type Effort, type ImageContent, type Message, type Model, type ProviderSessionState, type ServiceTier, type SimpleStreamOptions, type ThinkingBudgets, type ToolChoice } from "@oh-my-pi/pi-ai";
1
+ import { type ApiKeyResolveContext, type AssistantMessage, type AssistantMessageEvent, type Context, type CursorExecHandlers, type CursorToolResultHandler, type Effort, type ImageContent, type Message, type Model, type ProviderSessionState, type ServiceTier, type SimpleStreamOptions, type ThinkingBudgets, type ToolChoice } from "@oh-my-pi/pi-ai";
2
2
  import type { AppendOnlyContextManager } from "./append-only-context";
3
3
  import type { HarmonyAuditEvent } from "./harmony-leak";
4
4
  import type { AgentEvent, AgentLoopConfig, AgentMessage, AgentState, AgentTool, AgentToolContext, AsideMessage, StreamFn, ToolCallContext } from "./types";
@@ -17,6 +17,11 @@ export interface AgentOptions {
17
17
  * Use for context pruning, injecting external context, etc.
18
18
  */
19
19
  transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;
20
+ /**
21
+ * Optional transform applied after provider context assembly and before
22
+ * telemetry capture/provider send.
23
+ */
24
+ transformProviderContext?: (context: Context) => Context;
20
25
  /**
21
26
  * Steering mode: "all" = send all steering messages at once, "one-at-a-time" = one per turn
22
27
  */
@@ -294,6 +299,7 @@ export declare class Agent {
294
299
  setSystemPrompt(v: string[]): void;
295
300
  setModel(m: Model): void;
296
301
  setThinkingLevel(l: Effort | undefined): void;
302
+ setDisableReasoning(disabled: boolean): void;
297
303
  setSteeringMode(mode: "all" | "one-at-a-time"): void;
298
304
  getSteeringMode(): "all" | "one-at-a-time";
299
305
  setFollowUpMode(mode: "all" | "one-at-a-time"): void;
@@ -4,10 +4,10 @@
4
4
  * Pure functions for compaction logic. The session manager handles I/O,
5
5
  * and after compaction the session is reloaded.
6
6
  */
7
- import { type FetchImpl, type MessageAttribution, type Model, type Usage } from "@oh-my-pi/pi-ai";
7
+ import { type FetchImpl, type MessageAttribution, type Model, type Tool, type Usage } from "@oh-my-pi/pi-ai";
8
8
  import { type AgentTelemetry } from "../telemetry";
9
9
  import { ThinkingLevel } from "../thinking";
10
- import type { AgentMessage, AgentTool } from "../types";
10
+ import type { AgentMessage } from "../types";
11
11
  import type { SessionEntry } from "./entries";
12
12
  import { type ConvertToLlm } from "./messages";
13
13
  import { type FileOperations } from "./utils";
@@ -133,7 +133,7 @@ export interface HandoffOptions {
133
133
  /** Live agent system prompt — passed verbatim so providers hit the cached prefix. */
134
134
  systemPrompt: string[];
135
135
  /** Live agent tool list — same purpose. Forced to `toolChoice: "none"`. */
136
- tools?: AgentTool<any>[];
136
+ tools?: Tool[];
137
137
  customInstructions?: string;
138
138
  convertToLlm?: ConvertToLlm;
139
139
  initiatorOverride?: MessageAttribution;
@@ -1,4 +1,4 @@
1
- import type { ApiKeyResolveContext, AssistantMessage, AssistantMessageEvent, AssistantMessageEventStream, Effort, ImageContent, Message, Model, SimpleStreamOptions, Static, streamSimple, TextContent, Tool, ToolChoice, ToolResultMessage, TSchema } from "@oh-my-pi/pi-ai";
1
+ import type { ApiKeyResolveContext, AssistantMessage, AssistantMessageEvent, AssistantMessageEventStream, Context, Effort, ImageContent, Message, Model, SimpleStreamOptions, Static, streamSimple, TextContent, Tool, ToolChoice, ToolResultMessage, TSchema } from "@oh-my-pi/pi-ai";
2
2
  import type { AppendOnlyContextManager } from "./append-only-context";
3
3
  import type { HarmonyAuditEvent } from "./harmony-leak";
4
4
  import type { AgentRunCoverage, AgentRunSummary } from "./run-collector";
@@ -79,6 +79,12 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
79
79
  * ```
80
80
  */
81
81
  transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;
82
+ /**
83
+ * Optional transform applied to the final provider context after conversion,
84
+ * normalization, and append-only context handling, but before telemetry capture
85
+ * and provider send.
86
+ */
87
+ transformProviderContext?: (context: Context) => Context;
82
88
  /**
83
89
  * Resolves an API key dynamically for each LLM call.
84
90
  *
@@ -171,6 +177,14 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
171
177
  * the next model call instead of waiting for the next prompt.
172
178
  */
173
179
  getReasoning?: () => Effort | undefined;
180
+ /**
181
+ * Dynamic reasoning-disable override, resolved per LLM call. When set,
182
+ * its return value overrides the static `disableReasoning` from
183
+ * `SimpleStreamOptions` for that request. Pair with `getReasoning` so
184
+ * mid-run transitions into and out of the explicit `off` state propagate
185
+ * to the next provider call.
186
+ */
187
+ getDisableReasoning?: () => boolean | undefined;
174
188
  /**
175
189
  * Called after a tool call has been validated and is about to execute.
176
190
  *
@@ -307,6 +321,7 @@ export interface AgentState {
307
321
  systemPrompt: string[];
308
322
  model: Model;
309
323
  thinkingLevel?: Effort;
324
+ disableReasoning?: boolean;
310
325
  tools: AgentTool<any>[];
311
326
  messages: AgentMessage[];
312
327
  isStreaming: boolean;
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": "15.10.11",
4
+ "version": "15.10.12",
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,10 +35,10 @@
35
35
  "fmt": "biome format --write ."
36
36
  },
37
37
  "dependencies": {
38
- "@oh-my-pi/pi-ai": "15.10.11",
39
- "@oh-my-pi/pi-catalog": "15.10.11",
40
- "@oh-my-pi/pi-natives": "15.10.11",
41
- "@oh-my-pi/pi-utils": "15.10.11",
38
+ "@oh-my-pi/pi-ai": "15.10.12",
39
+ "@oh-my-pi/pi-catalog": "15.10.12",
40
+ "@oh-my-pi/pi-natives": "15.10.12",
41
+ "@oh-my-pi/pi-utils": "15.10.12",
42
42
  "@opentelemetry/api": "^1.9.1"
43
43
  },
44
44
  "devDependencies": {
package/src/agent-loop.ts CHANGED
@@ -829,6 +829,9 @@ async function streamAssistantResponse(
829
829
  tools: normalizeTools(context.tools, !!config.intentTracing),
830
830
  };
831
831
  }
832
+ if (config.transformProviderContext) {
833
+ llmContext = config.transformProviderContext(llmContext);
834
+ }
832
835
 
833
836
  const streamFunction = streamFn || streamSimple;
834
837
 
@@ -845,6 +848,7 @@ async function streamAssistantResponse(
845
848
 
846
849
  const dynamicToolChoice = config.getToolChoice?.();
847
850
  const dynamicReasoning = config.getReasoning?.();
851
+ const dynamicDisableReasoning = config.getDisableReasoning?.();
848
852
  const harmonyMitigationEnabled = isHarmonyLeakMitigationTarget(config.model);
849
853
  const harmonyAbortController = harmonyMitigationEnabled ? new AbortController() : undefined;
850
854
  const requestSignal = harmonyAbortController
@@ -856,6 +860,7 @@ async function streamAssistantResponse(
856
860
  harmonyRetryAttempt > 0 && config.temperature !== undefined ? config.temperature + 0.05 : config.temperature;
857
861
  const effectiveToolChoice = dynamicToolChoice ?? config.toolChoice;
858
862
  const effectiveReasoning = dynamicReasoning ?? config.reasoning;
863
+ const effectiveDisableReasoning = dynamicDisableReasoning ?? config.disableReasoning;
859
864
 
860
865
  const chatStepNumber = stepCounter.count;
861
866
  stepCounter.count += 1;
@@ -916,6 +921,7 @@ async function streamAssistantResponse(
916
921
  metadata: resolvedMetadata,
917
922
  toolChoice: effectiveToolChoice,
918
923
  reasoning: effectiveReasoning,
924
+ disableReasoning: effectiveDisableReasoning,
919
925
  temperature: effectiveTemperature,
920
926
  signal: requestSignal,
921
927
  onResponse: captureOnResponse,
package/src/agent.ts CHANGED
@@ -6,6 +6,7 @@ import {
6
6
  type ApiKeyResolveContext,
7
7
  type AssistantMessage,
8
8
  type AssistantMessageEvent,
9
+ type Context,
9
10
  type CursorExecHandlers,
10
11
  type CursorToolResultHandler,
11
12
  type Effort,
@@ -93,6 +94,12 @@ export interface AgentOptions {
93
94
  */
94
95
  transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;
95
96
 
97
+ /**
98
+ * Optional transform applied after provider context assembly and before
99
+ * telemetry capture/provider send.
100
+ */
101
+ transformProviderContext?: (context: Context) => Context;
102
+
96
103
  /**
97
104
  * Steering mode: "all" = send all steering messages at once, "one-at-a-time" = one per turn
98
105
  */
@@ -265,6 +272,7 @@ export class Agent {
265
272
  systemPrompt: [],
266
273
  model: getBundledModel("google", "gemini-2.5-flash-lite-preview-06-17"),
267
274
  thinkingLevel: undefined,
275
+ disableReasoning: false,
268
276
  tools: [],
269
277
  messages: [],
270
278
  isStreaming: false,
@@ -277,6 +285,7 @@ export class Agent {
277
285
  #abortController?: AbortController;
278
286
  #convertToLlm: (messages: AgentMessage[]) => Message[] | Promise<Message[]>;
279
287
  #transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;
288
+ #transformProviderContext?: (context: Context) => Context;
280
289
  #steeringQueue: AgentMessage[] = [];
281
290
  #followUpQueue: AgentMessage[] = [];
282
291
  #steeringMode: "all" | "one-at-a-time";
@@ -375,6 +384,7 @@ export class Agent {
375
384
  this.afterToolCall = opts.afterToolCall;
376
385
  this.#telemetry = opts.telemetry;
377
386
  this.#appendOnlyContext = opts.appendOnlyContext;
387
+ this.#transformProviderContext = opts.transformProviderContext;
378
388
  }
379
389
 
380
390
  /**
@@ -658,6 +668,10 @@ export class Agent {
658
668
  this.#state.thinkingLevel = l;
659
669
  }
660
670
 
671
+ setDisableReasoning(disabled: boolean) {
672
+ this.#state.disableReasoning = disabled;
673
+ }
674
+
661
675
  setSteeringMode(mode: "all" | "one-at-a-time") {
662
676
  this.#steeringMode = mode;
663
677
  }
@@ -942,6 +956,7 @@ export class Agent {
942
956
  const config: AgentLoopConfig = {
943
957
  model,
944
958
  reasoning,
959
+ disableReasoning: this.#state.disableReasoning,
945
960
  temperature: this.#temperature,
946
961
  topP: this.#topP,
947
962
  topK: this.#topK,
@@ -961,6 +976,7 @@ export class Agent {
961
976
  kimiApiFormat: this.#kimiApiFormat,
962
977
  preferWebsockets: this.#preferWebsockets,
963
978
  convertToLlm: this.#convertToLlm,
979
+ transformProviderContext: this.#transformProviderContext,
964
980
  transformContext: this.#transformContext,
965
981
  onPayload: this.#onPayload,
966
982
  onResponse: this.#onResponse,
@@ -985,6 +1001,7 @@ export class Agent {
985
1001
  onHarmonyLeak: this.#onHarmonyLeak,
986
1002
  getToolChoice,
987
1003
  getReasoning: () => this.#state.thinkingLevel,
1004
+ getDisableReasoning: () => this.#state.disableReasoning,
988
1005
  getSteeringMessages: async () => {
989
1006
  if (skipInitialSteeringPoll) {
990
1007
  skipInitialSteeringPoll = false;
@@ -12,6 +12,7 @@ import {
12
12
  type Message,
13
13
  type MessageAttribution,
14
14
  type Model,
15
+ type Tool,
15
16
  type Usage,
16
17
  } from "@oh-my-pi/pi-ai";
17
18
  import { clampThinkingLevelForModel } from "@oh-my-pi/pi-catalog/model-thinking";
@@ -19,7 +20,7 @@ import { countTokens } from "@oh-my-pi/pi-natives";
19
20
  import { logger, prompt } from "@oh-my-pi/pi-utils";
20
21
  import { type AgentTelemetry, instrumentedCompleteSimple } from "../telemetry";
21
22
  import { ThinkingLevel } from "../thinking";
22
- import type { AgentMessage, AgentTool } from "../types";
23
+ import type { AgentMessage } from "../types";
23
24
  import type { CompactionEntry, SessionEntry } from "./entries";
24
25
  import { type ConvertToLlm, convertToLlm, createBranchSummaryMessage, createCustomMessage } from "./messages";
25
26
  import {
@@ -690,7 +691,7 @@ export interface HandoffOptions {
690
691
  /** Live agent system prompt — passed verbatim so providers hit the cached prefix. */
691
692
  systemPrompt: string[];
692
693
  /** Live agent tool list — same purpose. Forced to `toolChoice: "none"`. */
693
- tools?: AgentTool<any>[];
694
+ tools?: Tool[];
694
695
  customInstructions?: string;
695
696
  convertToLlm?: ConvertToLlm;
696
697
  initiatorOverride?: MessageAttribution;
package/src/types.ts CHANGED
@@ -3,6 +3,7 @@ import type {
3
3
  AssistantMessage,
4
4
  AssistantMessageEvent,
5
5
  AssistantMessageEventStream,
6
+ Context,
6
7
  Effort,
7
8
  ImageContent,
8
9
  Message,
@@ -107,6 +108,13 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
107
108
  */
108
109
  transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;
109
110
 
111
+ /**
112
+ * Optional transform applied to the final provider context after conversion,
113
+ * normalization, and append-only context handling, but before telemetry capture
114
+ * and provider send.
115
+ */
116
+ transformProviderContext?: (context: Context) => Context;
117
+
110
118
  /**
111
119
  * Resolves an API key dynamically for each LLM call.
112
120
  *
@@ -210,6 +218,15 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
210
218
  */
211
219
  getReasoning?: () => Effort | undefined;
212
220
 
221
+ /**
222
+ * Dynamic reasoning-disable override, resolved per LLM call. When set,
223
+ * its return value overrides the static `disableReasoning` from
224
+ * `SimpleStreamOptions` for that request. Pair with `getReasoning` so
225
+ * mid-run transitions into and out of the explicit `off` state propagate
226
+ * to the next provider call.
227
+ */
228
+ getDisableReasoning?: () => boolean | undefined;
229
+
213
230
  /**
214
231
  * Called after a tool call has been validated and is about to execute.
215
232
  *
@@ -358,6 +375,7 @@ export interface AgentState {
358
375
  systemPrompt: string[];
359
376
  model: Model;
360
377
  thinkingLevel?: Effort;
378
+ disableReasoning?: boolean;
361
379
  tools: AgentTool<any>[];
362
380
  messages: AgentMessage[]; // Can include attachments + custom message types
363
381
  isStreaming: boolean;