Skip to content

fix: deterministic provider selection + error logging for Party Mode#175

Open
duhd-vnpay wants to merge 2 commits intonextlevelbuilder:feat/party-modefrom
duhd-vnpay:fix/party-mode-provider
Open

fix: deterministic provider selection + error logging for Party Mode#175
duhd-vnpay wants to merge 2 commits intonextlevelbuilder:feat/party-modefrom
duhd-vnpay:fix/party-mode-provider

Conversation

@duhd-vnpay
Copy link

Summary

Fixes two bugs in Party Mode that caused silent round failures:

  1. Empty model string → proxy 502: registerProvidersFromDB default case created NewOpenAIProvider(..., "") without reading default_model from the provider's settings JSONB. When Party Mode's llmCall sets no model, resolveModel("") returns "", and the upstream proxy returns 502 for an empty model field.

  2. Non-deterministic provider selection: getEngine() used names[0] from providerReg.List(), which returns Go map keys in random iteration order. With multiple providers registered (e.g. cli-proxy-api from DB + gemini from config), the wrong provider could be selected on each request.

  3. Silent error swallowing: handleRound sent errors to the WebSocket client but never logged them server-side, making debugging impossible.

Changes

cmd/gateway_providers.go

  • Add extractDefaultModel(settings json.RawMessage) helper that reads default_model from provider settings JSONB
  • Default case now passes defaultModel to NewOpenAIProvider instead of ""

internal/gateway/methods/party.go

  • getEngine() now prefers providers with non-empty DefaultModel(), breaks ties alphabetically for determinism
  • handleRound logs slog.Error("party: round failed", ...) before sending error response

Test plan

  • E2E tests: 9/9 Party Mode tests passing (TC1-TC8 + auth setup)
  • Manual test: wget with "model":"" → 502; with "model":"claude-sonnet-4-6" → 200

🤖 Generated with Claude Code

duhd-vnpay and others added 2 commits March 13, 2026 16:56
- gateway_providers: read default_model from provider settings JSONB
  instead of passing empty string (caused proxy 502 for empty model)
- party.go getEngine(): prefer providers with DefaultModel set,
  alphabetical fallback to avoid Go map random iteration order
- party.go handleRound: log slog.Error before sending error to client
  (round failures were silently swallowed server-side)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Frontend was dropping history/summary from backend response and
resetting messages to empty on session select. Also aligned all
RPC params/events with snake_case wire format (Go json tags).

- transformSession: preserve _history/_summary from backend
- hydrateMessages: convert RoundResult[] to PartyMessage[]
- selectSession: hydrate messages instead of resetting to []
- All WS calls use snake_case field names matching Go structs

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant