[codex] Fix profile-aware session deep links (#962)

* feat: add session deep links for chats

* feat: add deep links for history and group chat

* Fix profile-aware session deep links

---------

Co-authored-by: Maxim Kirilyuk <werserk@inbox.ru>
This commit is contained in:
ekko
2026-05-24 10:55:55 +08:00
committed by GitHub
parent 8d261c3fa6
commit df41d6b051
22 changed files with 871 additions and 63 deletions
+21 -10
View File
@@ -15,6 +15,7 @@ export interface StartRunRequest {
input: string | ContentBlock[]
instructions?: string
session_id?: string
profile?: string
model?: string
provider?: string
model_groups?: Array<{ provider: string; models: string[] }>
@@ -77,6 +78,7 @@ export interface RunEvent {
let chatRunSocket: Socket | null = null
let globalListenersRegistered = false
let chatRunSocketProfile: string | null = null
/**
* Session event handlers map
@@ -429,29 +431,36 @@ export function getChatRunSocket(): Socket | null {
return chatRunSocket
}
export function connectChatRun(): Socket {
if (chatRunSocket?.connected) return chatRunSocket
export function connectChatRun(requestedProfile?: string | null): Socket {
const normalizedRequestedProfile = requestedProfile?.trim() || null
if (chatRunSocket?.connected && (!normalizedRequestedProfile || chatRunSocketProfile === normalizedRequestedProfile)) {
return chatRunSocket
}
// Clean up old socket to prevent duplicate event listeners
if (chatRunSocket) {
chatRunSocket.removeAllListeners()
chatRunSocket.disconnect()
globalListenersRegistered = false
chatRunSocketProfile = null
}
const baseUrl = getBaseUrlValue()
const token = getApiKey()
// Get active profile from store (authoritative source)
let profile = 'default'
let profile = normalizedRequestedProfile || 'default'
try {
const { useProfilesStore } = require('@/stores/hermes/profiles')
const profilesStore = useProfilesStore()
profile = profilesStore.activeProfileName || 'default'
if (!normalizedRequestedProfile) {
const { useProfilesStore } = require('@/stores/hermes/profiles')
const profilesStore = useProfilesStore()
profile = profilesStore.activeProfileName || 'default'
}
} catch {
// Fallback to localStorage during early initialization
profile = localStorage.getItem('hermes_active_profile_name') || 'default'
profile = normalizedRequestedProfile || localStorage.getItem('hermes_active_profile_name') || 'default'
}
chatRunSocketProfile = profile
chatRunSocket = io(`${baseUrl}/chat-run`, {
auth: { token },
@@ -506,6 +515,7 @@ export function disconnectChatRun(): void {
if (chatRunSocket) {
chatRunSocket.disconnect()
chatRunSocket = null
chatRunSocketProfile = null
globalListenersRegistered = false
sessionEventHandlers.clear()
}
@@ -533,11 +543,12 @@ function removeSocketListener(socket: Socket, event: string, handler: (...args:
export function resumeSession(
sessionId: string,
onResumed: (data: { session_id: string; messages: any[]; isWorking: boolean; isAborting?: boolean; events: any[]; inputTokens?: number; outputTokens?: number; contextTokens?: number; queueLength?: number; queueMessages?: RunEvent['queued_messages'] }) => void,
profile?: string | null,
): Socket {
const socket = connectChatRun()
const socket = connectChatRun(profile)
socket.once('resumed', onResumed)
socket.emit('resume', { session_id: sessionId })
socket.emit('resume', { session_id: sessionId, ...(profile ? { profile } : {}) })
return socket
}
@@ -555,7 +566,7 @@ export function startRunViaSocket(
}
let closed = false
const socket = connectChatRun()
const socket = connectChatRun(body.profile)
const handleSocketError = (err: Error) => {
if (closed) return
closed = true
+7 -3
View File
@@ -62,10 +62,11 @@ export async function fetchSessions(source?: string, limit?: number, profile?: s
/**
* Fetch Hermes sessions only (exclude api_server source)
*/
export async function fetchHermesSessions(source?: string, limit?: number): Promise<SessionSummary[]> {
export async function fetchHermesSessions(source?: string, limit?: number, profile?: string | null): Promise<SessionSummary[]> {
const params = new URLSearchParams()
if (source) params.set('source', source)
if (limit) params.set('limit', String(limit))
if (profile) params.set('profile', profile)
const query = params.toString()
const res = await request<{ sessions: SessionSummary[] }>(`/api/hermes/sessions/hermes${query ? `?${query}` : ''}`)
return res.sessions
@@ -82,9 +83,12 @@ export async function searchSessions(q: string, source?: string, limit?: number,
return res.results
}
export async function fetchSession(id: string): Promise<SessionDetail | null> {
export async function fetchSession(id: string, profile?: string | null): Promise<SessionDetail | null> {
try {
const res = await request<{ session: SessionDetail }>(`/api/hermes/sessions/${id}`)
const params = new URLSearchParams()
if (profile) params.set('profile', profile)
const query = params.toString()
const res = await request<{ session: SessionDetail }>(`/api/hermes/sessions/${id}${query ? `?${query}` : ''}`)
return res.session
} catch {
return null