diff options
Diffstat (limited to 'internal/agentloop/tools.go')
| -rw-r--r-- | internal/agentloop/tools.go | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/internal/agentloop/tools.go b/internal/agentloop/tools.go index e92a12f..fcb17a2 100644 --- a/internal/agentloop/tools.go +++ b/internal/agentloop/tools.go @@ -8,6 +8,7 @@ import ( "github.com/thepeterstone/claudomator/internal/agentchannel" "github.com/thepeterstone/claudomator/internal/provider" + "github.com/thepeterstone/claudomator/internal/sandbox" ) // agentToolSpecs returns the eight tools available to the loop: the four @@ -193,6 +194,15 @@ func (l *Loop) dispatchTool(ctx context.Context, name, argsJSON string) (result } _ = json.Unmarshal([]byte(argsJSON), &a) if writeErr := l.Sandbox.WriteFile(ctx, a.Path, a.Content); writeErr != nil { + // A guardrail rejection (sandbox.Guarded wrapping the real + // Sandbox) is not a fatal execution error: feed the reason back + // to the model as ordinary tool content so it can self-correct, + // instead of aborting the whole run the way a genuine sandbox + // failure (e.g. no working directory) does. + var rej *sandbox.RejectionError + if errors.As(writeErr, &rej) { + return rej.Error(), false, nil + } return "", false, writeErr } return "Written.", false, nil @@ -204,6 +214,10 @@ func (l *Loop) dispatchTool(ctx context.Context, name, argsJSON string) (result _ = json.Unmarshal([]byte(argsJSON), &a) out, errOut, exitCode, runErr := l.Sandbox.RunBash(ctx, a.Command) if runErr != nil { + var rej *sandbox.RejectionError + if errors.As(runErr, &rej) { + return rej.Error(), false, nil + } return "", false, runErr } return fmt.Sprintf("exit_code: %d\nstdout:\n%s\nstderr:\n%s", exitCode, out, errOut), false, nil |
