mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-18 09:54:35 +08:00
feat: add streaming support for x402 payment flow to bypass Cloudflare timeout
- Extract ParseSSEStream as shared function from CallWithRequestStream - Add DoX402RequestStream and X402CallStream for streaming x402 payments - Switch Claw402Client.Call to use streaming (X402CallStream) - TeeReader fallback: SSE parsing with JSON fallback for non-SSE responses - Idle timeout watchdog (90s) protects against stalled streams
This commit is contained in:
@@ -687,15 +687,27 @@ func (client *Client) CallWithRequestStream(req *Request, onChunk func(string))
|
||||
return "", fmt.Errorf("API error (status %d): %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
var accumulated strings.Builder
|
||||
scanner := bufio.NewScanner(resp.Body)
|
||||
|
||||
for scanner.Scan() {
|
||||
// Ping the watchdog: we received a line, reset the idle timer.
|
||||
return ParseSSEStream(resp.Body, onChunk, func() {
|
||||
select {
|
||||
case resetCh <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// ParseSSEStream reads an SSE response body, accumulates text deltas,
|
||||
// and calls onChunk with the full accumulated text after each chunk.
|
||||
// If onLine is non-nil, it is called after each raw SSE line is scanned
|
||||
// (useful for resetting idle-timeout watchdogs).
|
||||
// Returns the complete accumulated text.
|
||||
func ParseSSEStream(body io.Reader, onChunk func(string), onLine func()) (string, error) {
|
||||
var accumulated strings.Builder
|
||||
scanner := bufio.NewScanner(body)
|
||||
|
||||
for scanner.Scan() {
|
||||
if onLine != nil {
|
||||
onLine()
|
||||
}
|
||||
|
||||
line := scanner.Text()
|
||||
if !strings.HasPrefix(line, "data: ") {
|
||||
@@ -706,7 +718,6 @@ func (client *Client) CallWithRequestStream(req *Request, onChunk func(string))
|
||||
break
|
||||
}
|
||||
|
||||
// Parse the SSE JSON chunk
|
||||
var chunk struct {
|
||||
Choices []struct {
|
||||
Delta struct {
|
||||
|
||||
Reference in New Issue
Block a user