51 lines
1.3 KiB
Go
51 lines
1.3 KiB
Go
package lifecycle
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"sync"
|
|
)
|
|
|
|
type releaseOnCloseReadCloser struct {
|
|
io.ReadCloser
|
|
releaseOnce sync.Once
|
|
release func()
|
|
}
|
|
|
|
func (r *releaseOnCloseReadCloser) Close() error {
|
|
err := r.ReadCloser.Close()
|
|
r.releaseOnce.Do(r.release)
|
|
return err
|
|
}
|
|
|
|
// ExportACPDebug fetches the selected execution's exact ACP conversation
|
|
// export. The caller must perform task/session authorization before invoking
|
|
// this method; lifecycle only resolves the in-memory execution seam.
|
|
func (m *Manager) ExportACPDebug(
|
|
ctx context.Context, taskSessionID string, maxBytes int64,
|
|
) (io.ReadCloser, error) {
|
|
if taskSessionID == "" {
|
|
return nil, fmt.Errorf("task session ID is required")
|
|
}
|
|
execution, ok := m.GetExecutionBySessionID(taskSessionID)
|
|
if !ok || execution == nil || execution.ACPSessionID == "" {
|
|
return nil, fmt.Errorf("ACP executor is unavailable")
|
|
}
|
|
client, release := execution.AcquireAgentCtlClient()
|
|
if client == nil {
|
|
release()
|
|
return nil, fmt.Errorf("ACP executor is unavailable")
|
|
}
|
|
body, err := client.ExportACPDebug(ctx, execution.ACPSessionID, maxBytes)
|
|
if err != nil {
|
|
release()
|
|
return nil, err
|
|
}
|
|
if body == nil {
|
|
release()
|
|
return nil, fmt.Errorf("ACP debug export returned no body")
|
|
}
|
|
return &releaseOnCloseReadCloser{ReadCloser: body, release: release}, nil
|
|
}
|