feat: inject cmd working directory into system prompt for hipico mode

When using :hipico from cmd mode after cd'ing to a subdirectory, the AI
now sees the current working directory in the system prompt instead of
just a weak user-message prefix. This ensures the AI resolves file paths
relative to the cmd working directory, not the workspace root.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
seagochen 2026-02-24 17:34:10 +09:00
parent f691068bae
commit 50ea9d97a2
2 changed files with 28 additions and 7 deletions

View file

@ -204,10 +204,8 @@ func interactiveMode(agentLoop *agent.AgentLoop, sessionKey string) {
continue
}
contextPrefix := fmt.Sprintf("[Command mode context: working directory is %s]\n\n", cmdWorkingDir)
ctx := context.Background()
response, err := agentLoop.ProcessDirect(ctx, contextPrefix+initialMsg, hipicoSessionKey)
response, err := agentLoop.ProcessDirectWithWorkDir(ctx, initialMsg, hipicoSessionKey, cmdWorkingDir)
if err != nil {
fmt.Printf("Error: %v\n", err)
continue
@ -295,10 +293,8 @@ func simpleInteractiveMode(agentLoop *agent.AgentLoop, sessionKey string) {
continue
}
contextPrefix := fmt.Sprintf("[Command mode context: working directory is %s]\n\n", cmdWorkingDir)
ctx := context.Background()
response, err := agentLoop.ProcessDirect(ctx, contextPrefix+initialMsg, hipicoSessionKey)
response, err := agentLoop.ProcessDirectWithWorkDir(ctx, initialMsg, hipicoSessionKey, cmdWorkingDir)
if err != nil {
fmt.Printf("Error: %v\n", err)
continue

View file

@ -63,6 +63,7 @@ type processOptions struct {
EnableSummary bool // Whether to trigger summarization
SendResponse bool // Whether to send response via bus
NoHistory bool // If true, don't load session history (for heartbeat)
WorkingDir string // Current working directory override (for hipico from cmd mode)
}
func NewAgentLoop(cfg *config.Config, msgBus *bus.MessageBus, provider providers.LLMProvider) *AgentLoop {
@ -273,6 +274,20 @@ func (al *AgentLoop) ProcessDirect(ctx context.Context, content, sessionKey stri
return al.ProcessDirectWithChannel(ctx, content, sessionKey, "cli", "direct")
}
// ProcessDirectWithWorkDir processes a message with an explicit working directory context.
// The workDir is injected into the system prompt so the AI resolves file paths relative to it.
func (al *AgentLoop) ProcessDirectWithWorkDir(ctx context.Context, content, sessionKey, workDir string) (string, error) {
msg := bus.InboundMessage{
Channel: "cli",
SenderID: "cron",
ChatID: "direct",
Content: content,
SessionKey: sessionKey,
Metadata: map[string]string{"work_dir": workDir},
}
return al.processMessage(ctx, msg)
}
func (al *AgentLoop) ProcessDirectWithChannel(
ctx context.Context,
content, sessionKey, channel, chatID string,
@ -371,7 +386,6 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
if workDir == "" {
workDir = agent.Workspace
}
userMessage = fmt.Sprintf("[Command mode context: working directory is %s]\n\n%s", workDir, userMessage)
hipicoSessionKey := sessionKey + ":hipico"
return al.runAgentLoop(ctx, agent, processOptions{
SessionKey: hipicoSessionKey,
@ -381,6 +395,7 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
DefaultResponse: "I've completed processing but have no response to give.",
EnableSummary: false,
SendResponse: false,
WorkingDir: workDir,
})
}
}
@ -399,6 +414,7 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
DefaultResponse: "I've completed processing but have no response to give.",
EnableSummary: true,
SendResponse: false,
WorkingDir: msg.Metadata["work_dir"],
})
}
}
@ -491,6 +507,15 @@ func (al *AgentLoop) runAgentLoop(ctx context.Context, agent *AgentInstance, opt
opts.ChatID,
)
// 2b. Inject current working directory into system prompt if set
if opts.WorkingDir != "" && len(messages) > 0 && messages[0].Role == "system" {
messages[0].Content += fmt.Sprintf(
"\n\n## Current Working Directory\nThe user is currently working in: %s\n"+
"When the user refers to files or directories, resolve them relative to this path, not the workspace root.",
opts.WorkingDir,
)
}
// 3. Save user message to session
agent.Sessions.AddMessage(opts.SessionKey, "user", opts.UserMessage)