wave-agent-sdk 0.18.0 → 0.18.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.
@@ -63,7 +63,7 @@ export class ForkedAgentManager {
63
63
  try {
64
64
  if (entry.logStream && !entry.logStream.destroyed) {
65
65
  entry.logStream.write(`[${new Date().toISOString()}] Final response:\n${result}\n`);
66
- entry.logStream.write(`[${new Date().toISOString()}] Agent completed successfully\n`);
66
+ entry.logStream.write(`[${new Date().toISOString()}] Agent completed\n`);
67
67
  entry.logStream.end();
68
68
  }
69
69
  }
@@ -10,8 +10,18 @@ export interface MessageManagerCallbacks {
10
10
  onUsagesChange?: (usages: Usage[]) => void;
11
11
  onUserMessageAdded?: (params: UserMessageParams) => void;
12
12
  onAssistantMessageAdded?: (messageId: string) => void;
13
- onAssistantContentUpdated?: (messageId: string, chunk: string, accumulated: string) => void;
14
- onAssistantReasoningUpdated?: (messageId: string, chunk: string, accumulated: string) => void;
13
+ onAssistantContentUpdated?: (params: {
14
+ messageId: string;
15
+ chunk: string;
16
+ accumulated: string;
17
+ stage: "streaming" | "end";
18
+ }) => void;
19
+ onAssistantReasoningUpdated?: (params: {
20
+ messageId: string;
21
+ chunk: string;
22
+ accumulated: string;
23
+ stage: "streaming" | "end";
24
+ }) => void;
15
25
  onToolBlockUpdated?: (params: ToolBlockUpdateCallbackParams) => void;
16
26
  onErrorBlockAdded?: (error: string) => void;
17
27
  onCompactBlockAdded?: (content: string) => void;
@@ -147,6 +157,13 @@ export declare class MessageManager {
147
157
  * Trigger usage change callback with all usage data from assistant messages
148
158
  */
149
159
  triggerUsageChange(): void;
160
+ /**
161
+ * Finalize a streaming block of the given type by setting its stage to "end".
162
+ * Fires the corresponding incremental callback with chunk="" to signal finalization.
163
+ * Does NOT call onMessagesChange — the caller is responsible for that.
164
+ * Returns true if a block was finalized.
165
+ */
166
+ private finalizeStreamingBlock;
150
167
  /**
151
168
  * Update the current assistant message content during streaming
152
169
  * This method updates the last assistant message's content without creating a new message
@@ -158,16 +175,12 @@ export declare class MessageManager {
158
175
  * This method updates the last assistant message's reasoning content without creating a new message
159
176
  */
160
177
  updateCurrentMessageReasoning(newAccumulatedReasoning: string): void;
161
- /**
162
- * Public wrapper for finalizeCurrentStreamingBlocks.
163
- * Finalizes text/reasoning blocks after streaming completes (e.g. final response with no tools).
164
- */
165
- finalizeStreamingBlocks(): void;
166
178
  /**
167
179
  * Finalize streaming text/reasoning blocks by setting their stage to "end".
168
- * Called when a new block (e.g. tool) is appended during streaming.
180
+ * Called when a new block (e.g. tool) is appended during streaming, or when streaming completes.
181
+ * Fires incremental callbacks for each finalized block.
169
182
  */
170
- private finalizeCurrentStreamingBlocks;
183
+ finalizeStreamingBlocks(): void;
171
184
  /**
172
185
  * Remove the last user message from the conversation
173
186
  * Used for hook error handling when the user prompt needs to be erased
@@ -1 +1 @@
1
- {"version":3,"file":"messageManager.d.ts","sourceRoot":"","sources":["../../src/managers/messageManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"messageManager.d.ts","sourceRoot":"","sources":["../../src/managers/messageManager.ts"],"names":[],"mappings":"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"}
@@ -289,7 +289,7 @@ export class MessageManager {
289
289
  }
290
290
  updateToolBlock(params) {
291
291
  // Finalize any streaming text/reasoning blocks before adding/updating a tool block
292
- this.finalizeCurrentStreamingBlocks();
292
+ this.finalizeStreamingBlocks();
293
293
  const { messages: newMessages, messageId: resolvedMessageId } = updateToolBlockInMessage({
294
294
  messages: this.messages,
295
295
  ...params,
@@ -310,7 +310,7 @@ export class MessageManager {
310
310
  */
311
311
  addToolBlockToMessage(messageId, params) {
312
312
  // Finalize any streaming text/reasoning blocks before adding a tool block
313
- this.finalizeCurrentStreamingBlocks();
313
+ this.finalizeStreamingBlocks();
314
314
  const { messages: newMessages, toolBlockId } = addToolBlockToMessageInMessages(this.messages, messageId, params);
315
315
  this.setMessages(newMessages);
316
316
  this.callbacks.onToolBlockUpdated?.({
@@ -463,6 +463,38 @@ export class MessageManager {
463
463
  triggerUsageChange() {
464
464
  this.callbacks.onUsagesChange?.([...this._usages]);
465
465
  }
466
+ /**
467
+ * Finalize a streaming block of the given type by setting its stage to "end".
468
+ * Fires the corresponding incremental callback with chunk="" to signal finalization.
469
+ * Does NOT call onMessagesChange — the caller is responsible for that.
470
+ * Returns true if a block was finalized.
471
+ */
472
+ finalizeStreamingBlock(lastMessage, type) {
473
+ const index = lastMessage.blocks.findIndex((block) => block.type === type &&
474
+ block.stage === "streaming");
475
+ if (index < 0)
476
+ return false;
477
+ const block = lastMessage.blocks[index];
478
+ lastMessage.blocks[index] = {
479
+ type: block.type,
480
+ content: block.content,
481
+ stage: "end",
482
+ };
483
+ // Fire incremental callback to signal finalization
484
+ const callbackParams = {
485
+ messageId: lastMessage.id,
486
+ chunk: "",
487
+ accumulated: block.content,
488
+ stage: "end",
489
+ };
490
+ if (type === "text") {
491
+ this.callbacks.onAssistantContentUpdated?.(callbackParams);
492
+ }
493
+ else {
494
+ this.callbacks.onAssistantReasoningUpdated?.(callbackParams);
495
+ }
496
+ return true;
497
+ }
466
498
  /**
467
499
  * Update the current assistant message content during streaming
468
500
  * This method updates the last assistant message's content without creating a new message
@@ -475,16 +507,7 @@ export class MessageManager {
475
507
  if (lastMessage.role !== "assistant")
476
508
  return;
477
509
  // Finalize any streaming reasoning blocks before text content arrives
478
- const reasoningIndex = lastMessage.blocks.findIndex((block) => block.type === "reasoning" &&
479
- block.stage === "streaming");
480
- if (reasoningIndex >= 0) {
481
- const reasoningBlock = lastMessage.blocks[reasoningIndex];
482
- lastMessage.blocks[reasoningIndex] = {
483
- type: "reasoning",
484
- content: reasoningBlock.content,
485
- stage: "end",
486
- };
487
- }
510
+ this.finalizeStreamingBlock(lastMessage, "reasoning");
488
511
  // Get the current content to calculate the chunk
489
512
  const textBlockIndex = lastMessage.blocks.findIndex((block) => block.type === "text");
490
513
  const currentContent = textBlockIndex >= 0
@@ -509,7 +532,12 @@ export class MessageManager {
509
532
  });
510
533
  }
511
534
  // FR-001: Trigger callbacks with chunk and accumulated content
512
- this.callbacks.onAssistantContentUpdated?.(lastMessage.id, chunk, newAccumulatedContent);
535
+ this.callbacks.onAssistantContentUpdated?.({
536
+ messageId: lastMessage.id,
537
+ chunk,
538
+ accumulated: newAccumulatedContent,
539
+ stage: "streaming",
540
+ });
513
541
  // Note: Subagent-specific callbacks are now handled by SubagentManager
514
542
  this.callbacks.onMessagesChange?.([...this.messages]); // Still need to notify of changes
515
543
  }
@@ -524,16 +552,7 @@ export class MessageManager {
524
552
  if (lastMessage.role !== "assistant")
525
553
  return;
526
554
  // Finalize any streaming text blocks before reasoning content arrives
527
- const textIndex = lastMessage.blocks.findIndex((block) => block.type === "text" &&
528
- block.stage === "streaming");
529
- if (textIndex >= 0) {
530
- const textBlock = lastMessage.blocks[textIndex];
531
- lastMessage.blocks[textIndex] = {
532
- type: "text",
533
- content: textBlock.content,
534
- stage: "end",
535
- };
536
- }
555
+ this.finalizeStreamingBlock(lastMessage, "text");
537
556
  // Get the current reasoning content to calculate the chunk
538
557
  const reasoningBlockIndex = lastMessage.blocks.findIndex((block) => block.type === "reasoning");
539
558
  const currentReasoning = reasoningBlockIndex >= 0
@@ -558,37 +577,28 @@ export class MessageManager {
558
577
  });
559
578
  }
560
579
  // Trigger callbacks with chunk and accumulated reasoning content
561
- this.callbacks.onAssistantReasoningUpdated?.(lastMessage.id, chunk, newAccumulatedReasoning);
580
+ this.callbacks.onAssistantReasoningUpdated?.({
581
+ messageId: lastMessage.id,
582
+ chunk,
583
+ accumulated: newAccumulatedReasoning,
584
+ stage: "streaming",
585
+ });
562
586
  this.callbacks.onMessagesChange?.([...this.messages]); // Still need to notify of changes
563
587
  }
564
- /**
565
- * Public wrapper for finalizeCurrentStreamingBlocks.
566
- * Finalizes text/reasoning blocks after streaming completes (e.g. final response with no tools).
567
- */
568
- finalizeStreamingBlocks() {
569
- this.finalizeCurrentStreamingBlocks();
570
- }
571
588
  /**
572
589
  * Finalize streaming text/reasoning blocks by setting their stage to "end".
573
- * Called when a new block (e.g. tool) is appended during streaming.
590
+ * Called when a new block (e.g. tool) is appended during streaming, or when streaming completes.
591
+ * Fires incremental callbacks for each finalized block.
574
592
  */
575
- finalizeCurrentStreamingBlocks() {
593
+ finalizeStreamingBlocks() {
576
594
  if (this.messages.length === 0)
577
595
  return;
578
596
  const lastMessage = this.messages[this.messages.length - 1];
579
597
  if (lastMessage.role !== "assistant")
580
598
  return;
581
- const newBlocks = lastMessage.blocks.map((block) => {
582
- if ((block.type === "text" || block.type === "reasoning") &&
583
- block.stage === "streaming") {
584
- return { ...block, stage: "end" };
585
- }
586
- return block;
587
- });
588
- // Only update if something changed
589
- const changed = newBlocks.some((b, i) => b !== lastMessage.blocks[i]);
590
- if (changed) {
591
- lastMessage.blocks = newBlocks;
599
+ const textFinalized = this.finalizeStreamingBlock(lastMessage, "text");
600
+ const reasoningFinalized = this.finalizeStreamingBlock(lastMessage, "reasoning");
601
+ if (textFinalized || reasoningFinalized) {
592
602
  this.callbacks.onMessagesChange?.([...this.messages]);
593
603
  }
594
604
  }
@@ -16,9 +16,21 @@ export interface SubagentManagerCallbacks {
16
16
  /** Triggered when subagent creates assistant message */
17
17
  onSubagentAssistantMessageAdded?: (subagentId: string, messageId: string) => void;
18
18
  /** Triggered during subagent content streaming updates */
19
- onSubagentAssistantContentUpdated?: (subagentId: string, messageId: string, chunk: string, accumulated: string) => void;
19
+ onSubagentAssistantContentUpdated?: (params: {
20
+ subagentId: string;
21
+ messageId: string;
22
+ chunk: string;
23
+ accumulated: string;
24
+ stage: "streaming" | "end";
25
+ }) => void;
20
26
  /** Triggered during subagent reasoning streaming updates */
21
- onSubagentAssistantReasoningUpdated?: (subagentId: string, messageId: string, chunk: string, accumulated: string) => void;
27
+ onSubagentAssistantReasoningUpdated?: (params: {
28
+ subagentId: string;
29
+ messageId: string;
30
+ chunk: string;
31
+ accumulated: string;
32
+ stage: "streaming" | "end";
33
+ }) => void;
22
34
  /** Triggered when subagent tool block is updated */
23
35
  onSubagentToolBlockUpdated?: (subagentId: string, params: ToolBlockUpdateCallbackParams) => void;
24
36
  /** Triggered when subagent messages change */
@@ -1 +1 @@
1
- {"version":3,"file":"subagentManager.d.ts","sourceRoot":"","sources":["../../src/managers/subagentManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"subagentManager.d.ts","sourceRoot":"","sources":["../../src/managers/subagentManager.ts"],"names":[],"mappings":"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"}
@@ -407,7 +407,7 @@ export class SubagentManager {
407
407
  if (instance.logStream && response) {
408
408
  instance.logStream.write(`[${new Date().toISOString()}] Final response:\n${response}\n`);
409
409
  }
410
- instance.logStream?.write(`[${new Date().toISOString()}] Agent completed successfully\n`);
410
+ instance.logStream?.write(`[${new Date().toISOString()}] Agent completed\n`);
411
411
  instance.logStream?.end();
412
412
  const task = backgroundTaskManager.getTask(instance.backgroundTaskId);
413
413
  if (task) {
@@ -542,16 +542,22 @@ export class SubagentManager {
542
542
  this.callbacks.onSubagentAssistantMessageAdded(subagentId, messageId);
543
543
  }
544
544
  },
545
- onAssistantContentUpdated: (messageId, chunk, accumulated) => {
545
+ onAssistantContentUpdated: (params) => {
546
546
  // Forward assistant content updates to parent via SubagentManager callbacks
547
547
  if (this.callbacks?.onSubagentAssistantContentUpdated) {
548
- this.callbacks.onSubagentAssistantContentUpdated(subagentId, messageId, chunk, accumulated);
548
+ this.callbacks.onSubagentAssistantContentUpdated({
549
+ ...params,
550
+ subagentId,
551
+ });
549
552
  }
550
553
  },
551
- onAssistantReasoningUpdated: (messageId, chunk, accumulated) => {
554
+ onAssistantReasoningUpdated: (params) => {
552
555
  // Forward assistant reasoning updates to parent via SubagentManager callbacks
553
556
  if (this.callbacks?.onSubagentAssistantReasoningUpdated) {
554
- this.callbacks.onSubagentAssistantReasoningUpdated(subagentId, messageId, chunk, accumulated);
557
+ this.callbacks.onSubagentAssistantReasoningUpdated({
558
+ ...params,
559
+ subagentId,
560
+ });
555
561
  }
556
562
  },
557
563
  onToolBlockUpdated: (params) => {
@@ -602,6 +608,12 @@ export class SubagentManager {
602
608
  this.callbacks.onSubagentLatestTotalTokensChange(subagentId, tokens);
603
609
  }
604
610
  },
611
+ onErrorBlockAdded: (error) => {
612
+ const instance = this.instances.get(subagentId);
613
+ if (instance?.logStream) {
614
+ instance.logStream.write(`[${new Date().toISOString()}] Error: ${error}\n`);
615
+ }
616
+ },
605
617
  };
606
618
  }
607
619
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAuBtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAuhBtB,CAAC"}
1
+ {"version":3,"file":"bashTool.d.ts","sourceRoot":"","sources":["../../src/tools/bashTool.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAA2B,MAAM,YAAY,CAAC;AAuBtE;;GAEG;AACH,eAAO,MAAM,QAAQ,EAAE,UAmiBtB,CAAC"}
@@ -3,6 +3,7 @@ import * as fs from "fs";
3
3
  import * as path from "path";
4
4
  import * as os from "os";
5
5
  import { logger } from "../utils/globalLogger.js";
6
+ import { resolveShellPath } from "../utils/shellResolver.js";
6
7
  import { stripAnsiColors } from "../utils/stringUtils.js";
7
8
  import { processToolResult } from "../utils/toolResultStorage.js";
8
9
  import { BASH_MAX_OUTPUT_CHARS } from "../constants/toolLimits.js";
@@ -23,6 +24,7 @@ function isAutobackgroundingAllowed(command) {
23
24
  */
24
25
  export const bashTool = {
25
26
  name: BASH_TOOL_NAME,
27
+ isConcurrencySafe: false,
26
28
  config: {
27
29
  type: "function",
28
30
  function: {
@@ -134,6 +136,15 @@ The working directory persists between commands. Try to maintain your current wo
134
136
  error: "Command parameter is required and must be a string",
135
137
  };
136
138
  }
139
+ // Resolve shell path: on Windows, use Git Bash; on other platforms, use default
140
+ const shellPath = resolveShellPath();
141
+ if (process.platform === "win32" && !shellPath) {
142
+ return {
143
+ success: false,
144
+ content: "",
145
+ error: "Git Bash not found. Please install Git for Windows or set GIT_BASH_PATH environment variable.",
146
+ };
147
+ }
137
148
  // Validate timeout
138
149
  if (timeout !== undefined &&
139
150
  (typeof timeout !== "number" || timeout < 0 || timeout > 600000)) {
@@ -202,7 +213,7 @@ The working directory persists between commands. Try to maintain your current wo
202
213
  const tempCwdFile = path.join(os.tmpdir(), `wave_cwd_${Date.now()}_${Math.random().toString(36).substring(2, 11)}.tmp`);
203
214
  const wrappedCommand = `${command} && pwd -P >| ${tempCwdFile}`;
204
215
  const child = spawn(wrappedCommand, {
205
- shell: true,
216
+ shell: shellPath || true,
206
217
  stdio: "pipe",
207
218
  detached: true,
208
219
  cwd: context.workdir,
@@ -0,0 +1,3 @@
1
+ export declare const WINDOWS_GIT_BASH_PATHS: string[];
2
+ export declare function resolveShellPath(): string | undefined;
3
+ //# sourceMappingURL=shellResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shellResolver.d.ts","sourceRoot":"","sources":["../../src/utils/shellResolver.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,sBAAsB,UAGlC,CAAC;AAEF,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAuBrD"}
@@ -0,0 +1,25 @@
1
+ import fs from "fs";
2
+ export const WINDOWS_GIT_BASH_PATHS = [
3
+ "C:\\Program Files\\Git\\bin\\bash.exe",
4
+ "C:\\Program Files (x86)\\Git\\bin\\bash.exe",
5
+ ];
6
+ export function resolveShellPath() {
7
+ if (process.platform !== "win32") {
8
+ return undefined;
9
+ }
10
+ if (process.env.GIT_BASH_PATH) {
11
+ return process.env.GIT_BASH_PATH;
12
+ }
13
+ const paths = [
14
+ ...WINDOWS_GIT_BASH_PATHS,
15
+ process.env.LOCALAPPDATA
16
+ ? `${process.env.LOCALAPPDATA}\\Programs\\Git\\bin\\bash.exe`
17
+ : null,
18
+ ].filter(Boolean);
19
+ for (const path of paths) {
20
+ if (fs.existsSync(path)) {
21
+ return path;
22
+ }
23
+ }
24
+ return undefined;
25
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wave-agent-sdk",
3
- "version": "0.18.0",
3
+ "version": "0.18.2",
4
4
  "description": "SDK for building AI-powered development tools and agents",
5
5
  "keywords": [
6
6
  "ai",
@@ -138,7 +138,7 @@ export class ForkedAgentManager {
138
138
  `[${new Date().toISOString()}] Final response:\n${result}\n`,
139
139
  );
140
140
  entry.logStream.write(
141
- `[${new Date().toISOString()}] Agent completed successfully\n`,
141
+ `[${new Date().toISOString()}] Agent completed\n`,
142
142
  );
143
143
  entry.logStream.end();
144
144
  }
@@ -43,17 +43,19 @@ export interface MessageManagerCallbacks {
43
43
  // MODIFIED: Remove arguments for separation of concerns
44
44
  onAssistantMessageAdded?: (messageId: string) => void;
45
45
  // NEW: Streaming content callback - FR-001: receives chunk and accumulated content
46
- onAssistantContentUpdated?: (
47
- messageId: string,
48
- chunk: string,
49
- accumulated: string,
50
- ) => void;
46
+ onAssistantContentUpdated?: (params: {
47
+ messageId: string;
48
+ chunk: string;
49
+ accumulated: string;
50
+ stage: "streaming" | "end";
51
+ }) => void;
51
52
  // NEW: Streaming reasoning callback
52
- onAssistantReasoningUpdated?: (
53
- messageId: string,
54
- chunk: string,
55
- accumulated: string,
56
- ) => void;
53
+ onAssistantReasoningUpdated?: (params: {
54
+ messageId: string;
55
+ chunk: string;
56
+ accumulated: string;
57
+ stage: "streaming" | "end";
58
+ }) => void;
57
59
  onToolBlockUpdated?: (params: ToolBlockUpdateCallbackParams) => void;
58
60
  onErrorBlockAdded?: (error: string) => void;
59
61
  onCompactBlockAdded?: (content: string) => void;
@@ -469,7 +471,7 @@ export class MessageManager {
469
471
 
470
472
  public updateToolBlock(params: AgentToolBlockUpdateParams): void {
471
473
  // Finalize any streaming text/reasoning blocks before adding/updating a tool block
472
- this.finalizeCurrentStreamingBlocks();
474
+ this.finalizeStreamingBlocks();
473
475
  const { messages: newMessages, messageId: resolvedMessageId } =
474
476
  updateToolBlockInMessage({
475
477
  messages: this.messages,
@@ -497,7 +499,7 @@ export class MessageManager {
497
499
  params: Omit<AgentToolBlockUpdateParams, "id">,
498
500
  ): string {
499
501
  // Finalize any streaming text/reasoning blocks before adding a tool block
500
- this.finalizeCurrentStreamingBlocks();
502
+ this.finalizeStreamingBlocks();
501
503
  const { messages: newMessages, toolBlockId } =
502
504
  addToolBlockToMessageInMessages(this.messages, messageId, params);
503
505
  this.setMessages(newMessages);
@@ -681,6 +683,49 @@ export class MessageManager {
681
683
  this.callbacks.onUsagesChange?.([...this._usages]);
682
684
  }
683
685
 
686
+ /**
687
+ * Finalize a streaming block of the given type by setting its stage to "end".
688
+ * Fires the corresponding incremental callback with chunk="" to signal finalization.
689
+ * Does NOT call onMessagesChange — the caller is responsible for that.
690
+ * Returns true if a block was finalized.
691
+ */
692
+ private finalizeStreamingBlock(
693
+ lastMessage: Message,
694
+ type: "text" | "reasoning",
695
+ ): boolean {
696
+ const index = lastMessage.blocks.findIndex(
697
+ (block) =>
698
+ block.type === type &&
699
+ (block as { stage?: string }).stage === "streaming",
700
+ );
701
+ if (index < 0) return false;
702
+
703
+ const block = lastMessage.blocks[index] as {
704
+ type: "text" | "reasoning";
705
+ content: string;
706
+ stage?: string;
707
+ };
708
+ lastMessage.blocks[index] = {
709
+ type: block.type,
710
+ content: block.content,
711
+ stage: "end" as const,
712
+ };
713
+
714
+ // Fire incremental callback to signal finalization
715
+ const callbackParams = {
716
+ messageId: lastMessage.id,
717
+ chunk: "",
718
+ accumulated: block.content,
719
+ stage: "end" as const,
720
+ };
721
+ if (type === "text") {
722
+ this.callbacks.onAssistantContentUpdated?.(callbackParams);
723
+ } else {
724
+ this.callbacks.onAssistantReasoningUpdated?.(callbackParams);
725
+ }
726
+ return true;
727
+ }
728
+
684
729
  /**
685
730
  * Update the current assistant message content during streaming
686
731
  * This method updates the last assistant message's content without creating a new message
@@ -693,23 +738,7 @@ export class MessageManager {
693
738
  if (lastMessage.role !== "assistant") return;
694
739
 
695
740
  // Finalize any streaming reasoning blocks before text content arrives
696
- const reasoningIndex = lastMessage.blocks.findIndex(
697
- (block) =>
698
- block.type === "reasoning" &&
699
- (block as { stage?: string }).stage === "streaming",
700
- );
701
- if (reasoningIndex >= 0) {
702
- const reasoningBlock = lastMessage.blocks[reasoningIndex] as {
703
- type: "reasoning";
704
- content: string;
705
- stage?: string;
706
- };
707
- lastMessage.blocks[reasoningIndex] = {
708
- type: "reasoning" as const,
709
- content: reasoningBlock.content,
710
- stage: "end" as const,
711
- };
712
- }
741
+ this.finalizeStreamingBlock(lastMessage, "reasoning");
713
742
 
714
743
  // Get the current content to calculate the chunk
715
744
  const textBlockIndex = lastMessage.blocks.findIndex(
@@ -745,11 +774,12 @@ export class MessageManager {
745
774
  }
746
775
 
747
776
  // FR-001: Trigger callbacks with chunk and accumulated content
748
- this.callbacks.onAssistantContentUpdated?.(
749
- lastMessage.id,
777
+ this.callbacks.onAssistantContentUpdated?.({
778
+ messageId: lastMessage.id,
750
779
  chunk,
751
- newAccumulatedContent,
752
- );
780
+ accumulated: newAccumulatedContent,
781
+ stage: "streaming",
782
+ });
753
783
 
754
784
  // Note: Subagent-specific callbacks are now handled by SubagentManager
755
785
 
@@ -767,23 +797,7 @@ export class MessageManager {
767
797
  if (lastMessage.role !== "assistant") return;
768
798
 
769
799
  // Finalize any streaming text blocks before reasoning content arrives
770
- const textIndex = lastMessage.blocks.findIndex(
771
- (block) =>
772
- block.type === "text" &&
773
- (block as { stage?: string }).stage === "streaming",
774
- );
775
- if (textIndex >= 0) {
776
- const textBlock = lastMessage.blocks[textIndex] as {
777
- type: "text";
778
- content: string;
779
- stage?: string;
780
- };
781
- lastMessage.blocks[textIndex] = {
782
- type: "text" as const,
783
- content: textBlock.content,
784
- stage: "end" as const,
785
- };
786
- }
800
+ this.finalizeStreamingBlock(lastMessage, "text");
787
801
 
788
802
  // Get the current reasoning content to calculate the chunk
789
803
  const reasoningBlockIndex = lastMessage.blocks.findIndex(
@@ -819,46 +833,33 @@ export class MessageManager {
819
833
  }
820
834
 
821
835
  // Trigger callbacks with chunk and accumulated reasoning content
822
- this.callbacks.onAssistantReasoningUpdated?.(
823
- lastMessage.id,
836
+ this.callbacks.onAssistantReasoningUpdated?.({
837
+ messageId: lastMessage.id,
824
838
  chunk,
825
- newAccumulatedReasoning,
826
- );
839
+ accumulated: newAccumulatedReasoning,
840
+ stage: "streaming",
841
+ });
827
842
 
828
843
  this.callbacks.onMessagesChange?.([...this.messages]); // Still need to notify of changes
829
844
  }
830
845
 
831
- /**
832
- * Public wrapper for finalizeCurrentStreamingBlocks.
833
- * Finalizes text/reasoning blocks after streaming completes (e.g. final response with no tools).
834
- */
835
- public finalizeStreamingBlocks(): void {
836
- this.finalizeCurrentStreamingBlocks();
837
- }
838
-
839
846
  /**
840
847
  * Finalize streaming text/reasoning blocks by setting their stage to "end".
841
- * Called when a new block (e.g. tool) is appended during streaming.
848
+ * Called when a new block (e.g. tool) is appended during streaming, or when streaming completes.
849
+ * Fires incremental callbacks for each finalized block.
842
850
  */
843
- private finalizeCurrentStreamingBlocks(): void {
851
+ public finalizeStreamingBlocks(): void {
844
852
  if (this.messages.length === 0) return;
845
853
  const lastMessage = this.messages[this.messages.length - 1];
846
854
  if (lastMessage.role !== "assistant") return;
847
855
 
848
- const newBlocks = lastMessage.blocks.map((block) => {
849
- if (
850
- (block.type === "text" || block.type === "reasoning") &&
851
- block.stage === "streaming"
852
- ) {
853
- return { ...block, stage: "end" as const };
854
- }
855
- return block;
856
- });
856
+ const textFinalized = this.finalizeStreamingBlock(lastMessage, "text");
857
+ const reasoningFinalized = this.finalizeStreamingBlock(
858
+ lastMessage,
859
+ "reasoning",
860
+ );
857
861
 
858
- // Only update if something changed
859
- const changed = newBlocks.some((b, i) => b !== lastMessage.blocks[i]);
860
- if (changed) {
861
- lastMessage.blocks = newBlocks;
862
+ if (textFinalized || reasoningFinalized) {
862
863
  this.callbacks.onMessagesChange?.([...this.messages]);
863
864
  }
864
865
  }
@@ -38,19 +38,21 @@ export interface SubagentManagerCallbacks {
38
38
  messageId: string,
39
39
  ) => void;
40
40
  /** Triggered during subagent content streaming updates */
41
- onSubagentAssistantContentUpdated?: (
42
- subagentId: string,
43
- messageId: string,
44
- chunk: string,
45
- accumulated: string,
46
- ) => void;
41
+ onSubagentAssistantContentUpdated?: (params: {
42
+ subagentId: string;
43
+ messageId: string;
44
+ chunk: string;
45
+ accumulated: string;
46
+ stage: "streaming" | "end";
47
+ }) => void;
47
48
  /** Triggered during subagent reasoning streaming updates */
48
- onSubagentAssistantReasoningUpdated?: (
49
- subagentId: string,
50
- messageId: string,
51
- chunk: string,
52
- accumulated: string,
53
- ) => void;
49
+ onSubagentAssistantReasoningUpdated?: (params: {
50
+ subagentId: string;
51
+ messageId: string;
52
+ chunk: string;
53
+ accumulated: string;
54
+ stage: "streaming" | "end";
55
+ }) => void;
54
56
  /** Triggered when subagent tool block is updated */
55
57
  onSubagentToolBlockUpdated?: (
56
58
  subagentId: string,
@@ -629,7 +631,7 @@ export class SubagentManager {
629
631
  );
630
632
  }
631
633
  instance.logStream?.write(
632
- `[${new Date().toISOString()}] Agent completed successfully\n`,
634
+ `[${new Date().toISOString()}] Agent completed\n`,
633
635
  );
634
636
  instance.logStream?.end();
635
637
  const task = backgroundTaskManager.getTask(instance.backgroundTaskId);
@@ -789,34 +791,32 @@ export class SubagentManager {
789
791
  }
790
792
  },
791
793
 
792
- onAssistantContentUpdated: (
793
- messageId: string,
794
- chunk: string,
795
- accumulated: string,
796
- ) => {
794
+ onAssistantContentUpdated: (params: {
795
+ messageId: string;
796
+ chunk: string;
797
+ accumulated: string;
798
+ stage: "streaming" | "end";
799
+ }) => {
797
800
  // Forward assistant content updates to parent via SubagentManager callbacks
798
801
  if (this.callbacks?.onSubagentAssistantContentUpdated) {
799
- this.callbacks.onSubagentAssistantContentUpdated(
802
+ this.callbacks.onSubagentAssistantContentUpdated({
803
+ ...params,
800
804
  subagentId,
801
- messageId,
802
- chunk,
803
- accumulated,
804
- );
805
+ });
805
806
  }
806
807
  },
807
- onAssistantReasoningUpdated: (
808
- messageId: string,
809
- chunk: string,
810
- accumulated: string,
811
- ) => {
808
+ onAssistantReasoningUpdated: (params: {
809
+ messageId: string;
810
+ chunk: string;
811
+ accumulated: string;
812
+ stage: "streaming" | "end";
813
+ }) => {
812
814
  // Forward assistant reasoning updates to parent via SubagentManager callbacks
813
815
  if (this.callbacks?.onSubagentAssistantReasoningUpdated) {
814
- this.callbacks.onSubagentAssistantReasoningUpdated(
816
+ this.callbacks.onSubagentAssistantReasoningUpdated({
817
+ ...params,
815
818
  subagentId,
816
- messageId,
817
- chunk,
818
- accumulated,
819
- );
819
+ });
820
820
  }
821
821
  },
822
822
 
@@ -876,6 +876,15 @@ export class SubagentManager {
876
876
  this.callbacks.onSubagentLatestTotalTokensChange(subagentId, tokens);
877
877
  }
878
878
  },
879
+
880
+ onErrorBlockAdded: (error: string) => {
881
+ const instance = this.instances.get(subagentId);
882
+ if (instance?.logStream) {
883
+ instance.logStream.write(
884
+ `[${new Date().toISOString()}] Error: ${error}\n`,
885
+ );
886
+ }
887
+ },
879
888
  };
880
889
  }
881
890
  }
@@ -3,6 +3,7 @@ import * as fs from "fs";
3
3
  import * as path from "path";
4
4
  import * as os from "os";
5
5
  import { logger } from "../utils/globalLogger.js";
6
+ import { resolveShellPath } from "../utils/shellResolver.js";
6
7
  import { stripAnsiColors } from "../utils/stringUtils.js";
7
8
  import { processToolResult } from "../utils/toolResultStorage.js";
8
9
  import { BASH_MAX_OUTPUT_CHARS } from "../constants/toolLimits.js";
@@ -34,6 +35,7 @@ function isAutobackgroundingAllowed(command: string): boolean {
34
35
  */
35
36
  export const bashTool: ToolPlugin = {
36
37
  name: BASH_TOOL_NAME,
38
+ isConcurrencySafe: false,
37
39
  config: {
38
40
  type: "function",
39
41
  function: {
@@ -151,6 +153,17 @@ The working directory persists between commands. Try to maintain your current wo
151
153
  };
152
154
  }
153
155
 
156
+ // Resolve shell path: on Windows, use Git Bash; on other platforms, use default
157
+ const shellPath = resolveShellPath();
158
+ if (process.platform === "win32" && !shellPath) {
159
+ return {
160
+ success: false,
161
+ content: "",
162
+ error:
163
+ "Git Bash not found. Please install Git for Windows or set GIT_BASH_PATH environment variable.",
164
+ };
165
+ }
166
+
154
167
  // Validate timeout
155
168
  if (
156
169
  timeout !== undefined &&
@@ -236,7 +249,7 @@ The working directory persists between commands. Try to maintain your current wo
236
249
  const wrappedCommand = `${command} && pwd -P >| ${tempCwdFile}`;
237
250
 
238
251
  const child: ChildProcess = spawn(wrappedCommand, {
239
- shell: true,
252
+ shell: shellPath || true,
240
253
  stdio: "pipe",
241
254
  detached: true,
242
255
  cwd: context.workdir,
@@ -0,0 +1,31 @@
1
+ import fs from "fs";
2
+
3
+ export const WINDOWS_GIT_BASH_PATHS = [
4
+ "C:\\Program Files\\Git\\bin\\bash.exe",
5
+ "C:\\Program Files (x86)\\Git\\bin\\bash.exe",
6
+ ];
7
+
8
+ export function resolveShellPath(): string | undefined {
9
+ if (process.platform !== "win32") {
10
+ return undefined;
11
+ }
12
+
13
+ if (process.env.GIT_BASH_PATH) {
14
+ return process.env.GIT_BASH_PATH;
15
+ }
16
+
17
+ const paths = [
18
+ ...WINDOWS_GIT_BASH_PATHS,
19
+ process.env.LOCALAPPDATA
20
+ ? `${process.env.LOCALAPPDATA}\\Programs\\Git\\bin\\bash.exe`
21
+ : null,
22
+ ].filter(Boolean) as string[];
23
+
24
+ for (const path of paths) {
25
+ if (fs.existsSync(path)) {
26
+ return path;
27
+ }
28
+ }
29
+
30
+ return undefined;
31
+ }