Files
m e935aadc94
CI / test (push) Failing after 20s
CI / test (pull_request) Failing after 18s
feat: connect agent worker to execution bridge
2026-08-22 15:53:44 +03:00

62 lines
1.8 KiB
Go

package agentbridge
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"strings"
"git.cin.su/m/Assistant/contracts/work"
)
var ErrUnavailable = errors.New("agent execution bridge unavailable")
type HTTPExecutor struct {
URL string
Client *http.Client
}
func NewHTTPExecutor(url string, client *http.Client) (*HTTPExecutor, error) {
url = strings.TrimSpace(url)
if url == "" || !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") {
return nil, ErrUnavailable
}
if client == nil {
client = http.DefaultClient
}
return &HTTPExecutor{URL: strings.TrimRight(url, "/"), Client: client}, nil
}
func (e *HTTPExecutor) Execute(ctx context.Context, request work.AgentExecutionRequest) (work.AgentExecutionResult, error) {
body, err := json.Marshal(request)
if err != nil {
return work.AgentExecutionResult{}, err
}
httpRequest, err := http.NewRequestWithContext(ctx, http.MethodPost, e.URL+"/v1/execute", bytes.NewReader(body))
if err != nil {
return work.AgentExecutionResult{}, err
}
httpRequest.Header.Set("Content-Type", "application/json")
response, err := e.Client.Do(httpRequest)
if err != nil {
return work.AgentExecutionResult{}, fmt.Errorf("%w: %v", ErrUnavailable, err)
}
defer response.Body.Close()
if response.StatusCode < 200 || response.StatusCode >= 300 {
return work.AgentExecutionResult{}, fmt.Errorf("%w: status=%s", ErrUnavailable, response.Status)
}
decoder := json.NewDecoder(io.LimitReader(response.Body, 1<<20))
var result work.AgentExecutionResult
if err := decoder.Decode(&result); err != nil {
return work.AgentExecutionResult{}, err
}
if result.State == "" || result.Summary == "" || result.ObservedAtUnixMillis < 1 {
return work.AgentExecutionResult{}, errors.New("agent execution bridge returned invalid result")
}
return result, nil
}