@oh-my-pi/pi-agent-core 1.337.1 → 1.341.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-agent-core",
3
- "version": "1.337.1",
3
+ "version": "1.341.0",
4
4
  "description": "General-purpose agent with transport abstraction, state management, and attachment support",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
package/src/agent-loop.ts CHANGED
@@ -156,6 +156,7 @@ async function runLoop(
156
156
  stream,
157
157
  config.getQueuedMessages,
158
158
  config.getToolContext,
159
+ config.interruptMode,
159
160
  );
160
161
  toolResults.push(...toolExecution.toolResults);
161
162
  queuedAfterTools = toolExecution.queuedMessages ?? null;
@@ -282,6 +283,7 @@ async function executeToolCalls(
282
283
  stream: EventStream<AgentEvent, AgentMessage[]>,
283
284
  getQueuedMessages?: AgentLoopConfig["getQueuedMessages"],
284
285
  getToolContext?: AgentLoopConfig["getToolContext"],
286
+ interruptMode?: AgentLoopConfig["interruptMode"],
285
287
  ): Promise<{ toolResults: ToolResultMessage[]; queuedMessages?: AgentMessage[] }> {
286
288
  const toolCalls = assistantMessage.content.filter((c) => c.type === "toolCall");
287
289
  const results: ToolResultMessage[] = [];
@@ -353,7 +355,8 @@ async function executeToolCalls(
353
355
  stream.push({ type: "message_end", message: toolResultMessage });
354
356
 
355
357
  // Check for queued messages - skip remaining tools if user interrupted
356
- if (getQueuedMessages) {
358
+ // Only interrupt mid-execution if interruptMode is "immediate" (default)
359
+ if (interruptMode !== "wait" && getQueuedMessages) {
357
360
  const queued = await getQueuedMessages();
358
361
  if (queued.length > 0) {
359
362
  queuedMessages = queued;
package/src/agent.ts CHANGED
@@ -52,6 +52,12 @@ export interface AgentOptions {
52
52
  */
53
53
  queueMode?: "all" | "one-at-a-time";
54
54
 
55
+ /**
56
+ * Interrupt mode: "immediate" = check queue after each tool (interrupt remaining),
57
+ * "wait" = only process queue after turn completes
58
+ */
59
+ interruptMode?: "immediate" | "wait";
60
+
55
61
  /**
56
62
  * Custom stream function (for proxy backends, etc.). Default uses streamSimple.
57
63
  */
@@ -88,6 +94,7 @@ export class Agent {
88
94
  private transformContext?: (messages: AgentMessage[], signal?: AbortSignal) => Promise<AgentMessage[]>;
89
95
  private messageQueue: AgentMessage[] = [];
90
96
  private queueMode: "all" | "one-at-a-time";
97
+ private interruptMode: "immediate" | "wait";
91
98
  public streamFn: StreamFn;
92
99
  public getApiKey?: (provider: string) => Promise<string | undefined> | string | undefined;
93
100
  private getToolContext?: () => AgentToolContext | undefined;
@@ -99,6 +106,7 @@ export class Agent {
99
106
  this.convertToLlm = opts.convertToLlm || defaultConvertToLlm;
100
107
  this.transformContext = opts.transformContext;
101
108
  this.queueMode = opts.queueMode || "one-at-a-time";
109
+ this.interruptMode = opts.interruptMode || "immediate";
102
110
  this.streamFn = opts.streamFn || streamSimple;
103
111
  this.getApiKey = opts.getApiKey;
104
112
  this.getToolContext = opts.getToolContext;
@@ -134,6 +142,14 @@ export class Agent {
134
142
  return this.queueMode;
135
143
  }
136
144
 
145
+ setInterruptMode(mode: "immediate" | "wait") {
146
+ this.interruptMode = mode;
147
+ }
148
+
149
+ getInterruptMode(): "immediate" | "wait" {
150
+ return this.interruptMode;
151
+ }
152
+
137
153
  setTools(t: AgentTool<any>[]) {
138
154
  this._state.tools = t;
139
155
  }
@@ -256,6 +272,7 @@ export class Agent {
256
272
  transformContext: this.transformContext,
257
273
  getApiKey: this.getApiKey,
258
274
  getToolContext: this.getToolContext,
275
+ interruptMode: this.interruptMode,
259
276
  getQueuedMessages: async () => {
260
277
  if (this.queueMode === "one-at-a-time") {
261
278
  if (this.messageQueue.length > 0) {
package/src/types.ts CHANGED
@@ -82,6 +82,14 @@ export interface AgentLoopConfig extends SimpleStreamOptions {
82
82
  */
83
83
  getQueuedMessages?: () => Promise<AgentMessage[]>;
84
84
 
85
+ /**
86
+ * Controls when queued messages interrupt tool execution.
87
+ *
88
+ * - "immediate" (default): Check queue after each tool, interrupt remaining tools if messages exist
89
+ * - "wait": Only process queued messages after the entire turn completes
90
+ */
91
+ interruptMode?: "immediate" | "wait";
92
+
85
93
  /**
86
94
  * Provides tool execution context, resolved per tool call.
87
95
  * Use for late-bound UI or session state access.