@@ -4,7 +4,6 @@ import (
44 "context"
55 "encoding/json"
66 "fmt"
7− "log/slog"
87 "strings"
98 "time"
109
@@ -23,8 +22,10 @@ type BashPermissionsParams struct {
2322}
2423
2524type BashResponseMetadata struct {
26− StartTime int64 `json:"start_time"`
27− EndTime int64 `json:"end_time"`
25+ StartTime int64 `json:"start_time"`
26+ EndTime int64 `json:"end_time"`
27+ Output string `json:"output"`
28+ WorkingDirectory string `json:"working_directory"`
2829}
2930type bashTool struct {
3031 permissions permission.Service
@@ -146,6 +147,7 @@ Before executing the command, please follow these steps:
1461475. Return Result:
147148 - Provide the processed output of the command.
148149 - If any errors occurred during execution, include those in the output.
150+ - The result will also have metadata like the cwd (current working directory) at the end, included with <cwd></cwd> tags.
149151
150152Usage notes:
151153- The command argument is required.
@@ -389,9 +391,12 @@ func (b *bashTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error)
389391 ctx, cancel = context.WithTimeout(ctx, time.Duration(params.Timeout)*time.Millisecond)
390392 defer cancel()
391393 }
392− stdout, stderr, err := shell.
393− GetPersistentShell(b.workingDir).
394− Exec(ctx, params.Command)
394+
395+ persistentShell := shell.GetPersistentShell(b.workingDir)
396+ stdout, stderr, err := persistentShell.Exec(ctx, params.Command)
397+
398+ // Get the current working directory after command execution
399+ currentWorkingDir := persistentShell.GetWorkingDir()
395400 interrupted := shell.IsInterrupt(err)
396401 exitCode := shell.ExitCode(err)
397402 if exitCode == 0 && !interrupted && err != nil {
@@ -401,15 +406,6 @@ func (b *bashTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error)
401406 stdout = truncateOutput(stdout)
402407 stderr = truncateOutput(stderr)
403408
404− slog.Info("Bash command executed",
405− "command", params.Command,
406− "stdout", stdout,
407− "stderr", stderr,
408− "exit_code", exitCode,
409− "interrupted", interrupted,
410− "err", err,
411− )
412−
413409 errorMessage := stderr
414410 if errorMessage == "" && err != nil {
415411 errorMessage = err.Error()
@@ -438,9 +434,12 @@ func (b *bashTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error)
438434 }
439435
440436 metadata := BashResponseMetadata{
441− StartTime: startTime.UnixMilli(),
442− EndTime: time.Now().UnixMilli(),
437+ StartTime: startTime.UnixMilli(),
438+ EndTime: time.Now().UnixMilli(),
439+ Output: stdout,
440+ WorkingDirectory: currentWorkingDir,
443441 }
442+ stdout += fmt.Sprintf("\n\n<cwd>%s</cwd>", currentWorkingDir)
444443 if stdout == "" {
445444 return WithResponseMetadata(NewTextResponse(BashNoOutput), metadata), nil
446445 }