Add Seriatim trim adapter support
This commit is contained in:
@@ -111,11 +111,11 @@ func (r *SubprocessRunner) Run(ctx context.Context, req MergeRequest) (MergeResu
|
||||
return MergeResult{}, fmt.Errorf("seriatim report is enabled but report path is missing")
|
||||
}
|
||||
|
||||
args := r.buildArgs(req)
|
||||
args := r.buildMergeArgs(req)
|
||||
env := r.buildEnvOverrides()
|
||||
|
||||
if req.GeneratedConfigPath != "" {
|
||||
if err := r.writeInvocationConfig(req, args); err != nil {
|
||||
if err := r.writeMergeInvocationConfig(req, args); err != nil {
|
||||
return MergeResult{}, fmt.Errorf("write seriatim invocation config %q: %w", req.GeneratedConfigPath, err)
|
||||
}
|
||||
}
|
||||
@@ -188,7 +188,90 @@ func (r *SubprocessRunner) Run(ctx context.Context, req MergeRequest) (MergeResu
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *SubprocessRunner) buildArgs(req MergeRequest) []string {
|
||||
// Trim executes Seriatim trim with deterministic flags and validates output artifacts.
|
||||
func (r *SubprocessRunner) Trim(ctx context.Context, req TrimRequest) (TrimResult, error) {
|
||||
if r == nil {
|
||||
return TrimResult{}, fmt.Errorf("seriatim subprocess runner is nil")
|
||||
}
|
||||
if strings.TrimSpace(req.InputTranscriptPath) == "" {
|
||||
return TrimResult{}, fmt.Errorf("seriatim trim input path is required")
|
||||
}
|
||||
if strings.TrimSpace(req.OutputTrimmedPath) == "" {
|
||||
return TrimResult{}, fmt.Errorf("seriatim trim output path is required")
|
||||
}
|
||||
if strings.TrimSpace(req.KeepSelector) == "" {
|
||||
return TrimResult{}, fmt.Errorf("seriatim trim keep selector is required")
|
||||
}
|
||||
|
||||
binary := r.binary
|
||||
if strings.TrimSpace(req.Binary) != "" {
|
||||
binary = strings.TrimSpace(req.Binary)
|
||||
}
|
||||
|
||||
timeout := r.timeout
|
||||
if req.Timeout < 0 {
|
||||
return TrimResult{}, fmt.Errorf("seriatim trim timeout must be >= 0")
|
||||
}
|
||||
if req.Timeout > 0 {
|
||||
timeout = req.Timeout
|
||||
}
|
||||
|
||||
args := buildTrimArgs(req)
|
||||
if req.GeneratedConfigPath != "" {
|
||||
if err := writeTrimInvocationConfig(req, args, binary, timeout); err != nil {
|
||||
return TrimResult{}, fmt.Errorf("write seriatim trim invocation config %q: %w", req.GeneratedConfigPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
runRes, err := subprocess.Run(ctx, subprocess.RunRequest{
|
||||
Executable: binary,
|
||||
Args: args,
|
||||
Timeout: timeout,
|
||||
StdoutLogPath: req.StdoutLogPath,
|
||||
StderrLogPath: req.StderrLogPath,
|
||||
})
|
||||
if err != nil {
|
||||
return TrimResult{
|
||||
OutputTrimmedPath: req.OutputTrimmedPath,
|
||||
StdoutLogPath: req.StdoutLogPath,
|
||||
StderrLogPath: req.StderrLogPath,
|
||||
GeneratedConfigPath: req.GeneratedConfigPath,
|
||||
ExitCode: runRes.ExitCode,
|
||||
Duration: runRes.Duration,
|
||||
InvokedBinary: binary,
|
||||
KeepSelector: req.KeepSelector,
|
||||
}, fmt.Errorf("run seriatim trim (binary=%q): %w", binary, err)
|
||||
}
|
||||
|
||||
if err := validateJSONFileWithSegments(req.OutputTrimmedPath); err != nil {
|
||||
return TrimResult{
|
||||
OutputTrimmedPath: req.OutputTrimmedPath,
|
||||
StdoutLogPath: req.StdoutLogPath,
|
||||
StderrLogPath: req.StderrLogPath,
|
||||
GeneratedConfigPath: req.GeneratedConfigPath,
|
||||
ExitCode: runRes.ExitCode,
|
||||
Duration: runRes.Duration,
|
||||
InvokedBinary: binary,
|
||||
KeepSelector: req.KeepSelector,
|
||||
}, fmt.Errorf("validate seriatim trimmed output %q: %w", req.OutputTrimmedPath, err)
|
||||
}
|
||||
|
||||
return TrimResult{
|
||||
OutputTrimmedPath: req.OutputTrimmedPath,
|
||||
StdoutLogPath: req.StdoutLogPath,
|
||||
StderrLogPath: req.StderrLogPath,
|
||||
GeneratedConfigPath: req.GeneratedConfigPath,
|
||||
ExitCode: runRes.ExitCode,
|
||||
Duration: runRes.Duration,
|
||||
InvokedBinary: binary,
|
||||
KeepSelector: req.KeepSelector,
|
||||
Metadata: map[string]any{
|
||||
"adapter": "seriatim_subprocess",
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (r *SubprocessRunner) buildMergeArgs(req MergeRequest) []string {
|
||||
args := []string{"merge"}
|
||||
|
||||
for _, path := range req.InputTranscriptPaths {
|
||||
@@ -234,10 +317,11 @@ func (r *SubprocessRunner) buildEnvOverrides() map[string]string {
|
||||
return out
|
||||
}
|
||||
|
||||
func (r *SubprocessRunner) writeInvocationConfig(req MergeRequest, args []string) error {
|
||||
func (r *SubprocessRunner) writeMergeInvocationConfig(req MergeRequest, args []string) error {
|
||||
payload := map[string]any{
|
||||
"schema": "seriatim.generated.v1",
|
||||
"binary": r.binary,
|
||||
"command": "merge",
|
||||
"args": args,
|
||||
"timeout": r.timeout.String(),
|
||||
"output_schema": r.outputSchema,
|
||||
@@ -261,6 +345,29 @@ func (r *SubprocessRunner) writeInvocationConfig(req MergeRequest, args []string
|
||||
return subprocess.WriteYAMLAtomic(req.GeneratedConfigPath, payload, 0o644)
|
||||
}
|
||||
|
||||
func buildTrimArgs(req TrimRequest) []string {
|
||||
return []string{
|
||||
"trim",
|
||||
"--input-file", req.InputTranscriptPath,
|
||||
"--output-file", req.OutputTrimmedPath,
|
||||
"--keep", req.KeepSelector,
|
||||
}
|
||||
}
|
||||
|
||||
func writeTrimInvocationConfig(req TrimRequest, args []string, binary string, timeout time.Duration) error {
|
||||
payload := map[string]any{
|
||||
"schema": "seriatim.generated.v1",
|
||||
"command": "trim",
|
||||
"binary": binary,
|
||||
"args": args,
|
||||
"timeout": timeout.String(),
|
||||
"input_path": req.InputTranscriptPath,
|
||||
"output_path": req.OutputTrimmedPath,
|
||||
"keep_selector": req.KeepSelector,
|
||||
}
|
||||
return subprocess.WriteYAMLAtomic(req.GeneratedConfigPath, payload, 0o644)
|
||||
}
|
||||
|
||||
func validateJSONFile(path string) error {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
@@ -272,3 +379,24 @@ func validateJSONFile(path string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func validateJSONFileWithSegments(path string) error {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read file: %w", err)
|
||||
}
|
||||
|
||||
var payload map[string]any
|
||||
if err := json.Unmarshal(data, &payload); err != nil {
|
||||
return fmt.Errorf("parse json: %w", err)
|
||||
}
|
||||
|
||||
segments, ok := payload["segments"]
|
||||
if !ok {
|
||||
return fmt.Errorf("top-level segments is required")
|
||||
}
|
||||
if _, ok := segments.([]any); !ok {
|
||||
return fmt.Errorf("top-level segments must be an array")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user