mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-14 10:18:42 +00:00
fix(providers): iterate tool-call accumulators by map, not index
ChatStream parsed the tool-call accumulator map with a positional loop
(for i := 0; i < len(accumulators); i++ { acc := accumulators[i] }),
assuming OpenAI-compatible providers always emit contiguous zero-based
tc.Index values in streamed delta.tool_calls.
Some OpenAI-compatible gateways (observed with a self-hosted point-p1
proxy) emit non-contiguous or non-zero-based indices. When that
happens accumulators[i] misses a populated key and returns a nil
*toolCallAccumulator, and the next line dereferences acc.rawArgs on
that nil pointer, causing a SIGSEGV panic. The panic kills the
in-flight chat run's goroutine; the gateway's tracing safety-net logs
'finalizing orphan trace' and the user's message goes unanswered.
Fix: range over the accumulators map directly instead of indexing by
position, and skip nil entries defensively.
Verified: built a full backend image (make build-full equivalent,
CGO_ENABLED=0 go build -tags embedui) from this branch, deployed it
against a real point-p1-backed agent, and confirmed multiple
multi-tool-call turns (use_skill, read_file, exec x3) that previously
triggered the panic now complete via v3.run.completed with no panic
and no safety-net trace.
This commit is contained in:
1 parent
169e0bafaf
commit
db9600054c
1 file changed
+9
-3
@@ -195,9 +195,15 @@ func (p *OpenAIProvider) ChatStream(ctx context.Context, req ChatRequest, onChun
|
||||
return result, fmt.Errorf("%s: stream read error: %w", p.name, err)
|
||||
}
|
||||
|
||||
// Parse accumulated tool call arguments
|
||||
for i := 0; i < len(accumulators); i++ {
|
||||
acc := accumulators[i]
|
||||
// Parse accumulated tool call arguments.
|
||||
// Iterate the map directly (not 0..len(accumulators)-1): providers are not
|
||||
// guaranteed to emit contiguous zero-based tc.Index values in delta.ToolCalls,
|
||||
// so indexing by position can miss populated slots and hit a nil accumulator,
|
||||
// causing a nil-pointer panic (observed with the point-p1/9router provider).
|
||||
for _, acc := range accumulators {
|
||||
if acc == nil {
|
||||
continue
|
||||
}
|
||||
args := make(map[string]any)
|
||||
if err := json.Unmarshal([]byte(acc.rawArgs), &args); err != nil && acc.rawArgs != "" {
|
||||
slog.Warn("openai_stream: failed to parse tool call arguments",
|
||||
|
||||
Reference in new issue
Block a user