fix: reapply system prompts on restore
This commit is contained in:
parent
fa68474e6f
commit
fd04e11061
|
|
@ -122,6 +122,11 @@ func (p *Plugin) GetRestoreCommand(ctx context.Context, cfg ports.RestoreConfig)
|
|||
cmd = make([]string, 0, 5)
|
||||
cmd = append(cmd, binary)
|
||||
appendPermissionFlags(&cmd, cfg.Permissions)
|
||||
if cfg.SystemPrompt != "" {
|
||||
cmd = append(cmd, "--append-system-prompt", cfg.SystemPrompt)
|
||||
} else if cfg.SystemPromptFile != "" {
|
||||
cmd = append(cmd, "--append-system-prompt-file", cfg.SystemPromptFile)
|
||||
}
|
||||
cmd = append(cmd, "--resume", agentSessionID)
|
||||
return cmd, true, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -138,7 +138,9 @@ func TestGetRestoreCommand(t *testing.T) {
|
|||
Session: ports.SessionRef{
|
||||
Metadata: map[string]string{ports.MetadataKeyAgentSessionID: "T-abc123"},
|
||||
},
|
||||
Permissions: ports.PermissionModeBypassPermissions,
|
||||
Permissions: ports.PermissionModeBypassPermissions,
|
||||
SystemPrompt: "restore inline wins",
|
||||
SystemPromptFile: "/tmp/system.md",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -147,7 +149,7 @@ func TestGetRestoreCommand(t *testing.T) {
|
|||
t.Fatal("ok=false, want true")
|
||||
}
|
||||
|
||||
want := []string{"amp", "--permission-mode", "bypassPermissions", "--resume", "T-abc123"}
|
||||
want := []string{"amp", "--permission-mode", "bypassPermissions", "--append-system-prompt", "restore inline wins", "--resume", "T-abc123"}
|
||||
if !reflect.DeepEqual(cmd, want) {
|
||||
t.Fatalf("cmd = %#v, want %#v", cmd, want)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -152,7 +152,13 @@ func (p *Plugin) GetRestoreCommand(ctx context.Context, cfg ports.RestoreConfig)
|
|||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
cmd = []string{binary, "--print", "--resume", agentSessionID}
|
||||
cmd = []string{binary, "--print"}
|
||||
if cfg.SystemPrompt != "" {
|
||||
cmd = append(cmd, "--instruction", cfg.SystemPrompt)
|
||||
} else if cfg.SystemPromptFile != "" {
|
||||
cmd = append(cmd, "--instruction-file", cfg.SystemPromptFile)
|
||||
}
|
||||
cmd = append(cmd, "--resume", agentSessionID)
|
||||
return cmd, true, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,7 +134,9 @@ func TestGetRestoreCommand(t *testing.T) {
|
|||
Session: ports.SessionRef{
|
||||
Metadata: map[string]string{ports.MetadataKeyAgentSessionID: "sess-abc123"},
|
||||
},
|
||||
Permissions: ports.PermissionModeBypassPermissions,
|
||||
Permissions: ports.PermissionModeBypassPermissions,
|
||||
SystemPrompt: "restore inline wins",
|
||||
SystemPromptFile: "/tmp/system.md",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
|
|
@ -143,7 +145,7 @@ func TestGetRestoreCommand(t *testing.T) {
|
|||
t.Fatal("ok=false, want true")
|
||||
}
|
||||
|
||||
want := []string{"auggie", "--print", "--resume", "sess-abc123"}
|
||||
want := []string{"auggie", "--print", "--instruction", "restore inline wins", "--resume", "sess-abc123"}
|
||||
if !reflect.DeepEqual(cmd, want) {
|
||||
t.Fatalf("cmd = %#v, want %#v", cmd, want)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -110,8 +110,9 @@ func (p *Plugin) GetPromptDeliveryStrategy(ctx context.Context, cfg ports.Launch
|
|||
// GetRestoreCommand rebuilds the argv that continues an existing Autohand
|
||||
// session: `autohand resume [--path <workspace>] <sessionId>`. ok is false when
|
||||
// the hook-derived native session id has not landed yet, so callers can fall
|
||||
// back to fresh launch behavior. Autohand's resume sub-command does not accept
|
||||
// approval flags, so none are appended here.
|
||||
// back to fresh launch behavior. Autohand's resume sub-command only accepts the
|
||||
// workspace path and session id, so approval and system-prompt flags are not
|
||||
// re-applied here.
|
||||
func (p *Plugin) GetRestoreCommand(ctx context.Context, cfg ports.RestoreConfig) (cmd []string, ok bool, err error) {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return nil, false, err
|
||||
|
|
|
|||
|
|
@ -152,7 +152,8 @@ func TestGetRestoreCommandReadsAgentSessionID(t *testing.T) {
|
|||
plugin := &Plugin{resolvedBinary: "autohand"}
|
||||
|
||||
cmd, ok, err := plugin.GetRestoreCommand(context.Background(), ports.RestoreConfig{
|
||||
Permissions: ports.PermissionModeAuto,
|
||||
Permissions: ports.PermissionModeAuto,
|
||||
SystemPrompt: "restore instructions ignored by resume",
|
||||
Session: ports.SessionRef{
|
||||
WorkspacePath: "/work/space",
|
||||
Metadata: map[string]string{ports.MetadataKeyAgentSessionID: "sess-123"},
|
||||
|
|
|
|||
|
|
@ -122,6 +122,9 @@ func (p *Plugin) GetRestoreCommand(ctx context.Context, cfg ports.RestoreConfig)
|
|||
cmd = make([]string, 0, 8)
|
||||
cmd = append(cmd, binary, "--json")
|
||||
appendApprovalFlags(&cmd, cfg.Permissions)
|
||||
if cfg.SystemPrompt != "" {
|
||||
cmd = append(cmd, "-s", cfg.SystemPrompt)
|
||||
}
|
||||
cmd = append(cmd, "--id", agentSessionID)
|
||||
return cmd, true, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -241,7 +241,8 @@ func TestGetRestoreCommandReadsAgentSessionID(t *testing.T) {
|
|||
plugin := &Plugin{resolvedBinary: "cline"}
|
||||
|
||||
cmd, ok, err := plugin.GetRestoreCommand(context.Background(), ports.RestoreConfig{
|
||||
Permissions: ports.PermissionModeAuto,
|
||||
Permissions: ports.PermissionModeAuto,
|
||||
SystemPrompt: "restore instructions",
|
||||
Session: ports.SessionRef{
|
||||
Metadata: map[string]string{ports.MetadataKeyAgentSessionID: "session-123"},
|
||||
},
|
||||
|
|
@ -256,6 +257,7 @@ func TestGetRestoreCommandReadsAgentSessionID(t *testing.T) {
|
|||
"cline",
|
||||
"--json",
|
||||
"--auto-approve", "true",
|
||||
"-s", "restore instructions",
|
||||
"--id", "session-123",
|
||||
}
|
||||
if !reflect.DeepEqual(cmd, want) {
|
||||
|
|
|
|||
|
|
@ -125,6 +125,11 @@ func (p *Plugin) GetRestoreCommand(ctx context.Context, cfg ports.RestoreConfig)
|
|||
appendSessionHookFlags(&cmd)
|
||||
appendTerminalCompatibilityFlags(&cmd)
|
||||
appendWorkspaceTrustFlag(&cmd, cfg.Session.WorkspacePath)
|
||||
if cfg.SystemPrompt != "" {
|
||||
cmd = append(cmd, "-c", "developer_instructions="+codexTOMLConfigString(cfg.SystemPrompt))
|
||||
} else if cfg.SystemPromptFile != "" {
|
||||
cmd = append(cmd, "-c", "model_instructions_file="+cfg.SystemPromptFile)
|
||||
}
|
||||
cmd = append(cmd, agentSessionID)
|
||||
return cmd, true, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -398,7 +398,9 @@ func TestGetRestoreCommandReadsAgentSessionID(t *testing.T) {
|
|||
workspace := canonicalTempDir(t)
|
||||
|
||||
cmd, ok, err := plugin.GetRestoreCommand(context.Background(), ports.RestoreConfig{
|
||||
Permissions: ports.PermissionModeAuto,
|
||||
Permissions: ports.PermissionModeAuto,
|
||||
SystemPrompt: "restore inline wins",
|
||||
SystemPromptFile: filepath.Join("tmp", "restore-system.md"),
|
||||
Session: ports.SessionRef{
|
||||
Metadata: map[string]string{ports.MetadataKeyAgentSessionID: "thread-123"},
|
||||
WorkspacePath: workspace,
|
||||
|
|
@ -425,6 +427,7 @@ func TestGetRestoreCommandReadsAgentSessionID(t *testing.T) {
|
|||
}
|
||||
want = append(want,
|
||||
"-c", `projects={`+codexTOMLConfigString(workspace)+`={trust_level="trusted"}}`,
|
||||
"-c", "developer_instructions="+codexTOMLConfigString("restore inline wins"),
|
||||
"thread-123",
|
||||
)
|
||||
if !reflect.DeepEqual(cmd, want) {
|
||||
|
|
|
|||
|
|
@ -151,6 +151,11 @@ func (p *Plugin) GetRestoreCommand(ctx context.Context, cfg ports.RestoreConfig)
|
|||
return nil, false, err
|
||||
}
|
||||
cmd = append(cmd, settingsArgs...)
|
||||
if cfg.SystemPrompt != "" {
|
||||
cmd = append(cmd, "--append-system-prompt", cfg.SystemPrompt)
|
||||
} else if cfg.SystemPromptFile != "" {
|
||||
cmd = append(cmd, "--append-system-prompt-file", cfg.SystemPromptFile)
|
||||
}
|
||||
cmd = append(cmd, "-r", agentSessionID)
|
||||
return cmd, true, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,6 +141,8 @@ func TestGetLaunchCommandSystemPrompt(t *testing.T) {
|
|||
func TestGetRestoreCommand(t *testing.T) {
|
||||
plugin := &Plugin{resolvedBinary: "droid"}
|
||||
cmd, ok, err := plugin.GetRestoreCommand(context.Background(), ports.RestoreConfig{
|
||||
SystemPrompt: "restore inline wins",
|
||||
SystemPromptFile: "/tmp/system.md",
|
||||
Session: ports.SessionRef{
|
||||
ID: "mer-4",
|
||||
Metadata: map[string]string{
|
||||
|
|
@ -154,7 +156,7 @@ func TestGetRestoreCommand(t *testing.T) {
|
|||
if !ok {
|
||||
t.Fatal("ok=false, want true")
|
||||
}
|
||||
want := []string{"droid", "-r", "droid-ses-1"}
|
||||
want := []string{"droid", "--append-system-prompt", "restore inline wins", "-r", "droid-ses-1"}
|
||||
if !reflect.DeepEqual(cmd, want) {
|
||||
t.Fatalf("cmd = %#v, want %#v", cmd, want)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,7 +142,15 @@ func (p *Plugin) GetRestoreCommand(ctx context.Context, cfg ports.RestoreConfig)
|
|||
return nil, false, err
|
||||
}
|
||||
|
||||
cmd = append(gooseModeEnvPrefix(cfg.Permissions), binary, "run", "--resume", "--session-id", agentSessionID)
|
||||
cmd = append(gooseModeEnvPrefix(cfg.Permissions), binary, "run")
|
||||
systemPrompt, err := restoreSystemPromptText(cfg)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
if systemPrompt != "" {
|
||||
cmd = append(cmd, "--system", systemPrompt)
|
||||
}
|
||||
cmd = append(cmd, "--resume", "--session-id", agentSessionID)
|
||||
return cmd, true, nil
|
||||
}
|
||||
|
||||
|
|
@ -167,17 +175,26 @@ func (p *Plugin) SessionInfo(ctx context.Context, session ports.SessionRef) (por
|
|||
// flag takes inline text only (no file variant), so a system-prompt file is read
|
||||
// from disk only when inline instructions are unavailable.
|
||||
func systemPromptText(cfg ports.LaunchConfig) (string, error) {
|
||||
if cfg.SystemPrompt != "" {
|
||||
return cfg.SystemPrompt, nil
|
||||
return systemPromptTextFrom(cfg.SystemPrompt, cfg.SystemPromptFile)
|
||||
}
|
||||
|
||||
func restoreSystemPromptText(cfg ports.RestoreConfig) (string, error) {
|
||||
return systemPromptTextFrom(cfg.SystemPrompt, cfg.SystemPromptFile)
|
||||
}
|
||||
|
||||
func systemPromptTextFrom(inline, file string) (string, error) {
|
||||
if inline != "" {
|
||||
return inline, nil
|
||||
}
|
||||
if cfg.SystemPromptFile != "" {
|
||||
data, err := os.ReadFile(cfg.SystemPromptFile) //nolint:gosec // path is AO-owned launch config
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("read %s: %w", cfg.SystemPromptFile, err)
|
||||
}
|
||||
if text := strings.TrimSpace(string(data)); text != "" {
|
||||
return text, nil
|
||||
}
|
||||
if file == "" {
|
||||
return "", nil
|
||||
}
|
||||
data, err := os.ReadFile(file) //nolint:gosec // path is AO-owned launch config
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("read %s: %w", file, err)
|
||||
}
|
||||
if text := strings.TrimSpace(string(data)); text != "" {
|
||||
return text, nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -278,7 +278,9 @@ func TestGetRestoreCommandReadsAgentSessionID(t *testing.T) {
|
|||
plugin := &Plugin{resolvedBinary: "goose"}
|
||||
|
||||
cmd, ok, err := plugin.GetRestoreCommand(context.Background(), ports.RestoreConfig{
|
||||
Permissions: ports.PermissionModeAuto,
|
||||
Permissions: ports.PermissionModeAuto,
|
||||
SystemPrompt: "restore inline wins",
|
||||
SystemPromptFile: filepath.Join(t.TempDir(), "missing.md"),
|
||||
Session: ports.SessionRef{
|
||||
Metadata: map[string]string{ports.MetadataKeyAgentSessionID: "thread-123"},
|
||||
},
|
||||
|
|
@ -291,7 +293,7 @@ func TestGetRestoreCommandReadsAgentSessionID(t *testing.T) {
|
|||
}
|
||||
want := []string{
|
||||
"env", "GOOSE_MODE=auto",
|
||||
"goose", "run", "--resume", "--session-id", "thread-123",
|
||||
"goose", "run", "--system", "restore inline wins", "--resume", "--session-id", "thread-123",
|
||||
}
|
||||
if !reflect.DeepEqual(cmd, want) {
|
||||
t.Fatalf("restore cmd\nwant: %#v\n got: %#v", want, cmd)
|
||||
|
|
|
|||
|
|
@ -146,6 +146,15 @@ func (p *Plugin) GetRestoreCommand(ctx context.Context, cfg ports.RestoreConfig)
|
|||
return nil, false, err
|
||||
}
|
||||
cmd = []string{binary, "--print", "--session", agentSessionID}
|
||||
if cfg.SystemPrompt != "" {
|
||||
cmd = append(cmd, "--append-system-prompt", cfg.SystemPrompt)
|
||||
} else if cfg.SystemPromptFile != "" {
|
||||
data, err := os.ReadFile(cfg.SystemPromptFile) //nolint:gosec // path is AO-owned launch config
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
cmd = append(cmd, "--append-system-prompt", string(data))
|
||||
}
|
||||
return cmd, true, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -148,6 +148,8 @@ func TestGetLaunchCommandSystemPromptFileReadError(t *testing.T) {
|
|||
func TestGetRestoreCommand(t *testing.T) {
|
||||
p := &Plugin{resolvedBinary: "pi"}
|
||||
cmd, ok, err := p.GetRestoreCommand(context.Background(), ports.RestoreConfig{
|
||||
SystemPrompt: "restore inline wins",
|
||||
SystemPromptFile: filepath.Join(t.TempDir(), "missing.md"),
|
||||
Session: ports.SessionRef{
|
||||
Metadata: map[string]string{ports.MetadataKeyAgentSessionID: "019e950e-52e0-7411-961b-d380ca7e610f"},
|
||||
},
|
||||
|
|
@ -160,7 +162,7 @@ func TestGetRestoreCommand(t *testing.T) {
|
|||
t.Fatal("ok=false, want true")
|
||||
}
|
||||
|
||||
want := []string{"pi", "--print", "--session", "019e950e-52e0-7411-961b-d380ca7e610f"}
|
||||
want := []string{"pi", "--print", "--session", "019e950e-52e0-7411-961b-d380ca7e610f", "--append-system-prompt", "restore inline wins"}
|
||||
if !reflect.DeepEqual(cmd, want) {
|
||||
t.Fatalf("cmd = %#v, want %#v", cmd, want)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -122,6 +122,9 @@ func (p *Plugin) GetRestoreCommand(ctx context.Context, cfg ports.RestoreConfig)
|
|||
cmd = make([]string, 0, 6)
|
||||
cmd = append(cmd, binary)
|
||||
appendApprovalFlags(&cmd, cfg.Permissions)
|
||||
if cfg.SystemPrompt != "" {
|
||||
cmd = append(cmd, "--append-system-prompt", cfg.SystemPrompt)
|
||||
}
|
||||
cmd = append(cmd, "-r", agentSessionID)
|
||||
return cmd, true, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -271,7 +271,8 @@ func TestGetRestoreCommandReadsAgentSessionID(t *testing.T) {
|
|||
plugin := &Plugin{resolvedBinary: "qwen"}
|
||||
|
||||
cmd, ok, err := plugin.GetRestoreCommand(context.Background(), ports.RestoreConfig{
|
||||
Permissions: ports.PermissionModeAuto,
|
||||
Permissions: ports.PermissionModeAuto,
|
||||
SystemPrompt: "restore instructions",
|
||||
Session: ports.SessionRef{
|
||||
Metadata: map[string]string{ports.MetadataKeyAgentSessionID: "sess-123"},
|
||||
},
|
||||
|
|
@ -285,6 +286,7 @@ func TestGetRestoreCommandReadsAgentSessionID(t *testing.T) {
|
|||
want := []string{
|
||||
"qwen",
|
||||
"--approval-mode", "auto",
|
||||
"--append-system-prompt", "restore instructions",
|
||||
"-r", "sess-123",
|
||||
}
|
||||
if !reflect.DeepEqual(cmd, want) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue