mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
feat(codex): import and resume sessions from runners (#1088)
* fix codex import resume flow * fix hub restart session active state * fix codex transcript workspace scoping * Address Codex import review findings * Fix Codex import machine selection * Update Codex sessions error test * Address Codex import review findings * Preserve forked Codex session id on sync * Make Codex duplicate cleanup source-aware * Handle Codex archive failures * Limit existing session flag to Codex * Preserve Codex import machine binding * fix: rebase runner Codex import onto current main * fix: preserve runner-scoped Codex import behavior --------- Co-authored-by: syy <815728149@qq.com>
This commit is contained in:
@@ -126,6 +126,58 @@ export const CursorChatStoreStatusSchema = z.object({
|
||||
|
||||
export type CursorChatStoreStatus = z.infer<typeof CursorChatStoreStatusSchema>
|
||||
|
||||
export const CodexImportedMessageSchema = z.union([
|
||||
z.object({
|
||||
role: z.literal('user'),
|
||||
content: z.object({ type: z.literal('text'), text: z.string() }),
|
||||
meta: z.object({ sentFrom: z.literal('cli') })
|
||||
}),
|
||||
z.object({
|
||||
role: z.literal('agent'),
|
||||
content: z.object({ type: z.literal('codex'), data: z.unknown() }),
|
||||
meta: z.object({ sentFrom: z.literal('cli') })
|
||||
})
|
||||
])
|
||||
|
||||
export const CodexLocalSessionSummarySchema = z.object({
|
||||
id: z.string().min(1),
|
||||
title: z.string(),
|
||||
lastUserMessage: z.string().nullable().optional(),
|
||||
cwd: z.string().nullable().optional(),
|
||||
file: z.string().min(1),
|
||||
modifiedAt: z.number(),
|
||||
originator: z.string().nullable().optional(),
|
||||
cliVersion: z.string().nullable().optional(),
|
||||
source: z.string().nullable().optional(),
|
||||
threadSource: z.string().nullable().optional(),
|
||||
forkedFromId: z.string().nullable().optional()
|
||||
})
|
||||
|
||||
export const CodexLocalSessionWithMessagesSchema = CodexLocalSessionSummarySchema.extend({
|
||||
messages: z.array(CodexImportedMessageSchema)
|
||||
})
|
||||
|
||||
export const ListCodexSessionsRpcRequestSchema = z.object({
|
||||
cwd: z.string().nullable().optional(),
|
||||
sessionIds: z.array(z.string().min(1)).optional()
|
||||
})
|
||||
|
||||
export const ListCodexSessionsRpcResponseSchema = z.union([
|
||||
z.object({ success: z.literal(true), sessions: z.array(z.union([CodexLocalSessionSummarySchema, CodexLocalSessionWithMessagesSchema])) }),
|
||||
z.object({ success: z.literal(false), error: z.string() })
|
||||
])
|
||||
|
||||
export const ArchiveCodexSessionRpcRequestSchema = z.object({ sessionId: z.string().min(1) })
|
||||
export const ArchiveCodexSessionRpcResponseSchema = z.union([
|
||||
z.object({ success: z.literal(true), archivedPath: z.string() }),
|
||||
z.object({ success: z.literal(false), error: z.string() })
|
||||
])
|
||||
|
||||
export type ListCodexSessionsRpcRequest = z.infer<typeof ListCodexSessionsRpcRequestSchema>
|
||||
export type ListCodexSessionsRpcResponse = z.infer<typeof ListCodexSessionsRpcResponseSchema>
|
||||
export type ArchiveCodexSessionRpcRequest = z.infer<typeof ArchiveCodexSessionRpcRequestSchema>
|
||||
export type ArchiveCodexSessionRpcResponse = z.infer<typeof ArchiveCodexSessionRpcResponseSchema>
|
||||
|
||||
export const SessionCollaborationModeRequestSchema = z.object({
|
||||
mode: CodexCollaborationModeSchema
|
||||
})
|
||||
|
||||
@@ -27,6 +27,8 @@ export const RPC_METHODS = {
|
||||
ListSlashCommands: 'listSlashCommands',
|
||||
ListSkills: 'listSkills',
|
||||
ListCodexModels: 'listCodexModels',
|
||||
ListCodexSessions: 'listCodexSessions',
|
||||
ArchiveCodexSession: 'archiveCodexSession',
|
||||
ListCursorModels: 'listCursorModels',
|
||||
ListPiModels: 'listPiModels',
|
||||
ListOpencodeModels: 'listOpencodeModels',
|
||||
|
||||
@@ -35,6 +35,9 @@ export const MetadataSchema = z.object({
|
||||
machineId: z.string().optional(),
|
||||
claudeSessionId: z.string().optional(),
|
||||
codexSessionId: z.string().optional(),
|
||||
// 原始 Codex thread id。导入 Codex 历史后,HAPI 会 fork 出自己的续写 thread;
|
||||
// codexSessionId 保存 fork 后的 thread,codexSourceSessionId 保留来源 thread 便于同步/展示。
|
||||
codexSourceSessionId: z.string().optional(),
|
||||
geminiSessionId: z.string().optional(),
|
||||
opencodeSessionId: z.string().optional(),
|
||||
grokSessionId: z.string().optional(),
|
||||
|
||||
@@ -59,6 +59,7 @@ export type SessionSummary = {
|
||||
/** Epoch ms of the soonest uninvoked future scheduled message, or null. */
|
||||
nextScheduledAt: number | null
|
||||
model: string | null
|
||||
modelReasoningEffort?: string | null
|
||||
effort: string | null
|
||||
}
|
||||
|
||||
@@ -146,6 +147,7 @@ export function toSessionSummary(session: Session): SessionSummary {
|
||||
futureScheduledMessageCount: 0,
|
||||
nextScheduledAt: null,
|
||||
model: session.model,
|
||||
modelReasoningEffort: session.modelReasoningEffort,
|
||||
effort: session.effort
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user