This is an automated email from the ASF dual-hosted git repository.

hsluoyz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/casbin-gateway.git


The following commit(s) were added to refs/heads/master by this push:
     new 2810e97  fix(chat): run a driven agent in the working directory that 
was asked for (#230)
2810e97 is described below

commit 2810e97113e538ca55336bd1eacd4788b36ea66d
Author: qioo777 <[email protected]>
AuthorDate: Sat Sep 19 23:06:49 2026 +0800

    fix(chat): run a driven agent in the working directory that was asked for 
(#230)
---
 agentsession/runner.go     | 25 ++++++++++++++++++++-----
 agentsession/store.go      | 11 +++++++++++
 web/src/pages/ChatPage.tsx |  5 ++++-
 3 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/agentsession/runner.go b/agentsession/runner.go
index a6cff5e..5529e9e 100644
--- a/agentsession/runner.go
+++ b/agentsession/runner.go
@@ -21,6 +21,7 @@ import (
        "fmt"
        "io"
        "os"
+       "path/filepath"
        "strings"
        "time"
 
@@ -56,7 +57,7 @@ func run(ctx context.Context, headless *agent.Headless, 
session Session, prompt
                return errors.New("this agent takes its prompt on the command 
line, which cannot carry more than one line")
        }
 
-       workDir, err := resolveWorkDir(session.WorkDir)
+       workDir, err := ResolveWorkDir(session.WorkDir)
        if err != nil {
                return err
        }
@@ -169,17 +170,31 @@ func fill(template []string, session Session, prompt 
string, promptOnStdin bool)
        return args
 }
 
-// resolveWorkDir is the directory the agent runs in. An empty one is the home 
of
+// ResolveWorkDir is the directory the agent runs in. An empty one is the home 
of
 // the account Gateway runs as, which is where an agent started by hand would
-// have been.
-func resolveWorkDir(workDir string) (string, error) {
+// have been. A relative path is refused rather than resolved, which would take
+// it against Gateway's own directory and run the agent where nobody asked.
+func ResolveWorkDir(workDir string) (string, error) {
+       workDir = strings.TrimSpace(workDir)
        if workDir == "" {
                return agenthome.Resolve("")
        }
 
+       if workDir == "~" || strings.HasPrefix(workDir, "~/") || 
strings.HasPrefix(workDir, `~\`) {
+               home, err := agenthome.Resolve("")
+               if err != nil {
+                       return "", err
+               }
+               workDir = filepath.Join(home, workDir[1:])
+       }
+       if !filepath.IsAbs(workDir) {
+               return "", fmt.Errorf("the working directory must be a full 
path, not %q", workDir)
+       }
+       workDir = filepath.Clean(workDir)
+
        info, err := os.Stat(workDir)
        if err != nil {
-               return "", fmt.Errorf("the working directory cannot be opened: 
%w", err)
+               return "", fmt.Errorf("the working directory %s cannot be 
opened", workDir)
        }
        if !info.IsDir() {
                return "", fmt.Errorf("%s is not a directory", workDir)
diff --git a/agentsession/store.go b/agentsession/store.go
index 7c4c3a8..5964f6a 100644
--- a/agentsession/store.go
+++ b/agentsession/store.go
@@ -91,6 +91,17 @@ func Open(spec Spec) (Session, error) {
                return Session{}, ErrNotDrivable
        }
 
+       // Settled here rather than on the first turn, so a path that is not 
there is
+       // refused while somebody is still looking at the form. The resolved 
one is
+       // what is kept, restored and handed to the agent.
+       if spec.WorkDir != "" {
+               workDir, err := ResolveWorkDir(spec.WorkDir)
+               if err != nil {
+                       return Session{}, err
+               }
+               spec.WorkDir = workDir
+       }
+
        entry := &live{
                session: Session{
                        Id:          uuid.NewString(),
diff --git a/web/src/pages/ChatPage.tsx b/web/src/pages/ChatPage.tsx
index 93933ce..9c346c9 100644
--- a/web/src/pages/ChatPage.tsx
+++ b/web/src/pages/ChatPage.tsx
@@ -366,7 +366,10 @@ export default function ChatPage({account}: {account: 
Account}) {
               <button
                 key={session.id}
                 type="button"
-                onClick={() => setActiveId(session.id)}
+                onClick={() => {
+                  setActiveId(session.id);
+                  setWorkDir(session.workDir);
+                }}
                 className={cn(
                   "group hover:bg-muted/60 flex items-center gap-2 rounded-md 
border border-transparent px-2 py-1.5 text-left text-sm",
                   session.id === activeId && "bg-muted border-border",


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to