-
Notifications
You must be signed in to change notification settings - Fork 0
fix: wire Firestore client and memory store into main.go (#126) #129
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,9 +11,11 @@ import ( | |
| "github.com/Two-Weeks-Team/missless/internal/auth" | ||
| "github.com/Two-Weeks-Team/missless/internal/config" | ||
| "github.com/Two-Weeks-Team/missless/internal/live" | ||
| "github.com/Two-Weeks-Team/missless/internal/memory" | ||
| "github.com/Two-Weeks-Team/missless/internal/retry" | ||
| "github.com/Two-Weeks-Team/missless/internal/scene" | ||
| "github.com/Two-Weeks-Team/missless/internal/session" | ||
| "github.com/Two-Weeks-Team/missless/internal/store" | ||
| "github.com/gorilla/websocket" | ||
| "google.golang.org/genai" | ||
| ) | ||
|
|
@@ -58,13 +60,13 @@ func newUpgrader(cfg *config.Config) websocket.Upgrader { | |
| } | ||
|
|
||
| // RegisterWebSocket registers the WebSocket endpoint for browser ↔ Go proxy. | ||
| func RegisterWebSocket(mux *http.ServeMux, cfg *config.Config, sessions *auth.SessionStore) { | ||
| func RegisterWebSocket(mux *http.ServeMux, cfg *config.Config, sessions *auth.SessionStore, sessionStore *store.FirestoreStore, memStore *memory.Store) { | ||
| mux.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) { | ||
| handleWebSocket(w, r, cfg, sessions) | ||
| handleWebSocket(w, r, cfg, sessions, sessionStore, memStore) | ||
| }) | ||
| } | ||
|
|
||
| func handleWebSocket(w http.ResponseWriter, r *http.Request, cfg *config.Config, sessions *auth.SessionStore) { | ||
| func handleWebSocket(w http.ResponseWriter, r *http.Request, cfg *config.Config, sessions *auth.SessionStore, sessionStore *store.FirestoreStore, memStore *memory.Store) { | ||
| // Protection: Origin check (in upgrader) + rate limiter + connection limit. | ||
| // Session auth is NOT required here because the onboarding flow connects | ||
| // the WebSocket before the user completes OAuth login. | ||
|
|
@@ -87,7 +89,12 @@ func handleWebSocket(w http.ResponseWriter, r *http.Request, cfg *config.Config, | |
| activeWSConns.Add(1) | ||
| defer activeWSConns.Add(-1) | ||
|
|
||
| slog.Info("websocket_connected", "remote", r.RemoteAddr, "active_ws", activeWSConns.Load()) | ||
| slog.Info("websocket_connected", | ||
| "remote", r.RemoteAddr, | ||
| "active_ws", activeWSConns.Load(), | ||
| "has_session_store", sessionStore != nil, | ||
| "has_memory_store", memStore != nil, | ||
| ) | ||
|
|
||
| ctx, cancel := context.WithCancel(r.Context()) | ||
| defer cancel() | ||
|
|
@@ -114,6 +121,9 @@ func handleWebSocket(w http.ResponseWriter, r *http.Request, cfg *config.Config, | |
| toolHandler := live.NewToolHandler() | ||
| toolHandler.SetGenerator(sceneGen) | ||
| toolHandler.SetGenaiClient(client) | ||
| if memStore != nil { | ||
| toolHandler.SetMemoryStore(memStore, "") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The The |
||
| } | ||
|
|
||
| // Connect to Live API with onboarding config and retry | ||
| liveConfig := mgr.BuildOnboardingConfig() | ||
|
|
@@ -155,6 +165,20 @@ func handleWebSocket(w http.ResponseWriter, r *http.Request, cfg *config.Config, | |
| cancel() | ||
| proxy.Close() | ||
|
|
||
| // Persist session state to Firestore on disconnect. | ||
| if sessionStore != nil { | ||
| saveCtx, saveCancel := context.WithTimeout(context.Background(), 3*time.Second) | ||
| defer saveCancel() | ||
| sd := &store.SessionData{ | ||
| PersonaName: mgr.PersonaName(), | ||
| MatchedVoice: mgr.MatchedVoice(), | ||
| State: string(mgr.State()), | ||
|
Comment on lines
+173
to
+175
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Useful? React with 👍 / 👎. |
||
| } | ||
|
Comment on lines
+172
to
+176
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The session state being persisted to Firestore is incomplete. It's missing fields like This could lead to inconsistent state if the session is restored later. Consider saving all relevant session data. Note that sd := &store.SessionData{
PersonaName: mgr.PersonaName(),
State: string(mgr.State()),
MatchedVoice: mgr.MatchedVoice(),
ReunionCount: mgr.ReunionCount(),
} |
||
| if err := sessionStore.SaveSession(saveCtx, mgr.SessionID(), sd); err != nil { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The session is persisted under Useful? React with 👍 / 👎. |
||
| slog.Warn("session_persist_failed", "error", err) | ||
| } | ||
| } | ||
|
|
||
| shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 5*time.Second) | ||
| defer shutdownCancel() | ||
| mgr.Shutdown(shutdownCtx) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
recall_memorywill never return results from the injected store because this initialization hard-codes an empty persona ID. InhandleRecallMemory(internal/live/tools.go), the handler returns an empty memory list wheneverpid == "", so any memories saved under real persona keys (for example from analysis) are unreachable at runtime even thoughmemStoreis present.Useful? React with 👍 / 👎.