mirror of
https://github.com/stablyai/orca.git
synced 2026-10-07 08:02:21 +00:00
Merge branch 'nwparker/omp-child-history-resume' into nwparker/omp-nested-history
This commit is contained in:
@@ -27,7 +27,7 @@ import {
|
||||
} from './ai-vault-session-projects'
|
||||
import {
|
||||
resolveAiVaultSessionResumeActions,
|
||||
resolveAiVaultSessionResumeState
|
||||
resolveAiVaultHistorySessionResumeState
|
||||
} from './ai-vault-session-resume'
|
||||
import { useAiVaultSessionLaunchActions } from './ai-vault-session-launch-actions'
|
||||
import type { AiVaultResumeInChatEligibility } from './ai-vault-session-resume-in-chat'
|
||||
@@ -263,9 +263,8 @@ export default function AiVaultPanel(): React.JSX.Element {
|
||||
|
||||
const getSessionResumeState = useCallback(
|
||||
(session: AiVaultSession) =>
|
||||
resolveAiVaultSessionResumeState({
|
||||
sessionFilePath: session.filePath,
|
||||
sessionExecutionHostId: session.executionHostId,
|
||||
resolveAiVaultHistorySessionResumeState({
|
||||
session,
|
||||
worktreeInfo: getSessionWorktreeInfo(session),
|
||||
activeWorktreeId: effectiveActiveWorktreeId,
|
||||
worktrees: allWorktrees,
|
||||
|
||||
@@ -15,6 +15,7 @@ import { translate } from '@/i18n/i18n'
|
||||
import { parseWorkspaceKey } from '../../../../shared/workspace-scope'
|
||||
import {
|
||||
canJumpToAiVaultSessionWorktree,
|
||||
resolveAiVaultSessionWorktreeInfo,
|
||||
type AiVaultSessionWorktreeInfo
|
||||
} from './ai-vault-session-worktree'
|
||||
|
||||
@@ -85,6 +86,32 @@ export function resolveAiVaultSessionResumeState(args: {
|
||||
}
|
||||
}
|
||||
|
||||
export function resolveAiVaultHistorySessionResumeState(
|
||||
args: Omit<
|
||||
Parameters<typeof resolveAiVaultSessionResumeState>[0],
|
||||
'sessionFilePath' | 'sessionExecutionHostId'
|
||||
> & {
|
||||
session: AiVaultSession
|
||||
}
|
||||
): AiVaultSessionResumeState {
|
||||
const child = Boolean(args.session.subagent)
|
||||
return resolveAiVaultSessionResumeState({
|
||||
...args,
|
||||
sessionFilePath: args.session.filePath,
|
||||
sessionExecutionHostId: args.session.executionHostId,
|
||||
worktreeInfo: child
|
||||
? resolveAiVaultSessionWorktreeInfo({
|
||||
session: args.session,
|
||||
worktrees: args.worktrees,
|
||||
repos: args.repos,
|
||||
activeWorktreeId: args.activeWorktreeId
|
||||
})
|
||||
: args.worktreeInfo,
|
||||
// Lazy children are absent from the panel map; never resume them in an unrelated active workspace.
|
||||
activeWorktreeId: child ? null : args.activeWorktreeId
|
||||
})
|
||||
}
|
||||
|
||||
export function resolveAiVaultSessionResumeActions(args: {
|
||||
sessionFilePath: string | null
|
||||
sessionExecutionHostId?: AiVaultSession['executionHostId'] | null
|
||||
|
||||
@@ -235,3 +235,58 @@ describe('useAiVaultSessionWorktreeMap', () => {
|
||||
expect(elapsedMs).toBeLessThan(150)
|
||||
})
|
||||
})
|
||||
|
||||
import { resolveAiVaultHistorySessionResumeState } from './ai-vault-session-resume'
|
||||
|
||||
describe('lazy OMP child resume targets', () => {
|
||||
it.each([worktreeA.id, worktreeB.id, null])(
|
||||
'keeps child and grandchild in their own worktree with active %s',
|
||||
(activeWorktreeId) => {
|
||||
const parent = makeSession({ agent: 'omp', id: 'omp:parent', cwd: worktreeA.path })
|
||||
const { result } = renderHook(() =>
|
||||
useAiVaultSessionWorktreeMap({ sessions: [parent], repos, worktrees })
|
||||
)
|
||||
for (const id of ['child', 'grandchild']) {
|
||||
const session = makeSession({
|
||||
agent: 'omp',
|
||||
id,
|
||||
cwd: worktreeA.path,
|
||||
subagent: { parentSessionId: parent.sessionId, agentType: null, status: null }
|
||||
})
|
||||
expect(result.current.has(id)).toBe(false)
|
||||
const target = resolveAiVaultHistorySessionResumeState({
|
||||
session,
|
||||
worktreeInfo: result.current.get(id) ?? null,
|
||||
activeWorktreeId,
|
||||
worktrees,
|
||||
repos
|
||||
})
|
||||
expect(target).toEqual({
|
||||
blocked: false,
|
||||
worktreeId: worktreeA.id,
|
||||
usesSessionWorktree: true
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
it.each([{ cwd: null }, { cwd: '/missing' }, { executionHostId: 'ssh:other' as const }])(
|
||||
'refuses unmatched child %j instead of active-workspace fallback',
|
||||
(overrides) => {
|
||||
const session = makeSession({
|
||||
agent: 'omp',
|
||||
cwd: worktreeA.path,
|
||||
subagent: { parentSessionId: 'parent', agentType: null, status: null },
|
||||
...overrides
|
||||
})
|
||||
expect(
|
||||
resolveAiVaultHistorySessionResumeState({
|
||||
session,
|
||||
worktreeInfo: null,
|
||||
activeWorktreeId: worktreeB.id,
|
||||
worktrees,
|
||||
repos
|
||||
})
|
||||
).toEqual({ blocked: true, worktreeId: null, usesSessionWorktree: false })
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user