@@ -6,13 +6,13 @@ import (
66 "encoding/json"
77 "fmt"
88 "log/slog"
9+ "os"
910 "path/filepath"
1011 "slices"
1112 "strings"
1213 "sync"
1314
1415 "github.com/coder/acp-go-sdk"
15- "github.com/google/uuid"
1616
1717 "github.com/docker/cagent/pkg/config"
1818 "github.com/docker/cagent/pkg/runtime"
@@ -26,9 +26,10 @@ import (
2626
2727// Agent implements the ACP Agent interface for cagent
2828type Agent struct {
29- agentSource config.Source
30- runConfig * config.RuntimeConfig
31- sessions map [string ]* Session
29+ agentSource config.Source
30+ runConfig * config.RuntimeConfig
31+ sessionStore session.Store
32+ sessions map [string ]* Session
3233
3334 conn * acp.AgentSideConnection
3435 team * team.Team
@@ -47,11 +48,12 @@ type Session struct {
4748}
4849
4950// NewAgent creates a new ACP agent
50- func NewAgent (agentSource config.Source , runConfig * config.RuntimeConfig ) * Agent {
51+ func NewAgent (agentSource config.Source , runConfig * config.RuntimeConfig , sessionStore session. Store ) * Agent {
5152 return & Agent {
52- agentSource : agentSource ,
53- runConfig : runConfig ,
54- sessions : make (map [string ]* Session ),
53+ agentSource : agentSource ,
54+ runConfig : runConfig ,
55+ sessionStore : sessionStore ,
56+ sessions : make (map [string ]* Session ),
5557 }
5658}
5759
@@ -108,30 +110,75 @@ func (a *Agent) Initialize(ctx context.Context, params acp.InitializeRequest) (a
108110}
109111
110112// NewSession implements [acp.Agent]
111- func (a * Agent ) NewSession (_ context.Context , params acp.NewSessionRequest ) (acp.NewSessionResponse , error ) {
112- sid := uuid .New ().String ()
113- slog .Debug ("ACP NewSession called" , "session_id" , sid , "cwd" , params .Cwd )
113+ func (a * Agent ) NewSession (ctx context.Context , params acp.NewSessionRequest ) (acp.NewSessionResponse , error ) {
114+ slog .Debug ("ACP NewSession called" , "cwd" , params .Cwd )
114115
115116 // Log warning if MCP servers are provided (not yet supported)
116117 if len (params .McpServers ) > 0 {
117118 slog .Warn ("MCP servers provided by client are not yet supported" , "count" , len (params .McpServers ))
118119 }
119120
120- rt , err := runtime .New (a .team , runtime .WithCurrentAgent ("root" ))
121+ // Validate and normalize working directory
122+ var workingDir string
123+ if wd := strings .TrimSpace (params .Cwd ); wd != "" {
124+ absWd , err := filepath .Abs (wd )
125+ if err != nil {
126+ return acp.NewSessionResponse {}, fmt .Errorf ("invalid working directory: %w" , err )
127+ }
128+ info , err := os .Stat (absWd )
129+ if err != nil {
130+ return acp.NewSessionResponse {}, fmt .Errorf ("working directory does not exist: %w" , err )
131+ }
132+ if ! info .IsDir () {
133+ return acp.NewSessionResponse {}, fmt .Errorf ("working directory must be a directory" )
134+ }
135+ workingDir = absWd
136+ }
137+
138+ rt , err := runtime .New (a .team ,
139+ runtime .WithCurrentAgent ("root" ),
140+ runtime .WithSessionStore (a .sessionStore ),
141+ )
121142 if err != nil {
122143 return acp.NewSessionResponse {}, fmt .Errorf ("failed to create runtime: %w" , err )
123144 }
124145
146+ // Get root agent config for session settings
147+ rootAgent , err := a .team .Agent ("root" )
148+ if err != nil {
149+ return acp.NewSessionResponse {}, fmt .Errorf ("failed to get root agent: %w" , err )
150+ }
151+
152+ // Build session options (title will be set after we have the session ID)
153+ sessOpts := []session.Opt {
154+ session .WithMaxIterations (rootAgent .MaxIterations ()),
155+ session .WithThinking (rootAgent .ThinkingConfigured ()),
156+ }
157+ if workingDir != "" {
158+ sessOpts = append (sessOpts , session .WithWorkingDir (workingDir ))
159+ }
160+
161+ // Create session - use its auto-generated ID
162+ sess := session .New (sessOpts ... )
163+ sess .Title = "ACP Session " + sess .ID
164+
165+ // Persist session to the store
166+ if err := a .sessionStore .AddSession (ctx , sess ); err != nil {
167+ return acp.NewSessionResponse {}, fmt .Errorf ("failed to persist session: %w" , err )
168+ }
169+
170+ slog .Debug ("ACP session created" , "session_id" , sess .ID )
171+
125172 a .mu .Lock ()
126- a .sessions [sid ] = & Session {
127- id : sid ,
128- sess : session . New ( session . WithTitle ( "ACP Session " + sid )) ,
173+ a .sessions [sess . ID ] = & Session {
174+ id : sess . ID ,
175+ sess : sess ,
129176 rt : rt ,
130- workingDir : params . Cwd ,
177+ workingDir : workingDir ,
131178 }
132179 a .mu .Unlock ()
133180
134- return acp.NewSessionResponse {SessionId : acp .SessionId (sid )}, nil
181+ return acp.NewSessionResponse {SessionId : acp .SessionId (sess . ID )}, nil
135182}
136183
137184// Authenticate implements [acp.Agent]
0 commit comments